OpenSSL session parameters output fails when run via cron for TLS1.3
During work this week to deploy TLS1.3 to our traffic management system, one of my colleagues discovered that one of our new, automated tests for TLS1.3 which validates that TLS session resumption is configured and working as required worked fine when run manually (interactively, in a terminal) but failed when run via cron (which is one way our tests are run). This prompted a bit of digging and a message thread on the openssl users mailing list.
The test we run is a two-phase test, using the
-sess_out <filename> and
-sess_in <filename> directives of
openssl. These directives respectively output and input TLS session parameters to/from a file (stdout/stdin is not possible unfortunately). We use openssl for two operations in series, one which creates the TLS connection and outputs the session parameters then the next which takes those session parameters and attempts to resume the TLS session. The TLS1.3 test initially looked like this:
/path/to/openssl s_client -connect <server address>:443 -tls1_3 -sess_out /path/to/tls_session_params_file /path/to/openssl s_client -connect <server address>:443 -tls1_3 -sess_in /path/to/tls_session_params_file
We grep the output of the second operation for
Reused in the relevant section to verify that the TLS session was resumed successfully.
This worked fine when run interactively but silently failed when run via cron (in that the session parameters file was not being written).
After some suggestions fromsome of the openssl users mailing list members and testing of those suggestions, it emerged that a combination of Matt Caswell's suggestion and Jakob Bohm's suggestion were required. Since it's something of an edge case and I couldn't find any information, I thought it might be useful to document it.
I'll pull out the relevant suggestion specifics here:
Matt's suggestion was:
My guess is that s_client is closing the connection before the server has had a chance to send its new session tickets. You might want to experiment with the -ign_eof option to s_client. This will keep s_client running even after having hit EOF from stdin.
Jakob's suggestion was:
Maybe cron jobs are run without a valid stdin handle (rather than a readable handle at EOF), in which case explicitly adding "</dev/null" may be a fix.
This resulted in a change to our tests as follows:
/path/to/openssl s_client -connect <server address>:443 -tls1_3 -sess_out /path/to/tls_session_params_file -ign_eof </dev/null /path/to/openssl s_client -connect <server address>:443 -tls1_3 -sess_in /path/to/tls_session_params_file
(note the addition of
-ign_eof </dev/null to the first operation)
Which fixes the problem.