Consider this scenario:
[wanting to write] [sent token success]
Application -------> SSL ----------->
| *peer drops*
[waiting to read] |
***blocked***<------------
In other words, your application wants to write something, but the SSL internal state is WANT_READ. On the other end, the peer connection has dropped.
Can SSL detect this through some keep-alive check of it's own? What can you do in this case?
SSL usually leaves detection of connection problems to the underlying transport layer, i.e. TCP. This means that by using TCP keep alive it can be detected if the peer vanishes without proper connection close. Apart from that there is also the heartbeat extension at the TLS level but contrary to TCP keep alive it is not universally supported.
If SSL detects a connection that hasn't been correctly terminated from SSL's point of view via an SSL close_notify message, it will regard it as a truncation attack, and will give you an error message or an exception, depending on which API you are using.
your application wants to write something, but the SSL internal state is WANT_READ. On the other end, the peer connection has dropped.
What it wants you to read is either the close_notify or the error message or exception. Whatever the case, when it says WANT_READ, you have to read.
Related
What I wish to achieve:
When establish a connection, prevent user from sending any message until the connection had finished all the setup (with STUN/TURN server etc)
When there is a sudden disconnect, prevent the user from sending any message until the connection is re-established.
My best guess is either one of the event handler below will do the trick, but I don't know which one, and don't know what are the differences between the two.
onconnectionstatechange()
oniceconnectionstatechange()
oniceconnectionstatechange doesn't include the establishment of the DTLS handshake on top of the ice connection.
Use onconnectionstatechange to detect when the connection is fully established and also to detect disconnections.
I loaded a client-side .svclog file inside Microsoft Service Trace Viewer and there are a lot of entries in the log saying setting up secure session and close secure session. On the server side, I can see many instances of trust/RST/SCT/Cancel, indicating that the connections are being closed on the server side, but only after giving a response to a SOAP message. It seems like every web service call involves setting up a TLS session for SOAP, and then the connection being closed immediately after sending a response, requiring that TLS be set up again for the very next call.
I read this article: https://blogs.technet.microsoft.com/tspring/2015/02/23/poor-mans-guide-to-troubleshooting-tls-failures/
It said:
Keep in mind that TCP resets should always be expected at some point as the client closes out the session to the server. However, if there are a high volume of TCP resets with little or no “Application Data” (traffic which contains the encapsulated encrypted data between client and server) then you likely have a problem. Particularly if the server side is resetting the connection as opposed to the client.
Unfortunately, the article doesn't expand on this, because it is exactly what I am seeing!
This is a net.tcp web service installed in some customer environment, set up to use Windows authentication.
What's the next step in my diagnosis?
Most likely the behavior you are seeing is normal, and unless you are experiencing some problems I would not be concerned. The MSFT document you quote is referring to TCP resets, but you said your logs show trust/RST/SCT/Cancel entries, and in that context RST means RequestSecurityToken. In other words, your log messages don't in any way imply that there are TCP reset (RST) frames occurring.
The Web Services Secure Conversation Language (WS-SecureConversation) spec (here) says:
It is not uncommon for a requestor to be done with a security context
token before it expires. In such cases the requestor can explicitly
cancel the security context using this specialized binding based on
the WS-Trust Cancel binding. The following Action URIs are used with
this binding:
http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT/Cancel
http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/SCT/Cancel
Once a
security context has been cancelled it MUST NOT be allowed for
authentication or authorization or allow renewal. Proof of possession
of the key associated with the security context MUST be proven in
order for the context to be cancelled.
If you actually are experiencing transport problems due to unexpected TCP RST frames, or if you are seeing them and are curious to understand their underlying cause, then you'll need to capture network traffic to see how and why TCP resets are occurring, and whether they are normal or abnormal.
I'd do that by firing up WireShark and looking at the frames. If you see FIN, ACK messages from each side then you expect the connection to be closed gracefully after a waiting period. Otherwise you'll see RST frames for a variety of reasons: application resets (performed to avoid tying up a lot of ports in Wait states), bad sequence number when re-accessing a port that's in a Wait state, router or firewall RST messages (typically sent both directions), retransmit timeouts, port choice RST messages, and others.
There are lots of resources to help with TCP traffic analysis. You might find it helpful to take a look at https://blogs.technet.microsoft.com/networking/2009/08/12/where-do-resets-come-from-no-the-stork-does-not-bring-them/ for a quick overview.
If you're not familiar with WireShark it can seem a little complicated, but the thing you want to do here is very simple and you can get your answer very quickly even with no prior experience. Just search for wireshark tutorials and you'll find one that fits your cognitive style.
You can also use WireShark to troubleshoot higher level protocols, including TLS. You can find information about that in many places. I'll just list a few to get you started:
WireShark documentation on SSL is here.
Wikiversity section on HTTPS is here.
A 5-minute youtube tutorial for looking at SSL traffic is here.
I believe this covers your next diagnostic step reasonably well, but if not, feel free to post more information and I can try to provide a better answer.
On this previous question: Tell when wcf client lost connection One of the commenters states:
Your service should not care whether a network cable was disconnected.
One feature of TCP is that unless someone is actively sending data, it
can tolerate momentary interruptions in network connectivity.
This is even more true in WCF, where there are layers of extra
framework to help protect you against network unreliability.
I'm having an issue where this is not working correctly. I have WCF client that makes a connection to the server using a DuplexChannelFactory. The connection stays open for 3 minutes. I disconnect the client from the internet and reconnect. The client regains internet connection, however any calls made from the server to that client fail. Once the client reconnects it begins working again.
When I pull the plug on the internet, the client throws several exceptions but the channel is still listed as being in an open state. Once the connection is regained and I made a request from the server to the client, I get errors such as: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted.
Obviously if the request comes in when the client is offline it won't work, but I'm trying to get it so this channel will recover once the internet comes back without having to set up a new connection.
Should this be working as-is, based on the comment I listed above? Or is there something I need to change to make that actually work?
The issue here is that the channel you're trying to use is in a faulted state, and cannot be used any longer (as the error message indicates).
Your client needs to trap (catch) that exception, and then abort the current channel and create a new one. WCF will not do that for you automatically, you have to code for it yourself.
You could also check the CommunicationState of the channel to see if it is faulted, and recover that way.
A final option would be to use the OnFaulted event handler, and when the channel is faulted, abort the channel and create a new one.
I am new to TLS/SSL. I am facing an issue with SSL/TLS connectivity.
I could see in tcpdump traces that the handshake is done succefully(clienthello,serverhello,certificate,certifcate request,server hello done, client certificate, client key exchange,certificate verify,change cipher suite exchange and finished message from both server and client side). My understanding is that if finished message exchnaged means handshake is completed. Is it correct?
After 'finished' message, Client sending application data which is http get request. There is no response from server for ~2 minutes and client is sending an alert close_notify after that.
"11905 14:51:54.122049 10.62.73.221 10.62.68.4 TLSv1 105 Alert (Level: Warning, Description: Close Notify)"
Alert message 21 is received by server.
could any one please explain why the alert message has been received by server.?
Thanks for support.
Well, with the details in your question, it could be that the GET request is not properly formed or the TLS Record is not proper - perhaps there is a discrepancy in the payload specified and what it is. Are you constructing the TLS Record on your own or using an established library? It seems, that since you are new to SSL, an established library is being used. In this case, please make sure that the GET Request is formatted as per the HTTP spec with the necessary HTTP headers.
close_notify is normal. Nothing to be alarmed about. It is just the TLS version of close().
I have a situation where my (non netty) client is closing the SSLSocket but not the underlying Socket. This does exactly what would be expected it sends a close_notify to the server, which replies with a close_notify.
However my server is Netty based, and uses SSLHandler, by adding a LoggingHandler() I can see it getting the close_notify, and responding with a close_notify. The problem is my upstream handlers get no notifications at all, as the underlying Socket is not closing so there is no disconnect. I specifically want the sockets to remain open.
What I need is to get a notification that the SSLHandler has shutdown, so I can remove the SLLHandler from the pipeline and continue communicating with normal TCP.
Is this possible in Netty?
As part of my investigations I tried closing the SSlHandler from the server/netty side, and that would work except Netty closes down the sslhandler before getting the clients close_notify (as per design and spec), the trouble is that any subsequent read of the underlying socket gets that close_notify as raw data as the SslHandler has shutdown. If possible I would rather not have to write a handler that duplicates the SslEngines job of reading SSL messages. I understand why SSlHandler does not wait for the clients close_notify reply, which is why I tried to do it from the client side where I have more control of the SSL sockets.