TLS termination (encryption/decrytion) via proxy for non HTTP protocol - ssl

The protocol in question is the MRCP v2 protocol.
Problem overview:
The client sends MRCP/TLS requests, and the server can't understand these since it doesn't have the ability to perform a TLS handshake or encryption. I am hoping that HAProxy, or any other proxy (Nginx?) will decrypt these TLS packets, and send it to the server, to which the server can respond, and then HAProxy can encrypt and send it back to the client.
If possible, I also want a way to extend this to the SIP protocol. From what I understood of HAProxy, it can't do TLS termination for TCP (layer 4), only HTTP (layer 7). Is there any work around/alternative to this?

You are looking for NGINX and its ngx_stream_ssl_module. It allows you to encrypt arbitrary TCP traffic (doesn't have to be HTTP). No special installation is required. Just install NGINX and front it to your server instead of HAProxy or whatever TLS terminator. Configuration is straightforward:
stream {
...
server {
listen 12345 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/cert.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
...
}
}
Client -> NGINX (stream TLS termination) -> whichever TCP protocol.
NGINX will only do TLS encryption without inspecting the underlying protocol.

Related

Is it possible to bridge TLSv1 traffic to TLSv1.2 or TLSv1.3

I've got a web application with nginx supporting https with TLSv1, TLSv1.1, TLSv1.2 protocols. We'd like to stop supporting TLSv1 and TLSv1.1 due to well known security vulnerabilities. Unfortunately, we have some legacy clients running very old OSes that cannot be upgraded to connect over TLSv1.2. As a solution would it be possible to place a proxy in front of our web app that takes traffic solely from these legacy clients and have that proxy support decrypting TLSv1 but re-encrypt that traffic using TLSv1.2 before proxying it forward? Is this something that nginx can do? Would the responses returned to the client be encrypted with TLSv1?

Fail to address multiple TLS versions due to session caching

I am using WSO2 API Manager (which support every TLS version) to communicate with TLSv1.1 service. This SSL handshake happens like this.
Client(APIM) Hello TLSv1.2
Server Hello TLSv1.1
handshake successful which is expected.
Then i change the backend service to TLSv1.2 and the handshake fails as below.
Client(APIM) Hello TLSv1.1
Handshake fails.
Here, the APIM initiates the Client Hello with TLSv1.1 based on previous knowledge that the server is using TLSv1.1 . But, since the server is now upgraded to TLSv1.2, it rejects communicating with APIM which is TLSv1.1 .
This is acceptable. Since it is unlikely that the backend service is changing its TLS version on the fly. But if i try after 30 minutes idle time, APIM initiates Client Hello with TLSv1.2 and Server Hello with TLSv1.2 therefore, succesfull handshake.
My assumption is this happens because after around 30 minutes, APIM's SSL session gets timeout. What i want to know is this exact timeout value.
I have tried every timeout value in the configuration files in both APIM and its tomcat.
Thanks in advance

SSL and TLS Version Control

In regards to SSL and TLS security, is it possible to run multiple versions of each protocol on a server? If so, i would assume you would have to tell the apps which protocol to use since there are multiple versions installed. If not, what options are there for a similar environment?
Example: Server 1 has TLS 1.0, 1.1, and 1.2 on it.
It is certainly possible. Backwards compatibility necessitates it, some clients may not be able to talk TLS1.2, some may only be capable of TLS1.0, etc. The TLS protocol suite handles version negotiation in the server and client hello messages, so once the client is configured to use, say, TLS 1.2 only, it should be able to negotiate that version with the server. TLS Implementations such as GNUTLS and OpenSSL, which are widely used as the SSL backbone of popular server software such as Nginx, support such configuration trivially:
http {
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
listen 443 ssl;
server_name www.example.com;
keepalive_timeout 70;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;

Nginx; how to use OCSP to verify the SSL client certificate

I am using Nginx to create a secure connection; when I revoked the client certificate, I also can connect to Nginx by https, I know I should config the ssl_crl directives, but I want to use OCSP to verify the client certificate, How should I do? I found Nginx use OpenSSL library to establish ssl connection, Is there something I should do with openssl.cnf file?
Client certificate validation with OCSP feature has been added to nginx 1.19.0+.
For example:
ssl_verify_client on;
ssl_ocsp on;
resolver 192.0.2.1;
ssl_ocsp enables OCSP validation of the client certificate chain.
ssl_ocsp leaf; enables validation of the client certificate only. By default ssl_ocsp is set to off.
ssl_verify_client directive should be set to on or optional for the OCSP validation to work
resolver should be specified to resolve the OCSP responder hostname.
Update
Nginx added support for client certificate validation with OCSP in version 1.19.0, released 26 May 2020. See ssl_ocsp and related directives.
Original answer
Nginx does not support OCSP validation of client certificates. The only option of validating client certificates is to use CRLs, update them and reload Nginx to apply the changes.
In this thread one of the leading Nginx developers confirms that and says that nobody is working on it as of 2014:
https://forum.nginx.org/read.php?2,238506,245962
Prerequirements:
running pki with OCSP configured
NginX Server config
# Specifies a file with trusted CA certificates in the PEM format used to verify client certificates and OCSP responses if ssl_stapling is enabled.
# The list of certificates will be sent to clients. If this is not desired, the ssl_trusted_certificate directive can be used.
ssl_client_certificate /etc/nginx/client_certs/ca.crt;
ssl_verify_client on;
ssl_stapling on; #Yes this has to be configured to use OCSP
resolver 192.0.2.1;
information on ssl_verify_client
informations on ssl_client_certificate
This is just a sample of how the code should look like in your server block:
server {
# Listen on port 443
listen 443 default_server;
server_name example.com;
root /path/to/site-content/;
index index.html index.htm;
# Turn on SSL; Specify certificate & keys
ssl on;
ssl_certificate /etc/nginx/ssl/example.com/my_certificate.crt;
ssl_certificate_key /etc/nginx/ssl/example.com/example.key;
# Enable OCSP Stapling, point to certificate chain
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/full_chain.pem;
}
make sure the certificates match your paths, and then Save your work.
Test your configuration before reloading...
and last, restart or reload Nginx by either of the following commands:
sudo service nginx reload
or
sudo service nginx restart
Final step, test your OCSP Stapling through this link to make sure your SSL is working or not:
OCSP Stapling SSL Checker

curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

I am trying to connect my remote nginx server which is configured to use ssl.
I fired a command
$curl https://10.73.80.197:8080/
but after that i am getting error. Here is the whole log-
* Hostname was NOT found in DNS cache
* Trying 10.73.80.197...
* Connected to 10.73.80.197 (10.73.80.197) port 80 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
* Closing connection 0
curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
as explained in several other articles:
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
Curl returns "Unknown protocol"
this kind of curl error is often the result of using a web proxy over https instead of http
you should check your https_proxy env variable
if you have something like
https://myproxy.example.com:8080/
then you should change and set the following
https_proxy=http://myproxy.example.com:8080/
I encountered this today and in my case it was a misconfiguration in my nginx.conf file. My configuration contained something like this:
server {
listen 443;
listen [::]:443;
# Single underscore means 'matches any server name'
server_name _;
root /usr/share/nginx/html;
# Only allow more recent (still secure) versions of TLS
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# Explicitly set list of supported ciphers
ssl_ciphers ECDH+AESGCM:ECDH+AES256-CBC:ECDH+AES128-CBC:DH+3DES:!ADH:!AECDH:!MD5;
ssl_certificate "/etc/pki/atmloader/server.crt";
ssl_certificate_key "/etc/pki/atmloader/server.pem";
# ...
}
but it should have looked like this:
server {
listen 443 ssl;
listen [::]:443 ssl;
# Single underscore means 'matches any server name'
server_name _;
root /usr/share/nginx/html;
# Only allow more recent (still secure) versions of TLS
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# Explicitly set list of supported ciphers
ssl_ciphers ECDH+AESGCM:ECDH+AES256-CBC:ECDH+AES128-CBC:DH+3DES:!ADH:!AECDH:!MD5;
ssl_certificate "/etc/pki/atmloader/server.crt";
ssl_certificate_key "/etc/pki/atmloader/server.pem";
# ...
}
Notice the missing ssl in the listen parameter values.
A copy-and-paste mistake on my part when copying configuration that was originally created for a non-HTTPS port.