This configuration will setup an Nginx server that requires a valid client certificate for mutual tls. We'll cover some basic certificate setup, the nginx config, and some openssl conversions for browser certificate import.
openssl genrsa -out ca.key 4096
openssl req -new -x509 -key ca.key -out ca.crt
openssl genrsa -out server.key 4096
openssl rsa -in server.key -pubout -out server.pubkey
openssl req -new -key server.key -addext "subjectAltName = DNS:keyboardcrunch" -out server.csr
openssl x509 -req -in server.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -CAcreateserial -extfile <(printf "subjectAltName=DNS:keyboardcrunch") -out server.crt
openssl genrsa -out client1.key 4096
openssl req -new -key client1.key -addext "subjectAltName = DNS:keyboardcrunch" -out client1.csr
openssl x509 -req -in client1.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -CAcreateserial -extfile <(printf "subjectAltName=DNS:keyboardcrunch") -out client1.crt
This guide could be followed, but if you're using SmallStep they you've already created a CA so you just need to generate a server and client certificate and export the CA root cert.
# Generate a server certificate
step ca certificate "keyboardcrunch" server.crt server.key
# Generate a client certificate
step ca certificate "keyboardcrunch" client.crt client.key
# Export the CA Root certificate
step ca root ca.crt
Run the below command, choose a strong password when prompted. The browser will ask for this password when you import the p12 file.
openssl pkcs12 -export -in client1.crt -inkey client1.key -out browser.p12
This is a goofy example but it maps some short paths for redirects and secures all paths with mTLS through client cert validation by:
- Setting up an SSL only http server with server certs created from a CA.
- Enforces strict SSL connections.
- Defines the CA's cert for client validation.
- Uses ssl_verify_client on to ensure we only server pages for clients that present a valid certificate.
## Custom shortcut redirects
map $uri $redir {
/redirme https://google.com;
/twit https://twitter.com;
}
server {
## Require SSL, require valid client cert
listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
server_name keyboardcrunch;
ssl_certificate /etc/ssl/personal/server.crt;
ssl_certificate_key /etc/ssl/personal/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_client_certificate /etc/ssl/personal/ca.crt;
ssl_verify_client on;
## Rewrite our shortcuts for redirects
if ($redir) {
rewrite ^ $redir redirect;
}
## Still host payloads... I mean content.
root /var/www/html/;
## Allow directory navigation
autoindex on;
}