Linux – NGINX IPv4 SSL23_GET_SERVER_HELLO:unknown

linuxnginxopensslsslubuntu-18.04

I have an Ubuntu 18.04 server up and running using ipv4 and ipv6. The system is reachable (ssh) via ipv4 as well as ipv6. There is a NGINX up and running with a valid and payed certificate.

Clients using ipv6 have no problem at all using the setup. Clients with ipv4 on the other hand have SSL-issues and can not establish any connection.

Working

curl -ipv6 --verbose --trace-time -I https://clients.fanciety.com

01:18:14.653230 * Rebuilt URL to: https://clients.fanciety.com/
01:18:14.684108 *   Trying 2a01:4f8:231:d4b::2...
01:18:14.684156 * TCP_NODELAY set
01:18:14.702125 * Connected to clients.fanciety.com (2a01:4f8:231:d4b::2) port 443 (#0)
01:18:14.702296 * ALPN, offering h2
01:18:14.702333 * ALPN, offering http/1.1
01:18:14.702415 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
01:18:14.708653 * successfully set certificate verify locations:
01:18:14.708698 *   CAfile: /etc/ssl/cert.pem
  CApath: none
01:18:14.708792 * TLSv1.2 (OUT), TLS handshake, Client hello (1):
01:18:14.728231 * TLSv1.2 (IN), TLS handshake, Server hello (2):
01:18:14.728529 * TLSv1.2 (IN), TLS handshake, Certificate (11):
01:18:14.754838 * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
01:18:14.755787 * TLSv1.2 (IN), TLS handshake, Server finished (14):
01:18:14.759776 * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
01:18:14.759809 * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
01:18:14.759898 * TLSv1.2 (OUT), TLS handshake, Finished (20):
01:18:14.776641 * TLSv1.2 (IN), TLS change cipher, Client hello (1):
01:18:14.776778 * TLSv1.2 (IN), TLS handshake, Finished (20):
01:18:14.776813 * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
01:18:14.776850 * ALPN, server accepted to use http/1.1
01:18:14.776881 * Server certificate:
01:18:14.776917 *  subject: CN=clients.fanciety.com
01:18:14.776950 *  start date: Aug 24 00:00:00 2018 GMT
01:18:14.776976 *  expire date: Aug 23 12:00:00 2020 GMT
01:18:14.777025 *  subjectAltName: host "clients.fanciety.com" matched cert's "clients.fanciety.com"
01:18:14.777059 *  issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=Thawte TLS RSA CA G1
01:18:14.777084 *  SSL certificate verify ok.
01:18:14.777146 > HEAD / HTTP/1.1
01:18:14.777146 > Host: clients.fanciety.com
01:18:14.777146 > User-Agent: curl/7.54.0
01:18:14.777146 > Accept: */*
01:18:14.777146 > 
01:18:14.798724 < HTTP/1.1 200 OK
HTTP/1.1 200 OK
01:18:14.798820 < Server: nginx/1.14.0 (Ubuntu)
Server: nginx/1.14.0 (Ubuntu)
01:18:14.798852 < Date: Fri, 31 Aug 2018 23:18:14 GMT
Date: Fri, 31 Aug 2018 23:18:14 GMT
01:18:14.798883 < Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
01:18:14.798914 < Content-Length: 7
Content-Length: 7
01:18:14.798945 < Connection: keep-alive
Connection: keep-alive
01:18:14.798976 < X-Powered-By: Express
X-Powered-By: Express
01:18:14.799010 < Accept-Ranges: bytes
Accept-Ranges: bytes
01:18:14.799042 < Cache-Control: public, max-age=0
Cache-Control: public, max-age=0
01:18:14.799087 < Last-Modified: Fri, 31 Aug 2018 19:55:04 GMT
Last-Modified: Fri, 31 Aug 2018 19:55:04 GMT
01:18:14.799123 < ETag: W/"7-165918da924"
ETag: W/"7-165918da924"
01:18:14.799164 < Vary: Accept-Encoding
Vary: Accept-Encoding

01:18:14.799205 < 
01:18:14.799266 * Connection #0 to host clients.fanciety.com left intact

NOT working

curl -ipv4 --verbose --trace-time -I https://clients.fanciety.com

01:33:21.196560 * Rebuilt URL to: https://clients.fanciety.com/
01:33:21.202064 *   Trying 159.69.61.244...
01:33:21.202128 * TCP_NODELAY set
01:33:21.239275 * Connected to clients.fanciety.com (159.69.61.244) port 443 (#0)
01:33:21.239447 * ALPN, offering h2
01:33:21.239481 * ALPN, offering http/1.1
01:33:21.239561 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
01:33:21.243809 * successfully set certificate verify locations:
01:33:21.243842 *   CAfile: /etc/ssl/cert.pem
  CApath: none
01:33:21.243919 * TLSv1.2 (OUT), TLS handshake, Client hello (1):
01:33:21.275023 * error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
01:33:21.275129 * stopped the pause stream!
01:33:21.275224 * Closing connection 0
curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

NOT working

curl -ipv4 -3 --verbose --trace-time -I https://clients.fanciety.com

01:31:38.919241 * Rebuilt URL to: https://clients.fanciety.com/
01:31:38.924589 *   Trying 159.69.61.244...
01:31:38.924632 * TCP_NODELAY set
01:31:38.961890 * Connected to clients.fanciety.com (159.69.61.244) port 443 (#0)
01:31:38.962064 * ALPN, offering h2
01:31:38.962102 * ALPN, offering http/1.1
01:31:38.962183 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
01:31:38.966495 * successfully set certificate verify locations:
01:31:38.966530 *   CAfile: /etc/ssl/cert.pem
  CApath: none
01:31:38.966638 * SSLv3 (OUT), TLS handshake, Client hello (1):
01:31:38.997553 * SSLv3 (OUT), TLS alert, Server hello (2):
01:31:38.997718 * error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
01:31:38.997801 * stopped the pause stream!
01:31:38.997879 * Closing connection 0
curl: (35) error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number

Is there any protocol difference using openssl via ipv4 or ipv6?

openssl s_client -connect clients.fanciety.com:443 -state -debug


...
SSL_connect:SSLv2/v3 write client hello A
read from 0x11942e0 [0x11998c0] (7 bytes => 7 (0x7))
0000 - 48 54 54 50 2f 31 2e                              HTTP/1.
SSL_connect:error in SSLv2/v3 read server hello A
140130130867864:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:794:
...

NGINX SSL configuration

listen [::]:443 ssl;
listen 443 ssl;
ssl on;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DHE+AES128:!ADH:!AECDH:!MD5;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 120m;
ssl_prefer_server_ciphers on;

NGINX log

2018/09/01 00:45:06 [error] 1381#1381: *35 connect() failed (111: Connection refused) while connecting to upstream, client: 2003:e1:9717:1500:5858:af84:640e:bf02, server: clients.fanciety.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:9999/", host: "clients.fanciety.com:443"
2018/09/01 01:35:30 [crit] 3794#3794: *26 SSL_do_handshake() failed (SSL: error:1417D18C:SSL routines:tls_process_client_hello:version too low) while SSL handshaking, client: 2600:c02:1020:4202::ac10:8269, server: [::]:443

wget seems to receive the content using ipv4 with port 443 without ssl – the server doesn't provide http without ssl at all.

Best Answer

I'm pretty sure that this is not the complete configuration you show. Alternatively there is some misconfigured middlebox (like a load balancer) in between. While your server does not understand HTTPS at IPv4 port 443 as one would expect it actually answers to HTTP at IPv4 at the usual HTTPS port 443. And, while it denies access to port 80 (default plain HTTP) on IPv4 it actually answers to port 80 on IPv6.

In other words: something is messed up with your configuration but this is not in the part you show.

# HTTP (port 80) on IPv6 works, redirects to HTTPS (port 443)
$ curl -ipv6 -v http://clients.fanciety.com/
...
HTTP/1.1 301 Moved Permanently


# HTTPS (port 443) on IPv6 works
$ curl -ipv6 -v https://clients.fanciety.com/
...
HTTP/1.1 200 OK


# HTTP (port 80) on IPv4 results in connection refused
$ curl -ipv4 -v http://clients.fanciety.com/
...
curl: (7) Failed to connect to clients.fanciety.com port 80: Connection refused


# HTTPS (port 443) on IPv4 results in TLS error
$ curl -ipv4 -v https://clients.fanciety.com/
...
curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol


# but HTTP on to the default HTTPS port (443) works
$ curl -ipv4 -v http://clients.fanciety.com:443/
...
HTTP/1.1 200 OK