Настройка Postfix и почтового клиента BAT для отправки писем по tls SSL
Информация для статьи взята Корпоративный почтовый сервер на базе Postfix
Опишу здесь только то что связано с настройками SSL на сервере и на клиенте.
Содержание
Настройка сервера
Все настройки сервера можно посмотреть с статье Настройка почтового сервера на базе Postfix + abills + mysql
Создание сертификата сервера
Сразу скажу, что реализация данной части - дело тяжелое. Потому что будет очень много рутинной возни, если делать все по правилам.
Первым делом нам понадобится доверенный сертификат - Certificate Authority (далее CA), чтобы иметь возможность подписывать и проверять клиентские сертификаты. Если все делать по правилам, то такой сертификат нужно создать, а затем подписать его у одного из корневых доверенных центров сертификации. Но это стоит денег. Если ваша организация заинтересована, ска жем, в развитии своего представительства в Internet, то именно это и стоит сделать. Но если вы всего лишь небольшая фирма, которая нуждается всего-навсего в почтовом сервере, то можно обойтись самоподписанным доверенным сертификатом.
Итак, приступаем. Для начала определимся с местом, где у нас будут лежать наш сертификат и сертификаты пользователей. Поразмыслив, я решил держать их в каталоге /etc/ssl, но вы, возможно, решите, что есть и более подходящее для них место - оставляю это на ваше усмотрение.
Делаем следующее:
# cd /etc/ssl # mkdir db # mkdir ca # mkdir clients # touch /etc/ssl/db/index.txt # echo "01" > /etc/ssl/db/serial
Создаем скрипт для создания нашего самоподписанного доверенного сертификата (CA) /etc/ssl/make_ca.sh :
#!/bin/sh openssl req -new -newkey rsa:4096 -nodes -keyout ./ca/ca.key -x509 -days 3650 \ -subj /C=RU/ST=Russia/L=Vologda/O=EI/OU=IT/CN=mail.volmed.org.ru/emailAddress=misk@volmed.org.ru -out ./ca/ca.crt
Где mail.volmed.org.ru адрес нашего почтового сервера
Запускаем скрипт make_ca.sh. Какое-то время он будет возиться с генерацией секретного ключа длиной в 4096 бит, на слабой машине это займет время... можете уменьшить длину ключа до 1024 или 2048 бит, если очень не терпится все поскорее попробовать. В итоге мы получим два файла в каталоге /etc/ssl/ca:
ca.crt - это наш самоподписанным доверенный сертификат, и
ca.key - его секретный ключ.
Создание клиентских сертификатов
Теперь нам необходим скрипт для создания клиентских сертификатов:
Создаем скрипт для создания клиентских сертификатов: /etc/ssl/make_cleint_cert.sh
#!/bin/sh if [ -n "$3" ]; then openssl req -new -newkey rsa:4096 -nodes -keyout ./clients/client_$1.key \ -subj /C=RU/ST=Russia/L=Samara/O=HOMENET/OU=IT/CN=$1/emailAddress=$2 \ -out ./clients/client_$1.csr; openssl ca -config ca.config -in ./clients/client_$1.csr -out ./clients/client_$1.crt -batch; openssl pkcs12 -export -in ./clients/client_$1.crt -inkey ./clients/client_$1.key -certfile ./ca/ca.crt -out /clients/client_$1.p12 -passout pass:$3 else echo "usage $0 name_client client_email client_passwd" fi
Прежде чем запускать этот скрипт, создадим файл конфигурации для подписывания запросов на сертификацию: /etc/ssl/ca.config
[ ca ] default_ca = CA_CLIENT [ CA_CLIENT ] dir = /etc/ssl certs = $dir/clients new_certs_dir = $dir/db database = $dir/db/index.txt serial = $dir/db/serial certificate = $dir/ca/ca.crt private_key = $dir/ca/ca.key default_days = 3650 default_crl_days = 3 default_md = md5 policy = policy_anything [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional
Скрипт make_ca.sh будет использоваться крайне редко - для первого создания нашего СА, и для генерации нового по истечению срока действия текущего СА. Однако, опцией -days мы устанавливаем срок действия сертификата аж на 10 лет, так что часто это делать не придется, разве что в случае компрометации сертификата (тьфу-тьфу-тьфу!).
Скрипт make_cleint_cert.sh будет использоваться нами гораздо чаще, чем хотелось бы - если все делать по правилам. То есть, мы должны выдать уникальный сертификат каждому сотруднику, имеющему почтовый ящик на нашем сервере. Причем выдать его на не слишком дли тельный срок, в идеале - месяца на 3, но во всяком случае не больше, чем на год. А по прошествии этого срока выдать всем новые сертификаты. Прибавьте к этому увольняемых и нанимаемых сотрудников... в общем, если у вас много народу - этим лучше заниматься специальной группе security officer's. Зато при этом у вас будет полноценный шифрованный канал с авторизацией и аутентификацией пользователей.
Но можно поступить и проще. Создать всего лишь один клиентский сертификат, не на персону, а на всю контору, и использовать его. И можно еще дополнительно облегчить себе жизнь, за дав ему срок действия, равный сроку действия СА. Лет эдак на 20. Все это, естественно, будет делаться в ущерб безопасности, так как ни о какой аутентификации пользователей речи не идет, да и в случае кражи сертификата вы можете очень нескоро узнать об этом. Но шифрование у вас все равно останется. Какой вариант выбрать - решайте сами.
Теперь создадим клиентский сертификат. Запустим скрипт make_cleint_cert.sh с параметрами имя_клиента e-mail клиента пароль на файл клиентского сертификата:
make_cleint_cert.sh Test_User testuser@home.net q1w2e3
Сначала опять будет генерироваться ключ, затем будет создан и подписан сертификат пользователя. На экран вываливается информация о сертификате, и вот мы получили все необходимое:
client_Test_User.crt - файл клиентского сертификата client_Test_User.key - файл закрытого ключа client_Test_User.csr - запрос на подписание сертификата client_Test_User.p12 - клиентский сертификат для передачи клиенту
Остается только передать клиенту файл с расширением p12 - в этот файл записаны и защищены паролем записываются сертификат клиента, СА сертификат и секретный ключ клиента. По сле того, как сертификат передан клиенту, следует удалить на сервере файлы клиентского закрытого ключа, запроса на подписание и конечно самого сертификата в формате PKS#12. Ну и, разумеется, необходимо передать ему также и пароль q1w2e3 - пароль на файл клиентского сертификата. Предположим, что мы это уже проделали, попробуем его установить.
Настройка почтового клиента BAT для работы с SSL сертификатом
Запускаем The Bat!. Выбираем наш почтовый ящик, идем в Свойства почтового ящика - Общие сведения. Видим там кнопочку Сертификаты, и нажимаем ее. В открывшемся окне нажимаем кнопку Импортировать... и открываем файл client_Test_User.p12. В окне Пароль PFX - Введите пароль по расшифровке данных, хранимых в client_Test_User.p12 вводим пароль на файл клиентского сертификата - q1w2e3. Вылезает окно Пароль PFX - Введите пароль для расшифровки личного ключа, хранимого client_Test_User.p12 - еще раз вводим q1w2e3. И далее при запросе Сохранить личный ключ в брелоке отвечаем Да. И видим, что в окне теперь отображаются два сертификата - наш персональный и доверенный сертификат сервера. Выбрав любой из них, и нажав кнопку Просмотреть, увидим, что This CA root certificate is not trusted because it is not in the Trusted Root CA. То есть The Bat! не желает просто так доверять нашему самоподписанному сертификату. Исправляем ситуацию, переходим на закладку Путь сертификации, выбираем наш СА, и нажимаем кнопку Добавить к доверенным. На запрос подтверждения отвечаем Да. Теперь ви дим, что наши сертификаты The Bat! считает правильными.
Теперь настроим The Bat! на от правку почты через TLS: идем Пользователь - Свойства почтового ящика - Транспорт и в списке Соединение выбираем Безопасное на стандартный порт (STARTTLS). И дальше все должно работать.
Напишем письмо нашему test user'у, отправим отправим его и посмотрим в логи:
Nov 18 01:56:40 mail postfix/smtpd[1490]: initializing the server-side TLS engine Nov 18 01:56:40 mail postfix/smtpd[1490]: connect from unknown[192.168.211.3] Nov 18 01:56:41 mail postfix/smtpd[1490]: setting up TLS connection from unknown[192.168.211.3] Nov 18 01:56:41 mail postfix/smtpd[1490]: SSL_accept:before/accept initialization Nov 18 01:56:41 mail postfix/smtpd[1490]: read from 08096980 [080C0000] (11 bytes => -1 (0xFFFFFFFF)) Nov 18 01:56:41 mail postfix/smtpd[1490]: SSL_accept:error in SSLv2/v3 read client hello A Nov 18 01:56:41 mail postfix/smtpd[1490]: read from 08096980 [080C0000] (11 bytes => 11 (0xB)) Nov 18 01:56:41 mail postfix/smtpd[1490]: 0000 16 03 01 00 2f 01 00 00|2b 03 01 ..../... +.. [пропустим этот кошмар...] Nov 18 01:56:41 mail postfix/smtpd[1490]: 0020 fc 2e c5 3a dc d2 b3 23|9b 9c 51 bb 49 2b f9 ...:...# ..Q.I+. Nov 18 01:56:41 mail postfix/smtpd[1490]: SSL_accept:SSLv3 flush data Nov 18 01:56:41 mail postfix/smtpd[1490]: TLS connection established from unknown[192.168.211.3]: TLSv1 with cipher RC4-SHA (128/128 bits) Nov 18 01:56:41 mail postfix/smtpd[1490]: 6EF9860DE: client=unknown[192.168.211.3] Nov 18 01:56:41 mail postfix/cleanup[1496]: 6EF9860DE: message-id=<1852745703.20051119205209@home.net.> Nov 18 01:56:41 mail postfix/qmgr[1365]: 6EF9860DE: from=<testuser@home.net.>, size=752, nrcpt=1 (queue active) Nov 18 01:56:41 mail postfix/smtpd[1490]: disconnect from unknown[192.168.211.3] Nov 18 01:56:41 mail postfix/virtual[1498]: 6EF9860DE: to=<testuser@home.net.>, relay=virtual, delay=0, status=sent (delivered to maildir) Nov 18 01:56:41 mail postfix/qmgr[1365]: 6EF9860DE: removed
Боже, какой ужас... надо срочно изменить детализацию логов... вместо smtpd_tls_loglevel = 3 поставим smtpd_tls_loglevel = 1. Но главное, мы увидели, что установилось защищенное соеди нение - TLS connection established from unknown[192.168.211.3]: TLSv1 with cipher RC4-SHA (128/128 bits), и наше письмо ушло под его защитой. Но это еще не все. Если мы посмотрим в исходный текст письма на стороне получателя, то увидим там:
Received: from stationxp01.home.net (unknown [192.168.211.3]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by mail.home.net (Postfix) with ESMTP id 6EF9860DE for <testuser@home.net.>; Fri, 18 Nov 2005 01:56:41 +0000 (UTC)
То есть, на данный момент имеем защищенное соединение, но не имеем аутентификации.
Настройка аутентификации через TLS
Исправляемся. Добавим в /etc/postfix/main.cf строчки:
# требовать сертификаты от клиентов smtpd_tls_ask_ccert = yes # место расположения отпечатков клиентских сертификатов relay_clientcerts = hash:/etc/postfix/fingerprints
Снимем отпечаток с пользовательского сертификата:
openssl x509 -fingerprint -in client_Test_User.crt
и скопируем последовательность разделенных двоеточиями цифр из строки MD5 Finger print в файл usr/local/etc/postfix/fingerprints. После этой числовой последовательности можно (и нужно) для собственной информации и для того, чтобы отработала команда postmap дописать туда имя клиента.
Делаем:
postmap fingerprints postfix reload
И снова отправим письмо многострадальному ТестЮзеру. Оп-ля. Опять не то, потому что получаем:
Received: from stationxp01.home.net (unknown [192.168.211.3]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client did not present a certificate) by mail.home.net (Postfix) with ESMTP id CE91E60DA for <testuser@home.net.>; Sat, 19 Nov 2005 21:25:48 +0000 (UTC)
То есть я при отправке письма для testuser сертификат серверу почему-то не представил. Защищенное соединение установилось, но аутентификация не прошла. Очень долго я бился с этим вопросом,но ничего не выходило. Но вот я наткнулся на это:
http://www.opennet.ru/openforum/vsluhforumID14/414.html Процитирую оттуда:
>как заставить the bat (3.5 у меня) предоставлять клиентские сертификаты при отправке >почты с использованием технологии TLS? Т.е. в настройках аккаунта я сертификат >импортировал, однако в заголовке письма (Client did not present a certificate), >через почтового клиента мозиллы все работает.
Продолжение будет после проверки