Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Generate TLS certificates
run: |
./tools/gen-certificates.sh

- name: Set up the required containers
run: |
BUILDER_IMAGE=${{ matrix.container }} SERVER_IMAGE=${{ matrix.server }} docker compose -f tools/docker-compose.yml up -d --wait || (docker compose logs; exit 1)
Expand Down
2 changes: 1 addition & 1 deletion test/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void run(
conn->async_run(cfg, run_callback{conn, op, ec});
}

static std::string safe_getenv(const char* name, const char* default_value)
std::string safe_getenv(const char* name, const char* default_value)
{
// MSVC doesn't like getenv
#ifdef BOOST_MSVC
Expand Down
2 changes: 2 additions & 0 deletions test/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ std::string_view find_client_info(std::string_view client_info, std::string_view
void create_user(std::string_view port, std::string_view username, std::string_view password);

boost::redis::logger make_string_logger(std::string& to);

std::string safe_getenv(const char* name, const char* default_value);
52 changes: 24 additions & 28 deletions test/test_conn_tls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@
#include <boost/asio/ssl/host_name_verification.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>

#include <cerrno>
#include <cstddef>
#include <fstream>
#include <string>
#include <string_view>
#define BOOST_TEST_MODULE conn_tls
#include <boost/test/included/unit_test.hpp>
Expand All @@ -25,37 +29,28 @@ using boost::system::error_code;

namespace {

// CA certificate that signed the test server's certificate.
// This is a self-signed CA created for testing purposes.
// This must match tools/tls/ca.crt contents
static constexpr const char* ca_certificate = R"%(-----BEGIN CERTIFICATE-----
MIIDhzCCAm+gAwIBAgIUZGttu4o/Exs08EHCneeD3gHw7KkwDQYJKoZIhvcNAQEL
BQAwUjELMAkGA1UEBhMCRVMxGjAYBgNVBAoMEUJvb3N0LlJlZGlzIENJIENBMQsw
CQYDVQQLDAJJVDEaMBgGA1UEAwwRYm9vc3QtcmVkaXMtY2ktY2EwIBcNMjUwNjA3
MTI0NzUwWhgPMjA4MDAzMTAxMjQ3NTBaMFIxCzAJBgNVBAYTAkVTMRowGAYDVQQK
DBFCb29zdC5SZWRpcyBDSSBDQTELMAkGA1UECwwCSVQxGjAYBgNVBAMMEWJvb3N0
LXJlZGlzLWNpLWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu7XV
sOoHB2J/5VtyJmMOzxhBbHKyQgW1YnMvYIb1JqIm7VuICA831SUw76n3j8mIK3zz
FfK2eYyUWf4Uo2j3uxmXDyjujqzIaUJNLcB53CQXkmIbqDigNhzUTPZ5A2MQ7xT+
t1eDbjsZ7XIM+aTShgtrpyxiccsgPJ3/XXme2RrqKeNvYsTYY6pquWZdyLOg/LOH
IeSJyL1/eQDRu/GsZjnR8UOE6uHfbjrLWls7Tifj/1IueVYCEhQZpJSWS8aUMLBZ
fi+t9YMCCK4DGy+6QlznGgVqdFFbTUt2C7tzqz+iF5dxJ8ogKMUPEeFrWiZpozoS
t60jV8fKwdXz854jLQIDAQABo1MwUTAdBgNVHQ4EFgQU2SoWvvZUW8JiDXtyuXZK
deaYYBswHwYDVR0jBBgwFoAU2SoWvvZUW8JiDXtyuXZKdeaYYBswDwYDVR0TAQH/
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAqY4hGcdCFFPL4zveSDhR9H/akjae
uXbpo/9sHZd8e3Y4BtD8K05xa3417H9u5+S2XtyLQg5MON6J2LZueQEtE3wiR3ja
QIWbizqp8W54O5hTLQs6U/mWggfuL2R/HUw7ab4M8JobwHNEMK/WKZW71z0So/kk
W3wC0+1RH2PjMOZrCIflsD7EXYKIIr9afypAbhCQmCfu/GELuNx+LmaPi5JP4TTE
tDdhzWL04JLcZnA0uXb2Mren1AR9yKYH2I5tg5kQ3Bn/6v9+JiUhiejP3Vcbw84D
yFwRzN54bLanrJNILJhHPwnNIABXOtGUV05SZbYazJpiMst1a6eqDZhv/Q==
-----END CERTIFICATE-----)%";

static config make_tls_config()
// Loads the CA certificate that signed the certificate used by the server.
// Should be in /tmp/
std::string load_ca_certificate()
{
auto ca_path = safe_getenv("BOOST_REDIS_CA_PATH", "/opt/ci-tls/ca.crt");
std::ifstream f(ca_path);
if (!f) {
throw boost::system::system_error(
errno,
boost::system::system_category(),
"Failed to open CA certificate file '" + ca_path + "'");
}

return std::string(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>());
}

config make_tls_config()
{
config cfg;
cfg.use_ssl = true;
cfg.addr.host = get_server_hostname();
cfg.addr.port = "16380";
cfg.addr.port = "16379";
return cfg;
}

Expand Down Expand Up @@ -100,6 +95,7 @@ BOOST_AUTO_TEST_CASE(exec_default_ssl_context)
// Users can pass a custom context with TLS config
BOOST_AUTO_TEST_CASE(exec_custom_ssl_context)
{
std::string ca_pem = load_ca_certificate();
auto const cfg = make_tls_config();
constexpr std::string_view ping_value = "Kabuf";

Expand All @@ -113,7 +109,7 @@ BOOST_AUTO_TEST_CASE(exec_custom_ssl_context)

// Configure the SSL context to trust the CA that signed the server's certificate.
// The test certificate uses "redis" as its common name, regardless of the actual server's hostname
ctx.add_certificate_authority(net::const_buffer(ca_certificate, std::strlen(ca_certificate)));
ctx.add_certificate_authority(net::buffer(ca_pem));
ctx.set_verify_mode(net::ssl::verify_peer);
ctx.set_verify_callback(net::ssl::host_name_verification("redis"));

Expand Down
49 changes: 25 additions & 24 deletions tools/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ services:
--replica-announce-ip localhost \
--port 6379 \
--tls-port 16379 \
--tls-cert-file /docker/tls/server.crt \
--tls-key-file /docker/tls/server.key \
--tls-ca-cert-file /docker/tls/ca.crt \
--tls-cert-file /tls/server.crt \
--tls-key-file /tls/server.key \
--tls-ca-cert-file /tls/ca.crt \
--tls-auth-clients no \
--unixsocket /tmp/redis-socks/redis.sock \
--unixsocketperm 777'
volumes:
- ./docker:/docker
- /opt/ci-tls:/tls
- /tmp/redis-socks:/tmp/redis-socks

redis-replica-1:
Expand All @@ -30,13 +30,13 @@ services:
"--replicaof", "localhost", "6379",
"--port", "6380",
"--tls-port", "16380",
"--tls-cert-file", "/docker/tls/server.crt",
"--tls-key-file", "/docker/tls/server.key",
"--tls-ca-cert-file", "/docker/tls/ca.crt",
"--tls-cert-file", "/tls/server.crt",
"--tls-key-file", "/tls/server.key",
"--tls-ca-cert-file", "/tls/ca.crt",
"--tls-auth-clients", "no",
]
volumes:
- ./docker:/docker
- /opt/ci-tls:/tls


redis-replica-2:
Expand All @@ -50,13 +50,13 @@ services:
"--replicaof", "localhost", "6379",
"--port", "6381",
"--tls-port", "16381",
"--tls-cert-file", "/docker/tls/server.crt",
"--tls-key-file", "/docker/tls/server.key",
"--tls-ca-cert-file", "/docker/tls/ca.crt",
"--tls-cert-file", "/tls/server.crt",
"--tls-key-file", "/tls/server.key",
"--tls-ca-cert-file", "/tls/ca.crt",
"--tls-auth-clients", "no",
]
volumes:
- ./docker:/docker
- /opt/ci-tls:/tls


sentinel-1:
Expand All @@ -67,9 +67,9 @@ services:
sh -c 'cat << EOF > /etc/sentinel.conf && redis-sentinel /etc/sentinel.conf
port 26379
tls-port 36379
tls-cert-file /docker/tls/server.crt
tls-key-file /docker/tls/server.key
tls-ca-cert-file /docker/tls/ca.crt
tls-cert-file /tls/server.crt
tls-key-file /tls/server.key
tls-ca-cert-file /tls/ca.crt
tls-auth-clients no
sentinel resolve-hostnames yes
sentinel announce-hostnames yes
Expand All @@ -80,7 +80,7 @@ services:
sentinel parallel-syncs mymaster 1
EOF'
volumes:
- ./docker:/docker
- /opt/ci-tls:/tls


sentinel-2:
Expand All @@ -91,9 +91,9 @@ services:
sh -c 'cat << EOF > /etc/sentinel.conf && redis-sentinel /etc/sentinel.conf
port 26380
tls-port 36380
tls-cert-file /docker/tls/server.crt
tls-key-file /docker/tls/server.key
tls-ca-cert-file /docker/tls/ca.crt
tls-cert-file /tls/server.crt
tls-key-file /tls/server.key
tls-ca-cert-file /tls/ca.crt
tls-auth-clients no
sentinel resolve-hostnames yes
sentinel announce-hostnames yes
Expand All @@ -104,7 +104,7 @@ services:
sentinel parallel-syncs mymaster 1
EOF'
volumes:
- ./docker:/docker
- /opt/ci-tls:/tls

sentinel-3:
container_name: sentinel-3
Expand All @@ -114,9 +114,9 @@ services:
sh -c 'cat << EOF > /etc/sentinel.conf && redis-sentinel /etc/sentinel.conf
port 26381
tls-port 36381
tls-cert-file /docker/tls/server.crt
tls-key-file /docker/tls/server.key
tls-ca-cert-file /docker/tls/ca.crt
tls-cert-file /tls/server.crt
tls-key-file /tls/server.key
tls-ca-cert-file /tls/ca.crt
tls-auth-clients no
sentinel resolve-hostnames yes
sentinel announce-hostnames yes
Expand All @@ -127,7 +127,7 @@ services:
sentinel parallel-syncs mymaster 1
EOF'
volumes:
- ./docker:/docker
- /opt/ci-tls:/tls


builder:
Expand All @@ -137,4 +137,5 @@ services:
tty: true
volumes:
- ../:/boost-redis
- /opt/ci-tls:/opt/ci-tls
- /tmp/redis-socks:/tmp/redis-socks
21 changes: 0 additions & 21 deletions tools/docker/tls/ca.crt

This file was deleted.

28 changes: 0 additions & 28 deletions tools/docker/tls/ca.key

This file was deleted.

19 changes: 0 additions & 19 deletions tools/docker/tls/server.crt

This file was deleted.

28 changes: 0 additions & 28 deletions tools/docker/tls/server.key

This file was deleted.

10 changes: 9 additions & 1 deletion tools/gen-certificates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
#

# Generates the ca and certificates used for CI testing.
# Run this in the directory where you want the certificates to be generated.
# Usage: gen-certificates.sh [output-dir]

set -e

OUTPUT_DIR="${1:-/opt/ci-tls}"
mkdir -p "$OUTPUT_DIR"
cd "$OUTPUT_DIR"

# CA private key
openssl genpkey -algorithm RSA -out ca.key -pkeyopt rsa_keygen_bits:2048

Expand All @@ -28,3 +32,7 @@ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt -days 20000 -sha256
rm server.csr
rm ca.srl

# Required when running with Docker because of mismatched user IDs
chmod 444 *