You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2021/04/20 22:27:15 UTC

[trafficserver] branch master updated: Override proxy.config.ssl.client.sni_policy from sni.yaml (#7703)

This is an automated email from the ASF dual-hosted git repository.

masaori 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 d430efe  Override proxy.config.ssl.client.sni_policy from sni.yaml (#7703)
d430efe is described below

commit d430efe76ba0726ae64e8da9b8853c986d18af40
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Wed Apr 21 07:27:04 2021 +0900

    Override proxy.config.ssl.client.sni_policy from sni.yaml (#7703)
---
 doc/admin-guide/files/sni.yaml.en.rst |  4 ++++
 iocore/net/I_NetVConnection.h         |  4 ++++
 iocore/net/P_SNIActionPerformer.h     | 24 ++++++++++++++++++++++++
 iocore/net/P_UnixNetVConnection.h     |  1 +
 iocore/net/SSLSNIConfig.cc            |  3 +++
 iocore/net/YamlSNIConfig.cc           |  4 ++++
 iocore/net/YamlSNIConfig.h            |  2 ++
 proxy/http/HttpSM.cc                  |  7 +++++++
 8 files changed, 49 insertions(+)

diff --git a/doc/admin-guide/files/sni.yaml.en.rst b/doc/admin-guide/files/sni.yaml.en.rst
index 94b88c8..8478c50 100644
--- a/doc/admin-guide/files/sni.yaml.en.rst
+++ b/doc/admin-guide/files/sni.yaml.en.rst
@@ -114,6 +114,10 @@ client_key                The file containing the client private key that corres
                           |TS| tries to use a private key in client_cert.  Otherwise,
                           :ts:cv:`proxy.config.ssl.client.private_key.filename` is used.
 
+client_sni_policy         Policy of SNI on outbound connection.
+
+                          If not specified, the value of :ts:cv:`proxy.config.ssl.client.sni_policy` is used.
+
 http2                     Indicates whether the H2 protocol should be added to or removed from the
                           protocol negotiation list.  The valid values are :code:`on` or :code:`off`.
 
diff --git a/iocore/net/I_NetVConnection.h b/iocore/net/I_NetVConnection.h
index 9f42e5b..ea29017 100644
--- a/iocore/net/I_NetVConnection.h
+++ b/iocore/net/I_NetVConnection.h
@@ -202,6 +202,10 @@ struct NetVCOptions {
    */
   ats_scoped_str sni_hostname;
 
+  /** Outbound sni policy which overrides proxy.ssl.client.sni_policy
+   */
+  ats_scoped_str outbound_sni_policy;
+
   /**
    * Client certificate to use in response to OS's certificate request
    */
diff --git a/iocore/net/P_SNIActionPerformer.h b/iocore/net/P_SNIActionPerformer.h
index 636a07a..bcaec2b 100644
--- a/iocore/net/P_SNIActionPerformer.h
+++ b/iocore/net/P_SNIActionPerformer.h
@@ -344,3 +344,27 @@ public:
     return retval;
   }
 };
+
+/**
+   Override proxy.config.ssl.client.sni_policy by client_sni_policy in sni.yaml
+ */
+class OutboundSNIPolicy : public ActionItem
+{
+public:
+  OutboundSNIPolicy(const std::string_view &p) : policy(p) {}
+  ~OutboundSNIPolicy() override {}
+
+  int
+  SNIAction(TLSSNISupport *snis, const Context &ctx) const override
+  {
+    // TODO: change design to avoid this dynamic_cast
+    auto ssl_vc = dynamic_cast<SSLNetVConnection *>(snis);
+    if (ssl_vc && !policy.empty()) {
+      ssl_vc->options.outbound_sni_policy = policy;
+    }
+    return SSL_TLSEXT_ERR_OK;
+  }
+
+private:
+  std::string_view policy{};
+};
diff --git a/iocore/net/P_UnixNetVConnection.h b/iocore/net/P_UnixNetVConnection.h
index 8d34bf8..399e1d9 100644
--- a/iocore/net/P_UnixNetVConnection.h
+++ b/iocore/net/P_UnixNetVConnection.h
@@ -72,6 +72,7 @@ NetVCOptions::reset()
   sni_hostname                = nullptr;
   ssl_client_cert_name        = nullptr;
   ssl_client_private_key_name = nullptr;
+  outbound_sni_policy         = nullptr;
 }
 
 inline void
diff --git a/iocore/net/SSLSNIConfig.cc b/iocore/net/SSLSNIConfig.cc
index 647b687..ee92eb0 100644
--- a/iocore/net/SSLSNIConfig.cc
+++ b/iocore/net/SSLSNIConfig.cc
@@ -79,6 +79,9 @@ SNIConfigParams::loadSNIConfig()
     if (item.tunnel_destination.length() > 0) {
       ai->actions.push_back(std::make_unique<TunnelDestination>(item.tunnel_destination, item.tunnel_type, item.tunnel_alpn));
     }
+    if (!item.client_sni_policy.empty()) {
+      ai->actions.push_back(std::make_unique<OutboundSNIPolicy>(item.client_sni_policy));
+    }
 
     ai->actions.push_back(std::make_unique<SNI_IpAllow>(item.ip_allow, item.fqdn));
 
diff --git a/iocore/net/YamlSNIConfig.cc b/iocore/net/YamlSNIConfig.cc
index 6744bd3..0b66917 100644
--- a/iocore/net/YamlSNIConfig.cc
+++ b/iocore/net/YamlSNIConfig.cc
@@ -133,6 +133,7 @@ std::set<std::string> valid_sni_config_keys = {TS_fqdn,
                                                TS_verify_server_properties,
                                                TS_client_cert,
                                                TS_client_key,
+                                               TS_client_sni_policy,
                                                TS_http2,
                                                TS_ip_allow,
 #if TS_USE_HELLO_CB
@@ -266,6 +267,9 @@ template <> struct convert<YamlSNIConfig::Item> {
     if (node[TS_client_key]) {
       item.client_key = node[TS_client_key].as<std::string>();
     }
+    if (node[TS_client_sni_policy]) {
+      item.client_sni_policy = node[TS_client_sni_policy].as<std::string>();
+    }
 
     if (node[TS_ip_allow]) {
       item.ip_allow = node[TS_ip_allow].as<std::string>();
diff --git a/iocore/net/YamlSNIConfig.h b/iocore/net/YamlSNIConfig.h
index 47c2fa6..f1c4b61 100644
--- a/iocore/net/YamlSNIConfig.h
+++ b/iocore/net/YamlSNIConfig.h
@@ -43,6 +43,7 @@ TSDECL(verify_server_properties);
 TSDECL(verify_origin_server);
 TSDECL(client_cert);
 TSDECL(client_key);
+TSDECL(client_sni_policy);
 TSDECL(ip_allow);
 TSDECL(valid_tls_versions_in);
 TSDECL(http2);
@@ -69,6 +70,7 @@ struct YamlSNIConfig {
     Property verify_server_properties = Property::UNSET;
     std::string client_cert;
     std::string client_key;
+    std::string client_sni_policy;
     std::string ip_allow;
     bool protocol_unset = true;
     unsigned long protocol_mask;
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 8fa34ef..dece9fa 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -4867,6 +4867,13 @@ HttpSM::get_outbound_sni() const
   using namespace ts::literals;
   ts::TextView zret;
   ts::TextView policy{t_state.txn_conf->ssl_client_sni_policy, ts::TextView::npos};
+
+  if (ua_txn) {
+    if (const NetVConnection *netvc = ua_txn->get_netvc(); netvc->options.outbound_sni_policy) {
+      policy.assign(netvc->options.outbound_sni_policy.get(), ts::TextView::npos);
+    }
+  }
+
   if (policy.empty() || !strcmp(policy, "host"_tv)) {
     // By default the host header field value is used for the SNI.
     int len;