How to setup nginx requiring client certificates for authentication.
This is based on the articles from arcwebtech and Victor Barzin.
Assumption: everything is stored at /usr/local/etc/ca
This is just an example and probably not a good one.
Save this at /usr/local/etc/ca/ca.conf
:
[ ca ]
default_ca = CA_default # The name of the CA configuration to be used.
# can be anything that makes sense to you.
[ CA_default ]
dir = /usr/local/etc/ca # Directory where everything is kept
certs = $dir/certs # Directory where the issued certs are kept
crl_dir = $dir/crl # Directory where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several certificates with same subject.
new_certs_dir = $dir/certs # Default directory for new certs.
certificate = $dir/ca.crt # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # The current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/ca.key # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha1 # use public key default MD
preserve = no # keep passed DN ordering
policy = policy_match
[req]
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
C = US
ST = IL
L = City
mkdir /usr/local/etc/ca/certs
mkdir /usr/local/etc/ca/certs/users
mkdir /usr/local/etc/ca/crl
mkdir /usr/local/etc/ca/private
touch /etc/ssl/ca/index.txt
echo ’01’ > /etc/ssl/ca/crlnumber
openssl genrsa -des3 -out /usr/local/etc/ca/private/ca.key 4096
openssl req -config /usr/local/etc/ca/ca.conf \
-new -x509 -days 1095 \
-key /usr/local/etc/ca/private/ca.key \
-out /usr/local/etc/ca/certs/ca.crt
openssl ca -config /usr/local/etc/ca/ca.conf \
-name CA_default -gencrl \
-keyfile /usr/local/etc/ca/private/ca.key \
-cert /usr/local/etc/ca/certs/ca.crt \
-out /usr/local/etc/ca/private/ca.crl \
-crldays 1095
Please Note:
openssl genrsa -des3 -out /usr/local/etc/ca/certs/users/<USERNAME>.key 1024
openssl req -new \
-key /usr/local/etc/ca/certs/users/<USERNAME>.key \
-out /usr/local/etc/ca/certs/users/<USERNAME>.csr
openssl x509 -req \
-days 1095 \
-in /usr/local/etc/ca/certs/users/<USERNAME>.csr \
-CA /usr/local/etc/ca/certs/ca.crt \
-CAkey /usr/local/etc/ca/private/ca.key \
-CAserial /usr/local/etc/ca/serial \
-CAcreateserial \
-out /usr/local/etc/ca/certs/users/<USERNAME>.crt
openssl pkcs12 \
-export \
-certfile /usr/local/etc/ca/certs/ca.crt \
-in /usr/local/etc/ca/certs/users/<USERNAME>.crt \
-inkey /usr/local/etc/ca/certs/users/<USERNAME>.key \
-out /usr/local/etc/ca/certs/users/<USERNAME>.p12
Transfer the created certificate /usr/local/etc/ca/certs/users/<USERNAME>.p12
to the client's machine and install it in their favorite browser(s).
openssl ca -config /usr/local/etc/ca/ca.conf \
-revoke /usr/local/etc/ca/certs/users/<USERNAME>.crt \
-keyfile /usr/local/etc/ca/private/ca.key \
-cert /usr/local/etc/ca/certs/ca.crt
openssl ca -config /usr/local/etc/ca/ca.conf \
-gencrl \
-keyfile /usr/local/etc/ca/private/ca.key \
-cert /usr/local/etc/ca/certs/ca.crt \
-out /usr/local/etc/ca/private/ca.crl \
-crldays 1095
This will take effect after the defined session time (see nginx config) or immediately after reloading the nginx config.
Do not remove the https cert definitions. These are still needed.
Add the following lines to the server
block:
[...]
ssl_client_certificate /etc/ssl/ca/certs/ca.crt;
ssl_crl /etc/ssl/ca/private/ca.crl;
ssl_verify_client on;
ssl_session_timeout 5m;
There is a method to make client verification optional and then check in child
blocks (like location
) for verification success, e.g. described here.