alternator: change name of Alternator's SSL options

When Alternator is enabled over HTTPS - by setting the
"alternator_https_port" option - it needs to know some SSL-related options,
most importantly where to pick up the certificate and key.

Before this patch, we used the "server_encryption_options" option for that.
However, this was a mistake: Although it sounds like these are the "server's
options", in fact prior to Alternator this option was only used when
communicating with other servers - i.e., connections between Scylla nodes.
For CQL connections with the client, we used a different option -
"client_encryption_options".

This patch introduces a third option "alternator_encryption_options", which
controls only Alternator's HTTPS server. Making it separate from the
existing CQL "client_encryption_options" allows both Alternator and CQL to
be active at the same time but with different certificates (if the user
so wishes).

For backward compatibility, we temporarily continue to allow
server_encryption_options to control the Alternator HTTPS server if
alternator_encryption_options is not specified. However, this generates
a warning in the log, urging the user to switch. This temporary workaround
should be removed in a future version.

This patch also:
1. fixes the test run code (which has an "--https" option to test over
   https) to use the new name of the option.
2. Adds documentation of the new option in alternator.md and protocols.md -
   previously the information on how to control the location of the
   certificate was missing from these documents.

Fixes #7204.

Signed-off-by: Nadav Har'El <nyh@scylladb.com>
Message-Id: <20200930123027.213587-1-nyh@scylladb.com>
(cherry picked from commit 509a41db04)
This commit is contained in:
Nadav Har'El
2020-09-30 15:30:27 +03:00
parent e02defb3bf
commit 94b754eee5
6 changed files with 49 additions and 16 deletions

View File

@@ -662,6 +662,15 @@ db::config::config(std::shared_ptr<db::extensions> exts)
"\tpriority_string : GnuTLS priority string controlling TLS algorithms used/allowed.\n"
"\trequire_client_auth : (Default: false ) Enables or disables certificate authentication.\n"
"Related information: Client-to-node encryption")
, alternator_encryption_options(this, "alternator_encryption_options", value_status::Used, {/*none*/},
"When Alternator via HTTPS is enabled with alternator_https_port, where to take the key and certificate. The available options are:\n"
"\n"
"\tcertificate: (Default: conf/scylla.crt) The location of a PEM-encoded x509 certificate used to identify and encrypt the client/server communication.\n"
"\tkeyfile: (Default: conf/scylla.key) PEM Key file associated with certificate.\n"
"\n"
"The advanced settings are:\n"
"\n"
"\tpriority_string : GnuTLS priority string controlling TLS algorithms used/allowed.")
, ssl_storage_port(this, "ssl_storage_port", value_status::Used, 7001,
"The SSL port for encrypted communication. Unused unless enabled in encryption_options.")
, enable_in_memory_data_store(this, "enable_in_memory_data_store", value_status::Used, false, "Enable in memory mode (system tables are always persisted)")

View File

@@ -252,6 +252,7 @@ public:
named_value<uint32_t> permissions_cache_max_entries;
named_value<string_map> server_encryption_options;
named_value<string_map> client_encryption_options;
named_value<string_map> alternator_encryption_options;
named_value<uint32_t> ssl_storage_port;
named_value<bool> enable_in_memory_data_store;
named_value<bool> enable_cache;

View File

@@ -25,6 +25,15 @@ By default, Scylla listens on this port on all network interfaces.
To listen only on a specific interface, pass also an "`alternator-address`"
option.
In addition to (or instead of) serving HTTP requests on `alternator-port`,
Scylla can accept DynamoDB API requests over HTTPS (encrypted), on the port
specified by `alternator-https-port`. As usual for HTTPS servers, the
operator must specify certificate and key files. By default these should
be placed in `/etc/scylla/scylla.crt` and `/etc/scylla/scylla.key`, but
these default locations can overridden by specifying
`--alternator-encryption-options keyfile="..."` and
`--alternator-encryption-options certificate="..."`.
As we explain below in the "Write isolation policies", Alternator has
four different choices for the implementation of writes, each with
different advantages. You should consider which of the options makes

View File

@@ -137,10 +137,9 @@ TODO: is there an SSL version of Thrift?
# DynamoDB client protocol
Scylla also supports, as an experimental feature, Amazon's DynamoDB API.
The DynamoDB API is a JSON over HTTP (unencrypted) or HTTPS (encrypted)
protocol. Because Scylla's support for this protocol is experimental,
it is not turned on by default, and must be turned on manually by setting
Scylla also supports Amazon's DynamoDB API. The DynamoDB API is a JSON over
HTTP (unencrypted) or HTTPS (encrypted) protocol. Support for this protocol
is not turned on by default, and must be turned on manually by setting
the `alternator_port` and/or `alternator_https_port` configuration option.
"Alternator" is the codename of Scylla's DynamoDB API support, and is
documented in more detail in [alternator.md](alternator/alternator.md).
@@ -153,6 +152,13 @@ There is also an `alternator_address` configuration option to set the IP
address (and therefore network interface) on which Scylla should listen
for the DynamoDB protocol. This address defaults to 0.0.0.0.
When the HTTPS-based protocol is enabled, the server also needs to know
the certificate and key files to use. The default locations of these files
are `/etc/scylla/scylla.crt` and `/etc/scylla/scylla.key` respectively, but
can be overridden by specifying in `alternator_encryption_options` the
`keyfile` and `certificate` options. For example,
`--alternator-encryption-options keyfile="..."`.
# Redis client protocol
Scylla also has partial and experimental support for the Redis API.

28
main.cc
View File

@@ -1204,22 +1204,30 @@ int main(int ac, char** av) {
std::optional<uint16_t> alternator_https_port;
std::optional<tls::credentials_builder> creds;
if (cfg->alternator_https_port()) {
creds.emplace();
alternator_https_port = cfg->alternator_https_port();
creds->set_dh_level(tls::dh_params::level::MEDIUM);
creds->set_x509_key_file(cert, key, tls::x509_crt_format::PEM).get();
if (trust_store.empty()) {
creds->set_system_trust().get();
} else {
creds->set_x509_trust_file(trust_store, tls::x509_crt_format::PEM).get();
creds.emplace();
auto opts = cfg->alternator_encryption_options();
if (opts.empty()) {
// Earlier versions mistakenly configured Alternator's
// HTTPS parameters via the "server_encryption_option"
// configuration parameter. We *temporarily* continue
// to allow this, for backward compatibility.
opts = cfg->server_encryption_options();
if (!opts.empty()) {
startlog.warn("Setting server_encryption_options to configure "
"Alternator's HTTPS encryption is deprecated. Please "
"switch to setting alternator_encryption_options instead.");
}
}
creds->set_dh_level(tls::dh_params::level::MEDIUM);
auto cert = get_or_default(opts, "certificate", db::config::get_conf_sub("scylla.crt").string());
auto key = get_or_default(opts, "keyfile", db::config::get_conf_sub("scylla.key").string());
creds->set_x509_key_file(cert, key, tls::x509_crt_format::PEM).get();
auto prio = get_or_default(opts, "priority_string", sstring());
creds->set_priority_string(db::config::default_tls_priority);
if (!prio.empty()) {
creds->set_priority_string(prio);
}
if (clauth) {
creds->set_client_auth(seastar::tls::client_auth::REQUIRE);
}
}
bool alternator_enforce_authorization = cfg->alternator_enforce_authorization();
with_scheduling_group(dbcfg.statement_scheduling_group,

View File

@@ -94,8 +94,8 @@ ln -s "$SCYLLA" "$SCYLLA_LINK"
--prometheus-address $SCYLLA_IP \
--seed-provider-parameters seeds=$SCYLLA_IP \
--workdir "$tmp_dir" \
--server-encryption-options keyfile="$tmp_dir/scylla.key" \
--server-encryption-options certificate="$tmp_dir/scylla.crt" \
--alternator-encryption-options keyfile="$tmp_dir/scylla.key" \
--alternator-encryption-options certificate="$tmp_dir/scylla.crt" \
--auto-snapshot 0 \
--skip-wait-for-gossip-to-settle 0 \
>"$tmp_dir/log" 2>&1 &