Skip to content

Instantly share code, notes, and snippets.

@jnovack
Last active November 1, 2023 23:07
Show Gist options
  • Save jnovack/6d413463848b48435ea9df06149b8650 to your computer and use it in GitHub Desktop.
Save jnovack/6d413463848b48435ea9df06149b8650 to your computer and use it in GitHub Desktop.
Proxy SSL Client Certificate through NGINX Load-Balancer

Proxy SSL Client Certificate through NGINX Load-Balancer

The frontend stream proxy_pass can be used for load-balancing without SSL off-loading. All SSL connections will be terminated on the backend and client certificate information can be properly authenticated.

This should be used in cases:

  • you have enough CPU to decrypt SSL on the backend servers
  • you require direct client AUTHENTICATION on the backend servers

Backend

In this example, the PHP-FPM engine will receive the following variables:

  • $_ENV['X-SSL-CERT'] - Signed client certificate
  • $_ENV['X-SSL-VERIFIED'] - Status of verification
  • $_ENV['X-SSL-CLIENT-DN'] - Full DN of Client
  • $_ENV['X-SSL-ISSUER-DN'] - Full DN of Issuer

References

server {
listen 8443 default_server ssl;
server_name _;
root /website;
index index.php index.html index.htm;
ssl_certificate /etc/nginx/ssl/certificate.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!3DES:!DH:!SSLv3;
ssl_prefer_server_ciphers on;
error_log /dev/stderr notice;
access_log /dev/stdout;
# Client Certificate Verification
ssl_client_certificate /etc/nginx/ssl/ca.crt;
ssl_crl /etc/nginx/ssl/ca.crl;
ssl_verify_client on;
ssl_session_timeout 5m;
location / {
add_header 'Access-Control-Allow-Origin' '*';
# Check if a file or directory index file exists, else route it to index.php.
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.(php|PHP)$ {
try_files $uri =404;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param X-SSL-CERT $ssl_client_cert;
fastcgi_param X-SSL-VERIFIED $ssl_client_verify;
fastcgi_param X-SSL-CLIENT-DN $ssl_client_s_dn;
fastcgi_param X-SSL-ISSUER-DN $ssl_client_i_dn;
fastcgi_param HTTP_PROXY "";
include fastcgi_params;
}
}
stream {
upstream stream_backend {
server localhost:8443;
}
server {
listen 443;
proxy_pass stream_backend;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment