Sometimes you need to configure HTTPS for a web resource that works in a network without Internet access. It’s impossible to use Let’s Encrypt to issue a certificate. One solution is using your own certificate authority and sign certificates yourself.
Generate CA (Certificate Authority) key and certificate with a command:
openssl req -x509 -nodes \
-newkey RSA:2048 \
-keyout root-ca.key \
-days 3650 \
-out root-ca.crt \
-subj '/C=GB/ST=London/L=London/O=Home/CN=Home'
Copy root-ca.crt
to /usr/local/share/ca-certificates
and execute update-ca-certificates
. After
this action, utilities like curl
will trust certificates signed with a custom CA.
It’s required to add a new CA into your browser. In Firefox open Settings -> Privacy & Security,
find “View Certificates…” button and add root-ca.crt
.
Generate certificate with a command:
openssl x509 -req \
-CA root-ca.crt \
-CAkey root-ca.key \
-in example.com.csr \
-out example.com.crt \
-days 3650 \
-CAcreateserial \
-extfile <(printf "subjectAltName = DNS:example.com\nauthorityKeyIdentifier = keyid,issuer\nbasicConstraints = CA:FALSE\nkeyUsage = digitalSignature, keyEncipherment\nextendedKeyUsage=serverAuth")
As a result there are two files:
example.com.crt
— SSL certificate for domainexample.com
signed by custom CA;example.com.key
— the key for SSL certificate.
You can use this certificate with NGINX like this:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/certs/example.com.key;
location / {
return 200 'Hello world';
add_header Content-Type text/plain;
}
}