Categories
SysOps

How to log SSL cipher and protocol information in Nginx

Define custom Nginx log format to store SSL cipher and protocol information.

Install nginx HTTP proxy server.

$ sudo apt-get install nginx

Create a directory to store ssl certificate.

$ sudo mkdir /etc/nginx/ssl

Generate ssl certificate for an IP address.

$ sudo openssl req -subj "/commonName=$(ip address show dev eth0 scope global | awk '/inet / {split($2,var,"/"); print var[1]}')/" -x509 -nodes -days 730 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

Define custom log format that extends standard format with SSL protocol, cipher, and the list of ciphers supported by the client.

$ cat <<"EOF" | sudo tee /etc/nginx/conf.d/log_format_combined_ssl.conf
log_format combined_ssl '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        '$ssl_protocol/$ssl_cipher $ssl_ciphers';
EOF
log_format combined_ssl '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" '
                        '$ssl_protocol/$ssl_cipher $ssl_ciphers';

Disable default configuration.

$ sudo unlink /etc/nginx/sites-enabled/default

Generate minimal nginx virtual host configuration using a custom log format.

$ cat <<EOF | sudo tee /etc/nginx/sites-available/service
server {
  listen 8080 ssl;
  server_name default;
  ssl_certificate_key /etc/nginx/ssl/nginx.key;
  ssl_certificate     /etc/nginx/ssl/nginx.crt;
  access_log /var/log/nginx/service-access.log combined_ssl;
  error_log /var/log/nginx/service-error.log;
  location / {
     proxy_pass http://127.0.0.1:19999/;
  }
}
EOF
server {
  listen 8080 ssl;
  server_name default;
  ssl_certificate_key /etc/nginx/ssl/nginx.key;
  ssl_certificate     /etc/nginx/ssl/nginx.crt;
  access_log /var/log/nginx/service-access.log combined_ssl;
  error_log /var/log/nginx/service-error.log;
  location / {
     proxy_pass http://127.0.0.1:19999/;
  }
}

Enable this specific configuration.

$ sudo ln -s /etc/nginx/sites-available/service /etc/nginx/sites-enabled/

Reload nginx configuration.

$ sudo systemctl reload nginx

Inspect log file to determine used SSL protocol/SSL cipher and get the list of ciphers supported by the client.

$ tail -f /var/log/nginx/service-access.log
192.168.50.1 - - [21/Jan/2020:00:18:15 +0000] "GET / HTTP/1.1" 200 129572 "-" "curl/7.58.0" TLSv1.2/ECDHE-RSA-AES256-GCM-SHA384 TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:TLS_EMPTY_RENEGOTIATION_INFO_SCSV
192.168.50.1 - - [21/Jan/2020:00:18:59 +0000] "GET / HTTP/1.1" 200 20197 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36" TLSv1.2/ECDHE-RSA-AES256-GCM-SHA384 0x0a0a:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:0x000a
192.168.50.1 - - [21/Jan/2020:00:19:38 +0000] "GET / HTTP/1.1" 200 20197 "-" "Mozilla/5.0 (Windows NT 10.0; rv:68.0) Gecko/20100101 Firefox/68.0" TLSv1.2/ECDHE-RSA-AES256-GCM-SHA384 TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:0x000a

You can skip the list of ciphers supported by the client and focus on SSL protocol, especially when you want to ditch support for TLS 1.0 and TLS 1.1.

Additional information

Core functionality

Module ngx_http_log_module

Module ngx_http_ssl_module