Skip to content

Commit a8856f9

Browse files
committed
Add Redis ACL support
1 parent d89854f commit a8856f9

File tree

18 files changed

+169
-17
lines changed

18 files changed

+169
-17
lines changed

dockers/docker-database/Dockerfile.j2

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,27 @@ RUN pip3 install click
2323
{{ install_debian_packages(docker_database_debs.split(' ')) }}
2424
{%- endif %}
2525

26+
ENV REDIS_SHADOW_TLS=/etc/ssl/certs_redis/certs/tls/
2627
# Clean up
2728
RUN apt-get clean -y && \
2829
apt-get autoclean -y && \
2930
apt-get autoremove -y && \
3031
rm -rf /debs ~/.cache && \
3132
sed -ri 's/^(save .*$)/# \1/g; \
3233
s/^daemonize yes$/daemonize no/; \
33-
s/^logfile .*$/logfile ""/; \
34+
s|^logfile .*$|logfile /etc/redis/redis-server.log|; \
3435
s/^# syslog-enabled no$/syslog-enabled no/; \
3536
s/^# unixsocket/unixsocket/; \
3637
s/redis-server.sock/redis.sock/g; \
3738
s/^client-output-buffer-limit pubsub [0-9]+mb [0-9]+mb [0-9]+/client-output-buffer-limit pubsub 0 0 0/; \
39+
s/^port 6379/# port 6379/; \
40+
s/^# port 0/port 0/; \
41+
s/^# tls-port 6379/tls-port 6379/; \
42+
/tls-auth-clients no/s/^# //; \
43+
s|# tls-cert-file .*|tls-cert-file '"$REDIS_SHADOW_TLS"'/redis.crt|; \
44+
s|# tls-key-file .*|tls-key-file '"$REDIS_SHADOW_TLS"'/redis.key|; \
45+
s|# tls-ca-cert-file .*|tls-ca-cert-file '"$REDIS_SHADOW_TLS"'/ca.crt|; \
46+
/aclfile \/etc\/redis\/users.acl/s/^# //; \
3847
s/^notify-keyspace-events ""$/notify-keyspace-events AKE/; \
3948
s/^databases [0-9]+$/databases 100/ \
4049
' /etc/redis/redis.conf
@@ -48,5 +57,6 @@ COPY ["files/supervisor-proc-exit-listener", "/usr/bin"]
4857
COPY ["files/sysctl-net.conf", "/etc/sysctl.d/"]
4958
COPY ["files/update_chassisdb_config", "/usr/local/bin/"]
5059
COPY ["flush_unused_database", "/usr/local/bin/"]
60+
COPY ["users.acl.template", "/etc/redis/"]
5161

5262
ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"]

dockers/docker-database/docker-database-init.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,14 @@ ln -sf /usr/share/zoneinfo/$TZ /etc/localtime
115115

116116
chown -R redis:redis $REDIS_DIR
117117

118+
# Redis PW update in users.acl
119+
acl_template=$(< /etc/redis/users.acl.template)
120+
121+
USER_COUNTER_PASSWORD=$(cat /etc/shadow_redis_dir/shadow_redis_admin)
122+
acl_new_admin_user="${acl_template//\$\{USER_COUNTER_PASSWORD\}/$USER_COUNTER_PASSWORD}"
123+
124+
MONITOR_PASSWORD=$(cat /etc/shadow_redis_dir/shadow_redis_monitor)
125+
acl_new_admin_monitor_users="${acl_new_admin_user//\$\{MONITOR_PASSWORD\}/$MONITOR_PASSWORD}"
126+
echo "$acl_new_admin_monitor_users" > /etc/redis/users.acl
127+
118128
exec /usr/local/bin/supervisord

dockers/docker-database/supervisord.conf.j2

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ dependent_startup=true
3636
{%- else -%}
3737
{%- set LOOPBACK_IP = '' -%}
3838
{%- endif -%}
39-
command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --bind {{ LOOPBACK_IP }} {{ redis_items['hostname'] }} --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}"
39+
command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --bind {{ LOOPBACK_IP }} {{ redis_items['hostname'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}"
4040
priority=2
41-
user=redis
4241
autostart=true
4342
autorestart=false
4443
stdout_logfile=syslog
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
user admin on +@all -DEBUG ~* >${USER_COUNTER_PASSWORD}
2+
user monitor on +hgetall +keys +select +get +mget +hget -DEBUG ~* >${MONITOR_PASSWORD}
3+
user default off

dockers/docker-orchagent/buffermgrd.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22

3-
BUFFER_CALCULATION_MODE=$(redis-cli -n 4 hget "DEVICE_METADATA|localhost" buffer_model)
3+
BUFFER_CALCULATION_MODE=$(sonic-db-cli CONFIG_DB hget "DEVICE_METADATA|localhost" buffer_model)
44

55
if [ "$BUFFER_CALCULATION_MODE" == "dynamic" ]; then
66
BUFFERMGRD_ARGS="-a /etc/sonic/asic_table.json"

files/build_templates/docker_image_ctl.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ start() {
575575
# TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version
576576
{%- endif %}
577577
docker create {{docker_image_run_opt}} \
578+
-v /etc/shadow_redis_dir:/etc/shadow_redis_dir:ro \
578579
{%- if docker_container_name != "dhcp_server" %}
579580
--net=$NET \
580581
{%- endif %}
@@ -627,6 +628,7 @@ start() {
627628
{%- endif %}
628629
{%- if docker_container_name == "database" %}
629630
$DB_OPT \
631+
-v /etc/ssl/certs_redis:/etc/ssl/certs_redis:ro \
630632
{%- else %}
631633
-v /var/run/redis$DEV:/var/run/redis:rw \
632634
-v /var/run/redis-chassis:/var/run/redis-chassis:ro \

files/build_templates/sonic_debian_extension.j2

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
113113
# Install j2cli for handling jinja template
114114
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install j2cli
115115

116+
# Create an empty Redis dir for the generation of Redis ACL passwords
117+
sudo mkdir $FILESYSTEM_ROOT/etc/shadow_redis_dir
118+
119+
# Create an empty Redis dir for the public cacert of Redis TLS
120+
sudo mkdir $FILESYSTEM_ROOT/etc/shadow_redis_dir/certs_redis
121+
116122
# Install Python client for Redis
117123
sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "redis==3.5.3"
118124

@@ -932,6 +938,13 @@ sudo LANG=C cp $SCRIPTS_DIR/mgmt-framework.sh $FILESYSTEM_ROOT/usr/local/bin/mgm
932938
sudo LANG=C cp $SCRIPTS_DIR/asic_status.sh $FILESYSTEM_ROOT/usr/local/bin/asic_status.sh
933939
sudo LANG=C cp $SCRIPTS_DIR/asic_status.py $FILESYSTEM_ROOT/usr/local/bin/asic_status.py
934940

941+
# Copy Redis Certificate generator script
942+
FSROOT_ETC_SSL_CERTS_REDIS=$FILESYSTEM_ROOT/etc/ssl/certs_redis
943+
sudo LANG=C mkdir $FSROOT_ETC_SSL_CERTS_REDIS
944+
sudo LANG=C cp $SCRIPTS_DIR/gen-redis-certs.sh $FSROOT_ETC_SSL_CERTS_REDIS/gen-redis-certs.sh
945+
sudo chroot $FILESYSTEM_ROOT chown admin:admin /etc/ssl/certs_redis/gen-redis-certs.sh
946+
sudo chmod 770 $FSROOT_ETC_SSL_CERTS_REDIS/gen-redis-certs.sh
947+
935948
# Copy sonic-netns-exec script
936949
sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netns-exec
937950

files/image_config/pcie-check/pcie-check.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function check_and_rescan_pcie_devices()
3838
fi
3939

4040
if [ "$(eval $PCIE_CHK_CMD)" = "$EXPECTED" ]; then
41-
redis-cli -n 6 HSET $PCIE_STATUS_TABLE "status" "PASSED"
41+
sonic-db-cli STATE_DB HSET $PCIE_STATUS_TABLE "status" "PASSED"
4242
debug "PCIe check passed"
4343
exit
4444
else
@@ -54,7 +54,7 @@ function check_and_rescan_pcie_devices()
5454

5555
done
5656
debug "PCIe check failed"
57-
redis-cli -n 6 HSET $PCIE_STATUS_TABLE "status" "FAILED"
57+
sonic-db-cli STATE_DB HSET $PCIE_STATUS_TABLE "status" "FAILED"
5858
}
5959

6060
check_and_rescan_pcie_devices

files/image_config/platform/rc.local

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,37 @@ fi
240240

241241
program_console_speed
242242

243+
# Generate password for Redis DB
244+
echo "Redis PW generation"
245+
set +x
246+
REDIS_SHADOW_PATH=/etc/shadow_redis_dir
247+
openssl_random_cmd=$(openssl rand -base64 32)
248+
ADMIN_PASSWORD=''
249+
ADMIN_PASSWORD=$(echo "$openssl_random_cmd" | tr -d '\n')
250+
REDIS_SHADOW_ADMIN_PATH=$REDIS_SHADOW_PATH/shadow_redis_admin
251+
touch "$REDIS_SHADOW_ADMIN_PATH"
252+
chown admin:admin "$REDIS_SHADOW_ADMIN_PATH"
253+
chmod 640 "$REDIS_SHADOW_ADMIN_PATH"
254+
echo "$ADMIN_PASSWORD" > "$REDIS_SHADOW_ADMIN_PATH"
255+
MONITOR_PASSWORD=''
256+
MONITOR_PASSWORD=$(echo "$openssl_random_cmd" | tr -d '\n')
257+
echo "$MONITOR_PASSWORD" > $REDIS_SHADOW_PATH/shadow_redis_monitor
258+
259+
# TLS support
260+
ETC_SSL=/etc/ssl/certs_redis
261+
REDIS_CERTS=$ETC_SSL/certs
262+
REDIS_CERTS_TLS=$REDIS_CERTS/tls
263+
264+
# Check if the directory exists and remove it if it does
265+
[ -d "$REDIS_CERTS" ] && rm -rf "$REDIS_CERTS"
266+
267+
(cd $ETC_SSL && ./gen-redis-certs.sh)
268+
269+
# Copy CA cert to host share location for Redis client usage
270+
cp $REDIS_CERTS_TLS/ca.crt $REDIS_SHADOW_PATH/certs_redis
271+
272+
set -x
273+
243274
if [ -f $FIRST_BOOT_FILE ]; then
244275

245276
echo "First boot detected. Performing first boot tasks..."

files/scripts/gen-redis-certs.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/bash
2+
3+
# from redis official repo https://github.com/redis/redis/
4+
# Generate some test certificates which are used by the regression test suite:
5+
#
6+
# certs/tls/ca.{crt,key} Self signed CA certificate.
7+
# certs/tls/redis.{crt,key} A certificate with no key usage/policy restrictions.
8+
9+
generate_cert() {
10+
local name=$1
11+
local cn="$2"
12+
local opts="$3"
13+
14+
local keyfile=certs/tls/${name}.key
15+
local certfile=certs/tls/${name}.crt
16+
17+
[ -f $keyfile ] || openssl genrsa -out $keyfile 2048
18+
openssl req \
19+
-new -sha256 \
20+
-subj "/O=Redis Test/CN=$cn" \
21+
-key $keyfile | \
22+
openssl x509 \
23+
-req -sha256 \
24+
-CA certs/tls/ca.crt \
25+
-CAkey certs/tls/ca.key \
26+
-CAserial certs/tls/ca.txt \
27+
-CAcreateserial \
28+
-days 365 \
29+
$opts \
30+
-out $certfile
31+
}
32+
33+
mkdir -p certs/tls
34+
[ -f certs/tls/ca.key ] || openssl genrsa -out certs/tls/ca.key 4096
35+
openssl req \
36+
-x509 -new -nodes -sha256 \
37+
-key certs/tls/ca.key \
38+
-days 3650 \
39+
-subj '/O=Redis Test/CN=Certificate Authority' \
40+
-out certs/tls/ca.crt
41+
42+
cat > certs/tls/openssl.cnf <<_END_
43+
[ server_cert ]
44+
keyUsage = digitalSignature, keyEncipherment
45+
nsCertType = server
46+
47+
[ client_cert ]
48+
keyUsage = digitalSignature, keyEncipherment
49+
nsCertType = client
50+
_END_
51+
52+
generate_cert redis "Generic-cert"

0 commit comments

Comments
 (0)