How to disable TLS 1.0 in NGINX? - ssl

On the server level in nginx.conf I have:
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
but no matter what when I run:
openssl s_client -connect www.example.com:443 -tls1
I get a valid connection for TLS 1.0. SSLLabs puts the nginx setup for the site as an A but with TLS 1.0 .
root#qa-ebd:~# openssl version -a
OpenSSL 1.0.2j 26 Sep 2016
built on: reproducible build, date unspecified
platform: linux-x86_64
options: bn(64,64) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: gcc -I. -I.. -I../include -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
OPENSSLDIR: "/usr/local/openssl"
root#qa-ebd:~#
root#qa-ebd:~#
root#qa-ebd:~# nginx -V
nginx version: nginx/1.10.2
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
built with OpenSSL 1.0.1f 6 Jan 2014
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx --with-http_ssl_module --with-http_geoip_module --with-http_gzip_static_module --with-http_stub_status_module --with-pcre

Open nginx configuration file (/etc/nginx/nginx.conf) and add below line in http section :
ssl_protocols TLSv1.1 TLSv1.2;
This will disable TLS1.0 for all applications in that server. You can test with the following openssl command:
openssl s_client -connect example.com:443 -tls1
You should be getting output something like :
CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---

The following worked for me:
Since my nginx server hosted 3 applications, I had to set
ssl_protocols TLSv1.1 TLSv1.2;
in each of the applications.
The change will not be reflected if this is specified in the particular application that is under consideration. Instead, changing it in all the applications running on that server will be the solution. After this, the following error will be received when TLSv1.0 handshake is negotiated with the server.
CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1526041526
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---

Related

HAproxy gives no OCSP response back: Response not sent

I just can't manage to get an OCSP response. Here are the steps I did:
Haproxy cert directory:
Added CA file containing root and intermediate CA certificates with .issuer extension.
Added my .pem cert file including private key, crt etc
Generated OCSP response in DER format with openssl:
openssl ocsp -issuer my_cert.issuer -VAfile my_cert.issuer -cert my_cert.pem -url http://status.thawte.com -header Host status.thawte.com -no_nonce -respout my_cert.ocsp
Response verify OK
my_cert.pem: good
This Update: Mar 14 17:45:00 2022 GMT
Next Update: Mar 21 17:00:00 2022 GMT
3 files are now in my HAproxy cert directory:
my_cert.issuer
my_cert.ocsp
my_cert.pem
This is how my HAproxy config looks like:
global
maxconn 4096
ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:RSA+AES128:RC4:HIGH:!MD5:!aNULL:!EDH:!CAMELLIA
log 127.0.0.1 local0 debug
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
stats enable
stats uri /stats
timeout connect 3000ms
timeout client 25000ms
timeout server 25000ms
frontend ssl_check
bind :::80
bind :::443 ssl crt /usr/local/etc/haproxy/certs/my_cert.pem
acl https ssl_fc
http-request set-header X-Forwarded-Proto http if !https
http-request set-header X-Forwarded-Proto https if https
mode http
use_backend %[base,lower,map_beg(/usr/local/etc/haproxy/ssl.map)] if { base,lower,map_beg(/usr/local/etc/haproxy/ssl.map) -m found }
default_backend ssl_check
backend ssl_check
mode http
errorfile 503 /usr/local/etc/haproxy/errors/certificate_response.http
This is how my fake backend looks like using a manipulated 503 errorfile giving response 200 back:
HTTP/1.0 200 Found
Cache-Control: no-cache
Connection: close
Content-Type: text/plain
200 Found
Reloaded HAproxy afterwards but I get still the same output:
$ echo quit | openssl s_client -connect 127.0.0.1:443 -tlsextdebug -status
CONNECTED(00000003)
TLS server extension "renegotiation info" (id=65281), len=1
0001 - <SPACES/NULS>
TLS server extension "EC point formats" (id=11), len=4
0000 - 03 00 01 02 ....
TLS server extension "session ticket" (id=35), len=0
OCSP response: no response sent
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = Thawte RSA CA 2018
verify return:1
[...]
---
Certificate chain
0 s:/[...]
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=Thawte RSA CA 2018
1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=Thawte RSA CA 2018
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA
2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
subject=/[...]
issuer=/
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4377 bytes and written 441 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: FDAA738CD5049E2D14F5F7AD1C2CBCA36B938B94755F697E4CE0DCD40342791E
Session-ID-ctx:
Master-Key: [...]
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
[...]
Start Time: 1647360170
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
DONE
C=US/O=DigiCert Inc/OU=www.digicert.com/CN=Thawte RSA CA 2018
This is how the HAproxy package is setup regarding to OpenSSL etc:
# haproxy -vv
HA-Proxy version 1.8.19 2019/02/11
Copyright 2000-2019 Willy Tarreau <willy#haproxy.org>
Build options :
TARGET = linux2628
CPU = generic
CC = gcc
CFLAGS = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement -fwrapv -Wno-null-dereference -Wno-unused-label
OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1
Default settings :
maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with OpenSSL version : OpenSSL 1.1.0j 20 Nov 2018
Running on OpenSSL version : OpenSSL 1.1.0j 20 Nov 2018
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2
Built with Lua version : Lua 5.3.3
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Encrypted password support via crypt(3): yes
Built with multi-threading support.
Built with PCRE version : 8.39 2016-06-14
Running on PCRE version : 8.39 2016-06-14
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with zlib version : 1.2.8
Running on zlib version : 1.2.8
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with network namespace support.
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
Available filters :
[SPOE] spoe
[COMP] compression
[TRACE] trace
Tested it on a docker-compose setup and on a live machine also but in both cased I get ther certificate chain back etc but the OCSP response field is still empty:
OCSP response: no response sent
What am i doing wrong?!
Was able to sort it out. The naming convention of the certificate file name must be followed and was wrong.
Wrong:
my_cert.issuer
my_cert.ocsp
my_cert.pem
Correct:
my_cert.pem.issuer
my_cert.pem.ocsp
my_cert.pem
Then I was able to get an OCSP response from my HAproxy test instance back.

Go https client issue - remote error: tls: handshake failure

I am hitting this error 'remote error: tls: handshake failure':
~/go/bin/aci-tls 10.0.0.201 user pass
2016/12/20 18:12:04 post error: Post https://10.0.0.201/api/aaaLogin.json: remote error: tls: handshake failure
Code is basic HTTPS client: https://play.golang.org/p/cqPT0oR__q
OpenSSL is happy with this https server:
$ openssl s_client -connect 10.0.0.201:443
(snip)
SSL handshake has read 1383 bytes and written 431 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
(snip)
Tested on:
$ go version
go version go1.7.4 linux/386
C:\>go version
go version go1.7.4 windows/amd64
gotlsscan says:
lab#ubu:~$ go version
go version go1.8beta2 linux/386
lab#ubu:~$ ~/go/bin/gotlsscan -host 10.0.0.201 | grep -v NOT
Testing SSL30 (DISABLED)
Testing TLS1.0
Testing TLS1.1
Testing TLS1.2
lab#ubu:~$
lab#ubu:~$ ~/go/bin/gotlsscan -insecure -host 10.0.0.201 | grep -v NOT
Testing SSL30 (DISABLED)
Testing TLS1.0
Testing TLS1.1
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA [OK]
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA [OK]
Testing TLS1.2
How can I further troubleshoot this issue?
The server for some reason doesn't accept the TLS1.2 handshake, nor does it properly fall back to TLS1.1. You can force the client to use only TLS1.1 and the compatible cipher suites with
cfg := &tls.Config{
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
},
PreferServerCipherSuites: true,
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS11,
MaxVersion: tls.VersionTLS11,
}

Why can I connect TLSv1 if OpenSSL only support SSLv2 and SSLv3?

I am using openssl-0.9.8e-7.el5.
openssl ciphers -v shows support only for SSLv2 and SSLv3 cipher types.
However, if I test this connection using tls 1.0 it connects successfully:
openssl s_client -connect hostname:15000 -tls1
CONNECTED(00000003)
SSL handshake has read 2136 bytes and written 413 bytes
...
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
How does it show Protocol is TLSv1 yet OpenSSL itself only supports SSL 3 and 2?
SSLv3 cipher suites are usable with protocol versions SSLv3 and up, i.e also TLS1.x. The version of the cipher suite only tells you the minimal protocol version.
This also means that if you disable SSLv3 and SSLv2 ciphers suites you effectively disable not only SSLv3 but also TLS 1.0 and TLS 1.1, since new cipher suites were only introduced with TLS 1.2.

Problems getting a site's https certificates

I have an Android app that has some trouble with a site's certificate when connecting via https. As I'm experiencing trouble even when using a custom keystore with the certificates ("No peer certificate") I'm trying to get more information about the connection, handshake and certificates actually given by the server.
The version of openssl is follows:
$ openssl version
OpenSSL 1.0.1e 11 Feb 2013
When I just try to get info about the certificates I get this response:
$ openssl s_client -showcerts -connect [hostname]:443 </dev/null
CONNECTED(00000003)
3069977808:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:749:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 308 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
This is how Chrome describes the connection (sorry for the Norwegian text, but you get an idea of the connection and encryption type:
Based on the info from Chrome I've tried different commands to get the certificates, but they all seem to fail. My top candidate was this one:
$ openssl s_client -showcerts -connect [hostname]:443 -tls1_2 -cipher RC4-MD5
CONNECTED(00000003)
3069396176:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1258:SSL alert number 40
3069396176:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:596:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1414399499
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
Anyone got any hints based on the info given?
This might be an SNI issue, where the server has no default certificate defined for non-SNI clients. Android included a version of Apaches httpclient which is known to not support SNI and your openssl s_client command also does not use SNI.
Please try openssl s_client -servername hostname -connect ... to use SNI and see if this helps.

OpenSSL Command to check if a server is presenting a certificate

I'm trying to run an openssl command to narrow down what the SSL issue might be when trying to send an outbound message from our system.
I found this command in another topic: Using openssl to get the certificate from a server
openssl s_client -connect ip:port -prexit
The output of this results in
CONNECTED(00000003)
15841:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 121 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
Does this mean the server isn't presenting any certificate? I tried other systems on a different ip:port and they present a certificate successfully.
Does mutual authentication affect this command with -prexit?
--Update--
I ran the command again
openssl s_client -connect ip:port -prexit
And I get this response now
CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 121 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
I added -ssl3 to the command
openssl s_client -connect ip:port -prexit -ssl3
Response:
CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : SSLv3
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
Krb5 Principal: None
Start Time: 1403907236
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
Also trying -tls1
CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
Krb5 Principal: None
Start Time: 1403907267
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
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
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.
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.
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!
I was getting the below as well trying to get out to github.com as our proxy re-writes the HTTPS connection with their self-signed cert:
no peer certificate available
No client certificate CA names sent
In my output there was also:
Protocol : TLSv1.3
I added -tls1_2 and it worked fine and now I can see which CA it is using on the outgoing request. e.g.:
openssl s_client -connect github.com:443 -tls1_2
I had a similar issue. The root cause was that the sending IP was not in the range of white-listed IPs on the receiving server. So, all requests for communication were killed by the receiving site.
I have met the same problem . but use IP fine;
I specify ip host in /etc/hosts
use IP work fine, but host can't