Setup :
Erlang cluster with two Erlang nodes, different names, identical SSL setup (certificates, keys, authority)
the two nodes are listening for connections on the same port
the accept scheme is simple and doesn't have an acceptor pool in front : ListenSocket = ssl:listen() when the app starts -> then, in the children, I do AcceptSock = ssl:transport_accept(ListenSocket) + ssl:ssl_accept(AcceptSock) + mysup:start_child() which will start a new gen_server to listen on ListenSocket (in the gen_server init() I have timeout == 0, btw - to make the gen_server receive a timeout message which will be handled with handle_info(timeout...) which does the accept scheme above).
Expected behavior :
I expect all of this to work all the time :)
Observed behavior :
from time to time, one or both servers stop accepting ssl connections from the iOS apps. telnet to that port works - and it even passes transport_accept().
from the iOS app, I get a "SSLHandshake failed, error -9806" and it doesn't look like transport_accept() was successful (I have error logging before and after that line and I do not see any error messages printed in the log - theoretically, it looked like the iOS app is not trying to connect to that port, but it did try, because it says SSLHandshake failed).
I followed this thread - and got the followings :
openssl s_client -connect myserver:4321 -servername myserver -ssl3 -tls1 -prexit
CONNECTED(00000003)
write:errno=60
---
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
Start Time: 1460057622
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
same command executed with the second server (that is still accepting connections) returned a lot more infos and doesn't time out.
Any help is appreciated, thank you.
Related
I have been trying to implement HTTPS on a kubernetes cluster on Google Cloud Platform. I cannot understand what else I need to check or look for. I am using a Google Managed certificate.
dig output
; <<>> DiG 9.11.5-P4-5.1+deb10u5-Debian <<>> demo.abhikube.tk
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59409
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;demo.abhikube.tk. IN A
;; ANSWER SECTION:
demo.abhikube.tk. 300 IN A 35.190.47.137
;; Query time: 47 msec
;; SERVER: 169.254.169.254#53(169.254.169.254)
;; WHEN: Sun Sep 12 10:00:45 UTC 2021
;; MSG SIZE rcvd: 61
Command:- openssl s_client -connect demo.abhikube.tk:443 -tls1_2
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 213 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1631440972
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
I have tried multiple times but Google keeps showing FailedNotVisible. What else can I do to fix this? I am not an expert on ssl. Google doc said if the verify return is ok it should work..but it doesn't. The HTTP version works fine.
UPDATE:- I ran a check on https://dnssec-analyzer.verisignlabs.com/..it shows
No DS records found for abhikube.tk in the tk zone
ns-cloud-e2.googledomains.com returns REFUSED for abhikube.tk/DNSKEY
ns-cloud-e4.googledomains.com returns REFUSED for abhikube.tk/DNSKEY
ns-cloud-e3.googledomains.com returns REFUSED for abhikube.tk/DNSKEY
ns-cloud-e1.googledomains.com returns REFUSED for abhikube.tk/DNSKEY
Could this be because it is a free domain?Any inputs?
http version works fine.
Some added information
https://dns.google/query?name=demo.abhikube.tk&rr_type=A&ecs=&disable_dnssec=true&show_dnssec=true
I'm trying to publish message to a Tibco Queue on a SSL Tibco Server through JMeter 5.4.1 using JMS Point-to-Point Logic Controller.
JMS Point To Point Controller Config
But I'm getting the following error message:
2021-06-13 12:25:46,278 ERROR o.a.j.p.j.s.JMSSampler: Not permitted:
Failed to connect to any server at: ssl://[server-name]:7352,
ssl://[server-name]:7352 [Error: Failed to connect via SSL to
[ssl://[server-name]:7352]: Received fatal alert:
protocol_version: url that returned this exception =
SSL://[server-name]:7352 ]
javax.naming.AuthenticationException: Not permitted: Failed to connect
to any server at: ssl://[server-name]:7352,
ssl://[server-name]:7352 [Error: Failed to connect via SSL to
[ssl://[server-name]:7352]: Received fatal alert:
protocol_version: url that returned this exception =
SSL://[server-name] ] at
com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:670)
~[tibjms.jar:8.0.0] at
com.tibco.tibjms.naming.TibjmsContext.lookup(TibjmsContext.java:491)
~[tibjms.jar:8.0.0] at
javax.naming.InitialContext.lookup(InitialContext.java:417)
~[?:1.8.0_291] at
org.apache.jmeter.protocol.jms.sampler.JMSSampler.threadStarted(JMSSampler.java:638)
[ApacheJMeter_jms.jar:5.4.1] at
org.apache.jmeter.threads.JMeterThread$ThreadListenerTraverser.addNode(JMeterThread.java:784)
[ApacheJMeter_core.jar:5.4.1] at
org.apache.jorphan.collections.HashTree.traverseInto(HashTree.java:993)
[jorphan.jar:5.4.1] at
org.apache.jorphan.collections.HashTree.traverse(HashTree.java:976)
[jorphan.jar:5.4.1] at
org.apache.jmeter.threads.JMeterThread.threadStarted(JMeterThread.java:752)
[ApacheJMeter_core.jar:5.4.1] at
org.apache.jmeter.threads.JMeterThread.initRun(JMeterThread.java:740)
[ApacheJMeter_core.jar:5.4.1] at
org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:252)
[ApacheJMeter_core.jar:5.4.1]
I tried:
openssl s_client -connect [server-name]:7352
It gave the following output:
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID:
Session-ID-ctx:
So added the following line in jmeter.properties file.
https.default.protocol=TLSv1.2
Also commented jdk.tls.disabledAlgorithms from java.security file for JDK (I'm using jdk1.8.0_291)
# jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
# DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
# include jdk.disabled.namedCurves
But still I'm getting the same error. Someone please help.
I think you're using the wrong property (not only the wrong property but the wrong place as well), you're setting default protocol for HTTPS, while you need to set it for TLS, i.e. add the next line to system.properties file
jdk.tls.client.protocols=TLSv1.2
JMeter restart will be required to apply this property.
If it won't help or you will get different errors - consider adding the next line there as well:
javax.net.debug=all
and then check jmeter.log file and stdout for any suspicious entries
More information:
Configuring JMeter
Apache JMeter Properties Customization Guide
I resolved it by using the latest tibjms.jar in the lib directory in JMeter as the Tibco server was upgraded some hours before I raised this issue.
I am trying to connect to a web service which is written in Java language on the server side. My program is written in VB.NET 4.0 on the client side.
When i try to call any methods from the web service I receive the following error message :
WS-Metadata Exchange Error URI: [http://...] Metadata contains a reference that cannot be resolved. The request was aborted: Could not create SSL/TLS secure channel
I am using a certificate to connect to the web service, however it seems that the problem is on the communication level between my host machine (client) and the server. The certificate i am using is never been checked as the client and the server can even not communicate.
I have tried to set the security protocol to "SSLv3" or "TLS12" but it didn't help. Thank you in advance for any suggestions.
Also i should mention that i managed to connect to this web service using a Java class. It seems that when the client side is written in Java it works but when it's in VB.NET it doesn't work.
P. HAB
EDITED :
I used "Wireshark" to discover the HTTPS packets which are sent and received by my program, here what I found in the transmitted packets :
Request by the client :
Secure Sockets Layer
TLSv1 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 140
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 136
Version: TLS 1.0 (0x0301)
Random
Session ID Length: 0
Cipher Suites Length: 24
Cipher Suites (12 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 71
Extension: server_name
Extension: elliptic_curves
Extension: ec_point_formats
Extension: Extended Master Secret
Extension: renegotiation_info
Response from the server :
Secure Sockets Layer
TLSv1 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)
Content Type: Alert (21)
Version: TLS 1.0 (0x0301)
Length: 2
Alert Message
Level: Fatal (2)
Description: Handshake Failure (40)
I have tried to change the security protocol to different versions of SSL/TLS but it changed nothing. My client tries to send a "Client hello" with standard values (no user-customized parameters were specified) but the server is not accepting it. Any suggestions ?
Solution found :
The problem is in fact related to the Cipher suites and specially the RC4 algorithme. Actually my client is written in VB.NET 4.0 and in this version of .NET the deprecated RC4 algorithme is still supported and proposed by the .NET framework to any Web server during the "Hello Client" (Handshake) process.
The only presence of the RC4 cipher suites in the supported list of the cipher suites by my client was making the server to abort the connection with the following error message : "The request was aborted: Could not create SSL/TLS secure channel"
So I had to deactivate the RC4 cipher suites on my client machine by going in the system registry using regedit.exe and add the following key to these two specified paths :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\v4.0.30319
"SchUseStrongCrypto"=dword:00000001
And
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319
"SchUseStrongCrypto"=dword:00000001
After restarting the client machine I was able to connect to the web service succesfully.
For more information about the deprecated RC4 algorithmes :
https://technet.microsoft.com/en-us/library/security/2960358.aspx
=> Also you should notice that this problem exists only in .NET 4.0-4.5. From the version 4.6 and above its working fine.
I want to find out the protocols supported by a target but the problem is that their are quite a number websites which are not supporting a particular version but when i performed handshake it was successful becz target surpassed the version that i gave and perform handshake on the supported version
[ it happened on only 1 website]
example : i passed a version :TLSVersion.TLS_1_2 but the handshake is performed using TLSv1_0 becz it is not supporting TLSVersion.TLS_1_2
Because of the above issue i want to check the version on handshake and i dont want to use scapy.ssl_tls
version = [SSL.SSLv23_METHOD,
SSL.TLSv1_METHOD,
SSL.TLSv1_1_METHOD,
SSL.TLSv1_2_METHOD]
context = OpenSSL.SSL.Context(version)
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.settimeout(CONNECTION_TIMEOUT)
connection = OpenSSL.SSL.Connection(context,soc)
connection.connect((host,port))
connection.do_handshake()
#wants to check version here
i want to check the version on handshake
The relevant functions to check the version both client and server use for the remaining session in pyOpenSSL are get_protocol_version_name or get_protocol_version:
connection.do_handshake()
#wants to check version here
print(connection.get_protocol_version_name())
Note that these functions are only available since pyOpenSSL 0.16.0
Please not also that you cannot specify a list of TLS methods when creating the context but only a single method which essentially specifies the minimal TLS version supported by the client. Thus
context = OpenSSL.SSL.Context(SSL.TLSv1_METHOD)
allows the client to use TLS 1.0 and better. If you instead use SSL.TLSv1_2_METHOD the client would be restricted to TLS 1.2 and better and thus could not establish a SSL connection with a server supporting only TLS 1.0.
Find SSL Version after Handshake in OpenSSL...
If I am parsing what you want correctly... you want the protocol version like printed by openssl s_client:
$ openssl version
OpenSSL 1.1.0b 26 Sep 2016
$ openssl s_client -connect www.google.com:443 -servername www.google.com
CONNECTED(00000005)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
Server did acknowledge servername extension.
---
...
---
New, TLSv1.2, Cipher is ECDHE-RSA-CHACHA20-POLY1305
Server public key is 2048 bit
Secure Renegotiation IS supported
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
...
The first message of "New, TLSv1.2" tells you about the cipher. That is, when is ECDHE-RSA-CHACHA20-POLY1305 first arrived in TLS. In the case of ECDHE-RSA-CHACHA20-POLY1305, the cipher suite was first seen in TLS 1.2.
The source code for s_client is located at <openssl src>/apps/s_client.c. The code responsible in OpenSSL 1.0.2 is around line 2210:
/* line 2210 */
c = SSL_get_current_cipher(s);
BIO_printf(bio, "%s, Cipher is %s\n",
SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
...
The second message of "Protocol: TLSv1.2" tells you the protocol version used during key exchange and subsequent cipher selection and bulk transfer.
The code responsible in OpenSSL 1.0.2 is <openssl src>/ssl/ssl_txt.c around line 105:
/* line 105 */
int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
{
unsigned int i;
const char *s;
if (x == NULL)
goto err;
if (BIO_puts(bp, "SSL-Session:\n") <= 0)
goto err;
if (x->ssl_version == SSL2_VERSION)
s = "SSLv2";
else if (x->ssl_version == SSL3_VERSION)
s = "SSLv3";
else if (x->ssl_version == TLS1_2_VERSION)
s = "TLSv1.2";
else if (x->ssl_version == TLS1_1_VERSION)
s = "TLSv1.1";
else if (x->ssl_version == TLS1_VERSION)
s = "TLSv1";
else if (x->ssl_version == DTLS1_VERSION)
s = "DTLSv1";
else if (x->ssl_version == DTLS1_2_VERSION)
s = "DTLSv1.2";
else if (x->ssl_version == DTLS1_BAD_VER)
s = "DTLSv1-bad";
else
s = "unknown";
if (BIO_printf(bp, " Protocol : %s\n", s) <= 0)
goto err;
...
}
I want to find out the protocols supported by a target but the problem is that their are quite a number websites which are not supporting a particular version but when i performed handshake ...
This is a different problem. You should look at the source code for sslscan at SSLScan - Fast SSL Scanner to see how it works. The Sourceforge one seems abandoned. It lacks SNI and other new features, like secure negotiation and ALPN.
You might try this sslscan from GitHub: rbsec/sslscan. The GitHub one is actively maintained and seems to be more up to date.
example : i passed a version :TLSVersion.TLS_1_2 but the handshake is performed using TLSv1_0 becz it is not supporting TLSVersion.TLS_1_2
This will not happen. TLS specifies one protocol version only. The idea is your try TLS 1.2. If it fails, then you fall back to TLS 1.1. If it fails, then you fall back to TLS 1.0. Ad infinitum.
The try-and-fallback approach is the reason for RFC 7504, TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks. This was an awful band-aide from the Browser crowd. See, for example, Last Call: <draft-ietf-tls-downgrade-scsv-03.txt> (TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks) to Proposed Standard.
TLS does not accept a range of protocol versions like many folks think. We have tried to get it changed a few times. See, for example, A new TLS version negotiation mechanism.
I had set up a 6-node Cassandra cluster spanning two AWS regions / datacenters (3 in each) and everything was working fine. After getting that much working I attempted to enable internode encryption which I cannot get to work properly, despite reading innumerable documents on the subject and fiddling endlessly.
I don't see any errors or anything out of the ordinary in the logs. I do see the following line in the logs which indicates it has started the encrypted messaging service, as expected:
MessagingService.java:482 - Starting Encrypted Messaging Service on SSL port 7001
I have enabled verbose logging for SSL in cassandra-env.sh, however this does not produce any errors or additional information about SSL internode connections that I can see (update below):
JVM_OPTS="$JVM_OPTS -Djavax.net.debug=ssl"
I can connect to from one node to all the others on the encrypted messaging port 7001 using nc, so there's no firewall issue.
ubuntu#ip-5-6-7-8:~$ nc -v 1.2.3.4 7001
Connection to 1.2.3.4 7001 port [tcp/afs3-callback] succeeded!
I can connect to each node locally using cqlsh (I haven't enabled client-server encryption) and can query the system keyspace, etc.
However, if I run nodetool status I see that the nodes cannot see each other. Only the node that I'm querying the cluster on is present in the list. This was not the case before internode encryption was enabled, they could all see each other just fine then.
ubuntu#ip-5-6-7-8:~$ nodetool status
Datacenter: us-east_A
=====================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns Host ID Rack
UN 1.2.3.4 144.75 KB 256 ? 992ae1bc-77e4-4ab1-a18f-4db62bb0ce6f 1b
My process was this:
Created a certificate authority for my cluster
Created a keystore and truststore for each node and added my CA certificate chain to both
Generated a key pair and CSR for each node, signed it with my CA, and added the resulting certificate to each node's keystore
Updated each node's configuration as reads below
Restarted all nodes
The server encryption configuration I'm using is this, with the appropriate values in the $variables.
server_encryption_options:
internode_encryption: all
keystore: $keystore_path
keystore_password: $keystore_passwd
truststore: $truststore_path
truststore_password: $truststore_passwd
require_client_auth: true
protocol: TLS
algorithm: SunX509
store_type: JKS
cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
If anybody could offer some insight or a direction to look in it would be greatly appreciated.
Update: Cipher Suite Agreement
Apparently SSL debug logging prints to stdout, which is not logged to Cassandra's logfiles, so I didn't see that output before. Running Cassandra in the foreground I can see a ton of SSL errors tracing out, all of which complain of handshake failure, because:
javax.net.ssl.SSLHandshakeException: no cipher suites in common
In an attempt to solve this problem I have switched to the Oracle JRE (I was being lazy and using OpenJDK before) and installed the JCE unlimited strength cryptography policy files to ensure all possible ciphers would be supported.
It didn't fix anything.
This is especially confusing given that all these nodes are exactly identical: hardware, OS vendor and version, Java vendor and version, Cassandra version, and configuration file. I cannot imagine why they cannot agree on a cipher suite under these circumstances.
The following is the full error that is traced:
*** ClientHello, TLSv1.2
RandomCookie: GMT: 1449074039 bytes = { 205, 93, 27, 38, 184, 219, 250, 8, 232, 46, 117, 84, 69, 53, 225, 16, 27, 31, 3, 7, 203, 16, 133, 156, 137, 231, 238, 39 }
Session ID: {}
Cipher Suites: [TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
***
%% Initialized: [Session-3, SSL_NULL_WITH_NULL_NULL]
%% Invalidated: [Session-3, SSL_NULL_WITH_NULL_NULL]
ACCEPT-/1.2.3.4, SEND TLSv1.2 ALERT: fatal, description = handshake_failure
ACCEPT-/1.2.3.4, WRITE: TLSv1.2 Alert, length = 2
ACCEPT-/1.2.3.4, called closeSocket()
ACCEPT-/1.2.3.4, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
ACCEPT-/1.2.3.4, called close()
ACCEPT-/1.2.3.4, called closeInternal(true)
INFO 16:33:59 Waiting for gossip to settle before accepting client requests...
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
ACCEPT-/1.2.3.4, setSoTimeout(10000) called
ACCEPT-/1.2.3.4, READ: SSL v2, contentType = Handshake, translated length = 57
After a great deal more poking and prodding I've finally managed to get this to work. The problem was related to certificates and the keystore.
As a result of these problems the SSL handshake would fail either due to certificate chain problems or cipher suite agreement problems. Cassandra rather unhelpfully discards errors related to SSL and logs nothing.
In any case, I managed to get things working by doing the following:
Ensure that the CA generates node certificates with both client and server key usage attributes. Failing to include one or the other will prevent nodes from authenticating to each other properly. This presents itself as the cipher suite agreement error. If you're using OpenSSL to manage your CA, I've included the -extensions configuration I used below.
Ensure that both the root and any intermediate CA certificates you are using (if you're using an intermediary CA) are imported into both the keystore and truststore.
Ensure that the node certificate imported into the keystore includes the full trust chain from the primary certificate down to the CA root, including any intermediaries – even though you have already imported these CA certificates separately into the keystore. Failing to do this presents itself as an invalid certificate chain errors.
OpenSSL CA Config
Here's my extensions section for dual-role client/server certificates. You can include this in your OpenSSL config file and reference it when signing by specifying -extensions dual_cert.
[ dual_cert ]
# Extensions for dual-role user/server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, server
nsComment = "Client/Server Dual-role Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
Creating a PEM containing the full trust chain
To create a single PEM file which contains the full trust chain for your node certificate, simply cat all the certificate files in reverse order from the node certificate down to the CA root.
cat node1.crt ca-intermediate.crt ca-root.crt > node1-full-chain.crt