On 06/04/2013 03:39 AM, Conor McCarthy wrote:
On 3 June 2013 23:07, Rick Jones <[email protected]> wrote:

Hi -

I am very much a noob when it comes to SSL, and have a question
concerning a Close Notify Alert message.  Doing some web searching
suggests that at least some of the "commercial" load balancers
support disabling sending a close notify.  Thusfar I've not seen
anything similar in Pound.

Just how "according to Hoyle" should one be when it comes to
support for Close Notify?

I ask because I see a situation where a client out on the Big Bad
Internet (tm) is connecting through a (stateful) firewall to a
service over SSL. The service is using Pound to terminate the SSL.
The client requests something from the service, and the service
sends the data. When the last bytes of the data arrive at the
client, the client does a close() on the connection.  All well and
good, except the service seems to be sending a close notify alert
message, which is in flight at the time the client closes the
connection.


From http://www.openssl.org/docs/ssl/SSL_shutdown.html

     The shutdown procedure consists of 2 steps: the sending of the
``close notify''
     shutdown alert and the reception of the peer's ``close notify''
shutdown alert.

     According to the TLS standard, it is acceptable for an application
to only send
     its shutdown alert and then close the underlying connection without waiting
     for  the peer's response (this way resources can be saved, as the process
     can already terminate or serve another connection). When the underlying
     connection shall be used for more communications, the complete shutdown
     procedure (bidirectional ``close notify'' alerts) must be
performed, so that the
     peers stay synchronized.

So, the first part suggests the "most correct" thing to do is for the two peers to exchange close notify messages - send a close notify, wait to receive a close notify, close the connection yes?

But that second bit - allowing an application to send a close notify and close is then setting things up for the very TCP RST situation described in my initial message. Unless I'm missing something of course. One side sends a close notify and calls close(). The other side receives it, sends its own close notify, and bam, TCP RST (which may well be lost), followed by retransmissions of the TCP segments carrying the second close notify message.

Similarly for simultaneous closes by the peers though without the retransmissions. Each close notify message will find a close()ed TCP endpoint, triggering a RST in each direction and no more transmissions.

Unless it was supposed to be assumed that the client would do:

shutdown(SHUT_WR)
<wait via some means for the read return of zero indicating peer TCP FIN arrived>
close()

but in terms of time and calls, that would be no different really from waiting for a close notify from the peer. In fact, if I've understood the above correctly, the client would end-up "draining" a peer close notify message in the process of getting to the read return of zero on the socket.


This message hits the client, and since the client called close(),
TCP issues a ReSeT segment.  Generally speaking, apart from
bypassing the data integrity protections of TIME_WAIT this is not
*that* big a deal..., but the firewall in the middle sees the RST
and closes-off access.


The client SSL behaviour is not correct, badly implemented clients are
common, and unavoidable. See RFC2246 §7.2.1. close_notify alerts are
not optional (see the retrospective RFC6101 §5.4.1 for SSLv3).

If it's really just calling close(), then it's doing it wrong, hence
the RST.. TCP handshaking and application handshaking are not the same thing.

Though they end-up interacting, per the above. It would seem there needs to be two flavors of close notify? One that says I'm closing the session but continuing the TCP connection, and another that says I'm going away completely - thus informing the peer it should not send a close notify of its own.

The in-protocol shutdown was added in SSLv3.0 to provide detection and
mitigation for truncation and connection close attacks (an issue in SSL2.0),
so not properly supporting this  may have some effect on the security of
connections.


Meanwhile, the RST segment gets lost somewhere in the Big Bad
Internet (tm), and TCP on the Pound server continues to retransmit
the TCP segment containing the close notify.  These hit the
firewall, which discards them and logs a "DENY" message.

Again, probably all well and good, except the owner of the firewall
is particularly attentive to those log entries and is rather
determined to see them go away.


"out of state" packet drops, also unavoidable.

There are no calls to "SSL_CTX_set_quiet_shutdown()" in the Pound source,
so you would need to patch it to add this. There are possibly some
subtleties around the use of blocking or non-blocking I/O and calling
SSL_shutdown() twice. The shutdown in Pound is done via the "clean_all"
macro, it only calls one shutdown, and does not check the return code to
see if a second is required. Perhaps someone here who's more familiar
with the code could help fill in some details.

So, the question - convince Pound to make sure that no close notify
is sent, or convince the client side to make sure it waits for a
possible close notify to arrive?


The pragmatic approach might be to convince the other party  that there will
always be a level of noise logged when dealing with unknown (and poorly
written) clients.

Since the client is clearly out of spec, fixing that is the idealist
approach ;-)

Idealism. I remember that :) Are there "known, in-spec" SSL/TLS clients out there?

rick jones


C.

--
To unsubscribe send an email with subject unsubscribe to [email protected].
Please contact [email protected] for questions.



--
To unsubscribe send an email with subject unsubscribe to [email protected].
Please contact [email protected] for questions.

Reply via email to