Skip to content

maxuru ~ % cat memcached/enable-tls

Enable TLS on Memcached

Severity: mediumApplies to: Memcached 1.5.13+Applies to: Memcached 1.6.xApplies to: OpenSSL 1.1.0+
The fix/etc/memcached.conf
Terminal window
# Requires a binary built with --enable-tls
-Z
-o ssl_chain_cert=/etc/memcached/certs/server.pem
-o ssl_key=/etc/memcached/certs/server.key

Everything. The memcached protocol — ASCII and binary alike — is plaintext on the wire, so anything with visibility of the path sees:

  • the keys, which are frequently descriptive enough to matter on their own (session:, user:1234:profile, password_reset:)
  • the values, which is whatever you cached — session objects, rendered fragments, query results, personal data
  • the credentials, if you enabled authentication without TLS

That last one is the sharpest edge. Turning on -Y auth over a plaintext connection puts a reusable password on the network on every connect.

Honest scoping, because this is rated medium rather than high deliberately:

If memcached is bound to loopback — the recommended arrangement, and the Debian default — the traffic never touches a network. TLS adds handshake cost and operational burden for no gain. Skip it.

If clients are on other hosts, TLS is the control that makes that safe, and it moves up in importance the more sensitive the cached data is. A cache holding session tokens on a shared or cloud network is the case that justifies it.

The severity reflects the common deployment, where the exposure is already closed by the binding. It is not a comment on how well TLS works.

TLS arrived in 1.5.13 and requires ./configure --enable-tls with OpenSSL 1.1.0 or later. As with SASL, distribution packages have historically shipped without it — Ubuntu carried a bug specifically about TLS not being enabled in its memcached package for versions that supported it.

So check the binary before designing around this:

Terminal window
memcached -h | grep -i ssl

No output means this build cannot do TLS regardless of flags. Options at that point: use a build that has it, put the traffic on a private network you control, or terminate encryption outside memcached with a stunnel or a service mesh sidecar and keep memcached on loopback behind it. The last is often the least work and needs no rebuild.

ssl_chain_cert wants the certificate with its chain; ssl_key is the private key. Memcached drops privileges to the memcache user, and unlike a web server it does not read the key as root before dropping — so the key must be readable by the runtime user, and therefore protected by ownership rather than by being root-only:

Terminal window
sudo install -d -m 750 -o memcache -g memcache /etc/memcached/certs
sudo chown memcache:memcache /etc/memcached/certs/server.key
sudo chmod 400 /etc/memcached/certs/server.key

This differs from nginx and HAProxy, where the key stays root-owned because a privileged parent reads it at startup. Do not carry that habit across — here it produces a daemon that cannot read its own key.

ssl_verify_mode controls client-certificate verification, for mutual TLS where the clients are yours and you want the cache to refuse anything else.