ssl negotiation happens multiple times for same domain - ssl

I've done a speedtest with webpagetest. My website is SSL secured. For some reason the SSL Negotiation happens twice.
There is one SSL negotiation for the index html which seems to be correct. The second request is done by fetch. I assume that the second SSL negotiation is not neccessary.
fetch("/api/menu")
For the remaining requests to the same domain there are no more negotiations.

There is first a TCP connect for menu which is then followed by the SSL setup. This means that it is not using the previously established TCP connection for the new connection but creates a new one. And this new one of course needs SSL too.
It is quite normal that browsers have several connections open to the same site when HTTP/1.1 is in use since only a single request can be handled at a time within one connection (this is different with HTTP/2). Since in your case the first connection is still in use for other requests, creating a new connection might speed up the total delivery time.
It can also be seen that the second SSL setup takes less time than the first. This is probably because it is doing a session resume, i.e. using the same SSL session as established in the first connection which speeds up the TLS handshake.

Related

Multiple SSL/TLS handshakes despite Keep-Alive and Session Identifier/Ticket enabled

I have some trouble finding out why I'm experiencing several SSL/TLS handshakes on the same page (for several resources on the same page, i.e. multiple HTTP requests), when both Keep-Alive and Session Identifiers/Tickets are active on the website/server.
I've recently activated TLS (https) on my website and therefore I wanted to check what impact this had on the speed/load performance of the site. When going through the waterfall diagram from both various speed tests on the internet (e.g. tools.pingdom.com and webpagetest.org) and Chrome Developer Tools, i see multiple SSL handshakes/negotiations on the same page, on different content. You can see an image of this here:
As can be seen, there are multiple SSL negotiations on different http requests within the same domaian. I'm wondering about this, as both Keep-Alive and Session identifiers & -tickets are active (checked via multiple tests such as the ones from webpagetest.org and ssllabs.com/ssltest/). Please do also note that I dont have access to the server (apache) configurations as I'm on a shared host.
Is what I'm experiencing possibly:
due to the server configuration limiting some amount of connections?
a misconfiguration of some sort?
something entirely else?
Me that have misunderstood something?
Please note that I'm a complete rookie in this field, but I've tried to find as much information regarding this topic, but sadly not an answer.
In case you would like to test something for yourself, the website is https://www.aktie-skat.dk
It is normal for a browser to establish multiple parallel connections to the same site since each connection can only request and load a single resource at a time. Even with HTTP keep-alive these resources do not get loaded in parallel over a single HTTP/1.x connection but only one after the other. This is only different with HTTP/2. Apart from that some requests might result in an Connection: close from server which requires the client to use a different connection for the next requests.
In detail: The first two handshakes start at 0.362s and 0.333s and take each about 100ms. These are full handshakes. All the other TLS handshakes are way shorter (about 50ms) and are thus abbreviated handshakes using session resume. The second TCP/TLS connection could not use session resume yet since the TLS handshake for the first connection was not done yet and thus no session was available for resume.

TCP Load Balancer In Front of TLS/SSL Endpoints

Last week I was playing with a load balancer for my TLS-enabled endpoints (share the same certificate) and was surprised it is possible to have TPC load balancer in place in front of SSL endpoint. Having that configured it was possible to communicate with TCP load balancer as like it configured to support TLS/SSL. So, I would like to ensure such a network configuration is fully working solution:
TLS/SSL session and handshake workflow are stateless, meaning it is possible to start handshake with a primary server and end it with a mirror. Is it true?
Are there any hidden dangers I must be aware of?
If previous statements are true, what the reason to to do all TLS/SSL work on a load balancer itself?
P.s. the reason I do not do TLS/SSL work on a load balancer is that I need to balance multiple proprietary endpoint only supports SSL/TLS.
TLS/SSL session and handshake workflow are stateless, meaning it is possible to start handshake with a primary server and end it with a mirror. Is it true?
No. I suspect your load balancer is using TCP keep-alive so that the handshake is completing on the same server every time.
Are there any hidden dangers I must be aware of?
You may be incurring a significant performance penalty. HTTPS has "session keys" that are, probably by default, unique to the server. If you aren't able to do something like sticky sessions with the load balancer, then you will do a full handshake every time a client moves from one server to the other.
You also will have session tickets that won't work between servers, so session resumption will probably not work either, and fall back to a full handshake. Some servers support configuring a common session ticket key, like nginx.
If previous statements are true, what the reason to to do all TLS/SSL work on a load balancer itself?
Well, they aren't entirely true. There are other benefits though. The main one being that the load balancer can be more intelligent since it can see the plaintext of the session. An example might be examining the request's cookies to determine which server to send the request to. This is a common need for blue/green deployments.

gnutls and openssl handshake in NGINX

I'm testing SSL/TLS stream proxying within NGINX that will connect to a web server using gnutls as the underlying TLS API. Using the command line test tool in gnutls (gnutls-serv) the entire process works, but I can't understand the logic:
the NGINX client (proxying HTTP requests from an actual client to the gnutls server) seems to want to handshake the connection multiple times. In fact in most tests it seems to handshake 3 times without error before the server will respond with a test webpage. Using wireshark, or just debugging messages, it looks like the socket on the client side (in the perspective of the gnutls server) is being closed and reopened on different ports. Finally on the successful connection, gnutls uses a resumed sessions, which I imagine is one of the previously mentioned successful handshakes.
I am failing to find any documentation about this sort of behaviour, and am wondering if this is just an 'NGINX thing.'
Though the handshake eventually works with the test programs, it seems kind of wasteful (to have multiple expensive handshakes) and implementing handshake logic in a non-test environment will be tricky without actually understanding what the client is trying to do.
I don't think there are any timeouts or problems happening on the transport, the test environment is a few different VMs on the same subnet connected between 1 switch.
NGINX version is the latest mainline: 1.11.7. I was originally using 1.10.something, and the behaviour was similar though there were more transport errors. Those errors seemed to get cleaned up nicely with upgrading.
Any info or experience from other people is greatly appreciated!
Use either RSA key exchange between NGINX and the backend server or use SSLKEYLOGFILE LD_PRELOAD for NGINX to have the necessary data for Wireshark to decrypt the data.
While a single incoming connection should generate just one outgoing connection, there may be some optimisations in NGINX to fetch common files (favicon.ico, robots.txt).

SSL Handshakes on connection setup

When I test my website performance I noticed SSL handshakes are happening as part of connection setup. I understand the first request (of the page) needs the full SSL handshake.
But, if you notice from the pingdom test, only certain other resources are doing the SSL handshake. The remaining requests in the page do not.
Can someone please explain the logic behind this.
Resources that are loaded via HTTPS will have their own SSL handshake if new TCP connections are used to retrieve them. If HTTP keep-alives are used, resources on the same server may be retrieved using existing connections. Resources retrieved via HTTP instead of HTTPS, or reside on different servers/domains, will have to use separate connections.
Your test results are fairly useless for diagnosing this, without knowing which resources are being retrieved, where they are being retrieved from, and what protocol they are being retrieved with.

haproxy single socket per client cert

Is is possible to configure HAProxy to only allow single connection per client certificate (based on CN or other attribute)?
Each client should be able to connect even if it has already open connections, though, after successful authentication any previous connection for that certificate should be dropped immediately.
I do not think ACL's would work for this purpose.
Thanks in advance