OpenSSL Command to check if a server is presenting a certificate

Solution 1:

I was debugging an SSL issue today which resulted in the same write:errno=104 error. Eventually I found out that the reason for this behaviour was that the server required SNI (servername TLS extensions) to work correctly. Supplying the -servername option to openssl made it connect successfully:

openssl s_client -connect domain.tld:443 -servername domain.tld

Hope this helps.

Solution 2:

15841:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:
...
SSL handshake has read 0 bytes and written 121 bytes

This is a handshake failure. The other side closes the connection without sending any data ("read 0 bytes"). It might be, that the other side does not speak SSL at all. But I've seen similar errors on broken SSL implementation, which do not understand newer SSL version. Try if you get a SSL connection by adding -ssl3 to the command line of s_client.

Solution 3:

I encountered the write:errno=104 attempting to test connecting to an SSL-enabled RabbitMQ broker port with openssl s_client.

The issue turned out to be simply that the user RabbitMQ was running as did not have read permissions on the certificate file. There was little-to-no useful logging in RabbitMQ.

Solution 4:

In my case the ssl certificate was not configured for all sites (only for the www version which the non-www version redirected to). I am using Laravel forge and the Nginx Boilerplate config

I had the following config for my nginx site:

/etc/nginx/sites-available/timtimer.at

server {
    listen [::]:80;
    listen 80;
    server_name timtimer.at www.timtimer.at;

    include h5bp/directive-only/ssl.conf;

    # and redirect to the https host (declared below)
    # avoiding http://www -> https://www -> https:// chain.
    return 301 https://www.timtimer.at$request_uri;
}

server {
    listen [::]:443 ssl spdy;
    listen 443 ssl spdy;

    # listen on the wrong host
    server_name timtimer.at;

    ### ERROR IS HERE ###
    # You eighter have to include the .crt and .key here also (like below)
    # or include it in the below included ssl.conf like suggested by H5BP

    include h5bp/directive-only/ssl.conf;

    # and redirect to the www host (declared below)
    return 301 https://www.timtimer.at$request_uri;
}

server {
    listen [::]:443 ssl spdy;
    listen 443 ssl spdy;

    server_name www.timtimer.at;

    include h5bp/directive-only/ssl.conf;

    # Path for static files
    root /home/forge/default/public;

    # FORGE SSL (DO NOT REMOVE!)
    ssl_certificate /etc/nginx/ssl/default/2658/server.crt;
    ssl_certificate_key /etc/nginx/ssl/default/2658/server.key;

    # ...

    # Include the basic h5bp config set
    include h5bp/basic.conf;
}

So after moving (cutting & pasting) the following part to the /etc/nginx/h5bp/directive-only/ssl.conf file everything worked as expected:

# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/default/2658/server.crt;
ssl_certificate_key /etc/nginx/ssl/default/2658/server.key;

So it is not enough to have the keys specified only for the www version even, if you only call the www version directly!