Difference between revisions of "Redis"
(19 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
= Install = | = [https://redis.io/download Install] = | ||
Install the cli client only | Install the cli client only | ||
<source lang=bash> | <source lang=bash> | ||
# Local laptop | # Local laptop | ||
apt install redis-tools | ## Version distributed with Ubuntu 20.04 | ||
apt install redis-tools # redis-cli 5.0.7, does not support redis-over-TLS --tls flag | |||
## Latest release, eg. redis-cli 6.2.3. supports redis-over-TLS --tls flag | |||
add-apt-repository ppa:redislabs/redis | |||
apt-get install redis | |||
# A pod | # A pod | ||
kubectl -n default run --image=ubuntu:20.04 ubuntu-1 --rm -it -- bash | kubectl -n default run --image=ubuntu:20.04 ubuntu-1 --rm -it -- bash | ||
export DEBIAN_FRONTEND=noninteractive | export DEBIAN_FRONTEND=noninteractive | ||
apt update; apt install -yqq dnsutils netcat | apt update; apt install -yqq dnsutils netcat stunnel vim net-tools # select 8, 27, these are optional packages | ||
apt install -yqq redis-tools # redis-cli 5.0.7 | |||
## Latest release, eg. redis-cli 6.2.3 | |||
apt-get install software-properties-common # installs 'add-apt-repository' | |||
add-apt-repository ppa:redislabs/redis | |||
apt-get install redis | |||
</source> | </source> | ||
Line 24: | Line 36: | ||
REDIS_AUTH_TOKEN='p#ssw0rd1' | REDIS_AUTH_TOKEN='p#ssw0rd1' | ||
redis-cli -h $REDIS_PRIMARY -p 6379 ping | redis-cli -h $REDIS_PRIMARY -p 6379 ping # no-encription-in-transit | ||
PONG | PONG | ||
</source> | </source> | ||
= Connect to the server and run [https://redis.io/commands commands] from cli = | |||
{{Note|All below examples are based on connecting to AWS Redis ElasticCache}} | |||
== No-auth, no-encryption-in-transit == | |||
== No auth == | |||
<source lang=bash> | <source lang=bash> | ||
# connect to the server cli | # connect to the server cli | ||
Line 57: | Line 70: | ||
telnet> Connection closed. | telnet> Connection closed. | ||
</source> | </source> | ||
== Auth == | |||
== Auth and encryption-in-transit == | |||
=== Stunnel proxy === | |||
{{Note|If your <code>redis-cli</code> <6.x use this method}} | |||
[https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/auth.html Authenticating Users with the Redis AUTH Command], with encryption in transport and at rest. This requires to use some sort of proxy that will enable SSL transport in beetween the redis-client and the AWS hosted redis-cache. | [https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/auth.html Authenticating Users with the Redis AUTH Command], with encryption in transport and at rest. This requires to use some sort of proxy that will enable SSL transport in beetween the redis-client and the AWS hosted redis-cache. | ||
<source lang=bash> | <source lang=bash> | ||
apt update; apt install -yqq dnsutils netcat redis-tools stunnel vim net-tools | apt update; apt install -yqq dnsutils netcat redis-tools stunnel vim net-tools procps iproute2 | ||
# | iproute2(ss), procps(ps), dnsutils(dig) | |||
# Config vars | # Config vars | ||
Line 67: | Line 86: | ||
PORT_PRIMARY=6379 | PORT_PRIMARY=6379 | ||
PORT_REPLICA=6380 | PORT_REPLICA=6380 | ||
REDIS_PRIMARY=master.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com | |||
REDIS_REPLICA=replica.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com | |||
# Config 'stunnel' - local laptop | # Config 'stunnel' - local laptop | ||
Line 76: | Line 97: | ||
debug = 7 | debug = 7 | ||
delay = yes | delay = yes | ||
options = NO_SSLv2 | #options = NO_SSLv2 # these options might be not valid anymore | ||
options = NO_SSLv3 | #options = NO_SSLv3 | ||
[redis-cli] | [redis-cli] | ||
client = yes | client = yes | ||
Line 89: | Line 110: | ||
cat /etc/stunnel/redis-cli.conf | cat /etc/stunnel/redis-cli.conf | ||
# Config 'stunnel' - container ( | # Config 'stunnel' - container (works with Istio sidecar, no-privilege mode needed) | ||
cat > /etc/stunnel/redis-cli.conf << EOF | cat > /etc/stunnel/redis-cli.conf << EOF | ||
fips = no | fips = no | ||
Line 97: | Line 118: | ||
debug = 7 | debug = 7 | ||
delay = yes | delay = yes | ||
options = NO_SSLv2 | #options = NO_SSLv2 # Illegal TLS option | ||
options = NO_SSLv3 | options = NO_SSLv3 | ||
[redis-cli] | [redis-cli] | ||
Line 127: | Line 148: | ||
redis-cli -h localhost -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" ping | redis-cli -h localhost -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" ping | ||
redis-cli -h localhost -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" info server | redis-cli -h localhost -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" info server | ||
redis-cli -h $REDIS_PRIMARY -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" | redis-cli -h $REDIS_PRIMARY -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" --stat | ||
redis-cli -u redis://"${REDIS_AUTH_TOKEN}"@${REDIS_PRIMARY}:${PORT_PRIMARY}/0 ping # never worked, could password contain unallowed chars | redis-cli -u redis://"${REDIS_AUTH_TOKEN}"@${REDIS_PRIMARY}:${PORT_PRIMARY}/0 ping # never worked, could password contain unallowed chars | ||
</source> | </source> | ||
{{Note|Auth <code>redis-cli -h localhost -p 8000 -a password</code>, alternatively, you can authenticate by running the auth command followed by your password after establishing the connection: <code>auth password1</code>}} | {{Note|Auth <code>redis-cli -h localhost -p 8000 -a password</code>, alternatively, you can authenticate by running the auth command followed by your password after establishing the connection: <code>auth password1</code>}} | ||
{{Note|Continuous stats mode <code>redis-cli --stat -i 5</code>, in this mode a new line is printed every second with useful information and the difference between the old data point, <code>-i 5</code> emits lines every 5 seconds, default is 1s}} | |||
=== <code>redis-cli --tls</code> (6.x) === | |||
<source lang=bash> | |||
REDIS_PRIMARY=master.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com | |||
REDIS_REPLICA=replica.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com | |||
REDIS_AUTH_TOKEN='passwprd1' # default env var is: REDISCLI_AUTH | |||
# connects to a cluster with [x]encryption enabled | |||
redis-cli -h $REDIS_PRIMARY -p 6379 --no-auth-warning --tls | |||
# connects to a cluster with [x]encryption and [x]authentication enabled | |||
redis-cli -h $REDIS_PRIMARY -p 6379 --no-auth-warning --tls -a $REDIS_AUTH_TOKEN --verbose | |||
# if using cname eg. REDIS_PRIMARY=redis then --sni is required | |||
redis-cli -h $REDIS_PRIMARY -p 6379 --no-auth-warning --tls -a $REDIS_AUTH_TOKEN --sni $REDIS_PRIMARY --verbose | |||
</source> | |||
[https://redislabs.com/blog/enabling-secure-connections-redis-enterprise-cloud-python/ Verify RedisCache SSL] | |||
<source lang=bash> | |||
openssl s_client -host [endpoint name] -port [endpoint port number] -cert redislabs_user.crt -key redislabs_user_private.key -CAfile redislabs_ca.pem -crlf | |||
openssl s_client -connect $REDIS_PRIMARY:6379 -servername $REDIS_PRIMARY | |||
</source> | |||
Running the command will produce a long sequence of output about various aspects of the TLS connection with a message at the end that looks like: <code>Verify return code: 0 (ok)</code>, any other return code or message, the connection wasn’t able to establish securely. | |||
= Redis server = | |||
Convenient sample tls certs used here can be found: [https://github.com/OpenVPN/openvpn/tree/master/sample/sample-keys OpenVPN/openvpn - sample-keys]. Redis-server implementation can use public/private certificates. The private part (server) and public part the (client). When using the redis-client, the public part of the certificates is expected instead of the private one. | |||
<source lang=bash> | |||
curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/ca.crt | |||
curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/server.crt | |||
curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/server.key | |||
curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/client.crt | |||
curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/client.key | |||
kubectl create secret generic redis-tls --from-file ca.crt --from-file server.key --from-file server.crt | |||
cat <<EOF >values.yaml | |||
cluster: | |||
enabled: false | |||
tls: | |||
enabled: true | |||
authClients: true | |||
certificatesSecret: redis-tls | |||
certFilename: server.crt | |||
certKeyFilename: server.key | |||
certCAFilename: ca.crt | |||
master: | |||
readinessProbe: | |||
enabled: false | |||
livenessProbe: | |||
enabled: false | |||
EOF | |||
helm install redis bitnami/redis -f values.yaml | |||
export REDIS_PASSWORD=$(kubectl get secret --namespace default redis -o jsonpath="{.data.redis-password}" | base64 --decode) | |||
kubectl run redis-client --restart='Never' --env REDIS_PASSWORD=$REDIS_PASSWORD --image docker.io/bitnami/redis:6.0.6-debian-10-r10 --command -- sleep infinity | |||
kubectl cp --namespace default client.crt redis-client:/tmp/client.crt | |||
kubectl cp --namespace default client.key redis-client:/tmp/client.key | |||
kubectl cp --namespace default ca.crt redis-client:/tmp/ca.crt | |||
kubectl exec -ti redis-client -- redis-cli -h redis-master -a $REDIS_PASSWORD --tls --cert /tmp/client.crt --key /tmp/client.key --cacert /tmp/ca.crt | |||
</source> | |||
{{Note|This should be not necessary in a near feature. Note that in the values.yaml, the readiness and liveness probes are disabled to avoid the master pod being restarted when enabling client authentication.}} | |||
= Commands = | = Commands = | ||
<source lang=bash> | <source lang=bash> | ||
# auth | |||
redis.acme.com:6379> AUTH p!ssw0rd1 | |||
# list who is connected | |||
localhost:6379> CLIENT LIST | |||
id=136260 addr=10.0.0.5:42257 fd=9 name=backendservice-11111f57fc-h7l9b age=96965 idle=49 flags=P db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping | |||
id=136261 addr=10.0.0.5:46525 fd=10 name=backendservice-11111f57fc-h7l9b age=96965 idle=6 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=evalsha | |||
id=138125 addr=10.0.0.5:56729 fd=20 name=authservice-2222265797-zkcnw age=42695 idle=22 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=info | |||
id=138126 addr=10.0.0.5:48548 fd=26 name=authservice-2222265797-zkcnw age=42694 idle=22 flags=P db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping | |||
# list keys 'KEYS pattern' | # list keys 'KEYS pattern' | ||
redis.acme.com:6379> KEYS *Auth* | redis.acme.com:6379> KEYS *Auth* | ||
Line 145: | Line 247: | ||
redis.acme.com:6379> DUMP mykey | redis.acme.com:6379> DUMP mykey | ||
"\u0000\xC0\n\t\u0000\xBEm\u0006\x89Z(\u0000\n" | "\u0000\xC0\n\t\u0000\xBEm\u0006\x89Z(\u0000\n" | ||
# monitor activity | |||
redis.acme.com:6379> MONITOR | |||
</source> | </source> |
Latest revision as of 06:49, 24 May 2021
This is most about AWS ElastiCache service, Redis cache that is fast key/value store.
Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Read more...
Install
Install the cli client only
# Local laptop ## Version distributed with Ubuntu 20.04 apt install redis-tools # redis-cli 5.0.7, does not support redis-over-TLS --tls flag ## Latest release, eg. redis-cli 6.2.3. supports redis-over-TLS --tls flag add-apt-repository ppa:redislabs/redis apt-get install redis # A pod kubectl -n default run --image=ubuntu:20.04 ubuntu-1 --rm -it -- bash export DEBIAN_FRONTEND=noninteractive apt update; apt install -yqq dnsutils netcat stunnel vim net-tools # select 8, 27, these are optional packages apt install -yqq redis-tools # redis-cli 5.0.7 ## Latest release, eg. redis-cli 6.2.3 apt-get install software-properties-common # installs 'add-apt-repository' add-apt-repository ppa:redislabs/redis apt-get install redis
Test connectivity
REDIS_PRIMARY=master.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com REDIS_REPLICA=replica.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com REDIS_AUTH_TOKEN='p#ssw0rd1' redis-cli -h $REDIS_PRIMARY -p 6379 ping # no-encription-in-transit PONG
Connect to the server and run commands from cli
Note: All below examples are based on connecting to AWS Redis ElasticCache
No-auth, no-encryption-in-transit
# connect to the server cli $ redis-cli -h redis.acme.com -p 6379 # Using docker $ docker run -it redis redis-cli -h redis.acme.com -p 6379 # Using telnet `apt install telnet` telnet redis.acme.com 6379 Trying 10.10.10.111... # <-- server IP Connected to redis.acme.com. Escape character is '^]'. monitor # command 1, streams back every command processed by Redis +OK # stop monitoring by Ctl^C or issue command `QUIT` if using Telnet session QUIT +OK Connection closed by foreign host. telnet redis.acme.com 6379 Trying 10.10.10.111... # <-- server IP KEYS AuthenticationService # command 2, show keys +1600340814.733253 [0 10.10.10.222:59730] "keys" "AuthenticationService" # <-- .222 client IP *0 ^] telnet> Connection closed.
Auth and encryption-in-transit
Stunnel proxy
Note: If your redis-cli
<6.x use this method
Authenticating Users with the Redis AUTH Command, with encryption in transport and at rest. This requires to use some sort of proxy that will enable SSL transport in beetween the redis-client and the AWS hosted redis-cache.
apt update; apt install -yqq dnsutils netcat redis-tools stunnel vim net-tools procps iproute2 # | iproute2(ss), procps(ps), dnsutils(dig) # Config vars STUNNEL_UID=root STUNNEL_GUID=root PORT_PRIMARY=6379 PORT_REPLICA=6380 REDIS_PRIMARY=master.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com REDIS_REPLICA=replica.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com # Config 'stunnel' - local laptop sudo bash -c "cat > /etc/stunnel/redis-cli.conf << EOF fips = no setuid = $STUNNEL_UID setgid = $STUNNEL_GUID pid = /var/run/stunnel.pid debug = 7 delay = yes #options = NO_SSLv2 # these options might be not valid anymore #options = NO_SSLv3 [redis-cli] client = yes accept = 127.0.0.1:${PORT_PRIMARY} connect = $REDIS_PRIMARY:6379 [redis-cli-replica] client = yes accept = 127.0.0.1:${PORT_REPLICA} connect = $REDIS_REPLICA:6379 EOF" cat /etc/stunnel/redis-cli.conf # Config 'stunnel' - container (works with Istio sidecar, no-privilege mode needed) cat > /etc/stunnel/redis-cli.conf << EOF fips = no setuid = $STUNNEL_UID setgid = $STUNNEL_GUID pid = /var/run/stunnel.pid debug = 7 delay = yes #options = NO_SSLv2 # Illegal TLS option options = NO_SSLv3 [redis-cli] client = yes accept = 127.0.0.1:${PORT_PRIMARY} connect = $REDIS_PRIMARY:6379 [redis-cli-replica] client = yes accept = 127.0.0.1:${PORT_REPLICA} connect = $REDIS_REPLICA:6379 EOF cat /etc/stunnel/redis-cli.conf
Create proxy-tunnel
stunnel /etc/stunnel/redis-cli.conf netstat -tulnp | grep -i stunnel root@ubuntu-1-57789d9bf7-pmg2j:/# netstat -tulnp | grep -i stunnel tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 1049/stunnel tcp 0 0 127.0.0.1:6380 0.0.0.0:* LISTEN 1049/stunnel pkill stunnel # kill stunnel # Connect redis-cli -h localhost -p $PORT_PRIMARY redis-cli -h localhost -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" redis-cli -h localhost -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" ping redis-cli -h localhost -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" info server redis-cli -h $REDIS_PRIMARY -p $PORT_PRIMARY -a "$REDIS_AUTH_TOKEN" --stat redis-cli -u redis://"${REDIS_AUTH_TOKEN}"@${REDIS_PRIMARY}:${PORT_PRIMARY}/0 ping # never worked, could password contain unallowed chars
Note: Auth redis-cli -h localhost -p 8000 -a password
, alternatively, you can authenticate by running the auth command followed by your password after establishing the connection: auth password1
Note: Continuous stats mode redis-cli --stat -i 5
, in this mode a new line is printed every second with useful information and the difference between the old data point, -i 5
emits lines every 5 seconds, default is 1s
redis-cli --tls
(6.x)
REDIS_PRIMARY=master.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com REDIS_REPLICA=replica.re111111111111.aaaaaa.ng.0001.aaa.cache.amazonaws.com REDIS_AUTH_TOKEN='passwprd1' # default env var is: REDISCLI_AUTH # connects to a cluster with [x]encryption enabled redis-cli -h $REDIS_PRIMARY -p 6379 --no-auth-warning --tls # connects to a cluster with [x]encryption and [x]authentication enabled redis-cli -h $REDIS_PRIMARY -p 6379 --no-auth-warning --tls -a $REDIS_AUTH_TOKEN --verbose # if using cname eg. REDIS_PRIMARY=redis then --sni is required redis-cli -h $REDIS_PRIMARY -p 6379 --no-auth-warning --tls -a $REDIS_AUTH_TOKEN --sni $REDIS_PRIMARY --verbose
openssl s_client -host [endpoint name] -port [endpoint port number] -cert redislabs_user.crt -key redislabs_user_private.key -CAfile redislabs_ca.pem -crlf openssl s_client -connect $REDIS_PRIMARY:6379 -servername $REDIS_PRIMARY
Running the command will produce a long sequence of output about various aspects of the TLS connection with a message at the end that looks like: Verify return code: 0 (ok)
, any other return code or message, the connection wasn’t able to establish securely.
Redis server
Convenient sample tls certs used here can be found: OpenVPN/openvpn - sample-keys. Redis-server implementation can use public/private certificates. The private part (server) and public part the (client). When using the redis-client, the public part of the certificates is expected instead of the private one.
curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/ca.crt curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/server.crt curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/server.key curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/client.crt curl -sLO https://raw.githubusercontent.com/OpenVPN/openvpn/master/sample/sample-keys/client.key kubectl create secret generic redis-tls --from-file ca.crt --from-file server.key --from-file server.crt cat <<EOF >values.yaml cluster: enabled: false tls: enabled: true authClients: true certificatesSecret: redis-tls certFilename: server.crt certKeyFilename: server.key certCAFilename: ca.crt master: readinessProbe: enabled: false livenessProbe: enabled: false EOF helm install redis bitnami/redis -f values.yaml export REDIS_PASSWORD=$(kubectl get secret --namespace default redis -o jsonpath="{.data.redis-password}" | base64 --decode) kubectl run redis-client --restart='Never' --env REDIS_PASSWORD=$REDIS_PASSWORD --image docker.io/bitnami/redis:6.0.6-debian-10-r10 --command -- sleep infinity kubectl cp --namespace default client.crt redis-client:/tmp/client.crt kubectl cp --namespace default client.key redis-client:/tmp/client.key kubectl cp --namespace default ca.crt redis-client:/tmp/ca.crt kubectl exec -ti redis-client -- redis-cli -h redis-master -a $REDIS_PASSWORD --tls --cert /tmp/client.crt --key /tmp/client.key --cacert /tmp/ca.crt
Note: This should be not necessary in a near feature. Note that in the values.yaml, the readiness and liveness probes are disabled to avoid the master pod being restarted when enabling client authentication.
Commands
# auth redis.acme.com:6379> AUTH p!ssw0rd1 # list who is connected localhost:6379> CLIENT LIST id=136260 addr=10.0.0.5:42257 fd=9 name=backendservice-11111f57fc-h7l9b age=96965 idle=49 flags=P db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping id=136261 addr=10.0.0.5:46525 fd=10 name=backendservice-11111f57fc-h7l9b age=96965 idle=6 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=evalsha id=138125 addr=10.0.0.5:56729 fd=20 name=authservice-2222265797-zkcnw age=42695 idle=22 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=info id=138126 addr=10.0.0.5:48548 fd=26 name=authservice-2222265797-zkcnw age=42694 idle=22 flags=P db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping # list keys 'KEYS pattern' redis.acme.com:6379> KEYS *Auth* # set value redis.acme.com:6379> SET mykey 10 "OK" # read value redis.acme.com:6379> DUMP mykey "\u0000\xC0\n\t\u0000\xBEm\u0006\x89Z(\u0000\n" # monitor activity redis.acme.com:6379> MONITOR