Become a Certificate Authority and sign your own certificates.
Based on scripts found at https://stackoverflow.com/questions/7580508/getting-chrome-to-accept-self-signed-localhost-certificate
Before you start:
- You need a real or fake hostname (like
mypc.example.com) that points to the server. You can set this up using your hosts file or some form of DNS.
./create_certificate_authority.py --help- Be sure to encrypt the private key, and store the password in a proper password manager.
- You can do this once, and generate many certificates from the one CA.
- Any client that has the CA will trust all certificates generated by the CA.
./create_certificate.py --help- You will need the password of the private key of the CA.
- Wildcard names only match one DNS label.
*.ts.netmatchesfoo.ts.net, but it does not matchfoo.tail123456.ts.net.- Browsers do not accept multi-label wildcards like
*.*.ts.net.
Some programs use the OS certificate store (e.g. curl, firefox)
while others use an application-specific store (e.g. chrome, chromium).
Some can be configured to use another store, and some cannot.
Normally, the CA file ends with .pem and the certificate file ends with .crt. However, Ubuntu wants the CA file to end in .crt. Don’t get confused between these two files!
- Make a link to your CA in /usr/local/share/ca-certificates
ln -s /path/to/caname_ca.pem /usr/local/share/ca-certificates/caname_ca.crt
- Update your CA Store
sudo update-ca-certificates
Chromium-based browsers do not use Ubuntu's CA store for locally installed roots.
They use an NSS Shared DB instead.
This also applies to Chromium/Electron-based desktop applications such as Codex/ChatGPT.
Since Chromium M146, the default location is ~/.local/share/pki/nssdb,
but Chromium continues to use the legacy ~/.pki/nssdb when it already exists.
See Chromium's Linux certificate management documentation.
Flatpak applications have a separate data directory.
Consequently, Flatpak Chrome uses its own NSS database at ~/.var/app/com.google.Chrome/data/pki/nssdb.
Install the NSS command-line tools:
sudo apt install libnss3-toolsThen run the following, replacing the CA path and nickname. Reusing the nickname makes certificate rotation idempotent; only the certificate with that exact nickname is replaced.
ca_file=/absolute/path/to/caname_ca.pem
ca_nickname='caname CA'
update_nss_ca() {
local nss_dir=$1
mkdir -p "$nss_dir"
if [ ! -f "$nss_dir/cert9.db" ]; then
certutil -N --empty-password -d "sql:$nss_dir"
fi
certutil -D -d "sql:$nss_dir" -n "$ca_nickname" 2>/dev/null || true
certutil -A -d "sql:$nss_dir" -n "$ca_nickname" -t 'C,,' -i "$ca_file"
}
if [ -d "$HOME/.pki/nssdb" ]; then
chromium_nss_dir="$HOME/.pki/nssdb"
else
chromium_nss_dir="$HOME/.local/share/pki/nssdb"
fi
update_nss_ca "$chromium_nss_dir"
if flatpak info com.google.Chrome >/dev/null 2>&1; then
flatpak_chrome_nss_dir="$HOME/.var/app/com.google.Chrome/data/pki/nssdb"
update_nss_ca "$flatpak_chrome_nss_dir"
fiRestart Chromium, Chrome, Codex, and other Chromium/Electron applications after updating the NSS databases. You can verify an import with:
certutil -L -d "sql:$chromium_nss_dir" -n "$ca_nickname"For Chrome on Windows, see https://blog.eldernode.com/install-root-certificate-in-chrome/
See https://support.mozilla.org/en-US/kb/setting-certificate-authorities-firefox
In your site config, e.g. at /etc/nginx/sites-enables/mysite, replacing 443 with your preferred port, and tld
with the same domain name for which you generated the certificate:
server {
listen 443 ssl;
server_name tld;
ssl_certificate "/path/to/tld.crt";
ssl_certificate_key "/path/to/tld.key";
...
}On the website's SSL tab, paste the contents of these files into the corresponding fields:
out/ca/domain/private.key→ SSL Keyout/ca/domain/request.csr→ SSL Requestout/ca/domain/certificate.crt→ SSL Certificateout/ca/root.pem→ SSL Bundle
Source: https://www.httpcs.com/en/help/certificats/tutorial/how-to-install-an-ssl-certificate-on-ispconfig
Here {{ .Values.crt | b64enc }} is helm syntax. If you are not using helm, replace this with the base64-encoded
contents of the corresponding files.
apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
name: my-certificate
namespace: my-app
data:
tls.crt: {{ .Values.crt | b64enc }} # From `out/ca/domain/certificate.crt`
tls.key: {{ .Values.key | b64enc }} # From `out/ca/domain/private.key`Alternatively, you can generate the above snippet using kubectl:
kubectl create secret tls --helpkubectl create secret tls my-certificate --key out/ca/domain/private.key --cert out/ca/domain/certificate.crt --dry-run=client --output=yaml This assumes you are using the nginx ingress controller.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
namespace: my-app
spec:
tls:
- hosts:
- mypc.example.com # This has to be one of the domains passed to `create_certificate.py`.
secretName: my-certificateYou can generate a root CA and give it to cert-manager to have certificates automatically generated for you Kubernetes
ingresses. Then you don't need the create_certificate.py script.