53

I want to add some root CAs that doesn't come with the default firefox on Ubuntu, but I don't know how.

I tried adding them to the local certificates with certutil, but it didn't work. It messed up my certificates database.

$ certutil -A -d .mozilla/firefox/kek3dogy.default/ -i /usr/local/share/ca-certificates/FNMT_ACRAIZ.crt -n "Certificado Raiz FNMT" -t "TCu,Cuw,Tuw"

and then

$ certutil -L -d .mozilla/firefox/kek3dogy.default/

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

Go Daddy Secure Certification Authority                      ,,   
VeriSign Class 3 Secure Server CA - G3                       ,,   
VeriSign Class 3 Extended Validation SSL CA                  ,,   
DigiCert High Assurance CA-3                                 ,,   
GlobalSign Domain Validation CA - G2                         ,,   
GeoTrust SSL CA                                              ,,   
StartCom Class 2 Primary Intermediate Server CA              ,,   
Google Internet Authority                                    ,,   
Certificado Raiz FNMT                                        CT,C,c
USERTrust Legacy Secure Server CA                            ,,   
HP Jetdirect 2B0EAD20                                        ,,   
Akamai Subordinate CA 3                                      ,,   
VeriSign, Inc.                                               ,,   
Thawte SGC CA                                                ,,   
VeriSign Class 3 Secure Server CA - G2                       ,,

The certificate won't show up on Firefox. I tried this several times, even deleting the profile, and it showed up once on the Firefox interface, but completely empty.

Anyways, that's only for a user, and I want to add them system-wide. Is there a system-wide database I can modify? How?

If there is no system-wide database I can modify, I can rely on a X start script (as /etc/X11/Xsession.d/ ones, or a script called by the xdg autostart system on /etc/xdg/autostart/) to modify the user profile at session start, but I need a solution that works. I can't even load certificates on the user profiles from the command line now!

  • Is editing the default profile an option (so that newly added certificates are added when a new profile is created, but old profiles are left unchanged)? – Andrea Corbellini Jan 27 '13 at 11:16
  • No, approximately +100 profiles already exist and new profiles are a rare thing. – Jorge Suárez de Lis Jan 27 '13 at 11:24
  • Can't you generate a new profile folder in Firefox's directory, and then add it to profiles.ini? Then you could add your changes to it, and then copy it and profiles.ini to each user directory. – Wilf Oct 30 '13 at 19:40
  • N.B. You can edit profiles for Firefox by running firefox -p - but you have to close Firefox first. – Wilf Oct 30 '13 at 20:11
  • Nope, there are +100 users with their own already existing profile. They won't like to lose their bookmarks, history, passwords, etc. – Jorge Suárez de Lis Nov 01 '13 at 23:05
  • Have you tried importing the certificates from within FF? – Mitch Nov 03 '13 at 12:25

12 Answers12

34

The problem here is that Firefox does not have a 'central' location where it looks for certificates. It just looks into the current profile. That's why modifying /usr/share/ca-certificates or other similar directories won't work with Firefox. This is something that has been requested for years; see issues 620373, 449498 and 454036 (and probably there are many others).

So you are left with just two kind of solutions: either modify each profile, or modify the behaviour of Firefox. I know this is not what you are looking for, but there are no ways because Firefox only looks at users' profiles.

Having said that, the solution I would choose is using hard or symbolic links, specifically I'd go with hardlinks. This solution is surely the easiest and probably the better, though I don't have enough information to judge.

What you have to do is basically removing each cert8.db and key3.db files for each profile and replace them with links to the "most complete" cert8.db and key3.db. If you go with hardlinks, the original cert8.db and key3.db will be indistinguishable from the new ones.

Remember to adjust permissions to fit your needs. Most likely, you will need to chmod a+rw so that everybody will be able to add/remove a certificate. If you want only certain users to be able to add/remove certificates, you can create a group, assign the two databases to that group and give +w permission just to the group.

  • Yup, same as I could come up with. It's a bit of a shame for Firefox, imo. – gertvdijk Jan 27 '13 at 18:06
  • But won't overwrite that the user certificates? Aren't the user certificates stored there? – Jorge Suárez de Lis Jan 27 '13 at 20:06
  • @JorgeSuárezdeLis: well, when you delete that files you will loose the certificates. If this is what you mean with "overwriting", then yes. You should first merge all the databases into one and then proceed creating the hardlinks. – Andrea Corbellini Jan 27 '13 at 21:54
  • But... I don't want one user to have the personal certificates of the others! I'm talking now about their certificates, not the certificate authorities. – Jorge Suárez de Lis Jan 27 '13 at 23:18
  • @JorgeSuárezdeLis: sorry, I can't understand: what are personal certificates? – Andrea Corbellini Oct 28 '13 at 17:07
  • The own personal user certificates (the ones on the first tab). Anyways, I don't know how to edit the certificates, because any attempt results on corrupted data. – Jorge Suárez de Lis Oct 29 '13 at 14:57
  • I'm still confused. I see what you mean with personal certificates, however I can't understand what they have to do with your question. In your question, I can see only the terms certificate authority and CA. Maybe it's just me who can't understand it, but please consider rewriting your question inserting the word personal at least once. – Andrea Corbellini Oct 29 '13 at 16:04
  • I think (maybe I'm wrong) that personal certificates are also stored on cert8.db and key3.db, so the problem is your answer. I can't just link the same files for all the people. Anyways, I CAN'T generate more complete files, because certutil mess up the databases. – Jorge Suárez de Lis Oct 31 '13 at 16:18
  • Jorge, I have re-read your question and this conversation and finally I got your point. The problem is that I misunderstood the meaning of "user certificates" in your first comment, hence the confusion. I'll think about a solution in the next days. – Andrea Corbellini Oct 31 '13 at 17:20
  • @AndreaCorbellini I would be very wary of suggesting making the shared db file across users R/W. I believe sqlite doesn't provide concurrent access, and I'm not sure if Firefox internally locks it with named mutexes (i.e. across processes). Plus if this file is on network location... good luck synchronizing this sqlite! My 2 cents: share it, but in R/O mode – Emanuele Jan 16 '16 at 10:52
  • Years is an understatement now. 7 years have passed since this answer was posted, and 2/3 of the linked issues are still open. Oldest linked issue is 12 years old now. – Zoran Pavlovic Dec 18 '19 at 08:54
19

The easiest way is to import the certificate into a sample firefox-profile and then copy the cert8.db to the users you want equip with the certificate.

First import the certificate by hand into the firefox profile of the sample-user. Then copy

/home/${USER}/.mozilla/firefox/${randomalphanum}.default/cert8.db

into the users firefox-profiles. That's it. If you want to make sure, that new users get the certificate automatically, copy cert8.db to:

/etc/firefox-3.0/profile

Here is an alternative way that doesn't override the existing certificates: [bash fragment for linux systems]

certificateFile="MyCa.cert.pem"
certificateName="MyCA Name" 
for certDB in $(find  ~/.mozilla* ~/.thunderbird -name "cert8.db")
do
  certDir=$(dirname ${certDB});
  #log "mozilla certificate" "install '${certificateName}' in ${certDir}"
 certutil -A -n "${certificateName}" -t "TCu,Cuw,Tuw" -i ${certificateFile} -d ${certDir}
done

You may find certutil in the libnss3-tools package (debian/ubuntu).

See also: Programmatic import of CA Certificate

Source: Programmatically Install Certificate into Mozilla

davelupt
  • 177
TomKat
  • 3,888
  • 1
    +1 but if you upvote this, you should perhaps also upvote the answers on StackOverflow which this was derived from. – tripleee Apr 25 '14 at 12:50
15

Found this solution to add certificates to firefox on ubuntu :

https://github.com/mozilla/policy-templates/#proxy

Simply need to add this file to :

/usr/lib/firefox/distribution/

touch policies.json

In policies.json add:

{
"policies": {
"Certificates": {
    "ImportEnterpriseRoots": true,
    "Install": [
               "somecert1.crt",
               "usr/local/share/ca-certificates/somecert1.crt"
               ]
         }
    }
}

The install part is first the name of the cert and then the path. And restart firefox. If something doesn't work try resetting firefox as if you have set something before it can stuck it.

This method works good without certutil.

  • Works fine, thanks – Onyr Jun 21 '22 at 15:05
  • https://github.com/mozilla/policy-templates/blob/master/README.md#policiesjson-15 – NicoKowe Nov 17 '22 at 16:24
  • The firefox policy docs recommend adding the policy.json file in the /etc/firefox/policies/ directory since the exact installation path may differ from distribution to distribution -- https://mozilla.github.io/policy-templates/ – sudormrfbin Oct 18 '24 at 09:18
14

Contrary to popular belief, you can get Firefox to look at the system certificates instead its own hard-coded set.

To do this, you will want to use a package called p11-kit. p11-kit provides a drop-in replacement for libnssckbi.so, the shared library that contains the hardcoded set of certificates. The p11-kit version instead reads the certificates from the system certificate store.

Since Firefox ships with its own version of libnssckbi.so, you'll need to track it down and replace it instead of the version provided in libnss3:

sudo mv /usr/lib/firefox/libnssckbi.so /usr/lib/firefox/libnssckbi.so.bak
sudo ln -s /usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-trust.so /usr/lib/firefox/libnssckbi.so

Next, delete the ~/.pki directory to get Firefox to refresh its certificate database (causing it to pull in the system certs) upon restarting Firefox. Note: this will delete any existing certificates in the store, so if have custom ones that you added manually, you might want to back up that folder and then re-import them.

wheeler
  • 752
  • 2
    Oh, wow, that's a bit of a hack, but +1. You may want to add a dpkg-divert step to avoid APT overwriting the file again when you upgrade Firefox package. – gertvdijk May 20 '18 at 14:06
  • @wheeler. Do you know if this still works? I've tried it with Ubuntu 18.04 and after I perform this Firefox won't load any of the certs at all. Have p11-kit 0.23.9-2 – Kevin Vasko Oct 22 '19 at 12:56
  • 1
    In Ubuntu 16.04 (32-bit) I successfully used /usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-proxy.so (with Firefox 52.6 ESR). This did not work in Ubuntu 20.04 (64-bit), here I used /usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-trust.so according to this answer (with Firefox 78.5 ESR) – user2149308 Nov 24 '20 at 14:18
  • Seems this trick isn't working on 24.04 – YamiYukiSenpai Jan 08 '25 at 14:37
4

Beginning with Firefox 64, Mozilla says, that an own "enterprise CA" can be imported from those system paths in Linux:

  • /usr/lib/mozilla/certificates
  • /usr/lib64/mozilla/certificates

Those paths do not exist by default in Ubuntu, but can be added manually.

Additionally, you have to name each certificate in the file /etc/firefox/policies/policies.json, so that it gets imported automatically:

{
    "policies": {
        "Certificates": {
            "ImportEnterpriseRoots": true,
            "Install": [
                "example.crt",
                "/specific/folder/another-example.crt"
            ]
       }
    }
}

In this case, a certificate file named "example.crt" in either of the named default directories will be added when firefox restarts.

As Batchen Regev showed in his answer, you can also point to a file with an absolute path. (This way the .NET core development server on linux is also adding the localhost certificate).

References:

minni
  • 171
  • 3
  • This seems like a nice and elegant solution, unfortunately, I couldn't make it work with Firefox 91.5.0esr on Debian 11. Is there an additional step to do besides adding the .pem certificates to /usr/lib/mozilla/certificates and settings security.enterprise_roots.enabled to true ? Is PEM (clear text) the right format to use ? Documentation on support.mozilla.org is unclear about that. – MoonSweep Jan 26 '22 at 11:53
  • @MoonSweep: I just tested this again, and it seams that not all files in those paths are imported automatically. You have to add them in the "Install" array of a policies.json file, just the way that Batchen Regev's answer describes here. I will update my answer on this. Thanks for the question! – minni Jan 29 '22 at 09:35
  • I just tried, and indeed, with the policies.json file, it works now. Thanks ! – MoonSweep Feb 14 '22 at 12:50
  • Does this still work for you? – adrelanos Jan 19 '23 at 18:05
  • https://github.com/mozilla/policy-templates/blob/master/README.md#certificates--importenterpriseroots "Note: This policy only works on Windows and macOS. For Linux discussion, see bug 1600509." – adrelanos Jan 19 '23 at 18:05
  • putting config in /etc/firefox/policies/policies.json worked for me – rhasti Jul 11 '23 at 12:27
  • I found that with the snap version of Firefox that you have to stick the certificate in /etc/firefox/policies/ (with the policy document using the full path) instead of /usr/lib/mozilla/certificates. Apparently the snap is not configured to properly use the normal folder location. – Compholio Jun 12 '24 at 18:02
  • The firefox policy docs recommend adding the policy.json file in the /etc/firefox/policies/ directory exactly because of discrepancies between distributions and package managers like snaps regarding install location of firefox -- https://mozilla.github.io/policy-templates/ – sudormrfbin Oct 18 '24 at 09:20
2

The answers here are mostly stale, and adding the Certificates->Install entry to policies.json did not work for me. However, the following did work for me with Firefox 129.0.2 on Ubuntu 24.04.1. It is also part of their most recent official documentation on the matter, which conspicuously omits the Certificates section of the json file.

  1. Confirm you have p11-kit installed with which p11-kit. Install it if missing with sudo apt install p11-kit (should be unnecessary as it comes with Ubuntu 24.04.1).
  2. Run p11-kit list-modules to find the path to the library module p11-kit-trust. On my machine, it's /usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-trust.so.
  3. Create the file (and path, if missing) /etc/firefox/policies/policies.json.
  4. Add the following to it:
    {
      "policies": {
        "SecurityDevices": {
          "p11-kit-trust": "/usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-trust.so"
        }
      }
    }
    
    Save and close.
  5. Restart Firefox.

It should now see any certificates you added to the main store. For a quick refresher on how to do that, see here.

Here is a BASH script to do it all the above steps (except installing the certs) in one fell swoop:

#!/bin/bash

Check if the script is run as root

if [ "$EUID" -ne 0 ]; then echo "Please run as root (e.g., using sudo)." exit 1 fi

Step 1: Confirm p11-kit is installed

echo "Checking if p11-kit is installed..." if ! command -v p11-kit &>/dev/null; then echo "p11-kit is not installed. Installing now..." apt update && apt install -y p11-kit else echo "p11-kit is already installed." fi

Step 2: Locate the p11-kit-trust module

echo "Locating p11-kit-trust module..." P11_TRUST_MODULE=$(p11-kit list-modules | grep -Eo '/.*/p11-kit-trust.so' | head -n 1)

if [ -z "$P11_TRUST_MODULE" ]; then echo "p11-kit-trust module not found. Please verify your p11-kit installation." exit 1 else echo "Found p11-kit-trust module at: $P11_TRUST_MODULE" fi

Step 3: Create the Firefox policies.json file

POLICIES_DIR="/etc/firefox/policies" POLICIES_FILE="$POLICIES_DIR/policies.json"

echo "Creating Firefox policies configuration..." mkdir -p "$POLICIES_DIR"

cat >"$POLICIES_FILE" <<EOL { "policies": { "SecurityDevices": { "p11-kit-trust": "$P11_TRUST_MODULE" } } } EOL

echo "Firefox policies.json file has been created at $POLICIES_FILE."

Step 4: Restart Firefox message

echo echo "Configuration complete! Please restart Firefox for the changes to take effect."

exit 0

And a one-liner of the above to paste into terminal, if that's your preferred route:

sudo bash -c 'apt install -y p11-kit && P11_TRUST_MODULE=$(p11-kit \
list-modules | grep -Eo "/.*/p11-kit-trust\.so" | head -n 1) && mkdir -p \
/etc/firefox/policies && echo -e \
"{\n\t\"policies\": {\n\t\t\"SecurityDevices\": {\n\t\t\t\"p11-kit-trust\": \"$P11_TRUST_MODULE\"\n\t\t}\n\t}\n}" \
> /etc/firefox/policies/policies.json && echo \
"Configuration complete! Restart Firefox to apply changes."'
2

I found out that most of the time and by default if not configured otherwise Firefox uses legacy security databases (cert8.db, key3.db, and secmod.db) that means you will need to use a different command line to inject the certificate into the correct database that Firefox use. (see more from the man of certutil)

so if your system uses the default data base the command should go like this: (dbm)

certutil -A -n "Description Name" -t "CT,C,C" -d dbm:/home/<username>/.mozilla/firefox/<default folder>/ -i certificate.crt

otherwise it should be like this: (sql)

certutil -A -n "Description Name" -t "CT,C,C" -d sql:/home/<username>/.mozilla/firefox/<default folder>/ -i certificate.crt

from man certutil:

-d [prefix]directory
Specify the database directory containing the certificate and key
database files.

certutil supports two types of databases: the legacy security databases
(cert8.db, key3.db, and secmod.db) and new SQLite databases (cert9.db,
key4.db, and pkcs11.txt).

NSS recognizes the following prefixes:

·   sql: requests the newer database

·   dbm: requests the legacy database

If no prefix is specified the default type is retrieved from
NSS_DEFAUL
  • Using my .pem files with the first certutil command worked. I was looking for automating a single-user setup script and this does the trick. You'll need to apt-get install libnss3-tools to have certutil. – xificurC Jul 06 '16 at 14:05
1

TL;DR: Create a policy file (/etc/firefox/policies/policy.json) with the following contents:

{
  "policies": {
    "Certificates": {
      "Install": ["/path/to/cert.pem", "/path/to/cert2.der"]
    }
  }
}

Firefox 120+ on Windows and MacOS loads certificates from the system trust store, but unfortunately such a mechanism does not exist on Linux.

On Firefox 64+, we can use a policy to circumvent this issue, but it does not automatically import certificates from the system store; they have to be specified manually. It involves creating a policy.json file:

On Linux, the file goes into firefox/distribution, where firefox is the installation directory for Firefox, which varies by distribution or you can specify system-wide policy by placing the file in /etc/firefox/policies/.

Note that if you're using Firefox ESR, the path may be /etc/firefox-esr/policies.

We can now use the Certificates | Install policy to specify certificates to be added to Firefox. The template is:

{
  "policies": {
    "Certificates": {
      "Install": ["cert1.der", "/home/username/cert2.pem"]
    }
  }
}

If only the filename is provided, Firefox will search the following directories for it:

  • /usr/lib/mozilla/certificates/
  • /usr/lib64/mozilla/certificates/
  • ~/.mozilla/certificates/

An absolute path can also be used from Firefox 65+.


Reference: https://mozilla.github.io/policy-templates/#certificates--install

1

One of the features of the CCK Wizard Firefox add-on is importing CA certs. I use this add-on to create a custom add-on that includes a company CA Cert. I then package the custom xpi in a .deb on the internal repository that all the workstations get updates from.

CCK Wizard

EDIT: In order to package the xpi for Ubuntu, you need to create a package that includes the directory /usr/lib/firefox-addons/extensions/[addon-name@servername] and unzip the entire contents of the xpi into this directory. For instance if you name your addon foobarbaz and the server you have it set to update from (if you were to enable that function) is intranet.example.com, then the directory would be foobarbaz@intranet.example.com. I never enable the auto update, but instead update the deb in the repo.

  • I prefer this method over the others because it is self-contained and can include a ton of other customizations in one place. The author seems to have removed his extension from AMO though. Now he has it on his own site here, and the latest xpi is here. – Amit Naidu Dec 31 '15 at 20:42
1

Firefox works after a clean installation. If certificate database in cert8.db is deleted, it is regenerated on next Firefox start. This strongly suggests that there is a system-wide default storage of CA certs.

Firefox's source code shows that built-in CA certs are in fact hard-coded into firefox executable. They reside in security/nss/lib/ckfw/builtins/certdata.txt

So there is no way to install a certificate system-wide. Beware that patching source code may bring up issues with intellectual property rights.

yanychar
  • 652
1

I am using a "User Environment Virtualization" (UEV) application that does this for my users, but you can do this with logon scripts in Windows clients just the same. I won't post all of the code to dynamically find the %APPDATA%\Mozilla\Firefox\%PROFILE% path, but when you do find it, you can import the scripts using some basic commands. I am basically reading the Firefox profiles.ini file to determine the path to the Firefox profile/cert8.db.

You may want to look at using the certutil.exe application. https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/tools/NSS_Tools_certutil

You can run logon scripts for users that automatically imports the trusted certs from a central location into the Firefox of all users on the system.

Here is the "core" of my certificate import vb script:

If Instr(strLine,"Path=Profiles/") Then
  arrLine = Split(strLine, "/")
  strProfile = strAppData & "\Mozilla\Firefox\Profiles\" & arrLine(1)
  strCertDB = strProfile & "\cert8.db"

  'Verify the DB exists, if not move to the next entry
  If objFSO.FileExists(strCertDB) Then
    'Run certutil command on this database
    strCertCommand1 = "\\SERVERNAME\SHARENAME$\certs\certutil\certutil.exe -A " &_
    "-n MYCA -t ""CT,C,C"" -d " & strProfile & " -i \\SERVERNAME\SHARENAME$\certs\MYCA_Root.cer"

    strCertCommand2 = "\\SERVERNAME\SHARENAME$\certs\certutil\certutil.exe -A " &_
    "-n MYSECONDCA -t ""CT,C,C"" -d " & strProfile & " -i \\SERVERNAME\SHARENAME$\certs\SecondCA_Root.cer"

    strCertCommand3 = "\\SERVERNAME\SHARENAME$\certs\certutil\certutil.exe -A " &_
    "-n MYTHIRDCA -t ""CT,C,C"" -d " & strProfile & " -i \\SERVERNAME\SHARENAME$\certs\ThirdCA_Root.cer"

    'Run the import commands for this Firefox profile
    objShell.Run("%comspec% /c " & strCertCommand1),0,TRUE
    objShell.Run("%comspec% /c " & strCertCommand2),0,TRUE
    objShell.Run("%comspec% /c " & strCertCommand3),0,TRUE
0

For Firefox run with Snap

I spent a lot of time trying every answer here, but didnt have any luck until I read Compoholio's comment which was hidden away. I also think this is the simplest and cleanest solution.

First, read the official firefox instructions, specifically for "Use policies to import CA certificates"...

However...

When running firefox with snap, it cannot read out of the /usr/lib/firefox directory. So instead, put the cert in /etc/firefox/policies along with policies.json. You may need to create this directory yourself.

Then write your policies.json to point to the cert file, along with the ImportEnterpriseRoots key set to true, as shown below:

{
    "policies": {
        "Certificates": {
            "ImportEnterpriseRoots": true,
            "Install": [
                "/etc/firefox/policies/example.crt"
            ]
       }
    }
}