Шифрование трафика Redis с помощью spiped в Ubuntu 16.04

Redis – открытое in-memory хранилище типа «ключ-значение». Redis поддерживает транзакции, шаблон проектирования pub-sub, автоматический обход сбоев и многое другое. Для Redis разработано множество клиентов в различных языках программирования.

Примечание: Список рекомендованных клиентов можно найти здесь.

Однако Redis не имеет никаких функций шифрования данных. Хранилище нужно развёртывать в изолированной частной сети, доступ к которой есть только у заведомо безопасных клиентов, либо же настроить шифрование трафика самостоятельно.

Данное руководство поможет настроить шифрование трафика Redis с помощью программы spiped. Трафик между клиентами и серверами Redis будет направляться через специальный шифрованный туннель, похожий на SSH-туннель.

Требования

В руководстве настройка продемонстрирована на примере двух серверов Ubuntu 16.04. На серверах должны быть:

  • Пользователь с доступом к sudo.
  • Базовый брандмауэр.

Все необходимые инструкции можно найти в руководстве по начальной настройке.

Что такое spiped?

Утилита spiped – простая в установке и настройке программа для защиты взаимодействия между двумя сетевыми сокетами (обычными портами или сокетами Unix). С её помощью можно настроить шифрование трафика между двумя удалёнными серверами. Клиент подключается к локальному порту, а spiped обеспечивает шифрование перед передачей его данных на удаленный сервер. На стороне сервера spiped прослушивает заданный порт и расшифровывает трафик перед отправкой его на локальный порт (в нашем случае, порт, который прослушивает сервер Redis).

Преимущества spiped:

  • Пакеты spiped можно найти в стандартном репозитории Ubuntu.
  • Проект Redis рекомендует spiped.
  • Утилита проста в установке и настройке.
  • Для каждой цели используется отдельный конвейер. В некоторых ситуациях это может стать недостатком, но благодаря этому вы получаете полный контроль над доступом.

Недостатки spiped:

  • Клиенты подключаются к удаленной машине с помощью нестандартного локального порта.
  • Объединяя два сервера 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. Это ключевое слово нужно использовать в дальнейшем для проверки соединения с spiped.

Установка клиента Redis

Второй сервер Ubuntu 16.04 будет использоваться в качестве клиента. Все необходимые пакеты можно загрузить из стандартного репозитория:

sudo apt-get update
sudo apt-get install redis-tools

Установка spiped

Примечание: Данный раздел нужно выполнить на каждом сервере и клиенте Redis.

Если вы пропустили предыдущий раздел, не забудьте обновить индекс пакетов перед установкой:

sudo apt-get update

Чтобы установить spiped, введите:

sudo apt-get install spiped

Теперь нужно создать ключ, с помощью которого spiped сможет шифровать трафик между машинами.

Генерирование ключа шифрования

Примечание: Данный раздел нужно выполнить на сервере Redis.

Создайте каталог для настроек spiped в каталоге /etc. В нем вы сможете хранить ключи шифрования.

sudo mkdir /etc/spiped

Теперь создайте ключ:

sudo dd if=/dev/urandom of=/etc/spiped/redis.key bs=32 count=1

Ограничьте доступ к ключу:

sudo chmod 600 /etc/spiped/redis.key

Теперь на сервере Redis есть ключ для шифрования.

Создание юнит-файла spiped для сервера Redis

Утилита spiped очень проста, она не умеет читать конфигурационный файл. Каждый туннель настраивается вручную, потому Ubuntu не предлагает сценарий инициализации для автозапуска spiped.

Для этого можно создать unit-файл systemd. Откройте новый файл в каталоге /etc/systemd/system :

sudo nano /etc/systemd/system/spiped-receive.service

Добавьте в него раздел [Unit] с описанием сервиса:

[Unit] Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target

Затем добавьте раздел [Service], он определяет команды, которые нужно запустить. Для spiped мы используем:

  • -F: запуск в фоновом режиме. Система system предпочитает запускать сервисы в фоновом режиме.
  • -d: дешифровка трафика исходного сокета. Эта команда сообщает spiped направление шифрования.
  • -s: определяет исходный сокет. IP-адреса нужно брать в квадратные скобки. Номер потра отделяется от адреса двоеточием. Для сервера Redis необходим внешний IP и порт.
  • -t: целевой сокет. На него поступает трафик после расшифровки. По умолчанию Redis слушает порт 6379.
  • -k: путь к файлу ключа.

Все эти опции нужно указать в директиве ExecStart. В результате получится:

[Unit] Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target
[Service] ExecStart=/usr/bin/spiped -F -d -s [redis_server_public_IP]:6379 -t [127.0.0.1]:6379 -k /etc/spiped/redis.key

Теперь нужно добавить раздел [Install]:

[Unit] Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target
[Service] ExecStart=/usr/bin/spiped -F -d -s [redis_server_public_IP]:6379 -t [127.0.0.1]:6379 -k /etc/spiped/redis.key
[Install] WantedBy=multi-user.target

Сохраните и закройте файл.

Запуск сервиса spiped и настройка брандмауэра

Примечание: Данный раздел нужно выполнить на сервере Redis.

Чтобы запустить и включить сервис spiped, введите:

sudo systemctl start spiped-receive.service
sudo systemctl enable spiped-receive.service

Проверьте сервисы, которые прослушивают соединения на сервере Redis; вы должны увидеть сервис spiped, использующий порт 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/spiped
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

Сервис spiped прослушивает открытый интерфейс, однако брандмауэр, скорее всего, блокирует этот трафик.

Чтобы разблокировать порт 6379, введите:

sudo ufw allow 6379

Перемещение ключа шифрования на клиент

Чтобы переместить ключ шифрования на клиентскую машину, нужно установить защищенное соединение между сервером и клиентом. Для этого можно использовать ssh.

Примечание: Если вы используете беспарольную аутентификацию на основе ключей, вам необходимо переслать ключ SSH на сервер Redis, чтобы установить соединение. При парольной аутентификации такой необходимости нет.

Дополнительно: аутентификация на основе ключей

Отключитесь от сервера Redis:

exit

На локальной машине убедитесь, что агент SSH запущен, и добавьте свой ключ:

eval `ssh-agent`
ssh-add

Снова подключитесь к серверу Redis, добавив в команду ключ –A:

ssh -A 8host@redis_server_public_IP

Перемещение ключа

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

sudo -E scp /etc/spiped/redis.key 8host@redis_client_public_IP:

Примечание: Обязательно добавьте после IP символ двоеточия.

Используйте scp для записи в домашнем каталоге пользователя клиентской машины.

Переместив ключ, перейдите на клиент и создайте каталог /etc/spiped:

sudo mkdir /etc/spiped

Переместите ключ в новый каталог:

sudo mv ~/redis.key /etc/spiped

Заблокируйте к нему доступ:

sudo chmod 600 /etc/spiped/redis.key

Теперь можно настроить клиентскую машину для поддержки шифрования spiped.

Создание юнит-файла spiped для клиента Redis

Теперь нужно создать юнит файл для spiped на клиентской машине.

Создайте новый файл:

sudo nano /etc/systemd/system/spiped-send.service

Добавьте в файл раздел [Unit]:

[Unit] Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target

Затем добавьте раздел [Service], который определяет команды. Для spiped на клиенте мы используем:

  • -e: указывает, что трафик исходного сокета нужно шифровать, а также устанавливает соединение между целевым и исходным сокетом.
  • -s: определяет исходный сокет. IP-адреса нужно брать в квадратные скобки. Номер потра отделяется от адреса двоеточием. В данном случае можно использовать любой доступный порт и локальный интерфейс .
  • -t: целевой сокет. Укажите внешний IP-адрес сервера Redis и открытый порт.

Укажите все данные в директиве ExecStart. У вас получится:

[Unit] Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target
[Service] ExecStart=/usr/bin/spiped -F -e -s [127.0.0.1]:8000 -t [redis_server_public_IP]:6379 -k /etc/spiped/redis.key

Затем добавьте раздел [Install]:

[Unit] Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target
[Service] ExecStart=/usr/bin/spiped -F -e -s [127.0.0.1]:8000 -t [redis_server_public_IP]:6379 -k /etc/spiped/redis.key
[Install] WantedBy=multi-user.target

Сохраните и закройте файл.

Запуск сервиса spiped и настройка брандмауэра на клиенте

Чтобы запустить и включить сервис spiped, введите:

sudo systemctl start spiped-send.service
sudo systemctl enable spiped-send.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      3264/spiped
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1705/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      1705/sshd

Как видите, spiped прослушивает порт 8000.

Теперь вы можете подключиться к удалённому серверу Redis. Для этого нужно направить клиент на порт 8000 локального интерфейса:

redis-cli -p 8000 ping
PONG

Запросите тестовый ключ, установленный в начале руководства:

redis-cli -p 8000 get test
"success"

Это значит, что у клиента есть доступ к удалённой базе данных.

Теперь нужно убедиться, что вы не можете подключиться к серверу без туннеля. Подключитесь напрямую к порту удалённого сервера:

redis-cli -h redis_server_public_IP -p 6379 ping
Error: Protocol error, got "\xac" as reply type byte

Как видите, трафик поступает только по туннелю.

Расширение настроек

Выше мы рассмотрели пример простой настройки шифрования для одного клиента и одного сервера Redis. Эту настройку вы можете применить и для большой инфраструктуры.

Чтобы настроить несколько клиентов, нужно просто повторить все вышеописанные действия:

  • Установить ПО клиента и утилиту spiped.
  • Переместить ключ шифрования на клиентскую машину.
  • Скопировать юнит-файл spiped на клиентскую машину.
  • Запустить сервис spiped и включить автозапуск.

Чтобы использовать эту настройку для репликации или кластеризации, нужно создать два параллельных туннеля:

  • Установите ПО сервера Redis и утилиту spiped.
  • Сгенерируйте новый ключ шифрования (имя файла должно быть уникальным).
  • Скопируйте ключ с одного сервера на другой в каталог /etc/spiped.
  • Создайте юнит-файл spiped на каждом сервере. Файлы должны обслуживать две роли: один файл должен настраивать входящий трафик (связывать внешний порт с локальным портом Redis), а второй – исходящий трафик (связывает локальный порт с удалённым портом).
  • Откройте внешний порт в брандмауэре сервера Redis.
  • Настройте каждый экземпляр Redis для подключения к локальному порту. Это позволит получить доступ к удаленному серверу с помощью файла конфигурации Redis (набор директив зависит от отношений между серверами; см. документацию Redis для получения более подробной информации).

При необходимости можно создать несколько юнит-файлов на каждой машине для соединения локального и удалённого порта. В таком случае не забудьте выбрать другой свободный локальный порт в качестве исходного сокета в юнит файле исходящего трафика.

Заключение

Redis – производительный и гибкий инструмент для хранения данных. Однако обмен данными Redis не защищен, что позволяет злоумышленникам похитить информацию. Поэтому очень важно зашифровать трафик между удалёнными серверами Redis.

Читайте также:

Шифрование трафика Redis с помощью stunnel в Ubuntu 16.04

Шифрование трафика Redis с помощью PeerVPN в Ubuntu 16.04

Tags: , , ,

Добавить комментарий