Modern systems maintain multiple independent certificate trust stores — one for the OS, and separate ones for each browser. install-ca handles all of them in a single run on Linux (Debian/Ubuntu) and Windows, so a custom CA is trusted everywhere without manual per-store setup.
- Accepts a CA certificate as a URL or local file path — or prompts interactively
- Derives the CA name and filename automatically from the certificate subject
- Compares the certificate against any existing installation before making changes — reports fingerprint, expiry, and whether an update is needed
- Exits early without changes if the certificate is already up-to-date (override with
-f) - Prompts for confirmation before each store is modified (suppress with
-y) - Verifies the installation at the end
| Platform | Script | Requirements |
|---|---|---|
install-ca.sh |
bash, curl, openssl, sudo, libnss3-tools (auto-installed if missing) |
|
install-ca.ps1 |
Windows 10+, PowerShell 5.1+, Administrator privileges |
| Browser | 🐧 Linux | 🪟 Windows |
|---|---|---|
| Google Chrome | Shared NSS ~/.pki/nssdb |
Windows Certificate Store¹ |
| Chromium | Shared NSS ~/.pki/nssdb (deb) · snap NSS ~/snap/chromium/ |
Windows Certificate Store¹ |
| Microsoft Edge | Shared NSS ~/.pki/nssdb |
Windows Certificate Store¹ |
| Brave | Shared NSS ~/.pki/nssdb (deb) · snap NSS ~/snap/brave/ (snap) |
Windows Certificate Store¹ |
| Firefox | Per-profile cert9.db (~/.mozilla/firefox/ · ~/snap/firefox/) |
Per-profile cert9.db via certutil.exe |
¹
LocalMachine\Root— one write covers all Chromium-based browsers on Windows.The shared NSS database
~/.pki/nssdbis created automatically on Linux if it does not exist.
| Flag | Long form | Description |
|---|---|---|
-u <url-or-path> |
--url <url-or-path> |
Certificate URL or local file path |
-y |
--yes |
Auto-approve all prompts |
-f |
--force |
Reinstall even if the certificate is already up-to-date |
Interactive — prompts for the certificate URL or file path:
curl -fsSL https://raw.githubusercontent.com/IlmLV/install-ca/main/install-ca.sh | bashNon-interactive — certificate URL and auto-approve provided upfront:
curl -fsSL https://raw.githubusercontent.com/IlmLV/install-ca/main/install-ca.sh | bash -s -- https://example.com/ca.crt -y
sudois required for writing to/usr/local/share/ca-certificates/. The script will prompt for your password at that step.
Interactive — prompts for the certificate URL or file path:
irm https://raw.githubusercontent.com/IlmLV/install-ca/main/install-ca.ps1 | iexNon-interactive — certificate URL and auto-approve provided upfront:
irm https://raw.githubusercontent.com/IlmLV/install-ca/main/install-ca.ps1 | iex; Install 'https://example.com/ca.crt' -yRequires Windows 10+, PowerShell 5.1+, and Administrator privileges.
Before modifying any trust store, the script checks whether the certificate is already installed:
- Fetches or copies the certificate from the provided source
- Validates it is a well-formed certificate (PEM on Linux; PEM or DER where supported by the platform implementation)
- Looks up any existing certificate with the same subject in the system trust store
- Compares SHA-256 fingerprints and expiry dates, and reports one of:
- Already up-to-date — exits without changes
- Remote is newer — recommends update, proceeds to install
- Installed is newer — warns that the remote cert expires sooner than what is installed
- Fresh install — no existing certificate found
The certificate is copied to /usr/local/share/ca-certificates/<derived-name>.crt and registered with update-ca-certificates. The filename is derived automatically from the certificate's Common Name (CN).
NSS (cert9.db) databases are located by scanning known directories for each browser. Each discovered database is listed before the user is asked to confirm. The CA is added using certutil from the libnss3-tools package.
The certificate is added to LocalMachine\Root using the .NET X509Store API. This single store is read by all Chromium-based browsers on Windows.
Firefox maintains its own NSS databases independent of the OS store. All profiles under the standard Firefox profile directory are discovered and listed. On Linux, certutil from libnss3-tools is used. On Windows, certutil.exe bundled with the Firefox installation is used.
install-ca/
├── install-ca.sh # Bash script for Linux
├── install-ca.ps1 # PowerShell script for Windows
└── tests/
├── run-tests.sh # Runs Docker-containerized test suites
├── linux.bats # Bats test suite for install-ca.sh
├── windows.ps1 # Pester test suite for install-ca.ps1
├── Dockerfile.debian # Debian test container image
├── Dockerfile.ubuntu # Ubuntu test container image
├── docker-linux-setup.sh # Installs browsers and tooling inside the test container
├── entrypoint.linux.sh # Container entry point — runs cert generation and Bats suite
├── generate-certs.sh # Generates test certificates at runtime (Bash)
└── generate-certs.ps1 # Generates test certificates at runtime (PowerShell)
Requires Docker.
# Run all suites (Debian + Ubuntu)
bash tests/run-tests.sh
# Run a specific suite
bash tests/run-tests.sh linux-ubuntu
bash tests/run-tests.sh linux-debianRequires Pester and PowerShell 5.1+.
Invoke-Pester tests/windows.ps1This project is licensed under the MIT License.