Ensuring TLSv1.2 in stunnel? - nginx

Please bear with me as I might lack some understanding on creating certificates to achieve a TLS connection.
I am trying to establish a connection with TLSv1.2 encrypted from client to server.
I have created my own CA certificate and CSR on client-side and proceeded to sign the client.
On client side after generating CSR and signing it with the CA cert:
client-cert.pem
client-csr.pem
client-key.pem
Commands used:
openssl req -nodes -newkey rsa:4096 -keyout client-key.pem -out client-csr.pem
openssl verify -CAfile ca-cert.pem client-cert.pem
On server-side, i also created a CSR and signed it with my own CA:
server-cert.pem
server-key.pem
On server-side, after I create the CA cert and sign the client cert:
ca-cert.pem
ca-cert.srl
ca-key.pem
Commands used:
openssl req -x509 -newkey rsa:4096 -days 3650 -keyout ca-key.pem -out ca-cert.pem
openssl x509 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
openssl verify -CAfile ca-cert.pem client-cert.pem
So on my nginx side, I had configured it this way. (stream connection)
server {
listen 10043;
proxy_ssl on;
proxy_ssl_protocols TLSv1.2;
proxy_ssl_session_reuse on;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_certificate /etc/nginx/certs/tls_certs/client-cert.pem;
ssl_certificate_key /etc/nginx/certs/tls_certs/client-key.pem;
ssl_dhparam /etc/nginx/certs/tls_certs/dhparam.pem;
access_log /var/log/nginx/lpe-ing.log proxy;
proxy_pass 123.456.789.123:12345;
}
At my server endpoint, it is using stunnel & I am not sure how to configure the CA certs.
cert = server-cert.pem
key = server-key.pem
CAfile = ca-cert.pem
verify = 3
sslVersion = all
options = NO_SSLv2
options = NO_SSLv3
options = NO_TLSv1
options = NO_TLSv1.1
[ABC-1]
accept = 12345
connect = localhost:11881
Is my config wrong?
Am I missing any more config on both server and client end?
If i turned off verify, verify = 0, then i am able to connect.
I am getting this error from stunnel when i do this 'openssl s_client -connect localhost:10043 -tls1_2'
CONNECTED(00000003)
write:errno=104
stunnel logs:
2021.11.01 08:17:05 LOG3[14538:140387789453056]: SSL_accept: 140890C7: error:140890C7:SSL routines:ssl3_get_client_certificate:peer did not return a certificate

I'm not familiar with Nginx configuration, so I don't know if you got it right. But I can tell what you're doing wrong in your test. You've successfully tested that an unauthenticated client is not allowed to connect. OpenSSL errors aren't always clear, but in this case, the message from the server is reasonably clear:
ssl3_get_client_certificate:peer did not return a certificate
You've configured the server to require client authentication. But the client did not send a certificate, so no client authentication can happen, and the server refused the connection attempt by closing the connection. (TLS client authentication works this way: the client sends a certificate, then it sends a signature that proves that it knows the corresponding private key.) The error on the client is “connection reset by peer”.
You need to pass the signed certificate and the private key to your client.
openssl s_client -connect localhost:10043 -tls1_2 -cert client_cert.pem -key client_key.pem

Related

Why Azure Gateway can't properly bind root certificate with nginx ingress controller?

I'm trying to create a solution based on Azure AKS Baseline.
I have and AKS with Nginx Ingress Controller and Azure Gateway V2.
I need to make a conversation between Azure Gateway V2 and Nginx Ingress controller secured, by using certificates that were generated by Azure Key Vault.
In the backend health probe I have this error:
The root certificate of the server certificate used by the backend does not match the trusted root certificate added to the application gateway. Ensure that you add the correct root certificate to whitelist the backend
3 certificates were added to the KeyVault: root, intermediate and vl.aks-ingress.mydomain.com
intermediate certificate's CSR was signed by root private key and merged to key vault.
domain's CSR was signed by intermediate private key and merged to key vault.
That's how I signed intermediate and domain certificates:
$signerCertSecret = Get-AzKeyVaultSecret -VaultName $KeyVaultName -Name $SignerCertificateName
$signerCertsecretByte = [Convert]::FromBase64String(($signerCertSecret.SecretValue | ConvertFrom-SecureString -AsPlainText))
$signerCertPfxFilePath = New-TemporaryFile
[System.IO.File]::WriteAllBytes($signerCertPfxFilePath, $signerCertsecretByte)
$policy = New-AzKeyVaultCertificatePolicy -SecretContentType "application/x-pkcs12" `
-SubjectName "CN=$Subject" `
-IssuerName "Unknown" `
-ValidityInMonths 60 `
-ReuseKeyOnRenewal
$_ = Add-AzKeyVaultCertificate -VaultName $KeyVaultName -Name $CertificateName -CertificatePolicy $policy
$csrTempFile = New-TemporaryFile
$certCsr = '-----BEGIN CERTIFICATE REQUEST-----' + `
[Environment]::NewLine + `
(Get-AzKeyVaultCertificateOperation -VaultName $keyVaultName -Name $CertificateName).CertificateSigningRequest + `
[Environment]::NewLine + `
'-----END CERTIFICATE REQUEST-----'
[System.IO.File]::WriteAllText($csrTempFile, $certCsr)
$signerKeyFile = New-TemporaryFile
$signerCertFile = New-TemporaryFile
$pass = "pass123"
openssl pkcs12 -in $signerCertPfxFilePath -nocerts -out $signerKeyFile -passin pass: -passout pass:$pass
openssl pkcs12 -in $signerCertPfxFilePath -clcerts -nokeys -out $signerCertFile -passin pass:
$signedNewCert = New-TemporaryFile
openssl x509 -req -in $csrTempFile -days 3650 -CA $signerCertFile -CAkey $signerKeyFile -CAcreateserial -out $signedNewCert -passin pass:$pass
az keyvault certificate pending merge --vault-name $KeyVaultName --name $CertificateName --file $signedNewCert
After that, I've imported everything to my Windows machine and export the full chain (I didn't find any way to do it automatically via Key Vault). This full chain certificates I've added to the keyvault as a secret. Then this secret was added as secret to the AKS. To test that everything is ok with nginx ingress, I've added a Windows VM to the same network. Inside AKS I've added some super small server and requested it from browser in my VM. Browser cried that certificate is unsafe, but I got the full chain:
Then I've downloaded ROOT CA cer from the keyvault and added it to the gateway.
My understanding is that everything should work properly after that.
But I'm still getting a "root certificate wrong error".
I will appreciate any help or advice, cause I've already waste a week for that and don't have any significant progress.
Thanks in advance!

haproxy not restricting to TLS 1.2

Having troubles understanding where I am messing up, I want to disable TLS 1 and TLS 1.1 so SSL Labs improves my cert score.
I have tried adding the force tls1_2 line in HAproxy as well to no avail. I am still learning more about TLS but from what I understand this should work.
Configuration:
Cloudflare -> Haproxy -> backend server
Cloudflare origin cert is between cloudflare and haproxy
Haproxy Config (in regards to TLS)
global
ssl-default-bind-options ssl-min-ver TLSv1.2 prefer-client-ciphers
ssl-default-bind-ciphers ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-server-options ssl-min-ver TLSv1.2
ssl-default-server-ciphers ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256```
frontend https-in
bind *:443 ssl crt /etc/haproxy/domainhere.com.pem ssl-min-ver TLSv1.2 force-tlsv12
Openssl.conf
#system Default
openssl_conf = default_conf
[default_conf]
ssl_conf = ssl_sect
[ssl_sec]
system_default = system_default_sect
[system_defualt_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT#SECLEVEL=2
Versions:
HAProxy version 2.4.4-1ppa1
OpenSSL 1.1.1f
The ha proxy config seems correct.
Did you try openssl command on your ha proxy? By varying the tls version?
Something like
openssl s_client -connect <YourHost>:443 -servername <YourHost> -tls1_0
openssl s_client -connect <YourHost>:443 -servername <YourHost> -tls1_1
openssl s_client -connect <YourHost>:443 -servername <YourHost> -tls1_2
Notice that you had to supply the hostname twice. The -connect switch is used to establish the TCP connection, but -servername is used to specify the hostname sent at the TLS level. Starting with OpenSSL 1.1.1, the s_client tool automatically configures the latter.
You’ll still need to use the -servername switch if
you’re using an earlier version of OpenSSL,
you’re connecting to an IP address
the TLS host needs to be different.
To anyone who stumbles upon this after fighting with HAProxy...
Cloudflare -> SSL/TLS -> Edge Certificates -> Minimum TLS Version
Cloudflare still defaults to TLSv1.0 so you will need to change this to get a better SSL Server Test score.

Mutal SSL authentication with Qt

I am new to ssl / networking and want to utilize mutal ssl ( client verifies server and server verifies peer) I found a white paper (http://www.infidigm.net/articles/qsslsocket_for_ssl_beginners/) online that gave me some guidance for setting up my certs and keys. Now this paper utilizes a local host ip address as the clients cert file. I want to switch this to a register domain name (scp.radiant.io). This FQDN is local to my ubuntu os for testing purposes
updated my localhost to have a domianname (scp.radiant.io). by modifying this file sudo nano /etc/hosts/ to say 127.0.0.1 scp.radiant.io localhost
Next I create certificate and private keys for both client and server
a. Steps for gen certs example for server below. same commands are run for client to create client certs
openssl req -out server_ca.pem -new -x509 -nodes -subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORG/OU=$ORG_UNIT/CN=server/emailAddress=radiant.$EMAIL"
mv privkey.pem server_privatekey.pem
touch server_index.txt
echo "00" >> server_index.txt
openssl genrsa -out server_local.key 1024
openssl req -key ${NAME}_local.key -new -out server_local.req -subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORG/OU=$ORG_UNIT/CN=scp.radiant.io/emailAddress=$EMAIL"
openssl x509 -req -in ${NAME}_local.req -CA ${NAME}_ca.pem -CAkey server_privatekey.pem -CAserial server_index.txt -out server_local.pem
b. this generates a CaCerts (server_ca.pem and client_ca.pem)
c. this generates a Local Cert files (server_local.pem and client_local.pem).. THIS IS WHERE I SET FQDN to scp.radiant.io
d. this generate a LocalKey (server_local.key and client_local.key)
I use the generated cert files for setting up the ssl configuration on the QSslSocket for both sides like so
//client socket setup
config.setPrivateKey("server_local.key");
config.setLocalCertificate("server_local.pem");
config.addCaCertificate("client_ca.pem");
config.setPeerVerifyMode("QSslSocket::VerifyPeer");
sslSocket->setSslConfiguration(config);
sslSocket->connectToHostEncrypted("scp.radiant.io",1200);
// server socket setup
config.setPrivateKey("client_local.key");
config.setLocalCertificate("client_local.pem");
config.addCaCertificate("server_ca.pem");
config.setPeerVerifyMode("QSslSocket::VerifyPeer");
sslSocket->setSslConfiguration(config);
sslSocket->startServerEncryption()
When running this code i get the following error in my ssl errors. "The host name did not match any of the valid hosts for this certificate
Now if I change the client socket to use this when connecting sslSocket->connectToHostEncrypted("scp.radiant.io",1200,"scp.radiant.io"); it will work.
I dont understand why I have to set the peerVerifyHost argument when connecting encrypted. I would like use the same certificates for my WebSockets implementation for this as well but the QWebSocket class does not allow you to set the peerverifyHost when connecting. So I must be doing something wrong at the cert level or the os level for my FQDN. any networking and ssl help would be helpful
I think you can ignore this error using "ignoreSslErrors" and let the handshake continue

Trust Self-signed SSL/TLS Certificate for Secure Inter-service Communication

We have an orchestration of microservices running on a server. An nginx service is acting as a proxy between microservices. We would like to have all the communications on SSL with our self-signed certificates.
We want to add our private CA to every service (running on Debian Buster), so that it is considered valid everywhere within that service. We generate our server certificate and CA as follows:
# Generate Root CA Certificate
openssl genrsa -des3 -out CA-key.pem 2048
openssl req -new -key CA-key.pem -x509 -days 1000 -out CA-cert.pem
# Generate a Signing a Server Certificate
openssl genrsa -des3 -out server-key.pem 2048
openssl req –new –config openssl.cnf –key server-key.pem –out signingReq.csr
openssl x509 -req -days 365 -in signingReq.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out server-cert.pem
However, we can't make the microservices to consider the certificate as valid and trust it. When a get request is issued using the request library of Python in the micro-service, the following exception is thrown:
requests.exceptions.SSLError: HTTPSConnectionPool(host='server.name', port=443): Max
retries exceeded with url: /url/to/microservice2/routed/via/nginx/ (Caused by
SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate
verify failed: self signed certificate (_ssl.c:1076)')))
What we have tried so far:
Copying the certificate to /usr/share/ca-certificate/ and running the sudo dpkg-reconfigure ca-certificates and/or update-ca-certificates commands.
Set the REQUESTS_CA_BUNDLE env variable to /path/to/internal-CA-cert.pem
Set the SSL_CERT_FILE env variable to /path/to/internal-CA-cert.pem
The only workaround that works is setting the valid=False in requests.get(url, params=params, verify=False, **kwargs), to ignore the validity of the SSL certificate is ignored. But, this is not the worfklow we would want to implement for all the microservices and communications.
The solution was to copy the self-signed server certificate (signed with our own CA) to the /usr/local/share/ca-certificates directory and use the update-ca-certificates which is shipped in debian distributions (similar solution is available for other linux distributions).
cp /path/to/certificate/mycert.crt /usr/local/share/ca-certificates/mycert.crt
update-ca-certificates
However, the tricky part is that the above solution is not sufficient for the python request library to consider the certificate as valid. To resolve that, one has to append the self-signed server certificate to the cat-certificates.crt and then set the environment variable REQUESTS_CA_BUNDLE to that appended file.
cat /path/to/certificate/mycert.crt >>/etc/ssl/certs/ca-certificates.crt
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

Ejabberd check cipher with openssl

I am trying to set up ciphers for port 5222 ejabberd 14.07
my ejabberd.yml:
I have removed ECDHE and DHE based ciphers
port: 5222
module: ejabberd_c2s
protocol_options:
- "no_sslv2"
- "no_sslv3"
- "no_tlsv1"
- "no_tlsv1_1"
max_stanza_size: 65536
shaper: c2s_shaper
access: c2s
ciphers: "EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"
starttls: true
And check with openssl:
$ openssl s_client -connect dev.my.server:5222 -starttls xmpp
CONNECTED(00000003)
^C
Connection accepted (from my server logs):
Accepted connection 10.2.3.1:41007 -> 10.2.3.2:5222
But when I run
openssl s_client -cipher 'ECDHE-RSA-AES256-SHA' -connect dev.mantu.im:5222 </dev/null -starttls xmpp
or -cipher 'DSS' I slill see "Accepted connection", but I am expecting it should fails
What was set up wrong? Or I run uncorrect command to check it?
I suggest you to configure port 5223 with tls: true and then trying to connect without starttls. Without this Accepted connection can mean anything, for example connecting without doing SSL magic.
finally I checked it with this tool tsp hello dump and escalus
./tls-hello-dump eth0 | sed -f ./readable.sed > /var/log/ejabberd/tlshello.txt
and found
10.2.1.18 10.2.1.44 TLSv1 ClientHello TLSv1.2 :TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:TLS_DHE_RSA_WITH_AES_256_CBC_SHA:TLS_DHE_DSS_WITH_AES_256_CBC_SHA:TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA:TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA:TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_CBC_SHA256:TLS_RSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_CAMELLIA_256_CBC_SHA:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:TLS_DHE_RSA_WITH_AES_128_CBC_SHA:TLS_DHE_DSS_WITH_AES_128_CBC_SHA:TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:TLS_DHE_RSA_WITH_SEED_CBC_SHA:TLS_DHE_DSS_WITH_SEED_CBC_SHA:TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA:TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA:TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:TLS_RSA_WITH_AES_128_GCM_SHA256:TLS_RSA_WITH_AES_128_CBC_SHA256:TLS_RSA_WITH_AES_128_CBC_SHA:TLS_RSA_WITH_SEED_CBC_SHA:TLS_RSA_WITH_CAMELLIA_128_CBC_SHA:TLS_RSA_WITH_3DES_EDE_CBC_SHA:TLS_RSA_WITH_IDEA_CBC_SHA:TLS_ECDHE_RSA_WITH_RC4_128_SHA:TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:TLS_ECDH_RSA_WITH_RC4_128_SHA:TLS_ECDH_ECDSA_WITH_RC4_128_SHA:TLS_RSA_WITH_RC4_128_SHA:TLS_RSA_WITH_RC4_128_MD5:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
10.2.1.44 10.2.1.18 TLSv1.2 ServerHello TLSv1.2 cipher TLS_RSA_WITH_AES_256_GCM_SHA384
So ServerHello TLSv1.2 cipher TLS_RSA_WITH_AES_256_GCM_SHA384 always correct cihpers
P.S. I can not remove this posted question

Resources