nginx: How to log TLS error (if unsupported ciphers / protocol)

7,088

I am not sure if you would be able to setup Nginx to log detailed errors when say SSLv3 connection is made. But you can definitely configure it to log all SSL or TLS connections and then you can parse the SSLv3 type connections. In order to do that you will need to add the '$ssl_protocol ' option to the log_format line in your nginx configuration file.

In my case for instance, i have the following lines in /etc/nginx/nginx.conf -

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

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

If i make an SSLv3 connection using curl -

daniel@localhost$ curl -k --sslv3 https://todo.home.net/login.php
curl: (35) error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

I see the following lines in /var/log/nginx/access.log -

192.168.10.206 - - [26/Apr/2015:18:21:25 -0700] "GET HTTP/1.0" SSLv3 400 173 "-" "-" "-"
192.168.10.206 - - [26/Apr/2015:18:21:43 -0700] "GET HTTP/1.0 /login.php" SSLv3  400 173 "-" "-" "-"
192.168.10.206 - - [26/Apr/2015:18:22:56 -0700] "-" SSLv3  400 0 "-" "-" "-"
192.168.10.206 - - [26/Apr/2015:18:23:04 -0700] "-" SSLv3  400 0 "-" "-" "-"

If you disable SSLv3 on the Nginx server, you will get an error on the client side -

And on the server side, the log file will contain the protocol version and an HTTP code of 400, you can use that information to identify the clients which are using SSLv3.

Share:
7,088
Florian Schneider
Author by

Florian Schneider

Updated on September 18, 2022

Comments

  • Florian Schneider
    Florian Schneider over 1 year

    I'm in the progress of switching to 100% https.
    Server is running nginx+libressl.

    Before going https:100% I'm interested in seeing which clients would no longer be able to connect to my site.
    E.g. As I do not support SSL3.

    I checked nginx error and access log, but none contains valuable information if I try to connect with SSL3.

    What I expect to see: E.g.:

    Client [IP]: Connection failed due to protocol/cipher mismatch.
    

    I would then be able to grep the access/error logs for that and see how many clients can no longer access my site.

    Is this possible?

    Current nginx.conf:

    user                        www-data www-data;
    
    pid                         /run/nginx.pid;
    
    worker_processes            auto;
    worker_rlimit_nofile        100000;
    
    error_log                   /var/log/nginx/error.log;
    
    events {
        worker_connections      2048;
        use                     epoll;
        multi_accept            on;
    }
    
    http {
        server_tokens           off;
        autoindex               off;
        charset                 UTF-8;
    
        include                 mime.types;
        default_type            application/octet-stream;
    
        log_format              main '$host - $remote_addr - $remote_user [$time_local] "$request" '
                                     '$status $body_bytes_sent "$http_referer" '
                                     '"$http_user_agent" "$http_x_forwarded_for"';
        access_log              /var/log/nginx/access.log main;
    
        keepalive_timeout       10;
    
        reset_timedout_connection   on;
        client_body_timeout         10;
        send_timeout                10;
    
        client_max_body_size    512k;
    
        sendfile                on;
        tcp_nopush              on;
        tcp_nodelay             on;
    
        server {
            listen              80;
            server_name         domain.com www.domain.com;
            return              301 https://www.domain.com$request_uri;
        }
    
        server {
            listen              443 ssl spdy;
            server_name         domain.com;
    
            include             conf.d/ssl.conf;
    
            return              301 https://www.domain.com$request_uri;
        }
    
        server {
            listen              443 ssl spdy;
            server_name         www.domain.com;
            root                /var/www/vhosts/domain.com/public_html;
    
            include             conf.d/ssl.conf;
    
            default_type        text/html;
    
            location / {
                return 200 'Hello World!';
            }
        }
    }
    

    conf.d/ssl.conf:

    ssl                         on;
    
    ssl_dhparam                 ssl/dhparam4096.pem;
    
    ssl_session_cache           shared:SSL:10m;
    ssl_session_timeout         10m;
    ssl_buffer_size             1400;
    spdy_headers_comp           6;
    add_header                  Alternate-Protocol 443:npn-spdy/3;
    
    ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers                 "AES256+EECDH:AES256+EDH";
    ssl_prefer_server_ciphers   on;
    ssl_ecdh_curve              secp384r1;
    
    add_header                  X-Frame-Options DENY;
    add_header                  X-Content-Type-Options nosniff;
    add_header                  Strict-Transport-Security "max-age=31536000; includeSubDomains";
    
    ssl_certificate             ssl/public.crt;
    ssl_certificate_key         ssl/private.key;
    
    ssl_stapling                on;
    ssl_stapling_verify         on;
    ssl_trusted_certificate     ssl/ca-certs.pem;
    resolver                    8.8.8.8 valid=300s;
    resolver_timeout            10s;
    
  • Florian Schneider
    Florian Schneider about 9 years
    Doesn't work for me. nginx doesn't log anything. Which version of nginx are you using? I tested on latest 1.8.0
  • Daniel t.
    Daniel t. about 9 years
    nginx version: nginx/1.0.15, did you restart the service?
  • Florian Schneider
    Florian Schneider about 9 years
    Sure, I restarted nginx.
  • Florian Schneider
    Florian Schneider about 9 years
    Maybe your nginx version is too old?
  • Daniel t.
    Daniel t. about 9 years
    Please post the content of your nginx.conf.
  • Florian Schneider
    Florian Schneider about 9 years
    Added my nginx.conf (see top)
  • Florian Schneider
    Florian Schneider about 9 years
    BTW: your curl command gives me this: curl: (35) SSL peer handshake failed, the server most likely requires a client certificate to connect
  • Daniel t.
    Daniel t. about 9 years
    I don't see '$ssl_protocol ' in your nginx.conf right to log_format under the http section. You can use a browser to confirm as well.
  • Florian Schneider
    Florian Schneider about 9 years
    It should log something regardless of this variable, right?