Astra Linux install Redis with SSL/TLS support

sudo apt update
sudo apt install git build-essential checkinstall zlib1g-dev -y
sudo apt install libssl-dev libsystemd-dev tcl
wget https://download.redis.io/redis-stable.tar.gz
tar -zxvf redis-stable.tar.gz
cd redis-stable/
make BUILD_TLS=yes USE_SYSTEMD=yes
sudo make test
sudo make install
groupadd -r redis
useradd -r -d /usr/local/redis redis
mkdir -p /usr/local/redis/data
chown -R redis:redis /usr/local/redis

Создаем файл описания сервиса /etc/systemd/system/redis-server.service

[Unit]
Description=Redis data structure server
Documentation=https://redis.io/documentation
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
LimitNOFILE=10032
NoNewPrivileges=yes
Type=notify
TimeoutStartSec=1
TimeoutStopSec=1
UMask=0077
User=redis
Group=redis
WorkingDirectory=/usr/local/redis/
[Install]
WantedBy=multi-user.target

CA Key, CA Cert

Для того, чтобы нам начать выдавать сертификаты пользователям нашей системы, необходимо сформировать корневую пару “ключ и сертификат” сервера сертификации (CA, Certificate Authority), который также будет проверяться на клиентской стороне. Это делается следующей последовательностью команд:

#!/bin/bash
openssl genrsa -des3 -out ca.key 4096

Оно создаст ключ, закрытый на пароль (от 6 знаков), который вы придумаете и введете на этапе создания ключа. Можно сделать и ключ, не требующий пароля:

openssl genrsa -out ca.key 4096

Теперь сделаем сертификат от ключа. Он уже не секретный и его можно раздавать.

openssl req \
     -x509 -new -nodes -sha256 \
     -key ca.key \
     -days 3650 \
     -subj '/O=Redis Test/CN=Certificate Authority' \
     -out ca.crt 

Соответственно, полученный CA.crt может быть импортирован на стороне клиента как доверенный корневой сертификат, что избавит пользователей от назойливых предупреждений о нарушении безопасности на десять лет. :) Все-ж таки лучше закрыть ключ на пароль. Т.к. получив (без проблем) сертификат, зная его сериальник и имея корневой ключ, можно будет плодить клиентские серты, что нехорошо

Также делаем файлик параметров openssl для сервера и клиента:

cat > openssl.cnf <<_END_
[ server_cert ]
keyUsage = digitalSignature, keyEncipherment
nsCertType = server

[ client_cert ]
keyUsage = digitalSignature, keyEncipherment
nsCertType = client
_END_

Он нам понадобится для генерации соответствующих ключей

Server key, Server Cert

#!/bin/sh
keyfile=server.key
certfile=server.crt
[ -f $keyfile ] || openssl genrsa -out $keyfile 2048
openssl req \
	-new -sha256 \
	-subj "/O=Redis Test/CN=Server-only" \
	-key $keyfile | \
	openssl x509 \
		-req -sha256 \
		-CA ca.crt \
		-CAkey ca.key \
		-CAserial /etc/ssl/certs/ca.txt \
		-CAcreateserial \
		-days 385 \
		-extfile openssl.cnf -extensions server_cert \
		-out $certfile 

С помощью этих ключа и сертификата подключиться к серверу не получится, поэтому они конфиденциальные условно, чтобы не подделали наш сервер.

Конфигурируем сервер

В рабочий конфиг редиса /etc/redis/redis.conf вставляем

port 0
daemonize "no"
supervised systemd 
pidfile /usr/local/redis/redis.pid
loglevel notice
logfile "/usr/local/redis/redis.log"
databases 16
save ""
dir /usr/local/redis/data/
replica-read-only yes
tls-port 6379
tls-cert-file /etc/redis/server.crt
tls-key-file /etc/redis/server.key
tls-dh-params-file /etc/redis/dhparam.pem 
tls-ca-cert-file /etc/ssl/certs/ca.crt
tls-protocols "TLSv1.3"

Строку

port 6379 

безжалостно удаляем из конфига.

Если нам надо пускать толпу народа с разных центров сертификации, в конфиг можно воткнуть

tls-ca-cert-dir /etc/ssl/certs

Но зачем тогда все?

Теперь запускаем редис

sudo systemctl start redis-server

Можно пробовать подключиться. Но оно нас пошлет. Ибо нет годного клиентского серта от нашего CA.

Ключи и сертификаты клиента

лепим файлик user-keygen.sh

#!/bin/sh
if [ $# -lt 1 ] 
	then echo "Usage: sh user-keygen.sh clientname"
fi
keyfile=$1.key
certfile=$1.crt
[ -f $keyfile ] || openssl genrsa -out $keyfile 2048
openssl req \
	-new -sha256 \
	-subj "/O=Redis Test/CN=Client-only" \
	-key $keyfile | \
	openssl x509 \
		-req -sha256 \
		-CA ca.crt \
		-CAkey ca.key \
		-CAserial ca.txt \
		-CAcreateserial \
		-days 365 \
		-extfile openssl.cnf -extensions client_cert \
		-out $certfile

выполняем его

sh user-keygen.sh client1

Пробуем подключение

/usr/local/bin/redis-cli --tls --cert client1.crt --key client1.key --cacert ca.crt

в базе длаем какое-либо изменение, например создаем пару “ключ-значение”

set supertest_key 654789 
отключаемся(Cntrl+D)

делаем вторй ключ

sh user-keygen.sh client2

и пробуем подключение от него:

/usr/local/bin/redis-cli --tls --cert client2.crt --key client2.key --cacert ca.crt

Подключились. Проверяемся:

get supertest_key

видим цифры, поставленные с первым сертом: 654789

КРУТО!

Осталось провести бенчмарк по сети с SSL и без него. Синтаксис одинаков с redis-cli:

/usr/local/bin/redis-benchmark --tls --cert export/client.crt --key export/client.key --cacert /etc/ssl/certs/ca.crt -q -n 500000

При тестировании локально, на витруальном сервере с 1 ядром и 3 Гб оперативной памяти, под AstraLinux получены следующие результаты:

~$ cd /home/sirabr/; /usr/local/bin/redis-benchmark --tls --cert export/client.crt --key export/client.key --cacert /etc/ssl/certs/ca.crt -q -n 500000
PING_INLINE: 25338.27 requests per second, p50=1.183 msec                   
PING_MBULK: 25287.01 requests per second, p50=1.159 msec                   
SET: 25147.11 requests per second, p50=1.255 msec                   
GET: 24647.54 requests per second, p50=1.255 msec                   
INCR: 24967.54 requests per second, p50=1.287 msec                   
LPUSH: 26487.26 requests per second, p50=1.327 msec                   
RPUSH: 25744.00 requests per second, p50=1.383 msec                   
LPOP: 26022.69 requests per second, p50=1.367 msec                   
RPOP: 26651.03 requests per second, p50=1.295 msec                   
SADD: 25046.34 requests per second, p50=1.231 msec                   
HSET: 26049.81 requests per second, p50=1.271 msec                   
SPOP: 24061.60 requests per second, p50=1.287 msec                   
ZADD: 24720.66 requests per second, p50=1.471 msec                   
ZPOPMIN: 23489.62 requests per second, p50=1.327 msec                   
LPUSH (needed to benchmark LRANGE): 25237.23 requests per second, p50=1.439 msec                   
LRANGE_100 (first 100 elements): 16185.94 requests per second, p50=1.751 msec                   
LRANGE_300 (first 300 elements): 9213.36 requests per second, p50=2.719 msec                  
LRANGE_500 (first 500 elements): 7085.67 requests per second, p50=3.519 msec                  
LRANGE_600 (first 600 elements): 6381.46 requests per second, p50=3.895 msec                    
MSET (10 keys): 24191.99 requests per second, p50=1.607 msec

и

~$ cd /home/sirabr/; /usr/local/bin/redis-benchmark --tls --cert export/client.crt --key export/client.key --cacert /etc/ssl/certs/ca.crt -q -n 500000
PING_INLINE: 25338.27 requests per second, p50=1.183 msec                   
PING_MBULK: 25287.01 requests per second, p50=1.159 msec                   
SET: 25147.11 requests per second, p50=1.255 msec                   
GET: 24647.54 requests per second, p50=1.255 msec                   
INCR: 24967.54 requests per second, p50=1.287 msec                   
LPUSH: 26487.26 requests per second, p50=1.327 msec                   
RPUSH: 25744.00 requests per second, p50=1.383 msec                   
LPOP: 26022.69 requests per second, p50=1.367 msec                   
RPOP: 26651.03 requests per second, p50=1.295 msec                   
SADD: 25046.34 requests per second, p50=1.231 msec                   
HSET: 26049.81 requests per second, p50=1.271 msec                   
SPOP: 24061.60 requests per second, p50=1.287 msec                   
ZADD: 24720.66 requests per second, p50=1.471 msec                   
ZPOPMIN: 23489.62 requests per second, p50=1.327 msec                   
LPUSH (needed to benchmark LRANGE): 25237.23 requests per second, p50=1.439 msec                   
LRANGE_100 (first 100 elements): 16185.94 requests per second, p50=1.751 msec                   
LRANGE_300 (first 300 elements): 9213.36 requests per second, p50=2.719 msec                  
LRANGE_500 (first 500 elements): 7085.67 requests per second, p50=3.519 msec                  
LRANGE_600 (first 600 elements): 6381.46 requests per second, p50=3.895 msec                    
MSET (10 keys): 24191.99 requests per second, p50=1.607 msec                   

то есть разница 1:1,5 в пользу нешифрованного подключения.

Думаю, что по сети разница будет меньше

Тестовый стенд:

cat /etc/*release | head -5; redis-server --version
DISTRIB_ID="AstraLinuxCE"
DISTRIB_DESCRIPTION="Astra Linux CE 2.12.43 (Orel)"
DISTRIB_RELEASE=2.12.43
DISTRIB_CODENAME=orel
PRETTY_NAME="Astra Linux (Orel 2.12.43)"
Redis server v=6.2.6 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=e6d0efdf761d8518
# free -m
              total        used        free      shared  buff/cache   available
Mem:           2989          84        2362          23         543        2728
Swap:          2045           0        2045

Родительский сервер работает под FreeBSD 12.2 и имеет четырехъядерный Intel(R) Xeon(R) CPU E3-1245 V2 @ 3.40GHz со включенным гипертредингом и 32 Гб оперативы.

security_lab/astralinux_redis_ssl.txt · Last modified: 2022/04/21 07:13 by rybario
About this template
CC Attribution-Share Alike 4.0 International
Powered by PHP Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0 Valid HTML5