You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by sh...@apache.org on 2018/10/30 20:56:27 UTC
[trafficserver] branch master updated: Enable reloadable
records.config client cert settings
This is an automated email from the ASF dual-hosted git repository.
shinrich pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new d483f49 Enable reloadable records.config client cert settings
d483f49 is described below
commit d483f4958fb642365b7d57d96906051dd1ae53f1
Author: Susan Hinrichs <sh...@oath.com>
AuthorDate: Tue Oct 23 13:47:43 2018 +0000
Enable reloadable records.config client cert settings
---
doc/admin-guide/files/records.config.en.rst | 4 +
iocore/net/SSLConfig.cc | 13 ++-
mgmt/RecordsConfig.cc | 8 +-
tests/gold_tests/tls/tls_client_cert.test.py | 154 +++++++++++++++++++--------
4 files changed, 125 insertions(+), 54 deletions(-)
diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst
index 152bf73..cc0c46b 100644
--- a/doc/admin-guide/files/records.config.en.rst
+++ b/doc/admin-guide/files/records.config.en.rst
@@ -3497,21 +3497,25 @@ Client-Related Configuration
:2: The provided certificate will be verified and the connection will be established
.. ts:cv:: CONFIG proxy.config.ssl.client.cert.filename STRING NULL
+ :reloadable:
The filename of SSL client certificate installed on |TS|.
.. ts:cv:: CONFIG proxy.config.ssl.client.cert.path STRING /config
+ :reloadable:
The location of the SSL client certificate installed on Traffic
Server.
.. ts:cv:: CONFIG proxy.config.ssl.client.private_key.filename STRING NULL
+ :reloadable:
The filename of the |TS| private key. Change this variable
only if the private key is not located in the |TS| SSL
client certificate file.
.. ts:cv:: CONFIG proxy.config.ssl.client.private_key.path STRING NULL
+ :reloadable:
The location of the |TS| private key. Change this variable
only if the private key is not located in the SSL client certificate
diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc
index f2290c9..018cfcf 100644
--- a/iocore/net/SSLConfig.cc
+++ b/iocore/net/SSLConfig.cc
@@ -68,7 +68,9 @@ char *SSLConfigParams::ssl_wire_trace_server_name = nullptr;
int SSLConfigParams::async_handshake_enabled = 0;
char *SSLConfigParams::engine_conf_file = nullptr;
-static ConfigUpdateHandler<SSLCertificateConfig> *sslCertUpdate;
+static std::unique_ptr<ConfigUpdateHandler<SSLCertificateConfig>> sslCertUpdate;
+static std::unique_ptr<ConfigUpdateHandler<SSLConfig>> sslConfigUpdate;
+static std::unique_ptr<ConfigUpdateHandler<SSLTicketKeyConfig>> sslTicketKey;
// Check if the ticket_key callback #define is available, and if so, enable session tickets.
#ifdef SSL_CTX_set_tlsext_ticket_key_cb
@@ -496,6 +498,11 @@ SSLConfigParams::getClientSSL_CTX() const
void
SSLConfig::startup()
{
+ sslConfigUpdate.reset(new ConfigUpdateHandler<SSLConfig>());
+ sslConfigUpdate->attach("proxy.config.ssl.client.cert.path");
+ sslConfigUpdate->attach("proxy.config.ssl.client.cert.filename");
+ sslConfigUpdate->attach("proxy.config.ssl.client.private_key.path");
+ sslConfigUpdate->attach("proxy.config.ssl.client.private_key.filename");
reconfigure();
}
@@ -523,7 +530,7 @@ SSLConfig::release(SSLConfigParams *params)
bool
SSLCertificateConfig::startup()
{
- sslCertUpdate = new ConfigUpdateHandler<SSLCertificateConfig>();
+ sslCertUpdate.reset(new ConfigUpdateHandler<SSLCertificateConfig>());
sslCertUpdate->attach("proxy.config.ssl.server.multicert.filename");
sslCertUpdate->attach("proxy.config.ssl.server.cert.path");
sslCertUpdate->attach("proxy.config.ssl.server.private_key.path");
@@ -654,7 +661,7 @@ SSLTicketParams::LoadTicketData(char *ticket_data, int ticket_data_len)
void
SSLTicketKeyConfig::startup()
{
- auto sslTicketKey = new ConfigUpdateHandler<SSLTicketKeyConfig>();
+ sslTicketKey.reset(new ConfigUpdateHandler<SSLTicketKeyConfig>());
sslTicketKey->attach("proxy.config.ssl.server.ticket_key.filename");
SSLConfig::scoped_config params;
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index c1dedd6..a03324f 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -1134,13 +1134,13 @@ static const RecordElement RecordsConfig[] =
,
{RECT_CONFIG, "proxy.config.ssl.client.verify.server.properties", RECD_STRING, "ALL", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
,
- {RECT_CONFIG, "proxy.config.ssl.client.cert.filename", RECD_STRING, nullptr, RECU_RESTART_TS, RR_NULL, RECC_STR, "^[^[:space:]]*$", RECA_NULL}
+ {RECT_CONFIG, "proxy.config.ssl.client.cert.filename", RECD_STRING, nullptr, RECU_DYNAMIC, RR_NULL, RECC_STR, "^[^[:space:]]*$", RECA_NULL}
,
- {RECT_CONFIG, "proxy.config.ssl.client.cert.path", RECD_STRING, TS_BUILD_SYSCONFDIR, RECU_RESTART_TS, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
+ {RECT_CONFIG, "proxy.config.ssl.client.cert.path", RECD_STRING, TS_BUILD_SYSCONFDIR, RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
,
- {RECT_CONFIG, "proxy.config.ssl.client.private_key.filename", RECD_STRING, nullptr, RECU_RESTART_TS, RR_NULL, RECC_STR, "^[^[:space:]]*$", RECA_NULL}
+ {RECT_CONFIG, "proxy.config.ssl.client.private_key.filename", RECD_STRING, nullptr, RECU_DYNAMIC, RR_NULL, RECC_STR, "^[^[:space:]]*$", RECA_NULL}
,
- {RECT_CONFIG, "proxy.config.ssl.client.private_key.path", RECD_STRING, TS_BUILD_SYSCONFDIR, RECU_RESTART_TS, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
+ {RECT_CONFIG, "proxy.config.ssl.client.private_key.path", RECD_STRING, TS_BUILD_SYSCONFDIR, RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
,
{RECT_CONFIG, "proxy.config.ssl.client.CA.cert.filename", RECD_STRING, nullptr, RECU_RESTART_TS, RR_NULL, RECC_STR, "^[^[:space:]]*$", RECA_NULL}
,
diff --git a/tests/gold_tests/tls/tls_client_cert.test.py b/tests/gold_tests/tls/tls_client_cert.test.py
index 4ebec4a..1973031 100644
--- a/tests/gold_tests/tls/tls_client_cert.test.py
+++ b/tests/gold_tests/tls/tls_client_cert.test.py
@@ -144,9 +144,10 @@ trbarfail.Processes.Default.TimeOut = 5
trbarfail.Processes.Default.Streams.stdout = Testers.ContainsExpression("Could Not Connect", "Check response")
trbarfail.TimeOut = 5
-tr2 = Test.AddTestRun("Update client cert file and reload")
+tr2 = Test.AddTestRun("Update config files")
# Update the SNI config
snipath = ts.Disk.ssl_server_name_yaml.AbsPath
+recordspath = ts.Disk.records_config.AbsPath
tr2.Disk.File(snipath, id = "ssl_server_name_yaml", typename="ats:config"),
tr2.Disk.ssl_server_name_yaml.AddLine(
'- fqdn: bar.com')
@@ -154,24 +155,52 @@ tr2.Disk.ssl_server_name_yaml.AddLine(
' client_cert: {0}/signed-bar.pem'.format(ts.Variables.SSLDir))
tr2.Disk.ssl_server_name_yaml.AddLine(
' client_key: {0}/signed-bar.key'.format(ts.Variables.SSLDir))
+# recreate the records.config with the cert filename changed
+tr2.Disk.File(recordspath, id = "records_config", typename="ats:config:records"),
+tr2.Disk.records_config.update({
+ 'proxy.config.diags.debug.enabled': 1,
+ 'proxy.config.diags.debug.tags': 'ssl|http',
+ 'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir),
+ 'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir),
+ 'proxy.config.http.server_ports': '{0}'.format(ts.Variables.port),
+ 'proxy.config.ssl.client.verify.server': 0,
+ 'proxy.config.ssl.server.cipher_suite': 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:RC4-MD5:AES128-SHA:AES256-SHA:DES-CBC3-SHA!SRP:!DSS:!PSK:!aNULL:!eNULL:!SSLv2',
+ 'proxy.config.ssl.client.cert.path': '{0}'.format(ts.Variables.SSLDir),
+ 'proxy.config.ssl.client.cert.filename': 'signed2-foo.pem',
+ 'proxy.config.ssl.client.private_key.path': '{0}'.format(ts.Variables.SSLDir),
+ 'proxy.config.ssl.client.private_key.filename': 'signed-foo.key',
+ 'proxy.config.url_remap.pristine_host_hdr' : 1,
+})
tr2.StillRunningAfter = ts
tr2.StillRunningAfter = server
tr2.StillRunningAfter = server2
-tr2.Processes.Default.Command = 'traffic_ctl config set proxy.config.ssl.client.cert.filename signed2-foo.pem; traffic_ctl config reload'
+tr2.Processes.Default.Command = 'echo Updated configs'
# Need to copy over the environment so traffic_ctl knows where to find the unix domain socket
tr2.Processes.Default.Env = ts.Env
tr2.Processes.Default.ReturnCode = 0
tr2.Processes.Default.TimeOut = 5
tr2.TimeOut = 5
+tr2reload = Test.AddTestRun("Reload config")
+tr2reload.StillRunningAfter = ts
+tr2reload.StillRunningAfter = server
+tr2reload.StillRunningAfter = server2
+tr2reload.Processes.Default.Command = 'traffic_ctl config reload'
+# Need to copy over the environment so traffic_ctl knows where to find the unix domain socket
+tr2reload.Processes.Default.Env = ts.Env
+tr2reload.Processes.Default.ReturnCode = 0
+tr2reload.Processes.Default.TimeOut = 5
+tr2reload.TimeOut = 5
+
+
#Should succeed
tr3bar = Test.AddTestRun("Make request with other bar cert to first server")
# Wait for the reload to complete
-tr3bar.DelayStart = 2
+tr3bar.DelayStart = 10
tr3bar.StillRunningAfter = ts
tr3bar.StillRunningAfter = server
tr3bar.StillRunningAfter = server2
-tr3bar.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case1'.format(ts.Variables.port)
+tr3bar.Processes.Default.Command = 'curl -H host:bar.com http://127.0.0.1:{0}/case1'.format(ts.Variables.port)
tr3bar.Processes.Default.ReturnCode = 0
tr3bar.Processes.Default.TimeOut = 5
tr3bar.Processes.Default.Streams.stdout = Testers.ExcludesExpression("Could Not Connect", "Check response")
@@ -182,73 +211,104 @@ tr3barfail = Test.AddTestRun("Make request with other bar cert to second server"
tr3barfail.StillRunningAfter = ts
tr3barfail.StillRunningAfter = server
tr3barfail.StillRunningAfter = server2
-tr3barfail.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case2'.format(ts.Variables.port)
+tr3barfail.Processes.Default.Command = 'curl -H host:bar.com http://127.0.0.1:{0}/case2'.format(ts.Variables.port)
tr3barfail.Processes.Default.ReturnCode = 0
tr3barfail.Processes.Default.TimeOut = 5
tr3barfail.Processes.Default.Streams.stdout = Testers.ContainsExpression("Could Not Connect", "Check response")
tr3barfail.TimeOut = 5
-# Skipping the last two cases until we get the certificate settings reloadable from records.config
-
#Should succeed
-#tr3 = Test.AddTestRun("Make request with other cert to second server")
+tr3 = Test.AddTestRun("Make request with other cert to second server")
# Wait for the reload to complete
-#tr3.StillRunningAfter = ts
-#tr3.StillRunningAfter = server
-#tr3.StillRunningAfter = server2
-#tr3.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case2'.format(ts.Variables.port)
-#tr3.Processes.Default.ReturnCode = 0
-#tr3.Processes.Default.TimeOut = 5
-#tr3.Processes.Default.Streams.stdout = Testers.ExcludesExpression("Could Not Connect", "Check response")
-#tr3.TimeOut = 5
-#
+tr3.StillRunningAfter = ts
+tr3.StillRunningAfter = server
+tr3.StillRunningAfter = server2
+tr3.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case2'.format(ts.Variables.port)
+tr3.Processes.Default.ReturnCode = 0
+tr3.Processes.Default.TimeOut = 5
+tr3.Processes.Default.Streams.stdout = Testers.ExcludesExpression("Could Not Connect", "Check response")
+tr3.TimeOut = 5
+
#Should fail
-#tr3fail = Test.AddTestRun("Make request with other cert to first server")
-#tr3fail.StillRunningAfter = ts
-#tr3fail.StillRunningAfter = server
-#tr3fail.StillRunningAfter = server2
-#tr3fail.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case1'.format(ts.Variables.port)
-#tr3fail.Processes.Default.ReturnCode = 0
-#tr3fail.Processes.Default.TimeOut = 5
-#tr3fail.Processes.Default.Streams.stdout = Testers.ContainsExpression("Could Not Connect", "Check response")
-#tr3fail.TimeOut = 5
+tr3fail = Test.AddTestRun("Make request with other cert to first server")
+tr3fail.StillRunningAfter = ts
+tr3fail.StillRunningAfter = server
+tr3fail.StillRunningAfter = server2
+tr3fail.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case1'.format(ts.Variables.port)
+tr3fail.Processes.Default.ReturnCode = 0
+tr3fail.Processes.Default.TimeOut = 5
+tr3fail.Processes.Default.Streams.stdout = Testers.ContainsExpression("Could Not Connect", "Check response")
+tr3fail.TimeOut = 5
+
# Test the case of updating certificate contents without changing file name.
trupdate = Test.AddTestRun("Update client cert file in place")
trupdate.StillRunningAfter = ts
trupdate.StillRunningAfter = server
trupdate.StillRunningAfter = server2
-trupdate.Setup.CopyAs("ssl/signed2-bar.pem", ".", "signed-bar.pem")
+# Make a meaningless config change on the path so the records.config reload logic will trigger
+trupdate.Setup.CopyAs("ssl/signed2-bar.pem", ".", "{0}/signed-bar.pem".format(ts.Variables.SSLDir))
+# in the config/ssl directory for records.config
trupdate.Setup.CopyAs("ssl/signed-foo.pem", ".", "{0}/signed2-foo.pem".format(ts.Variables.SSLDir))
-trupdate.Processes.Default.Command = 'traffic_ctl config reload'
+trupdate.Processes.Default.Command = 'traffic_ctl config set proxy.config.ssl.client.cert.path {0}/; touch {1}'.format(ts.Variables.SSLDir,snipath)
# Need to copy over the environment so traffic_ctl knows where to find the unix domain socket
trupdate.Processes.Default.Env = ts.Env
trupdate.Processes.Default.ReturnCode = 0
trupdate.Processes.Default.TimeOut = 5
-trupdate.TimeOut = 5
+
+trreload = Test.AddTestRun("Reload config after renaming certs")
+trreload.StillRunningAfter = ts
+trreload.StillRunningAfter = server
+trreload.StillRunningAfter = server2
+trreload.Processes.Default.Command = 'traffic_ctl config reload'
+trreload.Processes.Default.Env = ts.Env
+trreload.Processes.Default.ReturnCode = 0
+trreload.Processes.Default.TimeOut = 5
#Should succeed
-tr3bar = Test.AddTestRun("Make request with renamed bar cert to first server")
+tr4bar = Test.AddTestRun("Make request with renamed bar cert to second server")
# Wait for the reload to complete
-tr3bar.DelayStart = 2
-tr3bar.StillRunningAfter = ts
-tr3bar.StillRunningAfter = server
-tr3bar.StillRunningAfter = server2
-tr3bar.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case1'.format(ts.Variables.port)
-tr3bar.Processes.Default.ReturnCode = 0
-tr3bar.Processes.Default.TimeOut = 5
-tr3bar.Processes.Default.Streams.stdout = Testers.ExcludesExpression("Could Not Connect", "Check response")
-tr3bar.TimeOut = 5
+tr4bar.DelayStart = 10
+tr4bar.StillRunningAfter = ts
+tr4bar.StillRunningAfter = server
+tr4bar.StillRunningAfter = server2
+tr4bar.Processes.Default.Command = 'curl -H host:bar.com http://127.0.0.1:{0}/case2'.format(ts.Variables.port)
+tr4bar.Processes.Default.ReturnCode = 0
+tr4bar.Processes.Default.TimeOut = 5
+tr4bar.Processes.Default.Streams.stdout = Testers.ExcludesExpression("Could Not Connect", "Check response")
+tr4bar.TimeOut = 5
#Should fail
-tr3barfail = Test.AddTestRun("Make request with renamed bar cert to second server")
-tr3barfail.StillRunningAfter = ts
-tr3barfail.StillRunningAfter = server
-tr3barfail.StillRunningAfter = server2
-tr3barfail.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case2'.format(ts.Variables.port)
-tr3barfail.Processes.Default.ReturnCode = 0
-tr3barfail.Processes.Default.TimeOut = 5
-tr3barfail.Processes.Default.Streams.stdout = Testers.ContainsExpression("Could Not Connect", "Check response")
+tr4barfail = Test.AddTestRun("Make request with renamed bar cert to first server")
+tr4barfail.StillRunningAfter = ts
+tr4barfail.StillRunningAfter = server
+tr4barfail.StillRunningAfter = server2
+tr4barfail.Processes.Default.Command = 'curl -H host:bar.com http://127.0.0.1:{0}/case1'.format(ts.Variables.port)
+tr4barfail.Processes.Default.ReturnCode = 0
+tr4barfail.Processes.Default.TimeOut = 5
+tr4barfail.Processes.Default.Streams.stdout = Testers.ContainsExpression("Could Not Connect", "Check response")
+
+#Should succeed
+tr4 = Test.AddTestRun("Make request with renamed foo cert to first server")
+tr4.StillRunningAfter = ts
+tr4.StillRunningAfter = server
+tr4.StillRunningAfter = server2
+tr4.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case1'.format(ts.Variables.port)
+tr4.Processes.Default.ReturnCode = 0
+tr4.Processes.Default.TimeOut = 5
+tr4.Processes.Default.Streams.stdout = Testers.ExcludesExpression("Could Not Connect", "Check response")
+tr4.TimeOut = 5
+
+#Should fail
+tr4fail = Test.AddTestRun("Make request with renamed foo cert to second server")
+tr4fail.StillRunningAfter = ts
+tr4fail.StillRunningAfter = server
+tr4fail.StillRunningAfter = server2
+tr4fail.Processes.Default.Command = 'curl -H host:example.com http://127.0.0.1:{0}/case2'.format(ts.Variables.port)
+tr4fail.Processes.Default.ReturnCode = 0
+tr4fail.Processes.Default.TimeOut = 5
+tr4fail.Processes.Default.Streams.stdout = Testers.ContainsExpression("Could Not Connect", "Check response")
+tr4fail.TimeOut = 5
# Allow for error messages in diags
ts.Disk.diags_log.Content = Testers.ContainsExpression("ERROR", "Some connections should fail")