Open Bug 415196 Opened 16 years ago Updated 2 years ago

SSL session resumption independent of IP addr/port

Categories

(NSS :: Libraries, enhancement, P3)

enhancement

Tracking

(Not tracked)

People

(Reporter: ngm+mozilla, Unassigned)

References

Details

(Keywords: perf)

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11
Build Identifier: 

NSS clients currently will only resume an SSL session if the following fields match:
* servername
* server IP
* server port
* peer ID

Matching against server IP and port breaks DNS based load balancing and does not  provide additional security -- afterall an attacker will be able to resume a session only if the session keys are already known to him.

Similarly, NSS servers check the following fields before they will resume a session:
* client IP address
* session ID

Checking client IP means that mobile clients are unable to resume sessions (e.g. a wireless laptop that periodically obtains new IP addresses via DHCP).

The attached patch:
1.removes the checks against server IP and port (for clients doing session cache lookups)
2. removes the check against client IP (for servers doing session cache lookups)

This patch improves the utility of the TLS Session Ticket Extension feature described in bug 403563 as well as resume rates for servers that are DNS-load-balanced.

Reproducible: Didn't try

Steps to Reproduce:
1.
2.
3.
Depends on: tlsste
I am marking this bug as dependent on 403563 just to keep tabs (it does not really depend on 403563).
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment on attachment 300805 [details] [diff] [review]
Ignore IP/port info when looking up SSL sessions

This patch would be a disaster for server systems that run multiple
separate servers on separate ports, with separate session spaces.  

First, let's look at the effect of ignoring ports.

Consider a server that offers, say, SMTPS, POP3S and IMAPS in separate 
processes on separate ports.  Consider that, after establishing a session 
with one of those servers, the client then tries to reuse that session 
with another of those servers.  That is one effect of the proposed patch. 
The second server doesn't recognize the session ID, or cannot restart the 
session, so it creates a new session, implicitly invalidating (replacing) 
the session the client tried to restart.  The result would be greatly 
decreased SSL session reuse, and much more frequent full SSL handshakes.  

Even in the highly unusual circumstance where a server system is able to 
share SSL sessions across multiple conceptually separate server processes 
on the same box, there is nothing wrong with having separate SSL sessions 
for use with each port.

It would be much more efficient to have a session per port, that gets 
restarted, than having each visit to a port invalidate the sessions 
established with other ports on the same server system.  

Ignoring IP address would have a similar effect.  Remember that "Peer ID"
and "URL" are optional and are not used by all products.  In fact, very 
few products use Peer ID at all.  So, the effect of this patch would be
to effectively leave the session lookup with no information on which to 
differentiate servers.  It would try the same session with all servers on
all ports.  That's a non-starter.

I'm highly inclined to resolve this bug WONTFIX.
Attachment #300805 - Flags: review-
(In reply to comment #3)
> (From update of attachment 300805 [details] [diff] [review])
> This patch would be a disaster for server systems that run multiple
> separate servers on separate ports, with separate session spaces.  
> 
> First, let's look at the effect of ignoring ports.
> 
> Consider a server that offers, say, SMTPS, POP3S and IMAPS in separate 
> processes on separate ports.  Consider that, after establishing a session 
> with one of those servers, the client then tries to reuse that session 
> with another of those servers.  That is one effect of the proposed patch. 
> The second server doesn't recognize the session ID, or cannot restart the 
> session, so it creates a new session, implicitly invalidating (replacing) 
> the session the client tried to restart.  The result would be greatly 
> decreased SSL session reuse, and much more frequent full SSL handshakes.  
> 

You make a good point about ports.  Port numbers should be checked; I had not considered multi-protocol clients, of which I support Netscape Communicator is a good example.

> Even in the highly unusual circumstance where a server system is able to 
> share SSL sessions across multiple conceptually separate server processes 
> on the same box, there is nothing wrong with having separate SSL sessions 
> for use with each port.
> 
> It would be much more efficient to have a session per port, that gets 
> restarted, than having each visit to a port invalidate the sessions 
> established with other ports on the same server system.  
> 
> Ignoring IP address would have a similar effect.  Remember that "Peer ID"
> and "URL" are optional and are not used by all products.  In fact, very 
> few products use Peer ID at all.  So, the effect of this patch would be
> to effectively leave the session lookup with no information on which to 
> differentiate servers.  It would try the same session with all servers on
> all ports.  That's a non-starter.
> 

How are certificates verified in cases where there is no "URL"?  Do the certificates have IP addresses in them?  If not, then it is a bug to only check the IP address and port.

> I'm highly inclined to resolve this bug WONTFIX.  

This sounds fine to me, this fix is not necessary for session tickets to work well (DNS pinning will take care of session resumes), but in general there is no need to check IP addresses, but rather the "name" that has been verified in the server's certificate.  Retrofitting this behavior into NSS based applications may be more effort than it is worth.

There is also a portion of this patch that addresses server side session lookup: servers will only resume a session if the client's IP address matches the IP address that was used when originally creating the session.  This means that mobile clients will renegotiate whenever their IP address changes.  Is there a reason for this check?  (OpenSSL doesn't check the client IP address).
> How are certificates verified in cases where there is no "URL"? 

The criteria for validation of SSL/TLS certificates is explicitly outside of
the scope of the SSL/TLS specifications.  For that reason, and others, libSSL
does not (always) attempt to validate received certificates itself.  Instead,
it calls a callback function that is supplied by the application, and asks 
that function to validate the certificate (chain).  NSS also provides a 
function that can be used for this purpose.  An application can choose to 
pass NSS's own function to libSSL as that cert verification callback function,
or the application can create its own function for that purpose.  

When NSS calls the application-supplied callback, it passes certain arguments
to that function.  One of them is the "URL" pointer value that the application
may have previously registered with the SSL socket.  The meaning of the URL 
pointer is defined by the callback function, not by libSSL.  libSSL merely 
holds the value given by the application and passes it to the callback.

When NSS's own callback function is used for the cert verification callback
function, the "url" argument is taken to be the value of a name to be found in the certificate's SubjectAltName or Subject Common Name.  When some other callback function is used, the URL argument's meaning is unknown to libSSL.

> Do the certificates have IP addresses in them? 

Certificates may have IP addresses in them, and under some circumstances 
an IP address check may be used as a substitute for a host name check on 
the certificate.  Such certs are pretty rare, but not totally unknown.  
NSS has code to handle this.  I don't recall the details at the moment.
I keep thinking about this RFE.

There are server architectures in which servers operating on different boxes
in a server farm, and/or operating on different ports, can share a common SSL
session space.  Indeed, that is one of the major motivations for session 
tickets.  

It would be wrong, in general, for an SSL library to assume that servers on 
multiple IP addresses, or on multiple ports, could share a single TLS session
(and session ticket), and that fact is the basis for my reaction in comment 4.

But if a client somehow KNEW that it was talking to a server farm on a group
of IP addresses and/or port numbers, it should be able to tell NSS's libSSL
to attempt to reuse the same session (ticket) on one socket as had previously
been used on another for a different IP address and/or port number.  Today 
it cannot do so, with NSS's present APIs.  So, the challenge is to provide a
way for the application to do so, without losing any of libSSL's normal 
capabilities for matching SSL sessions to IP addresses, port numbers, and all
that other stuff.  

Here are some initial thoughts (thinking out loud) about how that might be done.

Have two new SSL socket options, with names something like SSL_IGNORE_PORT and
SSL_IGNORE_IP_ADDRESS.  These options would tell libSSL to behave somewhat 
differently when saving session info in the session cache, and also when fetching session info from the session cache.  I'm thinking they would be 
boolean options, that when set, caused NSS to use the number zero in place
of the true IP address and/or port number (respectively) when (a) storing an 
SSL session, and (b) trying to find a session with matching IP address and port.  Under those circumstances, finding a matching SSL session would be
done primarily based on the other session identifying attributes, such as 
"Peer ID" and "URL".  

For completeness, I should explain a little more about the optional "Peer ID" string attribute of SSL sockets.  This is optional, but when used, the suggested format for the PeerID string is:
   "<host name>:<port>:<user name>"
e.g. the output of 
   sprintf(buf, "%s:%s:%s", host_name, port, user_name);

This was originally devised to solve a problem that occurs when using an http 
proxy (or SOCKS proxy) to make SSL connections though a firewall.  When clients 
are configured to use a proxy, typically the "peer" at the other end of the TCP connection always has the same IP address and port number, and the true IP address of the destination server may be locally unknown (because clients behind the firewall typically cannot resolve host names that are not on the local intranet).  So, when using a proxy, indexing SSL sessions by the TCP 
peer's IP address and port is insufficient, because all connections have the same values for those.  So, the "Peer ID" provides a way for the client to differentiate SSL sessions among different servers that are accessed through 
a common IP address and/or port.  

But PeerID has been found to be useful even in cases where no http proxy is 
in use.  There are cases where a client represents multiple users 
simultaneously, each connected to a remote server, each authenticated in some
way, such that within the server, the user's identity is bound to the SSL 
session ID.  Frankly, this mostly occurs in testing scenarios, where one 
client process is trying to simulate the behavior of many clients, for load
testing a server, but there are rarely also other uses for this feature.
In such circumstances, it is desirable to have separate SSL sessions for each logical user, even when those sessions terminate in the same server at the 
same host name, IP address and port number.  Adding the user name to the 
PeerID string accomplishes that.

IINM, presently the Mozilla browser only uses the PeerID string when it is 
configured to use an http proxy.  But it could be changed to use it all the
time, in which case it might not depend so heavily upon IP address and port
number to index the SSL client session cache.

I think an enhancement along the lines I described above would be welcome.

I hope this information inspires someone ... (:-)
Priority: -- → P3
Version: unspecified → trunk
In the preceding comment, I meant to refer to comment 3, not comment 4. :-/
I believe that it is worth trying a strategy like the following:

Lookup: First, try to find an exact match in the cache, including the IP address and port. If no match, try to find an exact match in the cache, ignoring the IP address but requiring the port to match.

Invalidation, Addition, and Replacement:
* Match either the IP address or the session ticket bytes, along with the other fields. That is, if two sessions keys are identical, or if two session keys are identical except for IP address BUT they have the exact same session ticket, then consider them to be equal.
Keywords: perf
+1 for fixing this bug.

This issue prevents the use of FTPS for data transfers to servers that require a session reuse.

E.g. vsftpd with "require_ssl_reuse=YES" in vsftpd.conf.

In this scenario, the server port will never match and any client using NSS as its SSL/TLS backend will not be able to establish a data channel and do any transfer.

For details you can refer to:
https://bugzilla.redhat.com/show_bug.cgi?id=1552927
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: