M1
Databases AWS

Memcached 1.6.24 on AWS User Guide

| Product: Memcached 1.6.24 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using Memcached 1.6.24 on Ubuntu 24.04 from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened Redis, Memcached & Key-Value Stores and Caches AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch. The other key-value stores and caches in the listing are described on the listing's guide hub.

Memcached is a fast, distributed, in-memory key-value cache. Applications use it to keep the results of database queries, rendered pages, API calls and sessions in RAM so they do not have to be computed again. Data lives in memory only: it is lost when Memcached restarts, so Memcached is a cache in front of your real data store, never the only copy of anything.

The image installs Memcached 1.6.24 from the Ubuntu 24.04 LTS archive (package 1.6.24-1ubuntu0.3), which the Ubuntu security team patches. Unattended security upgrades stay on for your instance.

What is on the image:

  • Memcached 1.6.24 (memcached.service), running as the unprivileged memcache user inside the Ubuntu unit's systemd sandbox, with extra cloudimg hardening
  • SASL authentication required for every client (PLAIN over the Memcached binary protocol), with a password created on your instance's first boot
  • TCP on 127.0.0.1:11211 only and UDP disabled, so the cache is not reachable from the network and cannot be abused for UDP amplification attacks
  • The client tools memcstat, memccat, memcset and friends (libmemcached-tools) and the Python client pylibmc
  • A self-test, /usr/local/sbin/memcached-selftest

Default user: ubuntu · Architecture: x86_64 · Root volume: 8 GiB gp3

Security posture

  • No default password. Stock Memcached has no authentication at all. This image requires SASL for every request, and the password is generated on each instance's first boot into /root/memcached-credentials.txt (mode 0600, root only). No credential ships in the image and no two instances share one.
  • Localhost only, UDP off. Memcached listens on 127.0.0.1:11211 (TCP) and has UDP disabled (-U 0). Unauthenticated requests are refused with an authentication error, and the plain-text (ASCII) protocol is refused because SASL needs the binary protocol.
  • The listing security group opens SSH only. Port 11211 stays closed. If application servers on other instances need the cache, Step 7 shows how to serve your private network only.
  • Fails closed. Memcached does not start until first boot has created the instance's credential, and it refuses to start if the credential is missing or malformed. It never runs open.
  • No metadata access for the cache. memcached.service and its first-boot unit are blocked from reaching the instance metadata service (169.254.169.254 and fd00:ec2::254).
  • IMDSv2 required. The AMI is registered with ImdsSupport v2.0, so instances launched from it refuse token-less (IMDSv1) metadata requests.
  • Per-instance identity. SSH host keys and the machine ID are generated fresh on every instance.

Prerequisites

  1. An AWS account and permission to launch EC2 instances
  2. An EC2 key pair in the Region you launch in
  3. A VPC subnet, ideally the one your application servers use

Recommended instance type: m5.large. Memcached is light on CPU; size the instance by the memory you want to give the cache (Step 6).

Connecting to your instance

Version Operating system SSH user
Memcached 1.6.24 on Ubuntu 24.04 Ubuntu 24.04 LTS ubuntu

Step 1: Launch the instance

Option A: AWS Marketplace console

  1. Open the cloudimg Hardened Redis, Memcached & Key-Value Stores and Caches AMIs listing on AWS Marketplace and choose View purchase options, then Subscribe. One subscription covers every version in the listing.
  2. Once the subscription is active, choose Launch your software.
  3. Choose One-click launch from AWS Marketplace (or Launch from EC2 Console for the full launch wizard). In Version, choose Memcached 1.6.24 on Ubuntu 24.04, then choose your Region.
  4. Pick an instance type (m5.large recommended; the software charge is $0.04 per vCPU per hour) and your key pair.
  5. Security group: the listing's default group allows SSH (22) only. Restrict it to your own IP address.
  6. Choose your VPC and subnet, leave the metadata defaults (the image already requires IMDSv2), then choose Launch.

Option B: AWS CLI

Run this on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and the security group, subnet and key pair with your own (the security group should allow SSH from your management address only):

aws ec2 run-instances \
  --image-id ami-0123456789abcdef0 \
  --instance-type m5.large \
  --key-name my-key-pair \
  --security-group-ids sg-0123456789abcdef0 \
  --subnet-id subnet-0123456789abcdef0 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=memcached}]'

You do not need --metadata-options: the AMI already makes IMDSv2 required.

Step 2: Connect and find your credential

Connect as ubuntu with the key pair you chose:

ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>

First boot finishes within seconds of launch. It generates the instance's SASL password and writes it, with the user name and server address, to /root/memcached-credentials.txt. This command shows the file without the password line:

sudo grep -v '^MEMCACHED_PASSWORD=' /root/memcached-credentials.txt
# Memcached 1.6.24 (cloudimg) - generated on this instance's first boot. Root only (0600).
# SASL PLAIN over the memcached binary protocol. memcached listens on 127.0.0.1:11211 only; UDP is off.
# Rotate the password: edit MEMCACHED_PASSWORD below, then run: sudo systemctl restart memcached
MEMCACHED_USER=cloudimg
MEMCACHED_SERVER=127.0.0.1:11211

To print the password itself when you need to put it in your application's configuration, run sudo sed -n 's/^MEMCACHED_PASSWORD=//p' /root/memcached-credentials.txt. Treat it like any other secret.

Step 3: Confirm Memcached is running

memcached.service and its first-boot unit are active, and the self-test proves the cache works with this instance's credential and is private: it checks the version, that requests without a password or with a wrong one are refused, that the ASCII protocol is refused, a store, read and delete round-trip, the exact listening sockets, that nothing answers on UDP, and that the instance's private IP refuses port 11211.

systemctl is-active memcached.service memcached-firstboot.service
sudo /usr/local/sbin/memcached-selftest
active
active
  ok: memcached version 1.6.24
  ok: unauthenticated GET/SET refused (AUTH_ERROR 0x20)
  ok: wrong password refused (0x20); this instance's credential accepted on the same raw path
  ok: ASCII protocol refused
  ok: pylibmc SET/GET/DELETE with this instance's credential; wrong password refused
  ok: TCP listeners exactly 127.0.0.1:11211; no UDP listener and no UDP answer
  ok: private IP 172.31.83.193 refuses 11211 (22 answers)
SELFTEST_OK

The configuration is in /etc/memcached.conf, and Memcached listens on loopback TCP only:

grep -v '^#' /etc/memcached.conf
sudo ss -tulpn | grep memcached
-m 64
-p 11211
-U 0
-l 127.0.0.1
-u memcache
-c 1024
-S
-B binary
tcp   LISTEN 0      1024          127.0.0.1:11211      0.0.0.0:*    users:(("memcached",pid=834,fd=26))

-m is the cache size in MB, -c the connection limit, -U 0 turns UDP off, -S requires SASL and -B binary selects the binary protocol that SASL needs.

Step 4: Store and read values

This Python example reads the credential from the root-only file (so the password never appears on a command line), stores a value, increments a counter and reads the server statistics with pylibmc, which is installed on the image:

sudo python3 - <<'PY'
import pylibmc
creds = {}
for line in open("/root/memcached-credentials.txt"):
    if "=" in line and not line.startswith("#"):
        key, value = line.strip().split("=", 1)
        creds[key] = value
mc = pylibmc.Client(["127.0.0.1:11211"], binary=True,
                    username=creds["MEMCACHED_USER"], password=creds["MEMCACHED_PASSWORD"])
mc.set("greeting", "hello from cloudimg", time=300)
print("greeting =", mc.get("greeting"))
mc.set("page_views", 0)
mc.incr("page_views", 5)
print("page_views =", mc.get("page_views"))
stats = {k: v.decode() for k, v in mc.get_stats()[0][1].items()}
print("version", stats["version"], "| curr_items", stats["curr_items"], "| limit_maxbytes", stats["limit_maxbytes"])
mc.delete_multi(["greeting", "page_views"])
PY
greeting = hello from cloudimg
page_views = 5
version 1.6.24 | curr_items 2 | limit_maxbytes 67108864

time=300 makes the entry expire after five minutes; without it an entry stays until Memcached needs the memory for something newer.

The libmemcached-tools commands take the credential as options. memcstat prints the server statistics:

PASS="$(sudo sed -n 's/^MEMCACHED_PASSWORD=//p' /root/memcached-credentials.txt)"
memcstat --servers=127.0.0.1:11211 --binary --username=cloudimg --password="$PASS" | grep -E 'Server:|pid|version|curr_connections|limit_maxbytes|threads'
unset PASS
Server: 127.0.0.1 (11211)
    pid: 5311
    version: 1.6.24
    curr_connections: 1
    limit_maxbytes: 67108864
    threads: 4

Options on a command line are visible to other users of the instance while the command runs, so prefer a client library that reads the password from a file or your application's secret store.

Step 5: See authentication enforced

A wrong password is refused, and a plain-text request without a password gets no answer at all (Memcached closes the connection):

memcstat --servers=127.0.0.1:11211 --binary --username=cloudimg --password=wrong-password || echo "memcstat refused (exit $?)"
printf 'stats\r\n' | nc -w 2 127.0.0.1 11211 | wc -c
Failed to 'STAT ': (0x7ffe13914ab0) AUTHENTICATION FAILURE,  host: 127.0.0.1:11211 -> ./src/libmemcached/sasl.cc:257
memcstat refused (exit 1)
0

Step 6: Size the cache

The image gives Memcached 64 MB. Set -m in /etc/memcached.conf to the memory, in MB, you want the cache to use, leaving room for the operating system (on an 8 GiB m5.large, -m 6144 is a reasonable start), for example with sudo sed -i 's/^-m .*/-m 6144/' /etc/memcached.conf, then apply it with sudo systemctl restart memcached. Raise -c the same way if your applications open more than 1024 connections.

Restarting Memcached empties the cache. Your application should treat every key as optional and rebuild it from the real data source on a miss.

Step 7: Serve application servers in your VPC (optional)

Memcached on the same instance as your application needs nothing more. To let application servers on other instances use it:

  1. Add the instance's private IP to the -l line, keeping 127.0.0.1 and keeping -S (authentication) and -U 0 (UDP off):
PRIVATE_IP=<private-ip>
sudo sed -i "s/^-l 127.0.0.1$/-l 127.0.0.1,${PRIVATE_IP}/" /etc/memcached.conf
sudo systemctl restart memcached
sudo ss -tlnp | grep memcached
sudo /usr/local/sbin/memcached-selftest

The self-test then checks that the private IP still demands the password. Never use 0.0.0.0: the self-test rejects a wildcard listener.

  1. In the instance's security group, add an inbound rule for TCP 11211 from your application servers' security group or subnet only. Never open it to 0.0.0.0/0.

  2. Point your clients at <private-ip>:11211 with the user cloudimg and the password from Step 2.

Memcached's binary protocol is not encrypted, so keep this traffic inside your VPC (security groups, private subnets), or run Memcached on the same instance as the application.

Step 8: Connect from your application

Use any client that supports SASL over the Memcached binary protocol, with the server 127.0.0.1:11211 (or the private IP from Step 7), the user cloudimg and the password from Step 2. Keep the password in your application's secret store or an environment file readable only by the application, never in source code. For example:

  • Python (pylibmc): pylibmc.Client(["127.0.0.1:11211"], binary=True, username="cloudimg", password=PASSWORD)
  • PHP (php-memcached): $m->setOption(Memcached::OPT_BINARY_PROTOCOL, true); $m->setSaslAuthData("cloudimg", $password);
  • Ruby (dalli): Dalli::Client.new("127.0.0.1:11211", username: "cloudimg", password: password)

Clients that only speak the plain-text protocol, or that do not support SASL, cannot authenticate and are refused.

Step 9: Change the password

The credential file is the source of truth: Memcached rebuilds its SASL entry from it every time it starts. To set a new password, replace the value of MEMCACHED_PASSWORD (at least 16 characters, no spaces) and restart Memcached:

sudo sed -i 's/^MEMCACHED_PASSWORD=.*/MEMCACHED_PASSWORD=<new-password>/' /root/memcached-credentials.txt
sudo systemctl restart memcached
sudo /usr/local/sbin/memcached-selftest

Then update your applications. Changing the instance's hostname is safe: the SASL entry follows the hostname on the next restart.

Step 10: Metadata access is blocked for the cache

Memcached and its first-boot unit carry a systemd rule that drops traffic to the instance metadata service, so nothing running inside them can read instance credentials:

systemctl show -p IPAddressDeny memcached.service memcached-firstboot.service
IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32

IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32

Step 11: Security recommendations

  • Keep port 11211 closed to the internet. Memcached is a cache for your own applications. Open it only to your application servers (Step 7), and SSH only to your management address.
  • Keep authentication and UDP settings. Leave -S and -U 0 in /etc/memcached.conf. Exposed Memcached servers without them are widely abused for data leaks and DDoS amplification.
  • Never store the only copy of data in Memcached. Everything in it disappears on a restart or under memory pressure.
  • Rotate the password if it may have been exposed (Step 9).
  • Keep the OS and Memcached patched. Unattended security upgrades are on; restart Memcached after a Memcached update.
  • Watch the statistics. memcstat reports hits, misses, evictions and memory use for your monitoring system.

Support and licensing

Memcached is distributed under the BSD 3-Clause licence. This image ships the unmodified Ubuntu 24.04 Memcached package. cloudimg provides the packaging, the secure defaults (required authentication, localhost only, UDP off), the per-instance credential, the metadata block, the self-test and 24/7 support.

cloudimg is not affiliated with or endorsed by the Memcached project. Memcached is a mark of its owner and is used here only to identify the software.

For help with deployment or configuration, email support@cloudimg.co.uk or visit cloudimg support.