📜 ⬆️ ⬇️

Authorizing clients in nginx via SSL certificates

Introduction:


It took me here to somehow write a small API, in which it was necessary in addition to the usual requests to receive requests with a "high degree of secrecy."
I was not the first to encounter this and the world has long been using SSL for such things.

Since nginx is used on my server, the SSL module was installed
Google has not issued any workable howto, but the information on the network is in parts.

So, step by step guide on how to configure nginx to authorize clients through SSL certificates .

Attention! The article uses self-signed certificates for example!
')
Before starting, we will create a folder in the nginx config file, where the fruits of our labors will be:

cd /path/to/nginx/config/ mkdir ssl && cd ssl 


Step 1. Create your own self-signed trusted certificate.



A self-trusted certificate (Certificate Authority or CA) is required for signing client certificates and verifying them when a client is authorized by a web server.
The following command creates a private key and a self-signed certificate.

 openssl req -new -newkey rsa:1024 -nodes -keyout ca.key -x509 -days 500 -subj /C=RU/ST=Moscow/L=Moscow/O=Companyname/OU=User/CN=etc/emailAddress=support@site.com -out ca.crt 


Argument Description:

req Request to create a new certificate.
-new Create a certificate request (hereinafter referred to as CSR).
-newkey rsa: 1023 A new, closed 1024-bit RSA key will automatically be created. The length of the key can be customized at your discretion.
-nodes Do not encrypt the private key.
-keyout ca.key Save the private key to the ca.key file.
-x509 Instead of creating a CSR (see option -new) create a self-signed certificate.
-days 500 Certificate validity period 500 days. You can customize the size of the validity period. It is not recommended to enter small values, since with this certificate you will sign client certificates.
-subj /C=RU/ST=Moscow/L=Moscow/O=Companyname/OU=User/CN=etc/emailAddress=support@site.com
Certificate data, parameter = value pairs, are listed in '/'. Characters in the parameter value can be "podsecheny" using the backslash "\", for example, "O = My \ Inc". You can also take the argument value in quotes, for example, -subj "/ xx / xx / xx".

Step 2. Server Certificate


Create a certificate for nginx and request for it
 openssl genrsa -des3 -out server.key 1024 openssl req -new -key server.key -out server.csr 


We will sign the certificate with our own signature
 openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt 


So that nginx does not ask for a password when rebooting, we will make a passwordless copy of the certificate for it
 openssl rsa -in server.key -out server.nopass.key 


Nginx config

 listen *:443; ssl on; ssl_certificate /path/to/nginx/ssl/server.crt; ssl_certificate_key /path/to/nginx/ssl/server.nopass.key; ssl_client_certificate /path/to/nginx/ssl/ca.crt; ssl_verify_client on; keepalive_timeout 70; fastcgi_param SSL_VERIFIED $ssl_client_verify; fastcgi_param SSL_CLIENT_SERIAL $ssl_client_serial; fastcgi_param SSL_CLIENT_CERT $ssl_client_cert; fastcgi_param SSL_DN $ssl_client_s_dn; 


Now the server is ready to accept requests for https.
variables with the backend appeared variables with information about the certificate, primarily SSL_VERIFIED (takes the value SUCCESS).

However, if you try to enter the site, it will give an error:
 400 Bad Request No required SSL certificate was sent 


Well, it is logical, that's the whole point!

Step 3. Create client certificates



3.1 Preparing the CA


Create a config
nano ca.config

with the following content:
 [ ca ] default_ca = CA_CLIENT #    #   CA_CLIENT [ CA_CLIENT ] dir = ./db #     certs = $dir/certs #    new_certs_dir = $dir/newcerts #     database = $dir/index.txt #       serial = $dir/serial #      (  ) certificate = ./ca.crt #   CA private_key = ./ca.key #    CA default_days = 365 #     default_crl_days = 7 #   CRL default_md = md5 #   policy = policy_anything #          [ policy_anything ] countryName = optional #  optional -  , supplied -  stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = optional emailAddress = optional 


Next you need to prepare the structure of directories and files corresponding to the one described in the configuration file.

 mkdir db mkdir db/certs mkdir db/newcerts touch db/index.txt echo "01" > db/serial 


3.2. Creating a client private key and certificate request (CSR)


To create a signed client certificate, you must first create a certificate request to sign it. The command arguments are completely analogous to the arguments used to create the self-signed trusted certificate, but the -x509 parameter is missing.

 openssl req -new -newkey rsa:1024 -nodes -keyout client01.key -subj /C=RU/ST=Moscow/L=Moscow/O=Companyname/OU=User/CN=etc/emailAddress=support@site.com -out client01.csr 


As a result of the command, two files client01.key and client01.csr will appear.

3.3. Signed a certificate request (CSR) using a trusted certificate (CA).


When signing a request, the parameters specified in the ca.config file are used.

 openssl ca -config ca.config -in client01.csr -out client01.crt -batch 


As a result of the command execution, the client01.crt client certificate file will appear.

To create the following certificates you need to repeat these two steps.

3.4. Creating certificate in PKCS # 12 format for client browser

This is in case, if not soulless machines are connected to your server, as in my case, but live people through a browser.
The password-protected PKCS # 12 file must be fed to the browser so that it can visit your site.

 openssl pkcs12 -export -in client01.crt -inkey client01.key -certfile ca.crt -out client01.p12 -passout pass:q1w2e3 


3.5 Connecting to the received ssl server using curl

 curl -k --key client.key --cert client1.crt --url "https://site.com" 


The -k option is used because the certificate in the example is self-signed

Used software


Ubuntu Server 10.10 (Linux 2.6.35-22-server # 35-Ubuntu SMP x86_64 GNU / Linux)
nginx 0.9.3
OpenSSL 0.9.8o 01 Jun 2010

useful links




I hope, was useful to someone.

PS This post was my first publication on January 16, 2011, the old copy was deleted (at the request of the site administration, and because it was not tied to my account).

Source: https://habr.com/ru/post/213741/


All Articles