АНДРЕЙ БЕШКОВ
Защита сетевых сервисов с помощью stunnel
Часть 2
В первой части статьи мы говорили о том, как защищать сервисы с помощью программы stunnel. SSL-шифрование данных выполняется посредством OpenSSL. Как обычно, все, о чем шла речь, работало под управлением FreeBSD 4.10. Чтобы проверить, как эта конструкция будет жить на пятой ветке, я перенес тестовое окружение на FreeBSD 5.3. Так что теперь мы будем работать на этой платформе. Процедура установки и настройки практически ничем не отличается от того, что было описано в первой части статьи, если, конечно, следовать официально рекомендованному пути и ставить все из портов.
Продолжим рассмотрение новых способов применения stunnel. На предложение шифровать http-трафик с помощью stunnel большинство читателей, cкорее всего, посмотрит на меня с некоторой долей удивления во взгляде, а кое кто, возможно, даже покрутит пальцем у виска. А ведь они частично правы. Зачем использовать внешнюю утилиту, если для этой задачи у нас есть отлично работающий Apache и mod_ssl? Но все же не Apache единым жив администратор. Во многих организациях используется Samba. Для облегчения жизни вместе с ней поставляется программа SWAT, которая позволяет управлять демонами, принтерами, правами и учетными записями пользователей с помощью веб-интерфейса. Беда в том, что в качестве веб-сервера, отображающего интерфейс управления, используется не Apache, а собственная разработка. С точки зрения экономии ресурсов такое решение вполне оправданно, ведь Apache даже в самом обглоданном состоянии все равно будет содержать в себе больше возможностей, чем нам необходимо для выполнения задачи. На первый взгляд все очень хорошо, но, к сожалению, реализация веб-сервера SWAT не поддерживает никакого шифрования. А это значит, что пароли, имена, явки, адреса конспиративных квартир и прочие секреты передаются по сети с помощью стандартного HTTP. Переносить интерфейс на Apache лениво, да и трудозатраты себя не оправдают, а взять на себя миссию переписывать SWAT для поддержки SSL рискнет тоже не каждый. Невооруженным глазом видно, что в нашем положении применение stunnel – это как раз то, что доктор прописал.
Сразу после инсталляции SWAT вписываем директивы вызова в /etc/services следующим образом:
swat 901/tcp # Samba web configuration tool
Ну а в /etc/inetd.conf будет такая строка:
swat stream tcp nowait/400 root /usr/local/sbin/swat swat
Это значит, что SWAT принимает входящие соединения на порт 901. Из этой точки мы можем пойти несколькими путями. Повесить stunnel на порт 902 и соответственно на нем принимать SSL-соединения. Затем расшифровывать данные и отдавать их на порт 901.
Тут снова есть варианты – запускать stunnel как отдельный демон или из inetd. Если не стоит задача жесткой экономии ресурсов, то, по моему мнению, наилучшим решением будет запуск stunnel в качестве самостоятельного демона. Так будет проще и надежнее. Ну а в следующих версиях программы возможность запуска stunnel из-под inetd, скорее всего, будет полностью удалена, потому что ей мало кто пользуется.
Для приема соединений на порту 901 и передачи расшифрованных данных на порт 901 нужно дописать в конфигурационный файл /usr/local/etc/stunnel/stunnel.conf вот такие строки:
[swats]
accept = 902
connect = 901
Второй способ состоит в том, чтобы прикрепить swat к порту 901 на локальной петле 127.0.0.1, а stunnel на порт 901 внешних интерфейсов. Примеры методики, которой нужно придерживаться, приводились в предыдущей статье. Дальнейшая механика полностью повторяет способ номер один.
Третий способ выглядит оригинальнее. Вешаем stunnel на порт 901 и при появлении входящих соединений самостоятельно, то есть без помощи inetd, запускаем SWAT.
[swats]
accept = 901
exec = /usr/local/bin/swat
execargs = swat
С воплощением в жизнь этого способа могут возникнуть проблемы. Во-первых, потому что мы работаем от имени пользователя stunnel, а значит, и SWAT будет запущен с такими же правами. Это можно обойти с помощью sudo. А вот вторая неувязка немного сложнее: после запуска сервер stunnel уходит в chroot и значит не сможет работать с файлами, находящимися за пределами /var/tmp/stunnel/. Это можно будет победить переназначением chroot для stunnel в директорию, где живет Samba.
На этом можно завершить рассмотрение приемов обращения с stunnel, который работает в качестве одиночного демона и общается только с SSL-клиентами.
Теперь хотелось бы продемонстрировать методику работы для случая, когда ни клиент, ни сервер не умеют работать с SSL. В качестве примера будут выбраны сервер MySQL, работающий под управлением FreeBSD, и стандартный консольный клиент MySQL под управлением Linux. Впрочем, клиент необязательно должен быть консольным, в его качестве может выступать любая программа, умеющая дружить с сервером MySQL через сеть. Схема взаимодействия будет выглядеть примерно так (см. рис. 1).
Рисунок 1
На рабочей станции MySQL-клиент общается с клиентом stunnel, ждушим входящих соединений на порту 127.0.0.1:3307. Stunnel-клиент шифрует полученные данные и отдает их через сеть демону stunnel, работающему на сервере баз данных. Тот, в свою очередь, расшифровывает пакеты и передает их MySQL-серверу. Обратная цепочка работает с точностью до наоборот.
Для простоты восприятия материала вместо создания нового SSL-сертификата будем использовать тот, что создали в первой статье. Сетевой адрес сервера базы данных 10.10.21.29, а рабочая станция соответственно имеет адрес 10.10.21.75.
Как я уже говорил, рабочая станция у нас функционирует под ALT Linux. К сожалению, в официальном репозитарии пакетов Sysyphus хранится stunnel весьма просроченной версии. К тому же в личной переписке человек, ответственный за сборку пакета, упомянул, что не планирует обновлять его в ближайшее время. Поэтому придется проводить самостоятельную компиляцию из исходников. Берем пакет с официального сайта http://stunnel.org, распаковываем, настраиваем и собираем. Всем желающим подправить установки по умолчанию предлагается воспользоваться ключами команды configure, благо их достаточно много.
# tar zxvf stunnel-4.05.tar.gz
# cd stunnel-4.05
# ./configure
# make all
# make install
Создаем пользователя, от имени которого будет работать stunnel.
# adduser stunnel
И, конечно же, проверяем, что из этого вышло.
# id stunnel
uid=502(stunnel) gid=503(stunnel) groups=503(stunnel) |
Не забываем про создание директорий для временных файлов и сертификатов. Плюс к этому настраиваем права доступа. Не хотелось бы, чтобы к столь важным сведениям имел доступ кто попало.
# mkdir /var/tmp/stunnel
# mkdir /usr/local/etc/stunnel/certs/
Затем копируем с сервера в папку клиента /usr/local/etc/stunnel/certs/ сертификат и ключ.
# chown stunnel:stunnel /var/tmp/stunnel/usr/local/etc/stunnel/certs/
# chmod –R 700 /var/tmp/stunnel/usr/local/etc/stunnel/certs/
Создаем файл /usr/local/etc/stunnel/mysql-client.conf следующего содержания:
cert = /usr/local/etc/stunnel/certs/mailserver.cert
key = /usr/local/etc/stunnel/certs/mailserver.key
chroot = /var/tmp/stunnel/
pid = /stunnel.pid
setuid = stunnel
setgid = stunnel
debug = 7
output = /var/log/stunnel.log
client = yes
[mysqls]
accept = 127.0.0.1:3307
connect = 10.10.21.29:3307
А на сервере соответственно создаем /usr/local/etc/stunnel/mysql-client.conf и вписываем в него вот это:
cert = /usr/local/etc/stunnel/certs/mailserver.cert
key = /usr/local/etc/stunnel/certs/mailserver.key
chroot = /var/tmp/stunnel
pid = /stunnel.pid
setuid = stunnel
setgid = stunnel
debug = 7
output = /var/log/stunnel.log
[mysqls]
accept = 10.10.21.29:3307
connect = 3306
Запускаем stunnel с обеих сторон:
# stunnel /usr/local/etc/stunnel/mysql-client.conf
# stunnel /usr/local/etc/stunnel/mysql-server.conf
Не забываем с помощью:
netstat –na | grep LISTEN
проверить состояние интересующих нас портов. И обязательно заглядываем в файлы протоколов /var/log/stunnel.log, дабы убедиться в отсутствии ошибок.
На рабочей станции пытаемся соединиться с MySQL-сервером. И, скорее всего, получаем ошибку.
# mysql -h 127.0.0.1 -P 3307 -u root –p
ERROR 1130: Host "localhost.unreal.net" is not allowed to connect to this MySQL server |
Дело в том, что демон stunnel после расшифровки отдает данные серверу MySQL от имени сетевого интерфейса 127.0.0.1. Соответственно, MySQL считает, что мы присоединяемся к нему с localhost. К сожалению, под FreeBSD избавиться от этого никак нельзя. Для Linux выход из ситуации есть, но о нем мы поговорим в следующей статье. Для того чтобы как-то обойти эту неприятность, добавьте пользователя root@localhost.unreal.net в таблицу users и не забудьте обновить текущие привилегии.
# mysql
> use mysq;
> INSERT INTO user VALUES ('localhost.unreal.net','root','Rw8304MH', \
'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','' ,'','',0,0,0);
> flush privileges;
> quit;
После этого соединение клиента MySQL с сервером должно пройти как по маслу.
В принципе работа stunnel под Linux почти ничем не отличается от работы под FreeBSD. Единственная загвоздка будет в том, что вместо inetd придется использовать xinetd. Думаю, что читатель, работающий с Linux, без труда сможет самостоятельно разобраться с этими мелкими несходствами.
Казалось бы, мы описали все возможные применения stunnel, но на самом деле это не так. В следующей статье поговорим о том как с помощью stunnel проводить проверку клиентских сертификатов и о том, какие выгоды это нам сулит.