nghttpx: Add sni keyword to --backend option
The --backend-tls-sni-field is deprecated in favor of sni keyword. --backend-tls-sni-field still works, and it overrides all sni keyword in --backend option. But it will be removed in the future release.
This commit is contained in:
parent
99f7e7e2a5
commit
fd801864e3
32
src/shrpx.cc
32
src/shrpx.cc
|
@ -1263,13 +1263,13 @@ Connections:
|
|||
|
||||
Several parameters <PARAM> are accepted after <PATTERN>.
|
||||
The parameters are delimited by ";". The available
|
||||
parameters are: "proto=<PROTO>", "tls", "fall=<N>", and
|
||||
"rise=<N>". The parameter consists of keyword, and
|
||||
optionally followed by "=" and value. For example, the
|
||||
parameter "proto=h2" consists of the keyword "proto" and
|
||||
value "h2". The parameter "tls" consists of the keyword
|
||||
"tls" without value. Each parameter is described as
|
||||
follows.
|
||||
parameters are: "proto=<PROTO>", "tls",
|
||||
"sni=<SNI_HOST>", "fall=<N>", and "rise=<N>". The
|
||||
parameter consists of keyword, and optionally followed
|
||||
by "=" and value. For example, the parameter "proto=h2"
|
||||
consists of the keyword "proto" and value "h2". The
|
||||
parameter "tls" consists of the keyword "tls" without
|
||||
value. Each parameter is described as follows.
|
||||
|
||||
The backend application protocol can be specified using
|
||||
optional "proto" keyword, and in the form of
|
||||
|
@ -1284,6 +1284,10 @@ Connections:
|
|||
TLS can be enabled by specifying optional "tls" keyword.
|
||||
TLS is not enabled by default.
|
||||
|
||||
With "sni=<SNI_HOST>" parameter, it can override the TLS
|
||||
SNI field value with given <SNI_HOST>. This will
|
||||
default to the backend <HOST> name
|
||||
|
||||
The feature to detect whether backend is online or
|
||||
offline can be enabled using optional "fall" and "rise"
|
||||
parameters. Using "fall=<N>" parameter, if nghttpx
|
||||
|
@ -1503,9 +1507,6 @@ SSL/TLS:
|
|||
indicated by client using TLS SNI extension. This
|
||||
option can be used multiple times. To make OCSP
|
||||
stapling work, <CERTPATH> must be absolute path.
|
||||
--backend-tls-sni-field=<HOST>
|
||||
Explicitly set the content of the TLS SNI extension.
|
||||
This will default to the backend HOST name.
|
||||
--dh-param-file=<PATH>
|
||||
Path to file that contains DH parameters in PEM format.
|
||||
Without this option, DHE cipher suites are not
|
||||
|
@ -2168,6 +2169,17 @@ void process_options(int argc, char **argv,
|
|||
}
|
||||
}
|
||||
|
||||
// backward compatibility: override all SNI fields with the option
|
||||
// value --backend-tls-sni-field
|
||||
if (!tlsconf.backend_sni_name.empty()) {
|
||||
auto &sni = tlsconf.backend_sni_name;
|
||||
for (auto &addr_group : addr_groups) {
|
||||
for (auto &addr : addr_group.addrs) {
|
||||
addr.sni = sni;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
LOG(INFO) << "Resolving backend address";
|
||||
}
|
||||
|
|
|
@ -644,6 +644,7 @@ int parse_upstream_params(UpstreamParams &out, const StringRef &src_params) {
|
|||
} // namespace
|
||||
|
||||
struct DownstreamParams {
|
||||
StringRef sni;
|
||||
size_t fall;
|
||||
size_t rise;
|
||||
shrpx_proto proto;
|
||||
|
@ -709,6 +710,8 @@ int parse_downstream_params(DownstreamParams &out,
|
|||
out.tls = true;
|
||||
} else if (util::strieq_l("no-tls", param)) {
|
||||
out.tls = false;
|
||||
} else if (util::istarts_with_l(param, "sni=")) {
|
||||
out.sni = StringRef{first + str_size("sni="), end};
|
||||
} else if (!param.empty()) {
|
||||
LOG(ERROR) << "backend: " << param << ": unknown keyword";
|
||||
return -1;
|
||||
|
@ -750,6 +753,7 @@ int parse_mapping(DownstreamAddrConfig addr, const StringRef &src_pattern,
|
|||
|
||||
addr.fall = params.fall;
|
||||
addr.rise = params.rise;
|
||||
addr.sni = ImmutableString{std::begin(params.sni), std::end(params.sni)};
|
||||
|
||||
for (const auto &raw_pattern : mapping) {
|
||||
auto done = false;
|
||||
|
@ -2050,6 +2054,9 @@ int parse_config(const StringRef &opt, const StringRef &optarg,
|
|||
"default. See also " << SHRPX_OPT_BACKEND_TLS;
|
||||
return 0;
|
||||
case SHRPX_OPTID_BACKEND_TLS_SNI_FIELD:
|
||||
LOG(WARN) << opt << ": deprecated. Use sni keyword in --backend option. "
|
||||
"For now, all sni values of all backends are "
|
||||
"overridden by the given value " << optarg;
|
||||
mod_config()->tls.backend_sni_name = optarg.str();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -327,6 +327,8 @@ struct DownstreamAddrConfig {
|
|||
// <HOST>:<PORT>. This does not treat 80 and 443 specially. If
|
||||
// |host_unix| is true, this is "localhost".
|
||||
ImmutableString hostport;
|
||||
// hostname sent as SNI field
|
||||
ImmutableString sni;
|
||||
size_t fall;
|
||||
size_t rise;
|
||||
// backend port. 0 if |host_unix| is true.
|
||||
|
|
|
@ -360,9 +360,8 @@ int Http2Session::initiate_connection() {
|
|||
|
||||
conn_.set_ssl(ssl);
|
||||
|
||||
auto sni_name = !get_config()->tls.backend_sni_name.empty()
|
||||
? StringRef(get_config()->tls.backend_sni_name)
|
||||
: StringRef(addr_->host);
|
||||
auto sni_name =
|
||||
addr_->sni.empty() ? StringRef{addr_->host} : StringRef{addr_->sni};
|
||||
|
||||
if (!util::numeric_host(sni_name.c_str())) {
|
||||
// TLS extensions: SNI. There is no documentation about the return
|
||||
|
|
|
@ -239,9 +239,8 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
|
|||
addr_ = &addr;
|
||||
|
||||
if (ssl_ctx_) {
|
||||
auto sni_name = !get_config()->tls.backend_sni_name.empty()
|
||||
? StringRef(get_config()->tls.backend_sni_name)
|
||||
: StringRef(addr_->host);
|
||||
auto sni_name =
|
||||
addr_->sni.empty() ? StringRef{addr_->host} : StringRef{addr_->sni};
|
||||
if (!util::numeric_host(sni_name.c_str())) {
|
||||
SSL_set_tlsext_host_name(conn_.tls.ssl, sni_name.c_str());
|
||||
}
|
||||
|
|
|
@ -192,9 +192,8 @@ int LiveCheck::initiate_connection() {
|
|||
}
|
||||
|
||||
if (ssl_ctx_) {
|
||||
auto sni_name = !get_config()->tls.backend_sni_name.empty()
|
||||
? StringRef(get_config()->tls.backend_sni_name)
|
||||
: StringRef(addr_->host);
|
||||
auto sni_name =
|
||||
addr_->sni.empty() ? StringRef{addr_->host} : StringRef{addr_->sni};
|
||||
if (!util::numeric_host(sni_name.c_str())) {
|
||||
SSL_set_tlsext_host_name(conn_.tls.ssl, sni_name.c_str());
|
||||
}
|
||||
|
|
|
@ -1064,10 +1064,8 @@ int check_cert(SSL *ssl, const Address *addr, const StringRef &host) {
|
|||
}
|
||||
|
||||
int check_cert(SSL *ssl, const DownstreamAddr *addr) {
|
||||
auto &backend_sni_name = get_config()->tls.backend_sni_name;
|
||||
|
||||
auto hostname = !backend_sni_name.empty() ? StringRef(backend_sni_name)
|
||||
: StringRef(addr->host);
|
||||
auto hostname =
|
||||
addr->sni.empty() ? StringRef{addr->host} : StringRef{addr->sni};
|
||||
return check_cert(ssl, &addr->addr, hostname);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ bool match_shared_downstream_addr(
|
|||
|
||||
auto &b = rhs->addrs[i];
|
||||
if (a.host == b.host && a.port == b.port && a.host_unix == b.host_unix &&
|
||||
a.fall == b.fall && a.rise == b.rise) {
|
||||
a.sni == b.sni && a.fall == b.fall && a.rise == b.rise) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -159,6 +159,7 @@ Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
|
|||
dst_addr.hostport = src_addr.hostport;
|
||||
dst_addr.port = src_addr.port;
|
||||
dst_addr.host_unix = src_addr.host_unix;
|
||||
dst_addr.sni = src_addr.sni;
|
||||
dst_addr.fall = src_addr.fall;
|
||||
dst_addr.rise = src_addr.rise;
|
||||
|
||||
|
|
|
@ -80,6 +80,9 @@ struct DownstreamAddr {
|
|||
// true if |host| contains UNIX domain socket path.
|
||||
bool host_unix;
|
||||
|
||||
// sni field to send remote server if TLS is enabled.
|
||||
ImmutableString sni;
|
||||
|
||||
std::unique_ptr<ConnectBlocker> connect_blocker;
|
||||
std::unique_ptr<LiveCheck> live_check;
|
||||
size_t fall;
|
||||
|
|
|
@ -254,15 +254,15 @@ public:
|
|||
|
||||
ImmutableString() : len(0), base("") {}
|
||||
ImmutableString(const char *s, size_t slen)
|
||||
: len(slen), base(copystr(s, len)) {}
|
||||
ImmutableString(const char *s) : len(strlen(s)), base(copystr(s, len)) {}
|
||||
: len(slen), base(copystr(s, s + len)) {}
|
||||
ImmutableString(const char *s) : len(strlen(s)), base(copystr(s, s + len)) {}
|
||||
ImmutableString(const std::string &s)
|
||||
: len(s.size()), base(copystr(s.c_str(), s.size())) {}
|
||||
: len(s.size()), base(copystr(std::begin(s), std::end(s))) {}
|
||||
template <typename InputIt>
|
||||
ImmutableString(InputIt first, InputIt last)
|
||||
: len(std::distance(first, last)), base(copystr(first, len)) {}
|
||||
: len(std::distance(first, last)), base(copystr(first, last)) {}
|
||||
ImmutableString(const ImmutableString &other)
|
||||
: len(other.len), base(copystr(other.base, other.len)) {}
|
||||
: len(other.len), base(copystr(std::begin(other), std::end(other))) {}
|
||||
ImmutableString(ImmutableString &&other) noexcept : len(other.len),
|
||||
base(other.base) {
|
||||
other.len = 0;
|
||||
|
@ -282,7 +282,7 @@ public:
|
|||
delete[] base;
|
||||
}
|
||||
len = other.len;
|
||||
base = copystr(other.base, other.len);
|
||||
base = copystr(std::begin(other), std::end(other));
|
||||
return *this;
|
||||
}
|
||||
ImmutableString &operator=(ImmutableString &&other) noexcept {
|
||||
|
@ -325,12 +325,12 @@ public:
|
|||
const_reference operator[](size_type pos) const { return *(base + pos); }
|
||||
|
||||
private:
|
||||
const char *copystr(const char *s, size_t slen) {
|
||||
if (slen == 0) {
|
||||
template <typename InputIt> const char *copystr(InputIt first, InputIt last) {
|
||||
if (first == last) {
|
||||
return "";
|
||||
}
|
||||
auto res = new char[slen + 1];
|
||||
*std::copy_n(s, slen, res) = '\0';
|
||||
auto res = new char[std::distance(first, last) + 1];
|
||||
*std::copy(first, last, res) = '\0';
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue