Site doesn't load ssl, no handshake, [nginx] [centos]

Hiya,

If I run the following locally to see what’s wrong: OpenSSL s_client -connect www.site.co.uk:443 -prexit and get this:

CONNECTED(00000003)
52336:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64/src/ssl/s23_lib.c:185:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 130 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE

Seemed to have trouble generating a dhparams.pem earlier, not sure if it could still be that? I managed to generate it ok (I think) at a new folder, it’s loaded in my nginx.conf as - ssl_dhparam /etc/nginx/ssl.crt/dhparam.pem; with:
openssl dhparam -out /etc/nginx/ssl.crt/dhparams.pem 2048;

I’ve then generated a certificate with certbot-auto:
/opt/certbot-auto certonly --webroot -w /var/www/site.co.uk/build/public -d site.co.uk -d www.site.co.uk

setting the new ssl in my site specific nginx config:

ssl_certificate_key /etc/letsencrypt/live/site.co.uk/privkey.pem;```

Any suggestions on why it just appears completely broken?

Looks good, but can you post the whole block of configuration for the SSL piece of your site? Looks like nginx tries to do “normal” HTTP on port 443. You must explicitely add ssl to the listen 443 part of the configuration (or something like that, I’m not that familiar with nginx)

Unfortunately I already have the listen 443 ssl; set

Here is my site specific conf:

###################################################################################################################
#
#   ADDITIONAL DOMAINS
#
###################################################################################################################

server {
    ################################################
    ## Ports
    ################################################

    listen 80;

    ## Un-comment the appropriate line below depending on whether this project has its own SSL cert
    listen 443 ssl; ## shared self-signed SSL
    #listen 123.123.123.123:443 ssl; ## dedicated SSL with own IP

    ## Stop nginx including the port in any redirects
    port_in_redirect off;

    ################################################
    ## Domains
    ################################################

    ## List any additional (non-primary) domains for this project, including the non-www version of the primary domain if you want to force www.
    ## separate multiple domains with a space and use ~^(www\.)? to match both www and non-www for any additional domains
    ## do not include echost domains in this list, as we always want to be able to access those for testing purposes
    server_name ~^(www\.)?sitename\.co.uk;

    ## Set the primary domain that all additional domains should be redirected to (including whether or not they should be forced onto https:// and www.)
    rewrite / http://www.sitename.co.uk$request_uri? permanent;

    ################################################
    ## SSL
    ################################################

    ## Un-comment and update the lines below if this project has its own SSL cert
    ssl_certificate /etc/letsencrypt/live/sitename.co.uk/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sitename.co.uk/privkey.pem;
}

###################################################################################################################
#
#   PRODUCTION ENVIRONMENT FRONT END - WITH MAIN DOMAIN
#
###################################################################################################################

server {
    ################################################
    ## Ports
    ################################################

    listen 80;

    ## Un-comment the appropriate line below depending on whether this project has its own SSL cert
    # ssl on;
    listen 443 ssl; ## shared self-signed SSL
    #listen 123.123.123.123:443 ssl; ## dedicated SSL with own IP

    ## Stop nginx including the port in any redirects
    port_in_redirect off;

    ################################################
    ## Logs
    ################################################

    ## Update the lines below to set unique logs for this project
    access_log  /var/log/nginx/sitename-frontend-production-maindomain.access.log;
    error_log   /var/log/nginx/sitename-frontend-production-maindomain.error.log;

    ################################################
    ## Domains
    ################################################

    ## List domains that should be recognised
    server_name www.sitename.co.uk;

    ## Domain that redirects should use (should be same as primary domain)
    set $redirectDomain 'www.sitename.co.uk';

    ################################################
    ## SSL
    ################################################

    ## Un-comment and update the lines below if this project has its own SSL cert
    ssl_certificate /etc/letsencrypt/live/sitename.co.uk/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sitename.co.uk/privkey.pem;

    # Detect HTTPS for $_SERVER['HTTPS'] fix
    set $frontendhttps '';
    if ($scheme ~* ^https$) {
        set $frontendhttps on;
    }

    # If not on HTTPS, force it on
    if ($scheme ~* ^http$) {
        #rewrite / https://$redirectDomain$request_uri? permanent;
    }

    ################################################
    ## Gzip
    ################################################
    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    # Compression level (1-9).
    # 5 is a perfect compromise between size and cpu usage, offering about
    # 75% reduction for most ascii files (almost identical to level 9).
    gzip_comp_level 5;
    # Don't compress anything that's already small and unlikely to shrink much
    # if at all (the default is 20 bytes, which is bad as that usually leads to
    # larger files after gzipping).
    gzip_min_length    256;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types
        text/plain
        text/xml
        text/css
        text/javascript
        application/atom+xml
        application/javascript
        application/json
        application/x-javascript
        application/xml
        application/xml+rss
        application/rss+xml
        application/vnd.ms-fontobject
        application/x-font-ttf
        application/x-web-app-manifest+json
        application/xhtml+xml
        font/opentype
        image/svg+xml
        image/x-icon
        text/x-component;

    ################################################
    ## Redirects
    ################################################

    #rewrite ^\/(.*)\.php$ $scheme://$redirectDomain/$1 permanent;

    ## Remove trailing slash from urls
    set $rwslash 1;
    if ($request_uri ~ ^/admin312(.*)$) {
        set $rwslash 0;
    }
    if ($request_uri ~ ^/sitemap673(.*)$) {
        set $rwslash 0;
    }
    if ($request_method = POST) {
        set $rwslash 0;
    }
    if ($rwslash = 1) {
        rewrite ^/(.*)/$ $scheme://$redirectDomain/$1 permanent;
    }

    ################################################
    ## Proxy request to Varnish
    ################################################

    location / {

        proxy_pass  http://127.0.0.1:8080;

        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-Proto $scheme;
        proxy_set_header X-Frontend-Https $frontendhttps;
        proxy_pass_request_headers on;

        proxy_redirect     off;
    }
}

###################################################################################################################
#
#   PRODUCTION ENVIRONMENT BACKEND - WITH MAIN DOMAIN
#
###################################################################################################################

server {
    ## Ports to listen on
    listen 8090;
    port_in_redirect off;

    ## Primary domain(s) to respond to
    server_name www.sitename.co.uk;

    ## Directory that contains the website files
    root /var/www/sitename.co.uk/build/public;
    index index.php;

    ## deny access to .htaccess files
    location ~ /\.ht {
        deny  all;
    }

    # Get real client IP passed from frontend to Varnish
    real_ip_header X-Real-IP;
    set_real_ip_from 127.0.0.1;

    ################################################
    ## Logs
    ################################################

    access_log  /var/log/nginx/sitename-backend-production-maindomain.access.log;
    error_log   /var/log/nginx/sitename-backend-production-maindomain.error.log;

    ################################################
    ## Gzip
    ################################################

    # We can gzip the response at this stage, which will be passed to Varnish.
   	# Varnish will decide whether to serve up gzip or unzip depending on client support
   	# gzip compression settings are globally set in nginx.conf
    gzip on;

    ################################################
    ## Caching
    ################################################

    ## Leveraging Browser Caching
    location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff)$ {
        expires 14d;
        add_header Pragma public;
        add_header Cache-Control "public";
        try_files $uri @rewrite;
    }

    ################################################
    ## index.php request routing
    ################################################

    location / {
        # http://www.tweaktalk.net/60/nginx-remove-php-file-extension-from-url
        try_files $uri $uri/ @extensionless-php;
        index index.html index.htm index.php;
    }

    location ~ \.php$ {
        try_files $uri =404;
        include       /etc/nginx/fastcgi_params;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    }

    location @extensionless-php {
        rewrite ^(.*)$ $1.php last;
    }

    ## pass 404 errors to PHP
    error_page 404 /404.php;

    ################################################
    ## PHP-FPM
    ################################################

    location ~ \.php$ {
        set  $script     $uri;
        set  $path_info  "";

        if ($uri ~ "^(.+\.php)(/.+)") {
            set  $script     $1;
            set  $path_info  $2;
        }

        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;

        include fastcgi_params;

        fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
        fastcgi_param  PATH_INFO        $path_info;
        fastcgi_param  SCRIPT_NAME      $script;
        fastcgi_param  SCRIPT_FILENAME  $document_root$script;
        fastcgi_param  QUERY_STRING     $query_string;

        ## NewRelic Application Reporting
        fastcgi_param PHP_VALUE "newrelic.appname=sitename - jlinode - Production - Backend - Main Domain";

        try_files      $fastcgi_script_name =404;
    }
}

Here is my nginx.conf

user  nginx;
worker_processes  1;

worker_rlimit_nofile 65535;

error_log  /var/log/nginx/error.log;
#pid        /run/nginx.pid;

events {
    worker_connections  2048;
}

http {
    geo $acl_debug {
        default 0;
    }

    ################################################
    ## Headers
    ################################################

    #more_clear_headers 'Server';

    ################################################
    ## MIME types
    ################################################

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

    ################################################
    ## Logging
    ################################################

    log_format  main  '$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;

    ################################################
    ## General
    ################################################

    server_tokens off;

    sendfile        on;
    #tcp_nopush     on;

    ################################################
    ## Limits
    ################################################

    client_max_body_size 150M;

    keepalive_timeout  65;

    fastcgi_connect_timeout 900;
    fastcgi_send_timeout 900;
    fastcgi_read_timeout 900;

    proxy_connect_timeout       900;
    proxy_send_timeout          900;
    proxy_read_timeout          900;
    send_timeout                900;

    ################################################
    ## Internal caching
    ################################################

    proxy_cache_path /var/cache/nginx levels=1:2
                     keys_zone=microcache:5m max_size=1000m;

    ################################################
    ## gzip
    ################################################

    # gzip is disabled by default, but can be enabled
    # for some backends in site configs
    gzip off;

    gzip_comp_level 2;
    gzip_min_length 1000;
    gzip_proxied any;
    # Additional types to gzip (in addition to text/html which is always compressed)
    gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;

        ################################################
    ## SSL
    ################################################

    ssl_dhparam /etc/nginx/ssl.crt/dhparam.pem;

    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 10m;

    ssl_prefer_server_ciphers       on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

    add_header Strict-Transport-Security "max-age=31536000";

    ################################################
    ## Include config directory
    ################################################

    include /etc/nginx/conf.d/*.conf;
}

Turns out this command doesn't even work when used on https://www.facebook.com , but it is clearly still broken, if I try with curl -I https://www.site.co.uk I get

curl: (35) Server aborted the SSL handshake

So it appears that I could get the openssl line to work, just needed some modification, it gives a bit more data, but unfortunately nothing revealing, it appears to jump between 2 sets of results:

Joes-MBP:~ joepagan$ openssl s_client -connect www.site.co.uk:443
CONNECTED(00000003)
write:errno=54
Joes-MBP:~ joepagan$ openssl s_client -connect www.site.co.uk:443
CONNECTED(00000003)
56038:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64/src/ssl/s23_lib.c:185:

Comparing that to facebook.com

Joes-MBP:~ joepagan$ openssl s_client -connect www.facebook.com:443
CONNECTED(00000003)
depth=1 /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=CA/L=Menlo Park/O=Facebook, Inc./CN=*.facebook.com
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIHTzCCBjegAwIBAgIQDnQ+EartPbA34VVvKGw/4TANBgkqhkiG9w0BAQUFADBm...
-----END CERTIFICATE-----
subject=/C=US/ST=CA/L=Menlo Park/O=Facebook, Inc./CN=*.facebook.com
issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
---
No client certificate CA names sent
---
SSL handshake has read 3675 bytes and written 456 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES128-SHA
    Session-ID: 2DA26BC8E4075B8353D9907168160193FFDDFA9B8428F5E02A42D28F4DF60D0B
    Session-ID-ctx:
    Master-Key: 68AF4C30F67F27EE456BD425579C6E3FF5DB8A29A511681C108BB46B19F69B89711AA9B30DDDF8B853B3046D735CD6BA
    Key-Arg   : None
    Start Time: 1471955670
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

Just to confirm that your nginx config isn’t serving HTTP on port 443, could you run:
telnet www.site.co.uk 443
and when it connects type:
GET / HTTP/1.0
<enter>
If nginx is configured to return SSL it should return a 400 error that specifically states you’re speaking HTTP to an HTTPS port.

It would also be worth testing removing the listen 80; as normally you’d define each port with it’s own server {} context.

I managed to get it working after looking through the forums I found this post:

It suggests that I should use:

listen 443 default_server ssl http2;

I'm not using http2 to I changed to:

listen 443 default_server ssl;

restarted nginx and it worked....

Can anyone tell me why? It appears I only need to set this once in a sites server block, it does not like it if I try in all more than 1 site config. I guess I need to make a "default" config for my server's "default" environment.

I presume this is for the "default_server" page, as in the environment that loads if one is not set?

But why would this need to be set to allow ssls on other sites?

Thanks for your suggestions @Osiris & @alowde

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.