Как зашифровать трафик в Redis с помощью Stunnel в Ubuntu 16.04

Вступление

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.

Related