fix: Support TLS for Memcached without password authentication (#5085)

* fix: enable to use tls with memcached protocol without require password setting
This commit is contained in:
Volodymyr Yavdoshenko 2025-05-09 00:01:19 +03:00 committed by GitHub
parent b8ef7cdf69
commit 705d61e793
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 0 deletions

View file

@ -141,6 +141,7 @@ ABSL_DECLARE_FLAG(string, tls_ca_cert_file);
ABSL_DECLARE_FLAG(string, tls_ca_cert_dir);
ABSL_DECLARE_FLAG(int, replica_priority);
ABSL_DECLARE_FLAG(double, rss_oom_deny_ratio);
ABSL_DECLARE_FLAG(uint32_t, memcached_port);
bool AbslParseFlag(std::string_view in, ReplicaOfFlag* flag, std::string* err) {
#define RETURN_ON_ERROR(cond, m) \
@ -299,6 +300,12 @@ bool ValidateServerTlsFlags() {
has_auth = true;
}
// Allow TLS without authentication for memcached protocol
// We check if memcached_port is enabled, as this is a static check during startup
if (GetFlag(FLAGS_memcached_port) > 0) {
has_auth = true;
}
if (!has_auth) {
LOG(ERROR) << "TLS configured but no authentication method is used!";
return false;

View file

@ -5,6 +5,7 @@ from redis import Redis
import socket
import random
import time
import ssl
from . import dfly_args
from .instance import DflyInstance
@ -171,3 +172,41 @@ def test_expiration(memcached_client: MCClient):
assert memcached_client.get("key1") == None
assert memcached_client.get("key2") == None
assert memcached_client.get("key3") == None
@dfly_args(DEFAULT_ARGS)
def test_memcached_tls_no_requirepass(df_factory, with_tls_server_args, with_tls_ca_cert_args):
"""
Test for issue #5084: ability to use TLS for Memcached without requirepass.
Dragonfly required a password to be set when using TLS, but the Memcached protocol
does not support password authentication. This test verifies that we can start
the server with TLS enabled but without specifying requirepass and with the Memcached port.
"""
# Create arguments for TLS without specifying requirepass
server_args = {**DEFAULT_ARGS, **with_tls_server_args}
# Create and start the server - it should not crash
server = df_factory.create(**server_args)
server.start()
# Give the server time to start
time.sleep(1)
# Create SSL context for client
ssl_context = ssl.create_default_context()
ssl_context.load_verify_locations(with_tls_ca_cert_args["ca_cert"])
ssl_context.check_hostname = False
# Disable certificate verification (since we don't provide a client certificate)
ssl_context.verify_mode = ssl.CERT_NONE
# Output port information for diagnostics
print(f"Connecting to memcached port: {server.mc_port} on host: 127.0.0.1")
# Connect to Memcached over TLS
client = MCClient(("127.0.0.1", server.mc_port), tls_context=ssl_context)
# Test basic operations
assert client.set("foo", "bar")
assert client.get("foo") == b"bar"