26 авг. 2009 г.

STunnel - ssl-оболочка для *x систем

Для организации безопасного соединения с различными серверами на *x системах можно использовать утилиту STunnel. Она представляет собой оболочку, которая реализует SSL-туннель между внешним подключением и локальным сервисом. К примеру, сервер POP3 (popa3d), который не имеет функции шифрования трафика, вполне может использоваться для внешних подключений, если к нему устанавливать подключение через оболочку (wrapper) stunnel. Stunnel открывает указанный ей порт на прослушивание, обеспечивает SSL-шифрование данных для входящих подключений и пробрасывает данные между пользователем и сервером, который прослушивает указанный же порт на локальной машине.
Утилита проста в использовании и настройке. Ниже приведен пример поднятия pop3-сервера, защещенного stunnel. Пример взят с сайта Антона Крюкова.


Описание
Stunnel очень простая программа. Она слушает запрос на одном порту, передача данных на который шифруется при помощи SSL. Полученные данные извлекаются из SSL и в незашифрованном виде передаются на локальный порт.

При помощи stunnel можно шифровать любой траффик. Даже у тех программ, которые в принципе не поддерживают SSL, например сервер popa3d. Как раз на его примере и рассмотрим как использовать stunnle. Наша задача сделать так, что бы все пакеты с 995 (spop3) порта доставлялись на локальный порт 110.

Конфигурационный файл
Конфигурационный файл разместим в директории /etc/stunnel и назовем его stunnel.conf.

В файле сначала указывают глобальные параметры. И в первую очередь, параметры определяющие ключи и сертификаты, которыми будет пользоваться stunnel. По традиции, возьмем ключи, сгенерированные нами для работы OpenVPN.
CApath = /etc/openvpn/keys

Параметр CApath определяет путь к директории, где находятся ключи центров сертификации.
CAfile = /etc/openvpn/keys/ca.key

CAfile определяет ключ центра сертификации, которым подписаны серификаты нашего сервера.
cert = /etc/openvpn/keys/kryukov.ru.crt

Cert определяет сертификат нашего сервера.
key = /etc/openvpn/keys/kryukov.ru.key

Key определяет ключ, которым подписан сертификат сервера.
setuid = nobody
setgid = nogroup

Параметры setuid и setgid определяют пользователя и группу, с правами которых будет работать stunnel.
pid = /var/run/stunnel/stunnel.pid

Pid определяет файл, в котором после запуска будет храниться PID программы stunnel. Обратите внимание на то, что директории /var/run/stunnel по умолчанию не существует. Ее необходимо создать и передать пользователю, с правами которого запускается программа.
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

Socket определяет параметры сетевых соединений.

После глобальных параметров, необходимо описывать конкретные сервисы. Название сервиса помещается в квадратные скобки.

Параметр accept определяет порт на котором слушает запросы stunnel и куда должен подключаться клиент. По умолчанию порт открывается на всех сетевых интерфейсах. Если хотите, что бы stunnel слушал только на определенном интерфейсе, напишите его IP адрес перед номером порта. Например так:
192.168.0.1:995

Параметр connect определяет порт на локальной машине, куда будет передаваться информация. По умолчанию stunnel подключается к порту на lo интерфейсе и его IP указывать не надо. Для определения сервера pop3 необходимо добавить следующие три строки.
[pop3s]
accept = 995
connect = 110

В результате содержимое конфигурационного файла будет выглядеть следующим образом:
CApath = /etc/openvpn/keys
CAfile = /etc/openvpn/keys/ca.key
cert = /etc/openvpn/keys/kryukov.ru.crt
key = /etc/openvpn/keys/kryukov.ru.key
setuid = nobody
setgid = nogroup
pid = /var/run/stunnel/stunnel.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
[pop3s]
accept = 995
connect = 110

Запуск программы

Запуск программы происходит следующим образом:
stunnel /etc/stunnel/stunnel.conf

К сожалению в Slackware Linux в стартовых скриптах не предусмотрен запуск stunnel. Поэтому мы сами напишем стартовый скрипт. Разместим его в директории /etc/rc.d и назовем rc.stunnel.
#! /bin/bash

start()
{
if [ -f /var/run/stunnel/stunnel.pid ]; then
if ps xa | grep ^$(head -1 /var/run/stunnel/stunnel.pid) > /dev/null; then
echo "Stunnel working!"
exit 1
else
rm -r /var/run/stunnel/stunnel.pid
fi
fi
echo "Sarting stunnel"
/usr/sbin/stunnel /etc/stunnel/stunnel.conf
}

stop()
{
echo "Stunnel stop"
kill -9 $(head -1 /var/run/stunnel/stunnel.pid)
}

case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: rc.stunnel start|stop|restart"
exit 88
esac

Сделаем его исполняемым:
# chmod a+x /etc/rc.d/rc.stunnel
#

Допишем его вызов в файл /etc/rc.d/rc.local.
if [ -x /etc/rc.d/rc.stunnel ]; then
/etc/rc.d/rc.stunnel start
fi

Не забудьте создать директорию в которой будет создаваться файл stunnel.pid и переадть ее пользователю, с правами которого будет работать программа:
# mkdir /var/run/stunnel
# chown nobody /var/run/stunnel
#
Firewall

Если Вы следуете моим рекомендациям по созданию правил firewall (этотматериал я выложу на сайт позднее), то доступ к lo интерфейсу с локальной машины у Вас открыт. Поэтому осталось открыть доступ к 995 порту.
iptables -A INPUT -p tcp --dport 995 -j ACCEPT

Заключение

Аналогичным способом можно шифровать трафик любых программ.
Замечания по интеграции с другими программами
Sendmail

При использовании stunnel с sendmail возникает очень неприятная проблема. По умолчанию sendmail принимает на пересылку (RELAY) почту, пришедшую с локальной машины (localhost). С точки зрения sendmail трафик, передаваемый ему stunnel считается посланным с локальной машины и поэтому sendmail не потребует аутентификации и просто перешлет письмо! Вообщем, получаеи open ralay.

Решение проблемы очень простое. Требуется заставить sendmail при отсылке почты с локальной машины требовать аутентификацию. Для этого надо изменить параметры в файле sendmail.mc:
DAEMON_OPTIONS(`Port=smtp,Addr=0.0.0.0,Name=MTA,M=a')dnl

M=a -- заставляет спрашивать аутентификацию.

Правда возникает другая проблема, теперь всем локальным процессам, для отсылки писем требуется вводит логин и пароль. Так что, для того что бы использовать SSL с sendmail рекомендуется использовать внутренние возможности этой программы.

Комментариев нет:

Отправить комментарий