mTLS Client Authentication with NGINX

mtls Mar 04, 2020

In this article I will describe how we can  Mutual Authentication with Nginx

First, we create the necessary certificates for the server and client.

# CA key and certificate
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
# server key and csr(certificate sign request)
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
# sign server CSR with CA certificate and key
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
# client key and csr(certificate sign request)
openssl genrsa -des3 -out client.key 1024
openssl req -new -key client.key -out client.csr
# sign client CSR with CA certificate and key
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

Then it is necessary to configure the nginx server to verify client certificates.

server {
    listen 443 ssl;
    server_name localhost;
    # add hosts your domain for local requests

    # server certificate
    ssl_certificate     /etc/nginx/certs/server.crt;
    ssl_certificate_key /etc/nginx/certs/server.key;

    # CA certificate
    ssl_client_certificate /etc/nginx/certs/ca.crt;

    # need to validate client certificate(if this flag optional_no_ca it won't validate client certificates)
    ssl_verify_client on;
    location / {
        # remote ip and forwarding ip
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # certificate verification information
        # if the client certificate verified 
        # will have the value of 'SUCCESS' and 'NONE' otherwise
        proxy_set_header VERIFIED $ssl_client_verify;
        
        # client certificate information(DN)
        proxy_set_header DN $ssl_client_s_dn;

        proxy_pass https://echo:443;
    }
}

default.conf

Dockerize your Nginx

FROM ubuntu:14.04

MAINTAINER Muhammet GÜMÜŞ (muhgumus@gmail.com)

# install nginx
RUN apt-get update -y
RUN apt-get install -y python-software-properties
RUN apt-get install -y software-properties-common
RUN add-apt-repository -y ppa:nginx/stable
RUN apt-get update -y
RUN apt-get install -y nginx

# deamon mode off
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
RUN chown -R www-data:www-data /var/lib/nginx

# expose ports
EXPOSE 80 8443

COPY ./certs /etc/nginx/certs/
# add nginx conf
ADD config/default.conf /etc/nginx/conf.d/default.conf

WORKDIR /etc/nginx

CMD ["nginx"]

Dockerfile

You can build with docker-compose

version: '3.4'
services:
  nginx:
    image: mynginx
    ports:
      - "443:443"

  echo:
    image: "mendhak/http-https-echo"

docker-compose.yaml

docker-compose build

and run

docker-compose up -d

Now we can test Mutual Authentication request with postman. If you trying without Client certficate, server response like below
Screen-Shot-2020-03-10-at-14.41.45

It is necessary to add Client certificate for request with Mutual Autentication

and Server response is below
Screen-Shot-2020-03-10-at-14.49.47

You can access all of the above codes from the Github repository

muhgumus/mTLSAuthNginx
Mutual TLS Authentication with Nginx. Contribute to muhgumus/mTLSAuthNginx development by creating an account on GitHub.

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.