Generating a self signed server certificate for HTTPS security is easy enough but having your own certificate authority (CA) to sign with means you to only have to import one certificate to your devices for trust. This is the process i followed to generate my own root CA certificate and server certificates for HTTPS security on my internal network.

Generating a root CA certificate

First create a new root CA key and certificate pair. You only need to create the key once, the cert has a life of 3650 days (or 10 years). Keep the output files safe. These files are used when signing your new server certificates.

The below commands generates a root CA certificate we will use for the example home.lan domain. Edit the CN=home.lan part to match your own domain.

In order to import the CA on android 11 you need the following option in file ca.conf:

basicConstraints=CA:true
openssl genrsa -out homelan_rootCA.key 2048
openssl req -x509 -new -nodes -subj '/CN=home.lan' -key homelan_rootCA.key -sha256 -days 3650 -out homelan_rootCA.cert

?

openssl req -new -days 3650 -key homelan_rootCA.key -out homelan_rootCA.pem
openssl x509 -req -days 3650 -in homelan_rootCA.pem -signkey homelan_rootCA.key -extfile ./ca.conf -out CA.crt
openssl x509 -inform PEM -outform DER -in CA.crt -out CA.der.crt

output files:

  • homelan_rootCA.key
  • homelan_rootCA.cert

homelan_rootCA.cert is your CA certificate. This is the file you import into your devices for trust. Put it on your servers, desktops and mobile devices.

Generating a new server key and certificate request

This will generate the private key and certificate signing pair for a demonstration nginx server known as www.home.lan. The certificate has a life of 365 days.

openssl req -new -nodes -subj '/CN=www.home.lan' -days 365 -newkey rsa:4096 -sha256 -keyout www.key -out www.csr

output files

  • www.key
  • www.csr

Sign with the custom root CA

Sign the certificate request in the previous step with the root CA generated at the beginning of this process.

First create the extra info file www_csr.cnf with the following content to add a subject alt name.

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = www.home.lan

Now complete the request with the following command.

openssl x509 -req -in www.csr -CA homelan_rootCA.cert -CAkey homelan_rootCA.key -CAcreateserial -out www.crt -days 365 -sha256 -extfile www_csr.cnf

Nginx setup

Copy the files to your nginx ssl directory appending the root ca cert to the cert bundle.

cp www.crt /etc/nginx/ssl/www.crt
cat homelan_rootCA.cert >> /etc/nginx/ssl/www.crt
cp www.key /etc/nginx/ssl/www.key

Nginx config

Configure your server block to include server name and certificates.

server { 
...
server_name          www.home.lan;
ssl_certificate     /etc/nginx/ssl/www.crt;
ssl_certificate_key /etc/nginx/ssl/www.key;
...
}

Conclusion

This process allows you to self sign server certificates on private networks. You will need to keep your root ca certificate and private key safe and import the root CA certificate in keychains on devices to pass security warnings for trust.