Merge pull request #790 from nghttp2/nghttpx-backend-frontend-tls-parameter
nghttpx: Add frontend-tls parameter to backend to require client TLS
This commit is contained in:
commit
025ec85144
23
src/shrpx.cc
23
src/shrpx.cc
|
@ -1602,12 +1602,12 @@ Connections:
|
||||||
The parameters are delimited by ";". The available
|
The parameters are delimited by ";". The available
|
||||||
parameters are: "proto=<PROTO>", "tls",
|
parameters are: "proto=<PROTO>", "tls",
|
||||||
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>",
|
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>",
|
||||||
"affinity=<METHOD>", and "dns". The parameter consists
|
"affinity=<METHOD>", "dns", and "frontend-tls". The
|
||||||
of keyword, and optionally followed by "=" and value.
|
parameter consists of keyword, and optionally followed
|
||||||
For example, the parameter "proto=h2" consists of the
|
by "=" and value. For example, the parameter "proto=h2"
|
||||||
keyword "proto" and value "h2". The parameter "tls"
|
consists of the keyword "proto" and value "h2". The
|
||||||
consists of the keyword "tls" without value. Each
|
parameter "tls" consists of the keyword "tls" without
|
||||||
parameter is described as follows.
|
value. Each parameter is described as follows.
|
||||||
|
|
||||||
The backend application protocol can be specified using
|
The backend application protocol can be specified using
|
||||||
optional "proto" parameter, and in the form of
|
optional "proto" parameter, and in the form of
|
||||||
|
@ -1664,6 +1664,17 @@ Connections:
|
||||||
backend host name at start up, or reloading
|
backend host name at start up, or reloading
|
||||||
configuration is skipped.
|
configuration is skipped.
|
||||||
|
|
||||||
|
If "frontend-tls" parameter is used, the matched backend
|
||||||
|
requires frontend TLS connection. In other words, even
|
||||||
|
if pattern is matched, frontend connection is not TLS
|
||||||
|
protected, the request is forwarded to one of catch-all
|
||||||
|
backends. For this reason, catch-all backend cannot
|
||||||
|
have "frontend-tls" parameter. If at least one backend
|
||||||
|
has "frontend-tls" parameter, this feature is enabled
|
||||||
|
for all backend servers sharing the same <PATTERN>. It
|
||||||
|
is advised to set "frontend-tls" parameter to all
|
||||||
|
backends explicitly if this feature is desired.
|
||||||
|
|
||||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||||
not contain these characters. Since ";" has special
|
not contain these characters. Since ";" has special
|
||||||
meaning in shell, the option value must be quoted.
|
meaning in shell, the option value must be quoted.
|
||||||
|
|
|
@ -1008,6 +1008,13 @@ ClientHandler::get_downstream_connection(Downstream *downstream) {
|
||||||
CLOG(INFO, this) << "Downstream address group_idx: " << group_idx;
|
CLOG(INFO, this) << "Downstream address group_idx: " << group_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (groups[group_idx]->shared_addr->require_upstream_tls && !conn_.tls.ssl) {
|
||||||
|
CLOG(INFO, this) << "Downstream address group " << group_idx
|
||||||
|
<< " requires frontend TLS connection. Send request to "
|
||||||
|
"catch-all group.";
|
||||||
|
group_idx = catch_all;
|
||||||
|
}
|
||||||
|
|
||||||
auto &group = groups[group_idx];
|
auto &group = groups[group_idx];
|
||||||
auto &shared_addr = group->shared_addr;
|
auto &shared_addr = group->shared_addr;
|
||||||
|
|
||||||
|
|
|
@ -732,6 +732,7 @@ struct DownstreamParams {
|
||||||
shrpx_session_affinity affinity;
|
shrpx_session_affinity affinity;
|
||||||
bool tls;
|
bool tls;
|
||||||
bool dns;
|
bool dns;
|
||||||
|
bool frontend_tls;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -807,6 +808,8 @@ int parse_downstream_params(DownstreamParams &out,
|
||||||
}
|
}
|
||||||
} else if (util::strieq_l("dns", param)) {
|
} else if (util::strieq_l("dns", param)) {
|
||||||
out.dns = true;
|
out.dns = true;
|
||||||
|
} else if (util::strieq_l("frontend-tls", param)) {
|
||||||
|
out.frontend_tls = true;
|
||||||
} else if (!param.empty()) {
|
} else if (!param.empty()) {
|
||||||
LOG(ERROR) << "backend: " << param << ": unknown keyword";
|
LOG(ERROR) << "backend: " << param << ": unknown keyword";
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -899,6 +902,11 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
|
||||||
if (params.affinity != AFFINITY_NONE) {
|
if (params.affinity != AFFINITY_NONE) {
|
||||||
g.affinity = params.affinity;
|
g.affinity = params.affinity;
|
||||||
}
|
}
|
||||||
|
// If at least one backend requires frontend TLS connection,
|
||||||
|
// enable it for all backends sharing the same pattern.
|
||||||
|
if (params.frontend_tls) {
|
||||||
|
g.require_upstream_tls = true;
|
||||||
|
}
|
||||||
g.addrs.push_back(addr);
|
g.addrs.push_back(addr);
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
|
@ -913,6 +921,7 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
|
||||||
auto &g = addr_groups.back();
|
auto &g = addr_groups.back();
|
||||||
g.addrs.push_back(addr);
|
g.addrs.push_back(addr);
|
||||||
g.affinity = params.affinity;
|
g.affinity = params.affinity;
|
||||||
|
g.require_upstream_tls = params.frontend_tls;
|
||||||
|
|
||||||
if (pattern[0] == '*') {
|
if (pattern[0] == '*') {
|
||||||
// wildcard pattern
|
// wildcard pattern
|
||||||
|
@ -3625,6 +3634,12 @@ int configure_downstream_group(Config *config, bool http2_proxy,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr_groups[catch_all_group].require_upstream_tls) {
|
||||||
|
LOG(FATAL)
|
||||||
|
<< "backend: Catch-all backend cannot have frontend-tls parameter";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
downstreamconf.addr_group_catch_all = catch_all_group;
|
downstreamconf.addr_group_catch_all = catch_all_group;
|
||||||
|
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
|
|
@ -430,7 +430,9 @@ struct AffinityHash {
|
||||||
|
|
||||||
struct DownstreamAddrGroupConfig {
|
struct DownstreamAddrGroupConfig {
|
||||||
DownstreamAddrGroupConfig(const StringRef &pattern)
|
DownstreamAddrGroupConfig(const StringRef &pattern)
|
||||||
: pattern(pattern), affinity(AFFINITY_NONE) {}
|
: pattern(pattern),
|
||||||
|
affinity(AFFINITY_NONE),
|
||||||
|
require_upstream_tls(false) {}
|
||||||
|
|
||||||
StringRef pattern;
|
StringRef pattern;
|
||||||
std::vector<DownstreamAddrConfig> addrs;
|
std::vector<DownstreamAddrConfig> addrs;
|
||||||
|
@ -439,6 +441,8 @@ struct DownstreamAddrGroupConfig {
|
||||||
std::vector<AffinityHash> affinity_hash;
|
std::vector<AffinityHash> affinity_hash;
|
||||||
// Session affinity
|
// Session affinity
|
||||||
shrpx_session_affinity affinity;
|
shrpx_session_affinity affinity;
|
||||||
|
// true if this group requires that client connection must be TLS.
|
||||||
|
bool require_upstream_tls;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TicketKey {
|
struct TicketKey {
|
||||||
|
|
|
@ -76,7 +76,8 @@ bool match_shared_downstream_addr(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lhs->affinity != rhs->affinity) {
|
if (lhs->affinity != rhs->affinity ||
|
||||||
|
lhs->require_upstream_tls != rhs->require_upstream_tls) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +192,7 @@ void Worker::replace_downstream_config(
|
||||||
shared_addr->addrs.resize(src.addrs.size());
|
shared_addr->addrs.resize(src.addrs.size());
|
||||||
shared_addr->affinity = src.affinity;
|
shared_addr->affinity = src.affinity;
|
||||||
shared_addr->affinity_hash = src.affinity_hash;
|
shared_addr->affinity_hash = src.affinity_hash;
|
||||||
|
shared_addr->require_upstream_tls = src.require_upstream_tls;
|
||||||
|
|
||||||
size_t num_http1 = 0;
|
size_t num_http1 = 0;
|
||||||
size_t num_http2 = 0;
|
size_t num_http2 = 0;
|
||||||
|
|
|
@ -136,7 +136,8 @@ struct SharedDownstreamAddr {
|
||||||
next{0},
|
next{0},
|
||||||
http1_pri{},
|
http1_pri{},
|
||||||
http2_pri{},
|
http2_pri{},
|
||||||
affinity{AFFINITY_NONE} {}
|
affinity{AFFINITY_NONE},
|
||||||
|
require_upstream_tls{false} {}
|
||||||
|
|
||||||
SharedDownstreamAddr(const SharedDownstreamAddr &) = delete;
|
SharedDownstreamAddr(const SharedDownstreamAddr &) = delete;
|
||||||
SharedDownstreamAddr(SharedDownstreamAddr &&) = delete;
|
SharedDownstreamAddr(SharedDownstreamAddr &&) = delete;
|
||||||
|
@ -171,6 +172,8 @@ struct SharedDownstreamAddr {
|
||||||
WeightedPri http2_pri;
|
WeightedPri http2_pri;
|
||||||
// Session affinity
|
// Session affinity
|
||||||
shrpx_session_affinity affinity;
|
shrpx_session_affinity affinity;
|
||||||
|
// true if this group requires that client connection must be TLS.
|
||||||
|
bool require_upstream_tls;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DownstreamAddrGroup {
|
struct DownstreamAddrGroup {
|
||||||
|
|
Loading…
Reference in New Issue