Spiped - создаем шифрованный туннель на примере Redis
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