Настройка Postfix и почтового клиента BAT для отправки писем по tls SSL

Материал из Wiki МИАЦ ВО
Перейти к навигации Перейти к поиску

Информация для статьи взята Корпоративный почтовый сервер на базе 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),
>через почтового клиента мозиллы все работает.

Продолжение будет после проверки