Вступление
Redis - это хранилище данных значения ключа с открытым исходным кодом, использующее модель хранения в памяти с дополнительными записями на диск для сохранения. Он включает в себя транзакции, шаблон обмена сообщениями в пабах и подчиненных и автоматическое переключение при сбое, а также другие функции. В Redis клиенты написаны на большинстве языков, а рекомендуемые указаны вtheir website.
Redis не предоставляет никаких собственных возможностей шифрования. Он работает в предположении, что он был развернут в изолированной частной сети, доступной только доверенным сторонам. Если ваша среда не соответствует этому предположению, вам придется отдельно упаковывать трафик Redis в шифрование.
В этом руководстве мы продемонстрируем, как зашифровать трафик Redis с помощью программы безопасного туннелирования под названиемstunnel
. Трафик между клиентами и серверами Redis будет направляться через выделенный туннель с шифрованием SSL. Для демонстрации мы будем использовать два сервера Ubuntu 16.04.
Предпосылки
Для начала у вас должен быть пользователь без полномочий root с правамиsudo
, настроенными на каждой из ваших машин. Кроме того, в этом руководстве предполагается, что у вас установлен базовый брандмауэр. Вы можете следовать нашимUbuntu 16.04 initial server setup guide, чтобы выполнить эти требования.
Когда вы будете готовы продолжить, следуйте ниже.
Что такое stunnel?
Для базовой зашифрованной связи утилитуstunnel
просто установить и настроить. Это позволяет зашифрованную пересылку между двумя машинами. Клиент подключается к локальному порту, иstunnel
зашифровывает его перед пересылкой на удаленный сервер. На стороне сервераstunnel
прослушивает настроенный порт и расшифровывает трафик, прежде чем перенаправить его на локальный порт (в нашем случае порт, который прослушивает сервер Redis).
Некоторые преимущества использованияstunnel
:
-
Ubuntu поддерживает пакеты для
stunnel
в своих репозиториях по умолчанию. -
Ubuntu включает в себя сценарий инициализации для автоматического запуска процесса при загрузке
-
Конфигурация проста и интуитивно понятна
-
Новый туннель используется для каждой цели. Это может быть недостатком в некоторых ситуациях, но обеспечивает детальный контроль над доступом.
Некоторые недостатки:
-
Клиенты подключаются к удаленному компьютеру, подключаясь к локальному порту, отличному от используемого по умолчанию, который на первый взгляд может быть не интуитивным.
-
При подключении двух серверов Redis для репликации или кластеризации на каждом компьютере должны быть настроены два туннеля для обмена данными между серверами (один для исходящего и один для входящего трафика).
Имея в виду эти характеристики, давайте начнем.
Установите Redis Server и клиентские пакеты
Прежде чем мы начнем, на одном компьютере должен быть установлен сервер Redis, а на другом - клиентские пакеты. Если у вас уже есть один или оба из них настроены, не стесняйтесь пропустить.
[.note] #Note: Инструкции сервера Redis устанавливают тестовый ключ, который будет использоваться для проверки соединения позже. Если у вас уже установлен сервер Redis, вы можете установить этот ключ или использовать любой другой известный ключ при тестировании соединения.
#
Установка сервера Redis
Мы будем использоватьChris Lea’s Redis server PPA для установки последней версии Redis. Всегда соблюдайте осторожность при использовании стороннего хранилища. В этом случае Крис Ли - надежный упаковщик, который поддерживает высококачественные, современные пакеты для нескольких популярных проектов с открытым исходным кодом.
Добавьте 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
Если программное обеспечение установлено и запущено, вы должны увидеть:
Redis server outputPONG
Давайте установим ключ, который мы можем использовать позже:
redis-cli set test 'success'
Мы установили ключtest на значениеsuccess
. Мы попытаемся получить доступ к этому ключу с нашего клиентского компьютера после настройкиstunnel
.
Установка клиента Redis
Другой компьютер с Ubuntu 16.04 будет работать как клиент. Все необходимое нам программное обеспечение доступно в пакетеredis-tools
в репозитории по умолчанию:
sudo apt-get update
sudo apt-get install redis-tools
При активной конфигурации по умолчанию удаленного сервера Redis и брандмауэра в настоящее время мы не можем подключиться к удаленному экземпляру Redis для тестирования.
Установить и включить stunnel на каждом компьютере
Затем вам нужно будет установитьstunnel
на каждом из серверов и клиентов. Ubuntu включает четвертую версию утилиты под названиемstunnel4
в своих репозиториях по умолчанию. Если вам не нужно ничего устанавливать в предыдущем разделе, не забудьте включить командуsudo apt-get update
для обновления индекса вашего пакета перед установкой:
# sudo apt-get update
sudo apt-get install stunnel4
Службаstunnel
в Ubuntu использует для запуска старый сценарий SysVinit, которым можно управлять с помощью systemd. Вместо использования собственных методов systemd, чтобы настроить запуск службы при загрузке, вы должны изменить файл/etc/default/stunnel4
:
sudo nano /etc/default/stunnel4
Включите запуск службы при загрузке, установив для параметраENABLED
значение «1»:
/etc/default/stunnel4
. . .
ENABLED=1
. . .
Сохраните и закройте файл на каждом сервере.
Далее мы создадим самозаверяющий сертификат SSL и ключ, который будет использоваться для шифрования связи.
Создайте самоподписанный сертификат SSL и ключ на сервере Redis
На сервере Redis создайте самоподписанный сертификат SSL и ключ в каталоге/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
Вам будет предложено ввести информацию о сертификате, который вы создаете. Поскольку это будет использоваться только внутри, значения не имеют большого значения, поэтому заполните все, что вы хотите. Вы можете увидеть пример ниже:
Redis server output. . .
-----
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]:DigitalOcean
Organizational Unit Name (eg, section) []:Community
Common Name (e.g. server FQDN or YOUR name) []:redis-server
Email Address []:[email protected]
Ограничьте доступ к сгенерированному файлу.key
, набрав:
sudo chmod 600 /etc/stunnel/redis-server.key
Теперь, когда у нас есть сертификат и ключ SSL, мы можем создать файл конфигурации нашего сервера Redisstunnel
.
Создайте файл конфигурации Redis Server Stunnel
Откройте файл, заканчивающийся на.conf
, в каталоге/etc/stunnel
на сервере Redis, чтобы начать:
sudo nano /etc/stunnel/redis.conf
Внутри укажите местоположение для записи файла PID в главном разделе. Каталог/run
предназначен для хранения этих типов файлов, поэтому мы будем использовать это:
/etc/stunnel/redis.conf
pid = /run/stunnel-redis.pid
Далее создайте раздел для настройки доступа к сервису Redis. Вы можете называть это как хотите (мы будем называть этоredis-server
). Этот раздел отделяет эту конфигурацию от любых других туннелей, которые вам может потребоваться настроить на этом компьютере позднее.
Нам нужно указать расположение собственного сертификата и ключа сервера Redis с помощью директивcert
иkey
соответственно.
Мы также определим туннель для входящих данных здесь. Мы хотим, чтобы зашифрованный трафикaccept
направлялся на порт Redis по умолчанию (порт 6379) на внешнем IP-адресе сервера Redis. Затем нам нужноconnect
этот трафик на порт Redis по умолчанию на интерфейсеlocal, чтобы депонировать расшифрованный трафик. Вот где служба Redis действительно прослушивает:
/etc/stunnel/redis.conf
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 и настройте брандмауэр.
Теперь, когдаstunnel
настроен на сервере Redis, мы можем перезапустить службу, набрав:
sudo systemctl restart stunnel4.service
Если вы проверите службы, прослушивающие соединения на вашем сервере Redis, вы должны увидеть, чтоstunnel
прослушивает порт 6379 в общедоступном интерфейсе. Вы также должны увидеть, что Redis прослушивает этот же порт на локальном интерфейсе:
sudo netstat -plunt
Redis server outputActive 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
Это откроет доступ к порту 6379 на вашем публичном интерфейсе, который прослушиваетstunnel
. Портstunnel
принимает только зашифрованный трафик.
Раздайте сертификат клиенту
Каждому клиенту Redis потребуется копия файла сертификата сервера Redis. Самый простой способ распространить файлы.crt
- просто вывести содержимое файла на сервер, а затем скопировать содержимое в соответствующий файл на подключенных машинах.
Выведите содержимое файла.crt
на свой сервер Redis, набрав:
cat /etc/stunnel/redis-server.crt
Redis server output-----BEGIN CERTIFICATE-----
MIIEGTCCAwGgAwIBAgIJALUdz8P8q8UPMA0GCSqGSIb3DQEBCwUAMIGiMQswCQYD
VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENp
. . .
Tq7WJk77tk4nPI8iGv1WuK8xTAm5aOncxP16VoMpsDMV+GB1p3nBkMQ/GKF8pPXU
fn6BnDWKmeZqAlBM+MGYAfkbZWdBslrWasCJzs+tehTqL0LLJ6d3Gi9biBPb
-----END CERTIFICATE-----
Скопируйте отображаемый сертификатincluding the lines marked BEGIN CERTIFICATE and END CERTIFICATE в буфер обмена.
На клиентской машине откройте файл с таким же именем в каталоге/etc/stunnel
:
sudo nano /etc/stunnel/redis-server.crt
Вставьте содержимое, которое вы скопировали с сервера Redis. Сохраните и закройте файл, когда вы закончите.
Создайте файл конфигурации клиента Redis
Теперь, когда у клиента есть копия сертификата сервера, мы можем настроить клиентскую часть конфигурацииstunnel
.
Откройте файл, заканчивающийся на.conf
, в каталоге/etc/stunnel
на клиентском компьютере. Мы снова назовем файлredis.conf
:
sudo nano /etc/stunnel/redis.conf
Внутри, указав PID-файл, где служба снова будет хранить свой идентификатор процесса:
/etc/stunnel/redis.conf
pid = /run/stunnel-redis.pid
Затем добавьте раздел для настройки туннеля для исходящих данных. Вы можете назвать это как хотите (мы назовем егоredis-client
). Этот раздел отделяет эту конфигурацию от любых других туннелей, которые вам может потребоваться настроить на этом компьютере позднее.
Нам нужно явно пометить этот раздел как конфигурацию клиента с помощью директивыclient
. Задайте директивуaccept
для прослушивания неиспользуемого порта на локальном интерфейсе для обработки подключений от вашего локального клиента Redis (в этом примере мы будем использовать порт 8000). Установите в директивеconnect
общедоступный IP-адрес сервера Redis и порт, который мы открыли.
Затем используйтеCAfile
, чтобы указать на копию сертификата сервера Redis. Мы также должны установитьverify
равным 4, что заставляетstunnel
проверять сертификат только без учета цепочки сертификатов (поскольку мы сами подписали наш сертификат):
/etc/stunnel/redis.conf
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
Redis client outputActive 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, указав клиенту порт 8000 на локальном интерфейсе:
redis-cli -p 8000 ping
Redis client outputPONG
Запрос на тестовый ключ, который мы задали в начале этого руководства:
redis-cli -p 8000 get test
Redis client output"success"
Это подтверждает, что мы можем успешно подключиться к удаленной базе данных.
Чтобы подтвердить, что мыunable для связи с удаленным сервером Redis без использования туннеля, мы можем попробовать подключиться к удаленному порту напрямую:
redis-cli -h redis_server_public_IP -p 6379 ping
Redis client outputError: Connection reset by peer
Как видите, трафик принимается только через удаленный порт Redis, если он правильно зашифрован через туннель.
Расширение вышеприведенного примера для связи с несколькими клиентами и между серверами
В приведенном выше примере мы использовали простой пример одного сервера Redis и одного клиента. Тем не менее, эти же методы могут быть применены к более сложным взаимодействиям.
Расширить этот пример для обработки нескольких клиентов просто. Вам нужно будет выполнить следующие действия, описанные выше.
-
Установите клиентское программное обеспечение Redis и пакет
stunnel
на новый клиент -
Включите программное обеспечение
stunnel
для запуска при загрузке -
Скопируйте файл сертификата сервера в каталог
/etc/stunnel
-
Скопируйте файл конфигурации клиента
stunnel
на новый клиентский компьютер. -
Перезапустите службу
stunnel
Чтобы настроить защищенную связь между серверами (например, для репликации или кластеризации), вам потребуется настроить два параллельных туннеля:
-
На новом сервере установите пакет сервера Redis и
stunnel
-
Включите программное обеспечение
stunnel
для запуска при загрузке -
Создайте новый файл сертификата и ключа для нового сервера Redis (используйте уникальное имя для файлов)
-
Скопируйте каждый из файлов сертификатов с одного сервера на другой в каталог
/etc/stunnel
-
Отредактируйте или создайте файл конфигурации
stunnel
на каждом сервере (включая существующие), чтобы он содержал:-
Раздел сервера, отображающий внешний порт на локальный Redis
-
Раздел клиента, отображающий локальный порт на незащищенный порт удаленного сервера.
-
-
Откройте внешний порт в брандмауэре на новом сервере Redis
-
Настройте каждый экземпляр Redis для подключения к локально сопоставленному порту для доступа к удаленному серверу, изменив файл конфигурации Redis (требуемые директивы зависят от взаимоотношений серверов. Смотрите Redis документы для более подробной информации).
Файлы конфигурацииstunnel
для обоих серверов будут выглядеть примерно так:
файл конфигурации stunnel для межсерверной связи
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
При необходимости на каждом компьютере можно настроить несколько клиентских разделов для сопоставления локальных портов с удаленными серверами. В этих случаях обязательно выберите другой неиспользуемый локальный порт с директивойaccept
для каждого удаленного сервера.
Заключение
Redis - это мощный и гибкий инструмент, который неоценим для многих развертываний. Однако использование Redis в небезопасной среде - это огромная ответственность, которая делает ваши серверы и данные уязвимыми для атак или кражи. Важно защитить трафик другими способами, если у вас нет изолированной сети, заполненной только доверенными сторонами. Метод, описанный в этом руководстве, является лишь одним из способов обеспечения связи между сторонами Redis. Другие варианты включаютtunneling with spiped илиsetting up a VPN.