I have a strange phenomenon I can't explain. I'm running an nginx with letsencrypt and an Java application server. The nginx listens on 443 and the application server on 8008. Both use SSL and the same cert. Nginx works like a charm, but the application server is strange:
- Postman loads without an error
- CURL loads without an error
- Safari on macOS loads without an error
- Chrome on macOS loads the page, but the JavaScript fetch to
/openapi.json
fails - also the direct download - Firefox on macOS fails (can't establish secure connection)
- Safari on iOS fails
Using curl -v --http1.1 https://frascati.projectkeep.io:8008/openapi/
shows:
curl -v --http1.1 https://frascati.projectkeep.io:8008/openapi/
* Trying 18.218.218.93...
* TCP_NODELAY set
* Connected to frascati.projectkeep.io (18.218.218.93) port 8008 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=frascati.projectkeep.io
* start date: Jan 27 13:46:16 2020 GMT
* expire date: Apr 26 13:46:16 2020 GMT
* subjectAltName: host "frascati.projectkeep.io" matched cert's "frascati.projectkeep.io"
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
> GET /openapi/ HTTP/1.1
> Host: frascati.projectkeep.io:8008
> User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
> Accept: */*
> Referer:
>
< HTTP/1.1 200 OK
< accept-ranges: bytes
< content-length: 1394
< cache-control: public, max-age=86400
< last-modified: Mon, 27 Jan 2020 16:05:19 GMT
< date: Mon, 27 Jan 2020 18:11:52 GMT
< content-type: text/html;charset=UTF-8
<
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
Update
For comparison here the nginx output for the same content:
curl -v https://frascati.projectkeep.io/openapi/
* Trying 18.218.218.93...
* TCP_NODELAY set
* Connected to frascati.projectkeep.io (18.218.218.93) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=frascati.projectkeep.io
* start date: Jan 27 13:46:16 2020 GMT
* expire date: Apr 26 13:46:16 2020 GMT
* subjectAltName: host "frascati.projectkeep.io" matched cert's "frascati.projectkeep.io"
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
> GET /openapi/ HTTP/1.1
> Host: frascati.projectkeep.io
> User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
> Accept: */*
> Referer:
>
< HTTP/1.1 200 OK
< Server: nginx/1.16.1
< Date: Mon, 27 Jan 2020 18:07:02 GMT
< Content-Type: text/html;charset=UTF-8
< Content-Length: 1394
< Connection: keep-alive
< accept-ranges: bytes
< cache-control: public, max-age=86400
< last-modified: Mon, 27 Jan 2020 16:05:19 GMT
<
<!-- HTML for static distribution bundle build -->
What do I miss?
As came out in the comments to the question:
Your application server is using Java 8 with
JSSE
,It has
TLSv1.3
configured among the possible TLS protocols.The problem described is caused by the lack of support for TLSv1.3 in Java's standard SSLContext implementation. So:
curl
proposesTLS
up to version 1.3Remark: If you are using Tomcat, the
OpenSSLImplementation
supportsTLSv1.3
if the underlying native library does.