create_ca_based_cert
This script will create a private key key.pem
and a certificate cert.pem
in the given directory ($PWD
if not given) based on a certificate authority.
The given directory will be created if it does not exit yet.
The optional second positive integer parameter (range: [1, 24855]) specifies the number of days the generated certificate is valid for; the default is 30 days.
The optional third parameter is the common name (localhost
if not given) of the certificate to be added.
The certificate created by this script is useful if you want to use mutual TLS or if the server’s certificate verifier does not support using a trust anchor as both a CA certificate and an end-entity certificate (e.g. rusttls). |
Chrome, Docker, Firefox, and Safari need no further configuration.
|
Ensure that the certificate authority has been created before executing this script. |
Ensure that the common name (set via the third parameter of this script) of the generated certificate has an entry in
/etc/hosts
⇓ /etc/hosts
|
Both If the given directory is inside a Git working tree the script will offer to modify the .gitignore file:
Related Script: git-cleanup |
Certificates with more than 180 days validity will not be accepted by the Apple platform or Safari. |
Copy this script (and its related create_ca, delete_ca, copy_ca_root_cert, copy, delete, renew, verify and scripts) into your Node.js project and add it as a custom script to your package.json
|
Usage
$ scripts/cert/create_ca_based_cert.sh
$ date -Idate
2024-08-05
$ stat -f '%A %N' *.pem
600 cert.pem
600 key.pem
$ openssl x509 -ext subjectAltName -noout -in cert.pem
X509v3 Subject Alternative Name:
DNS:localhost
$ openssl x509 -startdate -noout -in cert.pem
notBefore=Aug 5 14:48:36 2024 GMT
$ openssl x509 -enddate -noout -in cert.pem
notAfter=Sep 4 14:48:36 2024 GMT
$ scripts/cert/create_ca_based_cert.sh certs
$ scripts/cert/create_ca_based_cert.sh . 10
$ scripts/cert/create_ca_based_cert.sh ~/.local/secrets/certs/https.internal 30 https.internal
Examples
Apache HTTP Server
$ scripts/cert/create_ca.sh
$ scripts/cert/create_ca_based_cert.sh ~/.local/secrets/certs/localhost
$ docker run --rm httpd:2.4.63-alpine3.21 cat /usr/local/apache2/conf/httpd.conf >httpd.conf.orig
$ sed -e 's/^#\(Include .*httpd-ssl.conf\)/\1/' \
-e 's/^#\(LoadModule .*mod_ssl.so\)/\1/' \
-e 's/^#\(LoadModule .*mod_socache_shmcb.so\)/\1/' \
httpd.conf.orig >httpd.conf
$ mkdir -p htdocs
$ printf '<!doctype html><title>Test</title><h1>Test</h1>' >htdocs/index.html
$ docker run -i -t --rm -p 3000:443 \
-v "$PWD/htdocs:/usr/local/apache2/htdocs:ro" \
-v "$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro" \
-v "$HOME/.local/secrets/certs/localhost/cert.pem:/usr/local/apache2/conf/server.crt:ro" \
-v "$HOME/.local/secrets/certs/localhost/key.pem:/usr/local/apache2/conf/server.key:ro" \
httpd:2.4.63-alpine3.21
nginx
$ scripts/cert/create_ca.sh
$ scripts/cert/create_ca_based_cert.sh ~/.local/secrets/certs/localhost
$ printf 'server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
location / {
root /usr/share/nginx/html;
index index.html;
}
}' >nginx.conf
$ mkdir -p html
$ printf '<!doctype html><title>Test</title><h1>Test</h1>' >html/index.html
$ docker run -i -t --rm -p 3000:443 \
-v "$PWD/html:/usr/share/nginx/html:ro" \
-v "$PWD/nginx.conf:/etc/nginx/conf.d/default.conf:ro" \
-v "$HOME/.local/secrets/certs/localhost/cert.pem:/etc/ssl/certs/server.crt:ro" \
-v "$HOME/.local/secrets/certs/localhost/key.pem:/etc/ssl/private/server.key:ro" \
nginx:1.27.4-alpine3.21-slim
Go
$ cd scripts/cert/go/stdlib
$ ../../create_ca.sh
$ ../../create_ca_based_cert.sh
$ go run server.go
NodeJS
$ cd scripts/cert/js/nodejs
$ ../../create_ca.sh
$ ../../create_ca_based_cert.sh
$ node server.mjs
Java
$ cd scripts/cert/java/stdlib
$ ../../create_ca.sh
$ ../../create_ca_based_cert.sh
$ openssl pkcs12 -export -in cert.pem -inkey key.pem -out certificate.p12 -name localhost -password pass:changeit
$ keytool -importkeystore -srckeystore certificate.p12 -srcstoretype pkcs12 -srcstorepass changeit -destkeystore keystore.jks -deststorepass changeit
$ KEYSTORE_PATH=keystore.jks KEYSTORE_PASS=changeit java Server.java
Spring Boot
$ cd scripts/cert/java/spring-boot
$ ../../create_ca.sh
$ ../../create_ca_based_cert.sh
$ ./gradlew bootRun
Quarkus
Instead of using this script, you might want to use Quarkus' own certificate tooling. |
$ cd scripts/cert/java/quarkus
$ ../../create_ca.sh
$ ../../create_ca_based_cert.sh
$ ./gradlew quarkusDev