Spiped - создаем шифрованный туннель на примере Redis

05/26/2016

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

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

apt search spiped #Для Debian дистрибутивов
yum search spiped #Для RedHat дистрибутивов
pacman Ss spiped #Для Arch дистрибутивов

Тем, у кого пакетный менеджер не вернет ничего интересного, следует загрузить архив со spiped с официального сайта http://www.tarsnap.com/spiped.html, разархивировать

tar -xzvf spiped-1.5.0 #Версия может отличаться

выполнить переход в образовавшуюся папку

cd spiped-1.5.0 #Версия может отличаться

и, наконец, выполнить сборку, указав папку для инсталляции (обычно это - /opt/spiped):

make BINDIR=/opt/spiped install

Если вы получили сообщение "Команда не найдена" или "Command not found", вам следует установить дополнительно компилятор и сборщик

apt install make gcc #Для Debian дистрибутивов
yum install make gcc #Для RedHat дистрибутивов
pacman -S make gcc #Для Arch дистрибутивов

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

dd if=/dev/urandom bs=32 count=1 of=/opt/spiped/spiped.key

Эта команда создаст файл со случайно выбранными символами размером 32 байт или 256 бит - это минимальный размер ключа, который можно использовать со spiped. Распространите этот ключ на те компьютеры, которые будут создавать шифрованный туннель. Стоит еще позаботиться о том, чтобы защитить ключ от возможности прочтения кем-то, кроме root. Для этого выполните

chmod u=rw,g=,o= /opt/spiped/spiped.key

Теперь все готово для запуска. Представим, что какое-ниудь приложение (а в нашем примере это сервер баз данных Redis), уже установлено на вашем компьютере, запущено и ожидает входящих подключений на порт, например 6379. Тогда на сервере запускаем spiped, указывая ему на каком порту принимать данные (пусть это будет порт 9000) и на какой отправлять (вданном случае нам необходимо будет полученные данные отправлять на порт 6379)

spiped -d \
-s '[0.0.0.0]:9000' \
-t '[127.0.0.1]:6379' \
-k /opt/spiped/spiped.key

На клиенте нужно будет развернуть команду в другую сторону - принимать данные с какого-либо порта на локальном IP адресе (127.0.0.1), а отправлять на IP и порт сервера, который эти данные ожидает получить.

spiped -e \
-s '[127.0.0.1]:1234 \
-t $SERVER_IP:9000 \
-k /opt/spiped/spiped.key

Теперь остается только запустить клиентское приложение и натравить его на только что созданный spiped сокет

redis-cli -h 127.0.0.1 -p 1234

redis-cli отправит данные на 127.0.0.1:1234, там их подхватит spiped, зашифрует, отправит на $SERVER_IP:9000, где их примет другой spiped, расшифрует и передаст серверу redis так, как будто бы ничего и не было.

А теперь немного о грустном. В начале статьи мы говорили о том, что шифрование увеличивает задержку при обмене информацией. Используя все тот же стенд с Redis, замерим производительность, что называется "до и после" вторжения spiped в процесс обмена информацией, а также посмотрим на сколько может увеличиться производительность, если вообще сеть не использовать, а использовать старый-добрый unix-сокет

Мы видим насколько разнятся результаты - при стандартной гигабитной сети нам удается получить лишь около 16000 запросов в секунду, увеличение пропускной способности сети увеличивает и результат (но, заметьте, далеко не в 10 раз), MTU никак не влияет на скорость передачи, тогда как отказ от сети вообще и передача трафика через интерфейс локальной петли (lo) увеличивает скорость в разы. А если еще избавиться от TCP/IP (а lo использует TCP/IP) и использовать для передачи данных unix-сокет, мы получаем совершенно удивительные результаты - возсожность обрабатывать до 260000 запросов в секунду! И, наконец, в самом дальнем углу находятся результаты замера производительности зашифрованного туннеля - теперь вы понимаете, почему разработчики Redis не рекомендуют ничего шифровать. Мы бы к этому добавили еще и рекомендацию не использовать сеть вообще, а запускать сервер и клиент Redis на одной и той же машине.

P.s

Если вы являетесь счастливым обладателем системы на базе SystemD, вам возможно захочется запускать spiped в качестве сервиса. Для этого создайте файл с именем spiped.service и положите его в /lib/systemd/system. Содержание файла приведено ниже (не забудь изменить пути и адреса на выбранные вами)

[Unit]
Description=Spiped server
After=syslog.target network.target
 
[Service]
Type=forking
ExecStart=/opt/spiped/spiped -d -s 0.0.0.0:9000 -t 127.0.0.1:6379 -k /opt/spiped/spiped.key
ExecStop=/usr/bin/pkill spiped
 
[Install]
WantedBy=multi-user.target

После инсталляции следует сказать systemd, чтобы он переситал свою конфигурацию

systemctl daemon-reload

А затем активировать и запустить сервис (можно и не активировать)

systemctl enable spiped
 
systemctl start spiped

Темы: