SSL certificate authority

From wikinotes

You can be your own certificate-authority,
which allows you to create signed certificates that are trusted on your local network.

NOTE:

This is a general overview, see openssl for more details, and up to date commands.


Tutorials

root CA SAN CSR https://www.golinuxcloud.com/openssl-subject-alternative-name/
stackexchange rootCA SAN https://security.stackexchange.com/questions/74345/provide-subjectaltname-to-openssl-directly-on-the-command-line
arch wiki https://wiki.archlinux.org/index.php/OpenSSL
openssl cert authority https://deliciousbrains.com/ssl-certificate-authority-for-local-https-development/
openssl cert authority (IIS) https://medium.com/@tbusser/creating-a-browser-trusted-self-signed-ssl-certificate-2709ce43fd15
python cert authority https://opensource.com/article/19/4/certificate-authority
ruby cert authority https://docs.ruby-lang.org/en/master/OpenSSL/X509/Certificate.html

Notes

Create CA key

# create private key (w/ pass)
openssl genpkey -aes256 -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out CA.key

# create root cert (CN is how you will identify pem)
openssl req -x509 -new -nodes \
  -key CA.key \
  -sha256 \
  -days 3650 `# 10 yrs` \
  -out CA.pem

Create a SAN cert for website

subject-alternative-name (SAN) certificates can be mapped to ip-addresses rather than domain names.
This is useful on small local networks, where you probably aren't running a DNS server.

# create website prvkey
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out website.key

Create file with CSR details.

# ./my.website.cnf
[req]
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[req_distinguished_name]
C   = CA
ST  = Ontario
L   = Ottawa
O   = ${ORGANIZATION}           # ex: 'my-ssid'
OU  = ${DESCRIPTION-OF-SERVER}  # ex: 'wiki'
CN  = ${HOSTNAME}               # ex: servername.local
[req_ext]
subjectAltName = @alt_names
[alt_names]
IP.1 = 192.168.1.111            # ip addr of server
DNS.1 = 192.168.1.1             # nameserver from /etc/resolv.conf

Create CSR

openssl req -new -key website.key -out website.csr -config server_cert.cnf

Configure Cert Creation

# ./my.website.csr.cnf

basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
IP.1 = 192.168.1.111            # ip addr of server
DNS.1 = 192.168.1.1             # nameserver from /etc/resolv.conf

Create certificate from CSR

# sign CSR
openssl x509 -req \
  -in website.com.csr \
  -CA CA.pem \
  -CAkey CA.key \
  -CAcreateserial \
  -out website.com.crt \
  -days 365 \
  -sha256 \
  -extfile my.website.csr.cnf

Create a wildcard cert for website

A wildcard certificate lets you authorize multiple subdomains using the same certificate.

TODO:

learn

Add certificate to OS keychain

Add to OS'es where you want to access the website.
See OpenSSL - Trust a Root CA cert.

Verify Certificate

# check cert is trusted (according to your OS trusted CA certs)
openssl verify website.crt  

# check cert is trusted by target CA
openssl verify -CAfile CA.pem website.crt