Changed term whitelist to allowlist (#54)
This commit is contained in:
parent
9bafaf9bbf
commit
ab9c21f315
10
keydb.conf
10
keydb.conf
@ -262,18 +262,18 @@ tcp-keepalive 300
|
|||||||
#
|
#
|
||||||
# tls-rotation no
|
# tls-rotation no
|
||||||
|
|
||||||
# Setup a whitelist of allowed Common Names (CNs)/Subject Alternative Names (SANs)
|
# Setup a allowlist of allowed Common Names (CNs)/Subject Alternative Names (SANs)
|
||||||
# that are allowed to connect to this server. This includes both normal clients as
|
# that are allowed to connect to this server. This includes both normal clients as
|
||||||
# well as other servers connected for replication/clustering purposes. If nothing is
|
# well as other servers connected for replication/clustering purposes. If nothing is
|
||||||
# specified, then no whitelist is used. Supports IPv4, DNS, RFC822, and URI SAN types.
|
# specified, then no allowlist is used. Supports IPv4, DNS, RFC822, and URI SAN types.
|
||||||
# You can opt to either put all of the names on one line as follows:
|
# You can opt to either put all of the names on one line as follows:
|
||||||
#
|
#
|
||||||
# tls-whitelist <dns1> <dns2> <dns3> ...
|
# tls-allowlist <dns1> <dns2> <dns3> ...
|
||||||
#
|
#
|
||||||
# or place then all on their own seperate line (or a combination of the two):
|
# or place then all on their own seperate line (or a combination of the two):
|
||||||
#
|
#
|
||||||
# tls-whitelist <dns1>
|
# tls-allowlist <dns1>
|
||||||
# tls-whitelist <dns2>
|
# tls-allowlist <dns2>
|
||||||
# ...
|
# ...
|
||||||
#
|
#
|
||||||
# This configuration also allows for wildcard characters with glob style formatting
|
# This configuration also allows for wildcard characters with glob style formatting
|
||||||
|
@ -741,11 +741,11 @@ void loadServerConfigFromString(char *config) {
|
|||||||
g_pserver->fActiveReplica = CONFIG_DEFAULT_ACTIVE_REPLICA;
|
g_pserver->fActiveReplica = CONFIG_DEFAULT_ACTIVE_REPLICA;
|
||||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(argv[0], "tls-whitelist")) {
|
} else if (!strcasecmp(argv[0], "tls-allowlist")) {
|
||||||
if (!g_pserver->tls_whitelist_enabled)
|
if (!g_pserver->tls_allowlist_enabled)
|
||||||
g_pserver->tls_whitelist_enabled = true;
|
g_pserver->tls_allowlist_enabled = true;
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
g_pserver->tls_whitelist.insert(zstrdup(argv[i]));
|
g_pserver->tls_allowlist.insert(zstrdup(argv[i]));
|
||||||
} else if (!strcasecmp(argv[0], "version-override") && argc == 2) {
|
} else if (!strcasecmp(argv[0], "version-override") && argc == 2) {
|
||||||
KEYDB_SET_VERSION = zstrdup(argv[1]);
|
KEYDB_SET_VERSION = zstrdup(argv[1]);
|
||||||
serverLog(LL_WARNING, "Warning version is overriden to: %s\n", KEYDB_SET_VERSION);
|
serverLog(LL_WARNING, "Warning version is overriden to: %s\n", KEYDB_SET_VERSION);
|
||||||
|
@ -2612,8 +2612,8 @@ struct redisServer {
|
|||||||
int tls_auth_clients;
|
int tls_auth_clients;
|
||||||
int tls_rotation;
|
int tls_rotation;
|
||||||
|
|
||||||
int tls_whitelist_enabled;
|
int tls_allowlist_enabled;
|
||||||
std::unordered_set<char *> tls_whitelist;
|
std::unordered_set<char *> tls_allowlist;
|
||||||
redisTLSContextConfig tls_ctx_config;
|
redisTLSContextConfig tls_ctx_config;
|
||||||
|
|
||||||
/* cpu affinity */
|
/* cpu affinity */
|
||||||
|
20
src/tls.cpp
20
src/tls.cpp
@ -478,13 +478,13 @@ typedef struct tls_connection {
|
|||||||
aeEventLoop *el;
|
aeEventLoop *el;
|
||||||
} tls_connection;
|
} tls_connection;
|
||||||
|
|
||||||
/* Check to see if a given client name matches against our whitelist.
|
/* Check to see if a given client name matches against our allowlist.
|
||||||
* Return true if it does */
|
* Return true if it does */
|
||||||
bool tlsCheckAgainstWhitelist(const char * client){
|
bool tlsCheckAgainstAllowlist(const char * client){
|
||||||
/* Because of wildcard matching, we need to iterate over the entire set.
|
/* Because of wildcard matching, we need to iterate over the entire set.
|
||||||
* If we were doing simply straight matching, we could just directly
|
* If we were doing simply straight matching, we could just directly
|
||||||
* check to see if the client name is in the set in O(1) time */
|
* check to see if the client name is in the set in O(1) time */
|
||||||
for (char * client_pattern: g_pserver->tls_whitelist){
|
for (char * client_pattern: g_pserver->tls_allowlist){
|
||||||
if (stringmatchlen(client_pattern, strlen(client_pattern), client, strlen(client), 1))
|
if (stringmatchlen(client_pattern, strlen(client_pattern), client, strlen(client), 1))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -497,7 +497,7 @@ bool tlsValidateCertificateName(tls_connection* conn){
|
|||||||
X509_NAME_ENTRY * ne = X509_NAME_get_entry(X509_get_subject_name(cert), X509_NAME_get_index_by_NID(X509_get_subject_name(cert), NID_commonName, -1));
|
X509_NAME_ENTRY * ne = X509_NAME_get_entry(X509_get_subject_name(cert), X509_NAME_get_index_by_NID(X509_get_subject_name(cert), NID_commonName, -1));
|
||||||
const char * commonName = reinterpret_cast<const char*>(ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(ne)));
|
const char * commonName = reinterpret_cast<const char*>(ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(ne)));
|
||||||
|
|
||||||
if (tlsCheckAgainstWhitelist(commonName))
|
if (tlsCheckAgainstAllowlist(commonName))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* If that fails, check through the subject alternative names (SANs) as well */
|
/* If that fails, check through the subject alternative names (SANs) as well */
|
||||||
@ -511,19 +511,19 @@ bool tlsValidateCertificateName(tls_connection* conn){
|
|||||||
switch (generalName->type)
|
switch (generalName->type)
|
||||||
{
|
{
|
||||||
case GEN_EMAIL:
|
case GEN_EMAIL:
|
||||||
if (tlsCheckAgainstWhitelist(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.rfc822Name)))){
|
if (tlsCheckAgainstAllowlist(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.rfc822Name)))){
|
||||||
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
|
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GEN_DNS:
|
case GEN_DNS:
|
||||||
if (tlsCheckAgainstWhitelist(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)))){
|
if (tlsCheckAgainstAllowlist(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)))){
|
||||||
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
|
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GEN_URI:
|
case GEN_URI:
|
||||||
if (tlsCheckAgainstWhitelist(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)))){
|
if (tlsCheckAgainstAllowlist(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)))){
|
||||||
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
|
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -534,7 +534,7 @@ bool tlsValidateCertificateName(tls_connection* conn){
|
|||||||
if (ipLen == 4){ //IPv4 case
|
if (ipLen == 4){ //IPv4 case
|
||||||
char addr[INET_ADDRSTRLEN];
|
char addr[INET_ADDRSTRLEN];
|
||||||
inet_ntop(AF_INET, ASN1_STRING_get0_data(generalName->d.iPAddress), addr, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, ASN1_STRING_get0_data(generalName->d.iPAddress), addr, INET_ADDRSTRLEN);
|
||||||
if (tlsCheckAgainstWhitelist(addr)){
|
if (tlsCheckAgainstAllowlist(addr)){
|
||||||
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
|
sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -554,7 +554,7 @@ bool tlsValidateCertificateName(tls_connection* conn){
|
|||||||
conn->c.last_errno = 0;
|
conn->c.last_errno = 0;
|
||||||
if (conn->ssl_error) zfree(conn->ssl_error);
|
if (conn->ssl_error) zfree(conn->ssl_error);
|
||||||
conn->ssl_error = (char*)zmalloc(512);
|
conn->ssl_error = (char*)zmalloc(512);
|
||||||
snprintf(conn->ssl_error, 512, "Client CN (%s) and SANs not found in whitelist.", commonName);
|
snprintf(conn->ssl_error, 512, "Client CN (%s) and SANs not found in allowlist.", commonName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,7 +776,7 @@ void tlsHandleEvent(tls_connection *conn, int mask) {
|
|||||||
conn->c.state = CONN_STATE_ERROR;
|
conn->c.state = CONN_STATE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
/* Validate name */
|
/* Validate name */
|
||||||
if (g_pserver->tls_whitelist_enabled && !tlsValidateCertificateName(conn)){
|
if (g_pserver->tls_allowlist_enabled && !tlsValidateCertificateName(conn)){
|
||||||
conn->c.state = CONN_STATE_ERROR;
|
conn->c.state = CONN_STATE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
conn->c.state = CONN_STATE_CONNECTED;
|
conn->c.state = CONN_STATE_CONNECTED;
|
||||||
|
@ -1,110 +1,110 @@
|
|||||||
test {TLS: Able to connect with no whitelist} {
|
test {TLS: Able to connect with no allowlist} {
|
||||||
start_server {tags {"tls"}} {
|
start_server {tags {"tls"}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to connect with whitelist '*'} {
|
test {TLS: Able to connect with allowlist '*'} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist *}} {
|
start_server {tags {"tls"} overrides {tls-allowlist *}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to connect with matching CN} {
|
test {TLS: Able to connect with matching CN} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist client.keydb.dev}} {
|
start_server {tags {"tls"} overrides {tls-allowlist client.keydb.dev}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to connect with matching SAN} {
|
test {TLS: Able to connect with matching SAN} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist san1.keydb.dev}} {
|
start_server {tags {"tls"} overrides {tls-allowlist san1.keydb.dev}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to connect with matching CN with wildcard} {
|
test {TLS: Able to connect with matching CN with wildcard} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist client*.dev}} {
|
start_server {tags {"tls"} overrides {tls-allowlist client*.dev}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to connect with matching SAN with wildcard} {
|
test {TLS: Able to connect with matching SAN with wildcard} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist san*.dev}} {
|
start_server {tags {"tls"} overrides {tls-allowlist san*.dev}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to connect while with CN having a comprehensive list} {
|
test {TLS: Able to connect while with CN having a comprehensive list} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {dummy.keydb.dev client.keydb.dev other.keydb.dev}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {dummy.keydb.dev client.keydb.dev other.keydb.dev}}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to connect while with SAN having a comprehensive list} {
|
test {TLS: Able to connect while with SAN having a comprehensive list} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {dummy.keydb.dev san2.keydb.dev other.keydb.dev}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {dummy.keydb.dev san2.keydb.dev other.keydb.dev}}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to connect while with CN having a comprehensive list with wildcards} {
|
test {TLS: Able to connect while with CN having a comprehensive list with wildcards} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {dummy.* client*.dev other.*}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {dummy.* client*.dev other.*}}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to connect while with SAN having a comprehensive list with wildcards} {
|
test {TLS: Able to connect while with SAN having a comprehensive list with wildcards} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {dummy.* san*.dev other.*}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {dummy.* san*.dev other.*}}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Not matching CN or SAN rejected} {
|
test {TLS: Not matching CN or SAN rejected} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {client.keydb.dev}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {client.keydb.dev}}} {
|
||||||
catch {set r2 [redis_client_tls -keyfile "$::tlsdir/client2.key" -certfile "$::tlsdir/client2.crt" -require 1 -cafile "$::tlsdir/ca.crt"]} e
|
catch {set r2 [redis_client_tls -keyfile "$::tlsdir/client2.key" -certfile "$::tlsdir/client2.crt" -require 1 -cafile "$::tlsdir/ca.crt"]} e
|
||||||
assert_match {*I/O error reading reply*} $e
|
assert_match {*I/O error reading reply*} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to match against DNS SAN} {
|
test {TLS: Able to match against DNS SAN} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {san1.keydb.dev}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {san1.keydb.dev}}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to match against email SAN} {
|
test {TLS: Able to match against email SAN} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {someone@keydb.dev}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {someone@keydb.dev}}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to match against IPv4 SAN} {
|
test {TLS: Able to match against IPv4 SAN} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {192.168.0.1}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {192.168.0.1}}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to match against IPv4 with a wildcard} {
|
test {TLS: Able to match against IPv4 with a wildcard} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {192.*}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {192.*}}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test {TLS: Able to match against URI SAN} {
|
test {TLS: Able to match against URI SAN} {
|
||||||
start_server {tags {"tls"} overrides {tls-whitelist {https://keydb.dev}}} {
|
start_server {tags {"tls"} overrides {tls-allowlist {https://keydb.dev}}} {
|
||||||
catch {r PING} e
|
catch {r PING} e
|
||||||
assert_match {PONG} $e
|
assert_match {PONG} $e
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user