Bidirectional authentication of Nginx

Bidirectional authentication of Nginx

1, Foreword

Reference link

OPENSSL encryption DSA,RSA introduction

By default, the client trusts the authoritative CA organization, and the operating system has built-in CA certificate.

To put it bluntly, the operating system has the public key of CA certificate by default. For example, we can access it https://www.baidu.com (Baidu) it is because Baidu is among CA certification bodies in our own operating system.

centos The trusted certificate in the operating system is usually in this file
cat /etc/pki/tls/certs/ca-bundle.crt

We can check a communication process of visiting Baidu

curl -v https://www.baidu.com

Subject: the subject represents the entity Name of the server. The organization applies for a certificate from the CA organization. The corresponding Name type is the same as that of the issuer. CN represents the domain Name of the server entity class.

Issuer: issuer, which represents the Name of the CA organization. The corresponding Name type is very important, which is abbreviated as DN

We can check whether the issuer GlobalSign in the process of accessing Baidu communication exists in the CA authentication of our operating system

If you are interested in learning about ECC Root CA - R4,Root CA - R6... You can refer to this article What is Globalsign Root CA?

2, What is CA

CA is the issuing authority of the certificate

  • CA is also hierarchical. The most advanced CA is called RootCA, that is, the CA certificate of the lower level of root certificate is issued and signed by it
  • In this way, we trust RootCA, and those CAS with certificates signed by RootCA can issue certificates to entities or other CAS
  • Who signed RootCA? The answer is that they sign for themselves. Ha ha, it's called self signature.

We can see the certificate information of Baidu

openssl s_client -connect www.baidu.com:443

For the specific parameters of openssl instruction, those interested can refer to openssl s_client Blog. Or use the instruction: openssl s_client help to query.

3, Certificate issuing process

  1. Service provider S submits public key, organization information, personal information (domain name) and other information to the third-party CA and applies for authentication;
  2. CA verifies the authenticity of the information provided by the applicant through online and offline means, such as whether the organization exists, whether the enterprise is legal, whether it has the ownership of the domain name, etc;
  3. If the information is approved, CA will issue the certification document certificate to the applicant. The certificate contains the following information: the applicant's public key, the applicant's organization information and personal information, the information of the issuing authority Ca, the effective time, the certificate serial number and other information in clear text, and includes a signature; Signature generation algorithm: firstly, the hash function is used to calculate the information summary of the public plaintext information, and then the private key of Ca is used to encrypt the information summary, and the ciphertext is the signature;
  4. When client C sends a request to server S, S returns the certificate file;
  5. Client C reads the relevant plaintext information in the certificate and calculates the information summary by using the same hash function. Then, decrypt the signature data by using the public key of the corresponding CA and compare the information summary of the certificate. If it is consistent, the legitimacy of the certificate can be confirmed, that is, the public key is legitimate;
  6. The client then verifies the domain name information, validity time and other information related to the certificate;
  7. The client will build in the certificate information of the trusted Ca (including the public key). If the CA is not trusted, the certificate of the corresponding CA cannot be found, and the certificate will also be judged illegal.

4, Nginx Https self signed certificate

First install Nginx (I've already installed a brief tape here)

yum -y install nginx

Modify nginx Conf configuration file

cat > /usr/local/nginx/conf/nginx.conf <<EOF
server {
        listen       443 ssl;
        server_name  localhost;
        
        ssl_certificate      /cert/server.crt;
        ssl_certificate_key  /cert/server.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }
EOF

Create a self signed certificate file

mkdir /cert
cd /cert
openssl genrsa -out server.key 2048
openssl req -x509 -new -nodes -key server.key -subj "/CN=achao666.xyz" -days 365 -out server.crt
openssl x509 -in server.crt -noout -text View Certificate

Restart Nginx

./nginx -s reload

Test access self signed certificate scenario:

1. Direct access to the server
curl https://localhost

2. Access directly with browser

3. Direct access without verifying the certificate (skip verification)
curl -k https://localhost

4. Visit with certificate
curl https://localhost --cacert /cert/server.crt

We clearly carried the certificate. Why did we still be rejected? The reason is that our domain name has not been resolved

Then let's try to resolve the domain name and carry the certificate or let the client resolve the domain name

Mode 1:

curl https://achao666.xyz --cacert /cert/server.crt --resolve achao666.xyz:443:"ip address"

Mode 2:

Backup configuration, etc. to restore

cp /etc/hosts /opt/
echo "ip address achao666.xyz" >> /etc/hosts
curl https://achao666.xyz --cacert /cert/server.crt

Restore after test

cp /opt/hosts /etc/

5. Direct access does not want to carry certificates

Make a backup of the CA authentication of the system

 cp /etc/pki/tls/certs/ca-bundle.crt /opt/

Put the certificate generated by ourselves into the CA authentication of the system

cat /cert/server.crt >> /etc/pki/tls/certs/ca-bundle.crt

visit

curl https://achao666.xyz --resolve achao666.xyz:443:"ip address"

Restore configuration after test

cp /opt/ca-bundle.crt /etc/pki/tls/certs/

5, Use CA to issue certificate

Create CA certificate file

rm -rf /cert/
mkdir /cert
cd /cert
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=achao666-ca.xyz" -days 365 -out ca.crt
openssl x509 -in ca.crt -noout -text View Certificate

Create a server certificate and give it to CA for signature

openssl genrsa -out server.key 2048
openssl req  -new  -key server.key -subj "/CN=achao666.xyz" -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365
openssl x509 -in server.crt -noout -text View Certificate

nginx.conf remains unchanged, restart Ng

./nginx -s reload

Test access scenario

1. Carry the server Whether the CRT certificate and domain name can be accessed
curl https://achao666.xyz --cacert /cert/server.crt --resolve achao666.xyz:443:139.224.50.94

2. Carry ca.crt certificate to test whether it can be accessed
curl https://achao666.xyz --cacert /cert/ca.crt --resolve achao666.xyz:443:139.224.50.94

3. Carry the ca.crt certificate, but do not resolve the domain name
curl https://achao666.xyz --cacert /cert/ca.crt

6, The client uses a self signed certificate for the server to verify (two-way authentication)

Modify nginx Conf configuration file

cat > /usr/local/nginx/conf/nginx.conf <<EOF
server {
        listen       443 ssl;
        server_name  localhost;
        
        ssl_certificate      /cert/server.crt;
        ssl_certificate_key  /cert/server.key;
        ssl_client_certificate  /cert/client.crt;
		ssl_verify_client on;
		
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }
EOF

Generate a client key and certificate

openssl genrsa -out client.key 2048
openssl req -x509 -new -nodes -key client.key -subj "/CN=client" -days 365 -out client.crt

Restart Nginx

./nginx -s reload

Test scenario:

1. Carry ca.crt certificate and resolve domain name
curl https://achao666.xyz --cacert /cert/ca.crt --resolve achao666.xyz:443:139.224.50.94

2. Carry ca.crt certificate and client certificate crt
curl https://achao666.xyz --cacert /cert/ca.crt --cert /cert/client.crt --key /cert/client.key --resolve achao666.xyz:443:139.224.50.94
--cacert /cert/ca.crt Client authentication server
--cert /cert/client.crt --key /cert/client.key Server authentication client

7, Use root certificate to issue client certificate and provide server authentication (two-way authentication)

Modify nginx Conf configuration file

cat > /usr/local/nginx/conf/nginx.conf <<EOF
server {
        listen       443 ssl;
        server_name  localhost;
        
        ssl_certificate      /cert/server.crt;
        ssl_certificate_key  /cert/server.key;
        ssl_client_certificate  /cert/client-ca.crt;
		ssl_verify_client on;
		
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }
EOF

Generate a root certificate

openssl genrsa -out client-ca.key 2048
openssl req -x509 -new -nodes -key client-ca.key -subj "/CN=client-ca" -days 365 -out client-ca.crt

Generate a client private key and a certificate signing request

openssl genrsa -out client.key 2048
openssl req -new -key client.key -subj "/CN=client" -out client.csr

enlarge file

Because it is a client authentication file plus an extended configuration file

This is about extended key usage, not key usage (this is a different setting). What is required depends on the purpose of the certificate, i.e. server authentication (usually required on the server side) and / or client authentication (client, less common).

cat > client.ext << EOF
extendedKeyUsage=clientAuth
EOF

CA signs the certificate request

openssl x509 -req -in client.csr -CA client-ca.crt -CAkey client-ca.key -CAcreateserial -extfile client.ext -out client.crt -days 356

Restart nginx

./nginx -s reload

Test scenario

1. Carry ca.crt certificate and client certificate crt
curl https://achao666.xyz --cacert /cert/ca.crt --cert /cert/client.crt --key /cert/client.key --resolve achao666.xyz:443:139.224.50.94

2. Browser Test

Since it is a two-way authentication, accessing the https address directly through the browser is informed of 400 Bad Request (No required SSL certificate was sent), and the client certificate needs to be installed locally.

The certificate installed on windows needs pfx format, also known as p12 format. The generation method is as follows:

openssl pkcs12 -export -inkey /cert/client.key -in /cert/client.crt -out client.pfx 
sz client.pfx Download to windows

Installation certificate

3. Whether multiple client certificates generated can be accessed successfully

Generate secret key and request signing certificate

openssl genrsa -out client2.key 2048
openssl req -new -key client2.key -subj "/CN=client2" -out client2.csr

Sign it with the CA certificate you created earlier

openssl x509 -req -in client2.csr -CA client-ca.crt -CAkey client-ca.key -CAcreateserial -extfile client.ext -out client2.crt -days 356

Generate pfx format required by browser

openssl pkcs12 -export -inkey /cert/client2.key -in /cert/client2.crt -out client1.pfx 

export

sz client1.pfx 

[external link image transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-t7pguxu5-1643041751129)( https://s2.loli.net/2022/01/20/QJSv9o1GKd6cj3r.png )]

Keywords: Nginx SSL http https

Added by stephaneey on Tue, 25 Jan 2022 21:46:02 +0200