NGINX: Client Certificate

My environment

I have an AWS API Gateway with an elastic Beanstalk. I want to use client side validation on the host side (Elastic Beanstalk). The elastic beanstalk consists of a load balancer (ELB) and EC2 with NGINX and my Ruby on Rails application. I created a client-side certificate on the API gateway. Current thread:

  • Gateway API sends a request
  • this request goes through the Elastic Load Balancer (TCP port 80) and sends it to the EC2 instance on port 80 (TCP)
  • on an EC2 instance. I have NGINX running in Docker. The NGINX container listens on port 443, which is connected to port 80 of the host.

API Gateway → (TCP 80) ELB (TCP 80) → (port 80) host → (port 443) NGINX container

My problem

I am using the following nginx.conf, where I am trying to do client side certificate validation:

user  root;

error_log  /var/log/app-nginx-error.log debug;
pid        /var/run/app-nginx.pid;

events {
    worker_connections  8096;
    multi_accept        on;
    use                 epoll;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$ssl_client_cert"';

    access_log /var/log/app-nginx-access.log  main;

    sendfile           on;
    tcp_nopush         on;
    tcp_nodelay        on;
    keepalive_timeout  10;

    upstream appserver {
      server unix:///var/run/puma.sock;
    }

    server {
      listen 443 default_server;
      root /var/www/public;
      client_max_body_size  16m;

      ssl_trusted_certificate /etc/nginx/ssl/api-gateway.pem;
      ssl_client_certificate /etc/nginx/ssl/api-gateway.pem;
      ssl_verify_client on;

      ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
      ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
      ssl_prefer_server_ciphers on;

      if ($ssl_client_verify = FAILED) {
        return 495;
      }

      if ($ssl_client_verify = NONE) {
        return 402;
      }

      if ($ssl_client_verify != SUCCESS) {
        return 403;
      }

      location ^~ /assets/ {
        gzip_static on;
        expires max;
        add_header Cache-Control public;
      }

      try_files $uri/index.html $uri @appserver;
      location @appserver {
        proxy_set_header  Host $host;
        proxy_set_header  X-Real-IP $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Host $server_name;
        proxy_set_header  Client-IP $remote_addr;
        proxy_pass        http://appserver;
        proxy_set_header X-Client-Verify $ssl_client_verify;
      }

      access_log    /var/log/app-nginx-access.log;
      error_log     /var/log/app-nginx-error.log debug;
      error_page    500 502 503 504 /500.html;
    }
}

, API Gateway, Cert, 403 - :

 if ($ssl_client_verify != SUCCESS) {
    return 403;
  }

, if FAILED NONE.

:

 ssl_verify_client on;

:

 if ($ssl_client_verify != SUCCESS) {
    return 403;
  }

ssl_verify_client if:

 if ($ssl_client_verify != SUCCESS) {
    return 403;
  }

- , .

  • nginx.conf ? ( , - TCP/HTTP?)
  • , NGINX ( - ?), ssl_verify_client , ?
+4
1

,

"API Gateway → (TCP 80) ELB (TCP 80) → ( 80) host → ( 443) NGINX

,

API → (TCP 80) ELB (TCP 443) → ( 443) NGINX → ( 80)

nginx , .

, nginx- 443 80 . - -.

, ? , (?) nginx-app Dockerrun.aws.json.

+1

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


All Articles