Redis – открытое in-memory хранилище типа «ключ-значение». Redis поддерживает транзакции, шаблон проектирования pub-sub, автоматический обход сбоев и многое другое. Для Redis разработано множество клиентов в различных языках программирования.
Примечание: Список рекомендованных клиентов можно найти здесь.
Однако Redis не имеет никаких функций шифрования данных. Хранилище нужно развёртывать в изолированной частной сети, доступ к которой есть только у заведомо безопасных клиентов, либо же настроить шифрование трафика самостоятельно.
Данное руководство поможет настроить шифрование трафика Redis с помощью программы stunnel. Трафик между клиентами и серверами Redis будет направляться через специальный шифрованный SSL-туннель.
Требования
В руководстве настройка продемонстрирована на примере двух серверов Ubuntu 16.04. На серверах должны быть:
- Пользователь с доступом к sudo.
- Базовый брандмауэр.
Все необходимые инструкции можно найти в руководстве по начальной настройке.
Что такое stunnel?
Утилита stunnel обеспечивает шифрованный обмен данными между двумя машинами. Клиент подключается к локальному порту, и stunnel шифрует данные перед передачей на удаленный сервер. На стороне сервера stunnel прослушивает заданный порт и расшифровывает трафик перед отправкой его на локальный порт, который прослушивает сервер Redis.
Преимущества stunnel:
- Пакеты stunnel можно найти в стандартном репозитории Ubuntu.
- Утилита проста в установке и настройке.
- Ubuntu предоставляет сценарий инициализации для автозапуска сервиса.
- Для каждой цели используется отдельный туннель. В некоторых ситуациях это может стать недостатком, но благодаря этому вы получаете полный контроль над доступом.
Недостатки stunnel:
- Клиенты подключаются к удаленной машине с помощью нестандартного локального порта.
- Объединяя два сервера Redis для репликации или кластеризации, вы должны настроить два туннеля на каждой машине (один для исходящего и один для входящего трафика).
Установка сервера и клиента Redis
На один сервер Ubuntu 16.04 нужно установить пакеты сервера Redis, на второй – пакеты клиента Redis. Если вы сделали это заранее, пропустите раздел.
Примечание: Сервер Redis устанавливает тестовый ключ, который в дальнейшем будет использоваться для проверки соединения. Если вы уже установили сервер Redis, вы можете продолжить и установить такой ключ (вы можете выбрать любое ключевое слово).
Установка сервера Redis
Чтобы установить последнюю доступную версию Redis, используйте этот PPA.
Примечание: Всегда проверяйте пакеты, загруженные из сторонних репозиториев.
Добавьте PPA и установите Redis.
sudo apt-add-repository ppa:chris-lea/redis-server
sudo apt-get update
sudo apt-get install redis-server
Чтобы ответить на запросы инсталлятора, нажмите Enter.
После завершения установки убедитесь, что вы можете подключиться к сервису Redis локально:
redis-cli ping
Если программа успешно установлена и запущена, на экране появится:
PONG
Теперь добавьте ключ для дальнейшего использования:
redis-cli set test 'success'
Это присвоит ключу test значение success. Это ключевое слово нужно использовать в дальнейшем для проверки соединения с stunnel.
Установка клиента Redis
Второй сервер Ubuntu 16.04 будет использоваться в качестве клиента. Все необходимые пакеты можно загрузить из стандартного реопзитория:
sudo apt-get update
sudo apt-get install redis-tools
Установка stunnel
Примечание: Данный раздел нужно выполнить на каждом сервере и клиенте Redis.
В репозиториях Ubuntu можно найти пакет stunnel4. Установите этот пакет. Если вы пропустили предыдущий раздел, не забудьте обновить индекс пакетов перед установкой:
sudo apt-get update
sudo apt-get install stunnel4
Сервис stunnel в Ubuntu использует для запуска старый сценарий SysVinit. Система system может управлять этим сценарием. Чтобы использовать его вместо встроенных функций system, отредактируйте файл /etc/default/stunnel4:
sudo nano /etc/default/stunnel4
Чтобы сервис запускался вместе с сервером, найдите ENABLED и задайте значение 1:
. . .
ENABLED=1
. . .
Сохраните и закройте файл.
Теперь нужно создать самоподписанный SSL-сертификат и ключ для шифрования трафика.
Создание самоподписанного SSL-сертификата на сервере Redis
Сертификат нужно создать на сервере Redis в каталоге /etc/stunnel. С его помощью stunnel сможет зашифровать обмен данными между сервером и клиентом. Файлы сертификата и ключа называются redis-server (при желании вы можете выбрать другое имя).
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/stunnel/redis-server.key -out /etc/stunnel/redis-server.crt
Программа запросит данные о сертификате. Поскольку этот сертификат предназначен только для внутреннего использования, эти данные не имеют большого значения. Заполните их по желанию.
. . .
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Community
Common Name (e.g. server FQDN or YOUR name) []:redis-server
Email Address []:admin@example.com
Ограничьте доступ к ключу:
sudo chmod 600 /etc/stunnel/redis-server.key
Создание конфигурационного файла stunnel на сервере Redis
На сервере Redis в каталоге /etc/stunnel откройте файл с расширением .conf.
sudo nano /etc/stunnel/redis.conf
Укажите в нём PID-файл. Для хранения таких файлов предназначен каталог /run.
pid = /run/stunnel-redis.pid
Теперь нужно настроить доступ к сервису Redis. Для этого создайте новый раздел (в данном руководстве он называется redis-server). Этот раздел сможет отделить параметры туннелей сервера Redis от других туннелей, которые вы добавите в файл.
Укажите путь к сертификату и ключу, для этого используйте cert и key.
Также здесь можно определить туннель для входящих данных. Для этого предназначена директива accept. Укажите порт Redis (6379) и внешний IP-адрес сервера Redis. Трафик должен передаваться на стандартный порт Redis и локальный интерфейс (эти данные укажите в директиве connect).
pid = /run/stunnel-redis.pid
[redis-server]
cert = /etc/stunnel/redis-server.crt
key = /etc/stunnel/redis-server.key
accept = redis_servers_public_IP:6379
connect = 127.0.0.1:6379
Сохраните и закройте файл.
Перезапуск stunnel и настройка брандмауэра
Примечание: Данный раздел нужно выполнить на сервере Redis.
Перезапустите сервис stunnel:
sudo systemctl restart stunnel4.service
Проверьте сервисы, которые прослушивают соединения на сервере Redis; вы должны увидеть сервис stunnel, использующий порт 6379 на открытом интерфейсе. На локальном интерфейсе Redis слушает тот же порт.
sudo netstat -plunt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 public_IP:6379 0.0.0.0:* LISTEN 4292/stunnel4
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 2679/redis-server 1
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1720/sshd
tcp6 0 0 :::22 :::* LISTEN 1720/sshd
Сервис stunnel прослушивает открытый интерфейс, однако брандмауэр, скорее всего, блокирует этот трафик.
Чтобы разблокировать порт 6379, введите:
sudo ufw allow 6379
Перемещение сертификата на клиент
Каждый клиент Redis должен иметь копию сертификата сервера Redis. Проще всего передать файл .crt следующим образом: отобразить содержимое файла, а затем скопировать его и поместить в соответствующий файл на клиенте.
Запросите содержимое сертификата на сервере Redis:
cat /etc/stunnel/redis-server.crt
-----BEGIN CERTIFICATE-----
MIIEGTCCAwGgAwIBAgIJALUdz8P8q8UPMA0GCSqGSIb3DQEBCwUAMIGiMQswCQYD
VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENp
. . .
Tq7WJk77tk4nPI8iGv1WuK8xTAm5aOncxP16VoMpsDMV+GB1p3nBkMQ/GKF8pPXU
fn6BnDWKmeZqAlBM+MGYAfkbZWdBslrWasCJzs+tehTqL0LLJ6d3Gi9biBPb
-----END CERTIFICATE-----
Примечание: Строки BEGIN CERTIFICATE и END CERTIFICATE также нужно скопировать.
Перейдите на клиентскую машину и откройте одноименный файл в каталоге /etc/stunnel.
sudo nano /etc/stunnel/redis-server.crt
Вставьте в него скопированный сертификат сервера. Сохраните и закройте файл.
Создание конфигурационного файла stunnel на клиенте Redis
Теперь нужно настроить сервис stunnel на клиентской стороне.
Перейдите на клиент. Откройте файл с расширением .conf в каталоге /etc/stunnel:
sudo nano /etc/stunnel/redis.conf
В нём укажите PID-файл.
pid = /run/stunnel-redis.pid
Теперь добавьте раздел для обработки исходящего трафика (в руководстве такой раздел называется redis-client).
С помощью директивы client нужно указать, что эти настройки относятся к клиентской машине. Директива accept должна прослушивать любой свободный порт локального интерфейса (например, 8000). В директиве connect укажите внешний IP сервера Redis и открытый порт.
С помощью CAfile укажите копию сертификата сервера Redis. В директиве verify укажите значение 4 (в этом режиме stunnel проверяет самоподписанные сертификаты).
pid = /run/stunnel-redis.pid
[redis-client]
client = yes
accept = 127.0.0.1:8000
connect = remote_server_IP_address:6379
CAfile = /etc/stunnel/redis-server.crt
verify = 4
Сохраните и закройте файл.
Перезапуск клиента и тестирование соединения
Перезапустите stunnel на клиенте, чтобы обновить настройки.
sudo systemctl restart stunnel4.service
Убедитесь, что туннель установлен правильно:
sudo netstat -plunt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN 3809/stunnel4
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1714/sshd
tcp6 0 0 :::22 :::* LISTEN 1714/sshd
Сервис stunnel прослушивает порт 8000.
Теперь вы можете подключиться к удалённому серверу Redis:
redis-cli -p 8000 ping
PONG
Запросите ключевое слово, установленное в начале:
redis-cli -p 8000 get test
"success"
Это значит, что у клиента есть доступ к удалённой базе данных.
Теперь нужно убедиться, что вы не можете подключиться к серверу без туннеля. Подключитесь напрямую к порту удалённого сервера:
redis-cli -h redis_server_public_IP -p 6379 ping
Error: Connection reset by peer
Как видите, трафик поступает только по туннелю.
Расширение настроек
Выше мы рассмотрели пример простой настройки шифрования для одного клиента и одного сервера Redis. Эту настройку вы можете применить и для большой инфраструктуры.
Чтобы настроить несколько клиентов, нужно просто повторить все вышеописанные действия:
- Установить ПО клиента и утилиту stunnel.
- Включить автозапуск сервиса stunnel.
- Скопировать сертификат сервера Redis в /etc/stunnel.
- Перезапустить stunnel.
Чтобы использовать эту настройку для репликации или кластеризации, нужно создать два параллельных туннеля:
- Установите ПО сервера Redis и утилиту stunnel.
- Включите автозапуск сервиса stunnel.
- Сгенерируйте новый сертификат и ключ шифрования (имя файла должно быть уникальным).
- Скопируйте сертификат с одного сервера на другой в каталог /etc/stunnel.
- Отредактируйте или создайте конфигурационный файл stunnel. Такой файл должен содержать раздел настроек сервера (связывать внешний порт с локальным портом Redis) и настройки клиента (связывать локальный порт с удалённым портом).
- Откройте внешний порт в брандмауэре сервера Redis.
- Настройте каждый экземпляр Redis для подключения к локальному порту. Это позволит получить доступ к удаленному серверу с помощью файла конфигурации Redis (набор директив зависит от отношений между серверами; см. документацию Redis для получения более подробной информации).
Конфигурационные файлы будут выглядеть примерно так:
pid = /run/stunnel-redis.pid
[redis-server]
cert = /etc/stunnel/this_servers_certificate.crt
key = /etc/stunnel/this_servers_key.key
accept = this_servers_public_IP:6379
connect = 127.0.0.1:6379
[redis-client]
client = yes
accept = 127.0.0.1:arbitrary_local_port
connect = remote_servers_public_IP:6379
CAfile = /etc/stunnel/remote_servers_certificate.crt
verify = 4
При необходимости можно создать несколько разделов client на каждой машине для соединения локального и удалённого порта. В таком случае не забудьте выбрать другой свободный локальный порт и указать его в директиве accept.
Заключение
Redis – производительный и гибкий инструмент для хранения данных. Однако обмен данными Redis не защищен, что позволяет злоумышленникам похитить информацию. Поэтому очень важно зашифровать трафик между удалёнными серверами Redis.
Читайте также: