The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

ISPMail-HOWTO - создание почтовой системы на базе Postfix и SquirrelMail (mail mysql postfix tls crypt sasl imap virus apache)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: mail, mysql, postfix, tls, crypt, sasl, imap, virus, apache,  (найти похожие документы)
From: Viacheslav Kaloshin (multik) <[email protected]> Date: Mon, 28 Feb 2004 14:31:37 +0000 (UTC) Subject: ISPMail-HOWTO - создание почтовой системы на базе Postfix и SquirrelMail Оригинал: http://www.multik.ru/linux/ispmailv2/ ISPMail-HOWTO. v.2.0 © 2003 Viacheslav "multik" Kaloshin, [email protected] Данный текст описывает создание почтовой системы, использующей MySQL, Postfix/TLS, Cyrus-SASL, Courier-IMAP, Dr.Web, Apache, PHP и SquirrelMail. Давным-давно я написал isp-mail-howto-1.2. Судя по откликам в почте и прочим признакам, эта рассказка оказалась довольно успешной, и на ее основе было поднято много систем и написана куча других статей. Там, где я работал, когда писал первую версию, система проработала больше года без каких либо претензий (потом я оттуда уволился ;-). Да и по отзывам в почте, аналогичные системы тоже не предъявляли претензий к своим владельцам. В общем, все было хорошо. Но недавно я проапгрейдил систему на домашней машине до RedHat9, заодно решил и обновить эту рассказку. Здесь вы найдете описание создания почтовой системы, которая подойдет для почтовых серверов, где число пользователей не измеряется миллионами. Максимально известное мне число пользователей, обсуживаемых системой по моему рассказу, составляет четыре с половиной тысячи. Размещение файлов и таблиц полностью совпадает с описанным в предыдущих рассказках, поэтому если вы как-то модифицировали свою систему, вам не составит труда аналогично модифицировать и описанное тут. Почему я использовал именно этот набор программ? Во-первых, из-за банальной лени - всегда проще работать с тем, что уже известно и не подводило. Во-вторых, на время написания первой рассказки из этой серии этот комплект программ оказался единственным, кто удовлетворял возложенным условиям. И, в-третьих ... ну додумайте сами ;-) В процессе написания этой рассказки я намеренно исключил spamassassin из описания. По одной простой причине - то, что для одного пользователя является спамом, для другого - манна небесная. Все современные почтовые клиенты имеют встроенные модули для борьбы со спамом, причем гораздо более эффективные. Первое предупреждение: если у вас не получается, то почитайте логи, примеры, ЧаВО и другие доступные документы. Я не буду отвечать на письма, вся суть которых сводится к <а почему у меня mysql.h не находится? Я смотрел - все есть>. Надоело. Второе предупреждение: все пакеты, используемые в системе, которые можно собрать вручную, я собрал вручную. Более того, я не всегда следовал канонам основных linux-дистрибутивов. Надо мне так. Вы можете использовать RPM пакеты, порты, пэкеджи и всю остальное, что вам больше нравится. Как минимум, сможете сэкономить процентов семьдесят времени. Третье предупреждение: это все реально работает. Если у вас не работает - смотрите первое предупреждение. И последнее предупреждение: если вы не разбираетесь в unix-системах и не владеете навыками программирования, вы не сможете собрать систему, даже если вы будете пошагово повторять все мои действия. Все нижеприведенное собрано на RedHat 9 со всеми апдейтами. Пароли специально выбраны очень простыми. Надеюсь, что вы их поменяете на что-нибудь более удобоваримое. Для начала объясню на пальцах, как вся эта связка работает. В центре всего стоит MySQL. В нем хранится информация о логинах, паролях, обслуживаемых доменах и всем остальном. Он является сердцем системы в самом прямом смысле - как только по каким-либо причинам он откажется работать - вся система вслед за ним объявит забастовку. Postfix - занимается самим почтой. Принимает, отправляет, перекладывает письма из папочки в папочку и так далее. На плечи Cyrus-SASL возложена процедура авторизации пользователей, если другие программы из связки не могут это сделать сами. Courier-IMAP работает pop3 и imap сервером. Там, где сможет, проверяет пользователя сам, где не может - через SASL и отдает пользователю почту, полученную postfix'ом. Dr.Web защищает пользователя от вирусов. К сожалению, действие имеющейся у меня лицензии кончилось, поэтому приходится использовать демонстрационную. Новую покупать пока лень. Apache и PHP обеспечивают работоспособность веб-почты и веб-страниц управления почтовой системой. SquirrelMail - почтовая веб-система, дающая пользователю возможность прочитать свою почту браузером. Теперь конкретнее. Представим себе, что пользователь хочет отправить письмо. После нажатия пользователем кнопки Send в почтовом клиенте происходит следующее: 1.почтовый клиент соединяется с указанным в настройках почтовым сервером и представляется. 2.почтовый сервер смотрит на ip-адрес клиента и сравнивая его со своими правилами, дает ответ. Ответов может быть два: отказ, разрешение и предложение авторизации. Отказ происходит в том случае, если ip-адрес клиента занесен в <черный> список. Разрешение - это стандартный ответ сервера, разрешающего дальнейшую работу. Предложение авторизации - опять же, стандартный ответ сервера, предлагающего перейти на более доверительный уровень отношений. Именно в этом момент почтовый клиент может авторизоваться у сервера. Postfix обрабатывает авторизацию по методу LOGIN сам, а CRAM и прочее отдает SASL. После успешной авторизации и установки протоколов и режимов работы клиент опять получает приглашение. 3.Почтовый клиент, получив приглашение, передает почтовому серверу сформированное письмо. 4.Сервер смотрит на команды и заголовки письма, решая его дальнейшую судьбу. Если письмо предназначено домену, обслуживаемому сервером, пользователь существует и не исчерпал своего лимита - оно принимается. Если клиент пришел из разрешенной сети или авторизовался, оно опять же принимается. Если не стоит специальных настроек (к примеру, принимать письма для несуществующих пользователей), то письмо отбрасывается. 5.сервер сообщает почтовому клиенту о своем решении относительно письма. 6.клиент отсоединяется или переходит назад на 3й шаг. 7.Сервер же, приняв письмо для обработки, отправляет его в очередь писем <для разбора> и принимается ждать следующего события. По пути в очередь письмо проверяется Dr.Web'ом. Он имеет право заблокировать письмо, поменять ему заголовки, подменить его другим и так далее. В общем, именно по пути в очередь с письмом происходят все положенные метаморфозы. На приеме в очередь письмо попадает к специальному процессу, отвечающему за поддержание очереди в целостности. Процесс смотрит на заголовки и, консультируясь с MySQL, решает, что делать с письмом: положить в папку пользователю, передать другому серверу или еще что. В случае каких-либо ошибок и прочего письмо ложится в очередь и периодически, с увеличивающимся интервалом, проверяется на предмет исчезновения мешающих доставке письма ошибок. По истечении некоторых промежутков автору письма отправляется соответствующее предупреждение и письмо либо остается дожидаться своей очереди, либо удаляется. Если письмо предназначено другому домену, обслуживаемому другим сервером, то наш почтовый сервер соединяется с удаленным сервером и выполняет все положенные процедуры для клиента. В общем, рано или поздно у пользователя в личном ящике оказывается письмо. Это может быть оригинал отправленного письма или сообщение от робота, который по тем или иным причинам не даль письму дойти до пользователя. Теперь пользователь нажимает на кнопку Receive. 1.Почтовый клиент соединяется с Courier-IMAP по pop3 или imap протоколу. 2.Сервер проверяет с помощью MySQL и SASL пользователя, его права и расположение почтового ящика. 3.Если все в порядке, сервер открывает почтовый ящик и передает пользователю сообщение об успехе 4.Почтовый клиент выполняет требуемые ему действия (смотрит число писем, забирает некоторые, перемещает и так далее) и отключается. 5.Сервер остается ждать следующего пользователя. Если пользователь читает или пишет почту из браузера, то почтовым клиентом выступает SquirrelMail. Вот так в принципе работает почтовая система. Понятно, что на самом деле там все сложней, но этот HOWTO и не предназначен для ликбеза - он просто описывает что и куда. Интересующиеся всегда смогут прочитать документацию и кучу RFC, описывающих весь процесс детально. Начнем, пожалуй, хватит писать умные и не очень мысли. [root@multik ispmail]# pwd /usr/src/ispmail [root@multik ispmail]# ls apache_1.3.29.tar.gz mysql-4.0.16.tar.gz courier-imap-2.2.0.tar.bz2 openssl-0.9.7c.tar.gz cyrus-sasl-2.1.15.tar.gz php-4.3.3.tar.bz2 drweb-4.30-glibc.2.3.tar.gz postfix-2.0.16.tar.gz drweb-postfix-4.29.12-F-linux.tar.gz squirrelmail-1.4.2.tar.bz2 Вот такой набор пакетов у меня в наличии. Начнем с OpenSSL. Я собрал его с динамически подключаемыми библиотеками. [root@multik ispmail]# tar zxvf openssl-0.9.7c.tar.gz [root@multik ispmail]# cd openssl-0.9.7c [root@multik openssl-0.9.7c]# ./config shared .... make[1]: Leaving directory `/usr/src/ispmail/openssl-0.9.7c/test' Configured for linux-pentium. [root@multik openssl-0.9.7c]# make .... make[1]: Entering directory `/usr/src/ispmail/openssl-0.9.7c/tools' make[1]: Nothing to be done for `all'. make[1]: Leaving directory `/usr/src/ispmail/openssl-0.9.7c/tools' [root@multik openssl-0.9.7c]# make test .... OpenSSL 0.9.7c 30 Sep 2003 built on: Sat Nov 1 14:06:20 MSK 2003 platform: linux-pentium options: bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) idea(int) blowfish(idx) compiler: gcc -fPIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -mcpu=pentium -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM OPENSSLDIR: "/usr/local/ssl" [root@multik openssl-0.9.7c]# rpm -e --nodeps openssl [root@multik openssl-0.9.7c]# make install .... installing libssl.a cp openssl.pc /usr/local/ssl/lib/pkgconfig chmod 644 /usr/local/ssl/lib/pkgconfig [root@multik openssl-0.9.7c]# echo "/usr/local/ssl/lib" >> /etc/ld.so.conf [root@multik openssl-0.9.7c]# ldconfig -v|grep libssl libssl.so.0.9.7 -> libssl.so.0.9.7 [root@multik openssl-0.9.7c]# cd .. Теперь наступила очередь MySQL. Тут мне понадобился полный набор локалей для других моих проектов. Так же включил поддержку OpenSSL - она тоже лишней не будет. [root@multik ispmail]# tar zxvf mysql-4.0.16.tar.gz [root@multik ispmail]# cd mysql-4.0.16 [root@multik mysql-4.0.16]# ./configure --prefix=/opt/mysql --with-mysqld-user=mysql --with-openssl --with-openssl-includes=/usr/local/ssl/include --with-openssl-libs=/usr/local/ssl/lib --with-extra-charsets=complex .... Thank you for choosing MySQL! [root@multik mysql-4.0.16]# make Тут вся малина прервалась ошибкой при сборке. gcc -DHAVE_CONFIG_H -I. -I. -I.. -I./../include -I../include -O3 -DDBUG_OFF -c `test -f strxmov.c || echo './'`strxmov.c In file included from strxmov.c:33: ../include/my_global.h:1109:30: openssl/opensslv.h: No such file or directory make[2]: *** [strxmov.o] Error 1 make[2]: Leaving directory `/usr/src/ispmail/mysql-4.0.16/strings' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/usr/src/ispmail/mysql-4.0.16' make: *** [all] Error 2 Как видно, при конфигурировании авторы MySQL почему-то пропустили одну строчку в конфиге. В результате в Makefile пропущен нужный параметр. Можно, конечно, поправить соответствующие Makefile или найти ошибку в configure скриптах, но я поступил проще: скопировал /usr/local/ssl/include в /usr/include. Все равно пригодится потом. .... /bin/mv MySQL-shared-compat.spec-t MySQL-shared-compat.spec make[3]: Leaving directory `/usr/src/ispmail/mysql-4.0.16/support-files' make[2]: Leaving directory `/usr/src/ispmail/mysql-4.0.16/support-files' make[1]: Leaving directory `/usr/src/ispmail/mysql-4.0.16' [root@multik mysql-4.0.16]# rpm -e mysql mysql-server mysql-devel perl-DBD-MySQ L [root@multik mysql-4.0.16]# adduser mysql [root@multik mysql-4.0.16]# make install .... make[3]: Leaving directory `/usr/src/ispmail/mysql-4.0.16/support-files' make[2]: Leaving directory `/usr/src/ispmail/mysql-4.0.16/support-files' make[1]: Leaving directory `/usr/src/ispmail/mysql-4.0.16/support-files' [root@multik mysql-4.0.16]# echo /opt/mysql/lib/mysql >> /etc/ld.so.conf [root@multik mysql-4.0.16]# ldconfig -v|grep mysql /opt/mysql/lib/mysql: libmysqlclient.so.12 -> libmysqlclient.so.12.0.0 [root@multik mysql-4.0.16]# mkdir /opt/mysql/var [root@multik mysql-4.0.16]# scripts/mysql_install_db .... http://www.mysql.com Support MySQL by buying support/licenses at https://order.mysql.com [root@multik mysql-4.0.16]# cat > /etc/my.cnf [mysqld] datadir=/opt/mysql/var socket=/tmp/mysql.sock [mysql.server] user=mysql basedir=/opt/mysql key_buffer_size=16M sort_buffer_size=1M [safe_mysqld] err-log=/opt/mysql/mysqld.log pid-file=/opt/mysql/mysqld.pid [mysqld] innodb_data_file_path = ibdata1:100M:autoextend set-variable = innodb_buffer_pool_size=50M set-variable = innodb_additional_mem_pool_size=10M set-variable = innodb_log_file_size=5M set-variable = innodb_log_buffer_size=8M innodb_flush_log_at_trx_commit=1 set-variable=lower_case_table_names=1 [root@multik mysql-4.0.16]# cd /opt/mysql/ [root@multik mysql]# chown mysql.mysql var [root@multik mysql]# cd var [root@multik var]# chown -R mysql.mysql * [root@multik var]# cd /opt/mysql ; /opt/mysql/bin/mysqld_safe Starting mysqld daemon with databases from /opt/mysql/var На этом месте индикатор активности винчестера должен загореться и через некоторое время погаснуть. Посмотрим в файл /opt/mysql/mysqld.log. В самом конце обнаружим строчки 031101 16:00:32 InnoDB: Started 031101 16:00:32 /opt/mysql/libexec/mysqld: Can't create/write to file '/opt/mysql/mysqld.pid' (Errcode: 13) /opt/mysql/libexec/mysqld: ready for connections. Version: '4.0.16' socket: '/opt/mysql/var/mysql.sock' port: 3306 Это и понятно. Все каталоги создавались от пользователя root и пользователь mysql не имеет права писать туда. Разрешим это маленькое противоречие следующими командами [root@multik mysql]# touch /opt/mysql/mysqld.pid [root@multik mysql]# chown mysql.mysql /opt/mysql/mysqld.pid Аккуратно остановим все относящееся к mysql с другой консоли. Теперь скопируем заботливо приготовленный скрипт запуска и заставим сервер включаться при каждом запуске машины. [root@multik mysql]# cp /usr/src/ispmail/mysql-4.0.16/support-files/mysql.server /etc/init.d/mysql [root@multik mysql]# chkconfig --add mysql [root@multik mysql]# chkconfig mysql on [root@multik mysql]# chkconfig --list mysql mysql 0:off 1:off 2:on 3:on 4:on 5:on 6:off А теперь запустим его. [root@multik mysql]# chmod +x /etc/init.d/mysql [root@multik mysql]# /etc/init.d/mysql start [root@multik mysql]# Starting mysqld daemon with databases from /opt/mysql/var [root@multik mysql]# Теперь проведем пару обязательных мероприятий - сменим пароль и проверим, как сервер откликается на команды [root@multik mysql]# /opt/mysql/bin/mysqladmin -u root password 'password' [root@multik mysql]# cd /opt/mysql/bin [root@multik bin]# ./mysqladmin status ./mysqladmin: connect to server at 'localhost' failed error: 'Access denied for user: 'root@localhost' (Using password: NO)' [root@multik bin]# ./mysqladmin status -p Enter password: Uptime: 95 Threads: 1 Questions: 4 Slow queries: 0 Opens: 7 Flush tables:1 Open tables: 1 Queries per second avg: 0.042 [root@multik bin]# Как видите, сервер запустился и даже заработал. Я оставляю дальнейшее конфигурирование сервера (файл /etc/my.cnf) на вашей совести - благо, об этом написано очень много статей. Да и документация на сайте mysql.com вполне вменяемая. Возвращаемся назад. Теперь настала очередь Cyrus-SASL. [root@multik root]# cd /usr/src/ispmail [root@multik ispmail]# tar zxvf cyrus-sasl-2.1.15.tar.gz [root@multik ispmail]# cd cyrus-sasl-2.1.15 [root@multik cyrus-sasl-2.1.15]# ./configure --enable-static --with-gnu-ld --with-mysql=/opt/mysql .... creating saslauthd.h Configuration Complete. Type 'make' to build. [root@multik cyrus-sasl-2.1.15]# make Собрался он у меня без каких-либо ошибок и сложностей. Теперь перед установкой осталось только удалить "родной" для дистрибутива sasl. Так как на него "завязано" очень много системных программ, удалим без сохранения зависимостей. .... make[2]: Entering directory `/usr/src/ispmail/cyrus-sasl-2.1.15' make[2]: Leaving directory `/usr/src/ispmail/cyrus-sasl-2.1.15' make[1]: Leaving directory `/usr/src/ispmail/cyrus-sasl-2.1.15' [root@multik cyrus-sasl-2.1.15]# rpm -e --nodeps cyrus-sasl cyrus-sasl-plain cyrus-sasl-devel cyrus-sasl-md5 [root@multik cyrus-sasl-2.1.15]# make install .... ******************************************************** * WARNING: * Plugins are being installed into /usr/local/lib/sasl2, * but the library will look for them in /usr/lib/sasl2. * You need to make sure that the plugins will eventually * be in /usr/lib/sasl2 -- the easiest way is to make a * symbolic link from /usr/lib/sasl2 to /usr/local/lib/sasl2, * but this may not be appropriate for your site, so this * installation procedure won't do it for you. * * If you don't want to do this for some reason, you can * set the location where the library will look for plugins * by setting the environment variable SASL_PATH to the path * the library should use. ******************************************************** make[2]: Nothing to be done for `install-data-am'. make[2]: Leaving directory `/usr/src/ispmail/cyrus-sasl-2.1.15' make[1]: Leaving directory `/usr/src/ispmail/cyrus-sasl-2.1.15' [root@multik cyrus-sasl-2.1.15]# ln -s /usr/local/lib/sasl2 /usr/lib/sasl2 [root@multik cyrus-sasl-2.1.15]# echo /usr/local/lib/sasl2 >> /etc/ld.so.conf [root@multik cyrus-sasl-2.1.15]# echo /usr/local/lib >> /etc/ld.so.conf [root@multik cyrus-sasl-2.1.15]# ldconfig -v|grep sasl libsasl2.so.2 -> libsasl2.so.2.0.15 /usr/local/lib/sasl2: libsasldb.so.2 -> libsasldb.so.2.0.15 Согласно выведенной после установки инструкции, создали мягкую ссылку и пропишем все необходимые пути для обнаружения библиотек. Теперь пора собрать вторую основу всей системы - Postfix. [root@multik cyrus-sasl-2.1.15]# cd .. [root@multik ispmail]# tar zxvf postfix-2.0.16.tar.gz [root@multik ispmail]# cd postfix-2.0.16 [root@multik postfix-2.0.16]# make -f Makefile.init makefiles 'CCARGS=-DDEF_SAMPLE_DIR=\"/etc/mail/sample\" -DHAS_MYSQL -I/opt/mysql/include/mysql -DUSE_SASL_AUTH -I/usr/local/include/sasl' 'AUXLIBS=-L/opt/mysql/lib/mysql -lmysqlclient -L/usr/local/lib -lsasl2 -lz -lm' В процессе конфигурирования будет много страшных сообщений со словами "DO NOT EDIT" - не пугайтесь, все в порядке. [root@multik postfix-2.0.16]# make В конце концов компиляция завершилась следующими строками: [src/proxymap] gcc -Wmissing-prototypes -Wformat -DDEF_SAMPLE_DIR=\"/etc/mail/sample\" -DHAS_MYSQL -I/opt/mysql/include/mysql -DUSE_SASL_AUTH -I/usr/local/include/sasl -g -O -I. -I../../include -DLINUX2 -c proxymap.c gcc -Wmissing-prototypes -Wformat -DDEF_SAMPLE_DIR=\"/etc/mail/sample\" -DHAS_MYSQL -I/opt/mysql/include/mysql -DUSE_SASL_AUTH -I/usr/local/include/sasl -g -O -I. -I../../include -DLINUX2 -o proxymap proxymap.o ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libutil.a -L/opt/mysql/lib/mysql -lmysqlclient -L/usr/local/lib -lsasl2 -lz -lm -ldb -lnsl -lresolv cp proxymap ../../libexec [root@multik postfix-2.0.16]# Уже собрав postfix, я вспомнил, что совсем забыл включить поддержку TLS. Нашел необходимый патч (в google по словам postfix TLS). Скачал его в тот же каталог, где у меня лежит все остальное [root@multik postfix-2.0.16]# cd .. [root@multik ispmail]# tar zxvf pfixtls-0.8.16-2.0.16-0.9.7b.tar.gz .... pfixtls-0.8.16-2.0.16-0.9.7b/doc_french/setup.html pfixtls-0.8.16-2.0.16-0.9.7b/doc_french/test.html pfixtls-0.8.16-2.0.16-0.9.7b/pfixtls.diff [root@multik ispmail]# patch -p0 < pfixtls-0.8.16-2.0.16-0.9.7b/pfixtls.diff .... patching file postfix-2.0.16/src/util/dict_sdbm.h patching file postfix-2.0.16/src/util/sdbm.c patching file postfix-2.0.16/src/util/sdbm.h [root@multik ispmail]# cd postfix-2.0.16 [root@multik postfix-2.0.16]# make tidy .... find . -type s -print | xargs rm -f find . -type d -print | xargs chmod 755 find . -type f -print | xargs chmod a+r [root@multik postfix-2.0.16]# make -f Makefile.init makefiles 'CCARGS=-DDEF_SAMPLE_DIR=\"/etc/mail/sample\" -DHAS_MYSQL -I/opt/mysql/include/mysql -DUSE_SASL_AUTH -I/usr/local/include/sasl -DUSE_SSL -I/usr/local/ssl/include' 'AUXLIBS=-L/opt/mysql/lib/mysql -lmysqlclient -L/usr/local/lib -lsasl2 -lz -lm -L/usr/local/ssl/lib -lssl -lcrypto' .... [src/tlsmgr] (set -e; echo "# DO NOT EDIT"; /bin/sh ../../makedefs; cat Makefile.in) >Makefile rm -f Makefile; (set -e; /bin/sh makedefs && cat Makefile.in) >Makefile [root@multik postfix-2.0.16]# make После окончания страшных и длинных ругательств на экране, означающих компиляцию, вы можете себя поздравить - postfix собрался. Теперь очередь за его первоначальной установкой. [root@multik postfix-2.0.16]# adduser postfix [root@multik postfix-2.0.16]# groupadd postdrop [root@multik postfix-2.0.16]# make install Вот как я ответил на вопросы инсталлятора install_root: [/] tempdir: [/usr/src/ispmail/postfix-2.0.16] /tmp config_directory: [/etc/postfix] daemon_directory: [/usr/libexec/postfix] command_directory: [/usr/sbin] queue_directory: [/var/spool/postfix] sendmail_path: [/usr/sbin/sendmail] newaliases_path: [/usr/bin/newaliases] mailq_path: [/usr/bin/mailq] mail_owner: [postfix] setgid_group: [postdrop] manpage_directory: [/usr/local/man] sample_directory: [/etc/mail/sample] readme_directory: [no] .... Updating /etc/mail/sample/sample-virtual.cf... Warning: you still need to edit myorigin/mydestination/mynetworks parameter settings in /etc/postfix/main.cf. See also http://www.postfix.org/faq.html for information about dialup sites or about sites inside a firewalled network. BTW: Check your /etc/aliases file and be sure to set up aliases that send mail for root and postmaster to a real person, then run /usr/bin/newaliases. [root@multik postfix-2.0.16]# Вот и все. Postfix установлен. Теперь время за настройкой. Глубокую настройку производить пока не будем, ограничимся самым необходимым, лишь бы вся эта конструкция заработала. Переходим в каталог /etc/postfix и начинаем редактировать файл main.cf. По необходимости смотрим в каталог /etc/mail/sample - там лежат примеры, разбитые по выполняемым функциям. Я поправил следующие строки default_privs = nobody myhostname = mail.multik.int mydomain = multik.int unknown_local_recipient_reject_code = 550 mynetworks_style = host smtpd_banner = $myhostname ESMTP $mail_name И добавил в конец следующее broken_sasl_auth_clients = yes smtpd_sasl_auth_enable = yes transport_maps = mysql:/etc/postfix/transport.cf virtual_mailbox_base = / virtual_uid_maps = mysql:/etc/postfix/ids.cf virtual_gid_maps = mysql:/etc/postfix/gids.cf virtual_mailbox_maps = mysql:/etc/postfix/aliases.cf virtual_maps = mysql:/etc/postfix/remote_aliases.cf relay_domains = $transport_maps smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated,check_relay_domains disable_vrfy_command = yes Что они означают и как действуют, вы можете спокойно найти в документации или в ЧаВО transport.cf user = postfix password = postfix dbname = mail table = transport select_field = transport where_field = domain hosts = localhost ids.cf user = postfix password = postfix dbname = mail table = aliases select_field = id where_field = alias hosts = localhost gids.cf user = postfix password = postfix dbname = mail table = aliases select_field = gid where_field = alias hosts = localhost aliases.cf user = postfix password = postfix dbname = mail table = aliases select_field = maildir where_field = alias hosts = localhost remote_aliases.cf user = postfix password = postfix dbname = mail table = remote_aliases select_field = rcpt where_field = alias hosts = localhost Проверяем, все ли в порядке с точки зрения postfix [root@multik postfix]# postfix check Если все хорошо, то команда должна отработать без каких-либо сообщений. Теперь зайдем в консоль MySQL и создадим необходимые таблицы. [root@multik postfix]# /opt/mysql/bin/mysql -p .... mysql> create database mail; Query OK, 1 row affected (0.19 sec) mysql> grant insert,select,delete,update on mail.* to postfix@localhost identif ied by 'postfix'; Query OK, 0 rows affected (0.35 sec) mysql> use mail; Database changed mysql> create table transport (domain varchar(255) PRIMARY KEY, transport char( 8)); Query OK, 0 rows affected (0.04 sec) mysql> create table aliases (id int(6), gid int(6), alias varchar(255) PRIMARY KEY, maildir varchar(255),password varchar(128), info varchar(128)); Query OK, 0 rows affected (0.01 sec) mysql> create table remote_aliases (alias varchar(255) PRIMARY KEY, rcpt varchar(255)); Query OK, 0 rows affected (0.02 sec) Теперь перезайдем пользователем postfix. Заодно и проверим, что пользователь postfix/postfix воспринимается системой нормально. [root@multik postfix]# /opt/mysql/bin/mysql -u postfix -p Enter password: mysql> use mail; .... mysql> insert into transport values ('multik.int','virtual:'); Query OK, 1 row affected (0.04 sec) .... mysql> insert into aliases values (1000,12,'[email protected]','/var/spool/vmail/multik.int_multik/','password',' m ultik account'); Query OK, 1 row affected (0.01 sec) [root@multik postfix]# mkdir /var/spool/vmail [root@multik postfix]# chown nobody.mail /var/spool/vmail [root@multik postfix]# chmod 770 /var/spool/vmail А теперь попытаемся со всей этой фигней взлететь. [root@multik postfix]# postfix start postfix/postfix-script: starting the Postfix mail system В логах Nov 1 18:28:00 multik postfix/postfix-script: starting the Postfix mail system Nov 1 18:28:01 multik postfix/master[1540]: daemon started -- version 2.0.16 Вроде взлетели, но удостовериться никогда не помешает. При первой же попытке присоедениться к серверу получаем в логах Nov 1 18:29:40 multik postfix/smtpd[1578]: fatal: open database /etc/aliases.db: No such file or directory Исправляем [root@multik postfix]# ln -s /etc/postfix/aliases /etc/aliases [root@multik postfix]# newaliases И пробуем снова [multik@multik multik]$ telnet localhost 25 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 mail.multik.int ESMTP Postfix mail from: [email protected] 250 Ok rcpt to: [email protected] 250 Ok data 354 End data with <CR><LF>.<CR><LF> Subject: Welcome to the brand new mail system subj ;-) Sincerely yours, postfix . 250 Ok: queued as 6E20116623A quit 221 Bye Connection closed by foreign host. А в логах Nov 1 18:31:54 multik postfix/smtpd[1655]: connect from localhost.localdomain[127.0.0.1] Nov 1 18:32:25 multik postfix/smtpd[1655]: 6E20116623A: client=localhost.localdomain[127.0.0.1] Nov 1 18:33:19 multik postfix/cleanup[1657]: 6E20116623A: message-id=<[email protected]> Nov 1 18:33:19 multik postfix/qmgr[1646]: 6E20116623A: from=<[email protected]>, size=439, nrcpt=1 (queue active) Nov 1 18:33:20 multik postfix/virtual[1666]: 6E20116623A: to=<[email protected]>, relay=virtual, delay=55, status=sent (maildir) Nov 1 18:33:23 multik postfix/smtpd[1655]: disconnect from localhost.localdomain[127.0.0.1] По логам письмо доставлено. Поглядим глазами на то место, где лежит письмо. [root@multik postfix]# ls -l /var/spool/vmail/ total 4 drwx------ 5 1000 mail 4096 Nov 1 18:33 multik.int_multik [root@multik postfix]# ls -l /var/spool/vmail/multik.int_multik/new/ total 4 -rw------- 1 1000 mail 526 Nov 1 18:33 1067700800.V301I16623d.multik [root@multik postfix]# cat /var/spool/vmail/multik.int_multik/new/1067700800.V301I16623d.multik Subject: Welcome to the brand new mail system Message-Id: <[email protected]> Date: Sat, 1 Nov 2003 18:32:25 +0300 (MSK) From: [email protected] To: undisclosed-recipients:; subj ;-) Sincerely yours, postfix [root@multik postfix]# Как видим, первый взлет прошел успешно. Письмо было доставлено адресату в своем первозданном виде. Теперь осталось сделать так, что бы этот самый адресат смог прочитать это письмо без применения оружия массового поражения в отношении администратора системы. [root@multik postfix]# cd /usr/src/ispmail/ [root@multik ispmail]# tar jxvf courier-imap-2.2.0.tar.bz2 [root@multik ispmail]# adduser courier [root@multik ispmail]# chown courier.courier courier-imap-2.2.0 [root@multik ispmail]# cd courier-imap-2.2.0 [root@multik courier-imap-2.2.0]# chown -R courier.courier * [root@multik courier-imap-2.2.0]# [root@multik courier-imap-2.2.0]# su - courier [courier@multik courier]$ cd /usr/src/ispmail/courier-imap-2.2.0 [courier@multik courier-imap-2.2.0]$ ./configure --enable-unicode --with-redhat Последний параметр нужен для того, что бы дать по рукам конфигурационному скрипту, который увидел, что я собираю систему на RedHat и предложил пойти мне и скачать rpm. .... config.status: creating pop3d.cnf config.status: creating config.h config.status: executing depfiles commands [courier@multik courier-imap-2.2.0]$ [courier@multik courier-imap-2.2.0]$ make .... cp imap/imapd.cnf . cp imap/pop3d.cnf . cp -f ./maildir/quotawarnmsg quotawarnmsg.example make[1]: Leaving directory `/usr/src/ispmail/courier-imap-2.2.0' [courier@multik courier-imap-2.2.0]$ authlib/authinfo AUTHENTICATION_MODULES="authdaemon" AUTHDAEMONMODULELIST="authcustom authcram authuserdb authpam" SASL_AUTHENTICATION_MODULES="CRAM-SHA1 CRAM-MD5 PLAIN LOGIN" Как видим, authmysql что-то не наблюдается. Это издержки того, что все необходимые файлы расположены не там, где их ожидают увидеть. Придется воспользоваться тайным знанием, почерпнутым из общедоступных источников. [courier@multik courier-imap-2.2.0]$ make clean [courier@multik courier-imap-2.2.0]$ ./configure --enable-unicode --with-redhat --with-mysql-libs=/opt/mysql/lib/mysql --with-mysql-includes=/opt/mysql/include/mysql [courier@multik courier-imap-2.2.0]$ make .... [courier@multik courier-imap-2.2.0]$ authlib/authinfo AUTHENTICATION_MODULES="authdaemon" AUTHDAEMONMODULELIST="authcustom authcram authmysql authuserdb authpam" SASL_AUTHENTICATION_MODULES="CRAM-SHA1 CRAM-MD5 PLAIN LOGIN" Ну вот теперь, как мы видим, все в полном порядке. [courier@multik courier-imap-2.2.0]$ exit [root@multik courier-imap-2.2.0]# make install-strip .... make[3]: Leaving directory `/usr/src/ispmail/courier-imap-2.2.0' make[2]: Leaving directory `/usr/src/ispmail/courier-imap-2.2.0' make[1]: Leaving directory `/usr/src/ispmail/courier-imap-2.2.0' [root@multik courier-imap-2.2.0]# make install-configure .... daemons: new version: new authdaemonvar: new make[1]: Leaving directory `/usr/src/ispmail/courier-imap-2.2.0' [root@multik courier-imap-2.2.0]# Обратите внимание на промелькнувшие параметры, которые понимает каждый из модулей. Вот, к примеру, наиболее нам интересные. pop3d-ssl: SSLPORT: new SSLADDRESS: new SSLPIDFILE: new POP3DSSLSTART: new POP3_STARTTLS: new POP3_TLS_REQUIRED: new COURIERTLS: new TLS_PROTOCOL: new TLS_STARTTLS_PROTOCOL: new TLS_CIPHER_LIST: new TLS_TIMEOUT: new TLS_DHCERTFILE: new TLS_CERTFILE: new TLS_TRUSTCERTS: new TLS_VERIFYPEER: new TLS_CACHE: new authmysqlrc: LOCATION: new MYSQL_SOCKET: new MYSQL_PORT: new MYSQL_OPT: new MYSQL_DATABASE: new MYSQL_USER_TABLE: new MYSQL_CRYPT_PWFIELD: new MYSQL_CLEAR_PWFIELD: new MYSQL_DEFAULT_DOMAIN: new MYSQL_UID_FIELD: new MYSQL_GID_FIELD: new MYSQL_LOGIN_FIELD: new MYSQL_HOME_FIELD: new MYSQL_NAME_FIELD: new MYSQL_MAILDIR_FIELD: new MYSQL_DEFAULTDELIVERY: new MYSQL_QUOTA_FIELD: new MYSQL_WHERE_CLAUSE: new MYSQL_SELECT_CLAUSE: new MYSQL_CHPASS_CLAUSE: new Именно их мы будем указывать в разных конфигурационных файлах, что бы дать понять демонам, куда смотреть и что использовать. Идем в каталог /usr/lib/courier-imap/etc и начинаем править следующие строчки в файлах authdaemonrc: authmodulelist="authmysql" authmysqlrc: MYSQL_SERVER localhost MYSQL_USERNAME postfix MYSQL_PASSWORD postfix MYSQL_SOCKET /tmp/mysql.sock MYSQL_PORT 3306 MYSQL_OPT 0 MYSQL_DATABASE mail MYSQL_USER_TABLE aliases MYSQL_CLEAR_PWFIELD password DEFAULT_DOMAIN multik.int MYSQL_UID_FIELD id MYSQL_GID_FIELD gid MYSQL_LOGIN_FIELD alias MYSQL_HOME_FIELD maildir MYSQL_NAME_FIELD info MYSQL_MAILDIR_FIELD maildir Что каждая из них означает, вы сможете прочитать в расположившихся рядом комментариях. Да и их названия по больше части говорят сами за себя, так что думаю, у вас не возникнет никаких проблем. Теперь попытаемся завести pop3 [root@multik courier-imap]# /usr/lib/courier-imap/libexec/pop3d.rc start На консоли ничего не должно появиться, а в логах должна появиться одинакая строчка о запуске демона авторизации Nov 1 19:24:26 multik authdaemond.mysql: authdaemon: modules="authmysql", daemons=5 Попробуем посмотреть, если ли для нас почта [multik@multik multik]$ telnet localhost 110 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. +OK Hello there. user [email protected] +OK Password required. pass password +OK logged in. list +OK POP3 clients that break here, they violate STD53. 1 540 . quit +OK Bye-bye. Connection closed by foreign host. Как и ожидалось, для нас лежит целое одно письмо размером в 540 байт. В логах же наша попытка была также разоблачена Nov 1 19:25:29 multik pop3d: Connection, ip=[::ffff:127.0.0.1] Nov 1 19:25:48 multik pop3d: LOGIN, [email protected], ip=[::ffff:127.0.0.1] Nov 1 19:25:57 multik pop3d: LOGOUT, [email protected], ip=[::ffff:127.0.0.1], top=0, retr=0 На этом этапе мы можем сказать, что ядро системы заработало. У нас есть все необходимое для обычного почтового сервера. IMAP можно проверить совершенно аналогичным способом, но мне лень вспоминать команды, поэтому я просто натравил на сервер mozill'у. Показало все тоже самое. Двигаемся дальше, к защите от злобных вирусов. Эту защиту нам будет обеспечивать Dr.Web. [root@multik courier-imap]# cd /usr/src/ispmail/ [root@multik ispmail]# tar zxvf drweb-4.30-glibc.2.3.tar.gz [root@multik ispmail]# tar zxvf drweb-postfix-4.29.12-F-linux.tar.gz Получившееся из распакованного я разнес в по соответствующим каталогам. Попробуем запустить и поглядим, что получится. [root@multik ispmail]# /opt/drweb/drweb Dr.Web (R) for Linux, version 4.30 (October 7, 2003) Copyright (c) Igor Daniloff, 1992-2003 Daniloff's Labs and DialogueScience http://www.drweb.ru, [email protected]: +7 (812) 387-64-08 http://www.dials.ru, [email protected]: +7 (095) 137-01-50 Key file: /opt/drweb/drweb.key Registration info: 0100000004 Evaluation key ID Anti-virus Lab St.Petersburg This is an EVALUATION version with limited functionality! To get your registration key, call regional dealer. Loading /var/drweb/bases/drw43009.vdb - Ok, virus records: 115 Loading /var/drweb/bases/drw43008.vdb - Ok, virus records: 183 Loading /var/drweb/bases/drw43007.vdb - Ok, virus records: 194 Loading /var/drweb/bases/drw43006.vdb - Ok, virus records: 195 Loading /var/drweb/bases/drw43005.vdb - Ok, virus records: 252 Loading /var/drweb/bases/drw43004.vdb - Ok, virus records: 134 Loading /var/drweb/bases/drw43003.vdb - Ok, virus records: 180 Loading /var/drweb/bases/drw43002.vdb - Ok, virus records: 164 Loading /var/drweb/bases/drw43001.vdb - Ok, virus records: 162 Loading /var/drweb/bases/drwebase.vdb - Ok, virus records: 39721 Total virus records: 41300 Как видим, все работает, хоть у нас и лицензия с ограниченной функциональностью. Как сказано в README If the evaluation key is used the following limitations are imposed: the scanner does not perform curing of infected objects, checking of the files placed into archives, into mail bases and packed by the programs for executable modules compression (DIET, PKLITE etc.). The same limitations valid for daemon except for working with mail bases and packed programs. В общем, лечить файлы и заглядывать в архивы мы не сможем. Жалко конечно, но по большому счету нам эти возможности не нужны. Dr.Web здесь работает не как лекарь, а как индикатор. Но все-таки, с лицензией жить проще, что не говори. Для начала заглянем в /etc/drweb и подредактируем drweb32.ini HeuristicAnalysis = Yes LogFileName = "syslog" SyslogFacility = "mail" SyslogPriority = "info" StopOnFirstInfected = Yes Теперь настает пора привить drweb немного хорошего вкуса. [root@multik ispmail]# chown -R drweb.drweb /var/drweb/ и добавляем в самое начало файла запуска, сразу после #!/bin/sh пару строчек # chkconfig: 2345 95 25 # description: Antivirus Engine. Записываем его в /etc/init.d/ и заставляем его запускаться при запуске системы. [root@multik root]# chkconfig --add drwebd [root@multik root]# chkconfig drwebd on [root@multik root]# chkconfig --list drwebd drwebd 0:off 1:off 2:on 3:on 4:on 5:on 6:off Запускаем его вручную. [root@multik root]# /etc/init.d/drwebd start Starting Dr. Web daemon...Dr.Web (R) daemon for Linux, version 4.30. (October 7, 2003) Copyright (c) Igor Daniloff, 1992-2003 Daniloff's Labs and DialogueScience http://www.drweb.ru, [email protected]: +7 (812) 387-64-08 http://www.dials.ru, [email protected]: +7 (095) 137-01-50 Key file: /opt/drweb/drwebd.key Registration info: 0100000003 Evaluation key ID Anti-virus Lab St.Petersburg This is an EVALUATION version with limited functionality! To get your registration key, call regional dealer. Engine version: 4.30 Loading /var/drweb/bases/drw43009.vdb - Ok, virus records: 115 Loading /var/drweb/bases/drw43008.vdb - Ok, virus records: 183 Loading /var/drweb/bases/drw43007.vdb - Ok, virus records: 194 Loading /var/drweb/bases/drw43006.vdb - Ok, virus records: 195 Loading /var/drweb/bases/drw43005.vdb - Ok, virus records: 252 Loading /var/drweb/bases/drw43004.vdb - Ok, virus records: 134 Loading /var/drweb/bases/drw43003.vdb - Ok, virus records: 180 Loading /var/drweb/bases/drw43002.vdb - Ok, virus records: 164 Loading /var/drweb/bases/drw43001.vdb - Ok, virus records: 162 Loading /var/drweb/bases/drwebase.vdb - Ok, virus records: 39721 Total virus records: 41300 Invalid line in INI-file: 99 Daemon is installed, active interfaces: 127.0.0.1:3000 [root@multik root]# Исправляем ошибку в 99й строчке, возникшую у меня из-за привычки - я сделал комментарий не тем символом. Теперь обращаем внимание на файл drweb_postfix.conf HeuristicAnalysis = on RuleFilter = off ArchiveRestriction = pass AdminMail = [email protected] RedirectMail = [email protected] FilterMail = [email protected] [VirusNotifications] SenderNotify = no AdminNotify = no [SkipNotifications] SenderNotify = no [ArchiveRestrictionNotifications] SenderNotify = no [ErrorNotifications] SenderNotify = no Обратите внимание, что я везде отключил оповещение автору письма. По одной простой причине - я не хочу, что бы при очередном взрыве почтовых троянцев, которые подменяют автора, совершенно невинным людям приходило оповещение о том, что они кому-то послали вирус. Знали бы вы, сколько вот таких вот оповещений я получил от идиотски настроенных серверов во время последних эпидемий ... Теперь попробуем подключить drweb к postfix. Для этого добавим в самый конец /etc/postfix/master.cf строчку filter unix - n n - - pipe flags=R user=drweb argv=/opt/drweb/drweb-postfix -f ${sender} -- ${recipient} И правим одну из первых строчек так, что бы она выглядела следующим образом smtp inet n - n - - smtpd -o content_filter=filter:dummy Перезапускаем postfix и пытаемся отправить письмо самому себе. Если все прошло успешно, то в логах вы должны увидеть строчки, подобные этим: Nov 1 20:19:54 multik postfix/qmgr[7566]: ED4C61662B3: from=<[email protected]>, size=403, nrcpt=1 (queue active) Nov 1 20:19:54 multik drwebd: 127.0.0.1 [7581] /var/drweb/spool/drweb.tmp.2aRNpr - archive MAIL Nov 1 20:19:54 multik drwebd: 127.0.0.1 [7581] /var/drweb/spool/drweb.tmp.2aRNpr - Ok Nov 1 20:19:54 multik drweb-postfix: dwlib: scan[7580]: message(/var/drweb/spool/drweb.tmp.2aRNpr) sent by [email protected] is passed Nov 1 20:19:54 multik postfix/pickup[7565]: BD39E1662B4: uid=503 from=<[email protected]> Как видите, письмо прошло проверку, было признано хорошим и пропущено. Заголовок же письма стал выглядеть вот так Received: by mail.multik.int (Postfix, from userid 503) id BD39E1662B4; Sat, 1 Nov 2003 20:19:54 +0300 (MSK) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by mail.multik.int (Postfix) with SMTP id ED4C61662B3 for <[email protected]>; Sat, 1 Nov 2003 20:19:23 +0300 (MSK) Под таинственным userid 503 как раз и скрывается drweb-postfix. Последнее, что осталось сделать - это автоматический апдейт антивирусных баз. С этим проще всего - благо многое поправили. Находясь в интернете, вы просто выполните прилагающийся скрипт update.pl [root@multik new]# cd /opt/drweb/update/ [root@multik update]# ./update.pl Если ваша машина постоянно подключена к интернету, то просто скопируйте скрипт в /etc/cron.daily и обновления будут автоматически забираться каждые сутки. Если вы заметили, я абсолютно оставил без внимания все фильтры, которые понавтыкали в drweb. Функциональность их на уровне допотопных поделок, да и drweb прежде всего антивирус, а не почтовый фильтр. На этом можно считать, что с drweb'ом покончено в лучших традициях ковбойских вестернов. Не забудьте только купить лицензию. Ибо вдруг появится какой-нибудь хитрый почтовый вирус, который распространяет себя в архивах. В принципе, здесь вы должны получить сервер с той же функциональностью, что и в прошлых рассказах. Но технологии не стоят на месте, поэтому пойдем дальше. Для начала поднимем связку apache+php+ssl. Документации, как сделать это, в интернете большая куча, да и я уже писал об этом, потому здесь я просто кратко все повторю все шаги. Сразу скажу, что я опять забыл скачать mod_ssl в самом начале, поэтому скачал сейчас. [root@multik ispmail]# tar zxvf apache_1.3.29.tar.gz [root@multik ispmail]# cd apache_1.3.29 [root@multik apache_1.3.29]# ./configure [root@multik apache_1.3.29]# cd .. [root@multik ispmail]# tar jxvf php-4.3.3.tar.bz2 [root@multik ispmail]# cd php-4.3.3 [root@multik php-4.3.3]# ./configure --with-apache=../apache_1.3.29 --disable-cgi --enable-safe-mode --with-mysql=/opt/mysql/ --with-mysql-sock=/tmp/mysql.sock [root@multik php-4.3.3]# make [root@multik php-4.3.3]# make install [root@multik php-4.3.3]# cd .. [root@multik ispmail]# tar zxvf mod_ssl-2.8.16-1.3.29.tar.gz [root@multik ispmail]# cd mod_ssl-2.8.16-1.3.29 [root@multik mod_ssl-2.8.16-1.3.29]# ./configure --prefix=/opt/apache/ --with-apache=../apache_1.3.29 --with-ssl=../openssl-0.9.7c --activate-module=src/modules/php4/libphp4.a [root@multik mod_ssl-2.8.16-1.3.29]# cd ../apache_1.3.29 [root@multik apache_1.3.29]# make [root@multik apache_1.3.29]# make certificate TYPE=custom STEP 2: Generating X.509 certificate signing request for CA [ca.csr] Signature Algorithm ((R)SA or (D)SA) [R]: R 1. Country Name (2 letter code) [XY]:RU 2. State or Province Name (full name) [Snake Desert]:Russia 3. Locality Name (eg, city) [Snake Town]:Moscow 4. Organization Name (eg, company) [Snake Oil, Ltd]:multik home 5. Organizational Unit Name (eg, section) [Certificate Authority]: 6. Common Name (eg, CA name) [Snake Oil CA]:multik home 7. Email Address (eg, name@FQDN) [[email protected]]:[email protected] 8. Certificate Validity (days) [365]:1095 STEP 3: Generating X.509 certificate for CA signed by itself [ca.crt] Certificate Version (1 or 3) [3]:3 ----- 1. Country Name (2 letter code) [XY]:RU 2. State or Province Name (full name) [Snake Desert]:Russia 3. Locality Name (eg, city) [Snake Town]:Moscow 4. Organization Name (eg, company) [Snake Oil, Ltd]:multik home 5. Organizational Unit Name (eg, section) [Webserver Team]:multik server 6. Common Name (eg, FQDN) [www.snakeoil.dom]:mail.multik.int 7. Email Address (eg, name@fqdn) [[email protected]]:[email protected] t 8. Certificate Validity (days) [365]:1095 STEP 6: Generating X.509 certificate signed by own CA [server.crt] Certificate Version (1 or 3) [3]:3 Encrypt the private key now? [Y/n]: n conf/ssl.key/server.key The PEM-encoded RSA private key file of the server which you configure with the 'SSLCertificateKeyFile' directive (automatically done when you install via APACI). KEEP THIS FILE PRIVATE! [root@multik apache_1.3.29]# make install Все. У нас стоит апач с уже сгенерированными сертификатами. [root@multik apache_1.3.29]# /opt/apache/bin/apachectl startssl [Sun Nov 2 12:53:48 2003] [alert] httpd: Could not determine the server's fully qualified domain name, using 127.0.0.1 for ServerName /opt/apache/bin/apachectl startssl: httpd started [root@multik apache_1.3.29]# Теперь мы имеем в /opt/apache/conf/ssl.crt публичные ключи нашего сертификационного центра и сервера, а в /opt/apache/conf/ssl.key приватные ключи, разбросанные по ca.* и server.* соответственно. Хотя мы их сгенерировали с помощью инсталляционного скрипта, они ничем не отличаются от тех, которые можно сгенерировать вручную. Что бы не нарушать отчетности, мы будем использовать те же самые сертификаты и для postfix с courier. Зачем? По одной простой причине - в последнее время развелось чересчур много всяких снифферов и прочих страшных штук, которые слушают трафик и вылавливают пароли из проходящего мимо трафика. Ну а чем грозит утечка паролей из открытых протоколов типа smtp и imap, я думаю, вам объяснять не надо. Да и по большому счету фиг с ними, с паролями, мне больше всего не охота как-нибудь узнать, что кто-то еще читает мои письма. Понятное дело, это не страшно, когда я нахожусь дома. А когда я пришел в неизвестное место и мне надо отправить письмо через потенциально опасную сеть? Вот тут-то и пригодится технология SSL. Она закрывает от просмотра http&imap трафик, а в виде TLS она закрывает smtp трафик. smtpd_use_tls = yes smtpd_tls_auth_only = yes smtpd_tls_key_file = /opt/apache/conf/ssl.key/server.key smtpd_tls_cert_file = /opt/apache/conf/ssl.crt/server.crt smtpd_tls_CAfile = /opt/apache/conf/ssl.crt/ca.crt smtpd_tls_loglevel = 3 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s tls_random_source = dev:/dev/urandom [root@multik root]# postfix reload postfix/postfix-script: refreshing the Postfix mail system Посмотрим, что получилось из нашей затеи. [multik@multik multik]$ telnet 127.0.0.1 25 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. 220 mail.multik.int ESMTP Postfix ehlo multik.int 250-mail.multik.int 250-PIPELINING 250-SIZE 10240000 250-ETRN 250-STARTTLS 250-XVERP 250 8BITMIME starttls 220 Ready to start TLS ^] telnet> close Connection closed. Nov 2 13:48:07 multik postfix/smtpd[19796]: starting TLS engine Nov 2 13:48:07 multik postfix/smtpd[19796]: connect from localhost.localdomain[127.0.0.1] Nov 2 13:48:18 multik postfix/smtpd[19796]: setting up TLS connection from localhost.localdomain[127.0.0.1] Nov 2 13:48:18 multik postfix/smtpd[19796]: SSL_accept:before/accept initialization Nov 2 13:48:18 multik postfix/smtpd[19796]: read from 0809B910 [080A9098] (11 bytes => -1 (0xFFFFFFFF)) Nov 2 13:48:18 multik postfix/smtpd[19796]: SSL_accept:error in SSLv2/v3 read client hello A Nov 2 13:48:20 multik postfix/smtpd[19796]: warning: Read failed in network_biopair_interop with errno=0: num_read=0, want_read=11 Nov 2 13:48:20 multik postfix/smtpd[19796]: SSL_accept error from localhost.localdomain[127.0.0.1]: -1 Nov 2 13:48:20 multik postfix/smtpd[19796]: disconnect from localhost.localdomain[127.0.0.1] В общем, весь механизм работает. Теперь начнем глубокую настройку всего хозяйства, что мы тут наваякали. Первым у нас на очереди SASL. Без него никакой авторизации и аунтификации не получится, как ни старайся. Вначале добавим в /etc/postfix/main.cf строку smtp_sasl_security_options = noanonymous Этим мы запретим анонимность пользователей. Администратор должен знать своих героев. Теперь расскажем SASL, где и как искать пароли, когда к нему обратится postfix. [root@multik sasl2]# pwd /usr/lib/sasl2 [root@multik sasl2]# touch smtpd.conf [root@multik sasl2]# cat > smtpd.conf auxprop_plugin: mysql pwcheck_method: auxprop mysql_user: postfix mysql_passwd: postfix mysql_hostnames: localhost mysql_database: mail mysql_statement: select password from aliases where alias='%u@%r' mysql_verbose: yes Последний параметр нужен для того, что бы посмотреть, что происходит во время авторизации. Я создал новый почтовый ящик в mozilla-mail, и указал, что необходима авторизация для отправки почты. Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql auxprop plugin has been requested Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin Parse the username [email protected] Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin try and connect to a host Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin trying to connect to localhost Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin create statement from userPassword multik multik.int Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin doing query select password from aliases where alias='[email protected]' Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin create statement from cmusaslsecretCRAM-MD5 multik multik.int Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin doing query select password from aliases where alias='[email protected]' Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin Parse the username [email protected] Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin try and connect to a hosе Nov 2 14:25:15 multik postfix/smtpd[20233]: mysql plugin trying to connect to localhost Nov 2 14:25:15 multik postfix/smtpd[20233]: starting TLS engine Nov 2 14:25:15 multik postfix/smtpd[20233]: connect from localhost.localdomain[127.0.0.1] Nov 2 14:25:15 multik postfix/smtpd[20233]: 762051662B6: client=localhost.localdomain[127.0.0.1], sasl_method=CRAM-MD5, [email protected] Nov 2 14:25:15 multik postfix/cleanup[20237]: 762051662B6: message-id=<[email protected]> Nov 2 14:25:15 multik postfix/qmgr[20162]: 762051662B6: from=<[email protected]>, size=579, nrcpt=1 (queue active) Nov 2 14:25:15 multik postfix/smtpd[20233]: disconnect from localhost.localdomain[127.0.0.1] Nov 2 14:25:15 multik drwebd: 127.0.0.1 [20249] /var/drweb/spool/drweb.tmp.HwvrF3 - archive MAIL Nov 2 14:25:15 multik drwebd: 127.0.0.1 [20249] /var/drweb/spool/drweb.tmp.HwvrF3/[text:plain] - Ok Nov 2 14:25:15 multik drweb-postfix: dwlib: scan[20247]: message(/var/drweb/spool/drweb.tmp.HwvrF3) sent by [email protected] is passed Nov 2 14:25:15 multik postfix/pickup[20161]: E69251662B7: uid=503 from=<[email protected]> Nov 2 14:25:15 multik postfix/cleanup[20237]: E69251662B7: message-id=<[email protected]> Nov 2 14:25:15 multik postfix/qmgr[20162]: E69251662B7: from=<[email protected]>, size=692, nrcpt=1 (queue active) Nov 2 14:25:15 multik postfix/virtual[20252]: E69251662B7: to=<[email protected]>, relay=virtual, delay=0, status=sent (maildir) Nov 2 14:25:15 multik postfix/pipe[20246]: 762051662B6: to=<[email protected]>, relay=filter, delay=0, status=sent (dummy) Как видно из логов, авторизация для пользователя [email protected] прошла успешно с использованием CRAM-MD5, что уже само по себе хорошо. Теперь скажем mozille, что необходимо использовать SSL и снова попытаемся отправить почту. Mozilla страшно заругается на то, что ей неизвестен центр авторизации, выдавший сертификат и вообще, он выглядит как-то подозрительно. Согласимся с со всем этим и разрешим отправить почту. В логах появится много-много мусора, из которых необходимой для нас является строчки Nov 2 14:31:10 multik postfix/smtpd[20258]: TLS connection established from localhost.localdomain[127.0.0.1]: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits) Nov 2 14:31:10 multik postfix/smtpd[20258]: D86781662B6: client=localhost.localdomain[127.0.0.1], sasl_method=CRAM-MD5, [email protected] Как видим, установилось соединение TLS с разрядностью 256 бит и уже поверх него прошла авторизация по CRAM-MD5. Но одновременно в логах появилось куча ругани про разные ошибки. Это произошло из-за того, что сервер не знает, кто к нему присоединился и не имеет публичного ключа клиента. Согласитесь, что это не наш метод. Надо исправлять это вопиющее беззаконие. Для начала нам необходимо отдать сертификат сервера еще и в бинарном формате. Ну по крайней мере mozilla так захотела. [root@multik ssl.crt]# /usr/local/ssl/bin/openssl x509 -in ca.crt -outform DER -outca.der Теперь в мозилле идем по меню Edit-Preferences-Privacy&Security-Sertificates и давим на кнопочку Manage Certificates. (Простите, но не могу дать вам перевод этих пунктов на русский - у меня нет и никогда не будет русифицированной мозиллы).Затем выберите вкладку Authorities. Будет светиться одна кнопочка - Import. Надавите на нее и выберите созданный выше ca.der. Вылезет окошко Downloading Certificate. В нем будет предложено посмотреть на тот сертификат, который мы закачиваем и выбрать, для каких целей его можно использовать. Я выбрал два пункта - для web и email. После нажатия на кнопоку ok я увидел в самом конце списка новый центр сертификации - multik home (Software Security Device). Все, теперь mozilla знает про такой центр сертификации. Если вы все сделали правильно, то теперь при заходе на созданный веб-сервер вы не будете получать предупреждения, что сертификат подписан неизвестно кем. Да и ругань на сертификаты при отправке почты так же должна исчезнуть. Теперь создадим сертификат для пользователя [root@multik root]# mkdir user [root@multik root]# cd user [root@multik user]# /usr/local/ssl/bin/openssl genrsa -des3 -out user.key 512 Generating RSA private key, 512 bit long modulus ...++++++++++++ ..............................++++++++++++ e is 65537 (0x10001) Enter pass phrase for user.key: Verifying - Enter pass phrase for user.key: Создадим запрос на подписание [root@multik user]# /usr/local/ssl/bin/openssl req -new -key user.key -out user.csr .... Country Name (2 letter code) [AU]:RU string is too long, it needs to be less than 2 bytes long Country Name (2 letter code) [AU]:RU State or Province Name (full name) [Some-State]:Russia Locality Name (eg, city) []:Moscow Organization Name (eg, company) [Internet Widgits Pty Ltd]:Viacheslav Kaloshin Organizational Unit Name (eg, section) []:notebook Common Name (eg, YOUR name) []:Viacheslav Kaloshin Email Address []:[email protected] И подпишем его подписью центра [root@multik user]# /usr/local/ssl/bin/openssl x509 -req -in user.csr -out user.crt -CA /opt/apache/conf/ssl.crt/ca.crt -CAkey /opt/apache/conf/ssl.key/ca.key -CAcreateserial -days 365 Signature ok subject=/C=RU/ST=Russia/L=Moscow/O=Viacheslav Kaloshin/OU=notebook/CN=Viacheslav Kaloshin/[email protected] Getting CA Private Key И теперь проэкспортируем подписанный сертификат в формат PKCS#12, понятный большинству программ. [root@multik user]# /usr/local/ssl/bin/openssl pkcs12 -export -in user.crt -inkey user.key -out user.p12 Enter pass phrase for user.key: Enter Export Password: Verifying - Enter Export Password: В итоге мы получили user.crt - публичный сертификат пользователя. Его всяко-разно можно выкладывать на web, отдавать другим пользователям и распространять как можно более широко. В user.key лежит приватный ключ. Его нельзя никому давать и показывать. И в user.p12 лежит все в куче, только в формате PKCS#12. Теперь делаем все тоже самое, что и с сертификатом центра, только на вкладке Your Certificates. Mozilla должна сообщить, что восстановление сертификата произошло успешно. Но если мы поглядим в заголовки отправленных писем, то увидим следующие строчки Received: from multik.int (localhost.localdomain [127.0.0.1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) То есть получатель письма не сможет удостовериться, что это письмо отправили именно мы. То, что с использованием TLS - да. Но вот что конкретно мы - нет. Непорядок. Добавляем следующие строчки в main.cf smtpd_tls_loglevel = 1 smtpd_tls_ask_ccert = yes relay_clientcerts = hash:/etc/postfix/relay_clientcerts Это резко уменьшит объем информации в логах и заставит postfix требовать сертификаты от клиента. Последняя строчка укажет, где смотреть отпечатки пользовательских сертификатов. Теперь можем поправить следующий параметр smtpd_recipient_restrictions = ... permit_tls_clientcerts Он даст разрешение на прием почты от клиентов, которые только имеют сертификат. То есть авторизация по логину-паролю будет желательна, но не обязательна. Теперь снимем отпечаток с пользовательского сертификата [root@multik user]# /usr/local/ssl/bin/openssl x509 -fingerprint -in user.crt MD5 Fingerprint=92:C1:A2:4F:F0:D6:57:4D:F5:70:56:BF:C3:C5:00:99 -----BEGIN CERTIFICATE----- MIICajCCAdMCAQIwDQYJKoZIhvcNAQEEBQAwgZ0xCzAJBgNVBAYTAlJVMQ8wDQYD .... Нам нужны цифры, разграниченные двоеточиями. Их просто записываем в файл /etc/postfix/relay_clientcerts [root@multik postfix]# cat relay_clientcerts 92:C1:A2:4F:F0:D6:57:4D:F5:70:56:BF:C3:C5:00:99 multik notebook После отпечатка можете написать что угодно - это только для вашей информации. Теперь создадим таблицу хэшей отпечатков и перезапустив postfix, будем проверять, что получилось [root@multik postfix]# postmap relay_clientcerts Отправляем письмо и смотрим в логи. Nov 2 16:42:18 multik postfix/smtpd[21011]: setting up TLS connection from localhost.localdomain[127.0.0.1] Nov 2 16:42:18 multik postfix/smtpd[21011]: fingerprint=92:C1:A2:4F:F0:D6:57:4D:F5:70:56:BF:C3:C5:00:99 Nov 2 16:42:18 multik postfix/smtpd[21011]: Verified: subject_CN=Viacheslav Kaloshin, issuer=multik home Nov 2 16:42:18 multik postfix/smtpd[21011]: TLS connection established from localhost.localdomain[127.0.0.1]: TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits) Nov 2 16:42:18 multik postfix/smtpd[21011]: 7A3041662BA: client=localhost.localdomain[127.0.0.1], sasl_method=CRAM-MD5, [email protected] Как видим, в логах появилось, что сертификат проверен. В заголовках полученного письма информация так же изменилась Received: from multik.int (localhost.localdomain [127.0.0.1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "Viacheslav Kaloshin", Issuer "multik home" (verified OK)) Теперь читатель письма может быть уверен, что в связке отправитель-сервер не было никого лишнего и письмо никем не было прочитано. Последний штрих - поправим /etc/postfix/master.cf так, что бы письма, приходящие по TLS, так же подвергались проверке drweb'ом. smtps inet n - n - - smtpd -o content_filter=filter:dummy Можете перезапустить postfix и считать на этом его настройку законченной. Теперь дело за imap-over-ssl. Почему не pop? Потому что гораздо проще купить еще один винт и загнать всех пользователей под IMAP, чем каждый раз архивировать их непонятно где и как хранящиеся ящики. Но если хотите pop3-over-ssl - без проблем. Он настраивается абсолютно так же. Идем в каталог /usr/lib/courier-imap/etc и смотрим на файл под названием imapd-ssl. Правим, то, что не понравится. Мне в общем, все понравилось. Теперь копируем user.crt в /usr/local/ssl/certs как [email protected]. Пусть все сертификаты лежат там. А имя я выбрал, что бы в дальнейшем не запутаться. [root@multik root]# /usr/lib/courier-imap/libexec/imapd-ssl.rc start [root@multik root]# netstat -npl|grep 993 tcp 0 0 0.0.0.0:993 0.0.0.0:* LISTEN 21314/couriertcpd Однако как только мы попробуем соединиться с сервером, мы тут же получим в логах. Nov 2 17:33:00 multik imapd-ssl: /usr/lib/courier-imap/bin/couriertls: No such file or directory Ну, при сборке courier-imap я как-то упустил из виду, что SSL тоже необходим. Исправляем ошибку, пересобрав его. [root@multik root]# cd /usr/src/ispmail/courier-imap-2.2.0 [root@multik courier-imap-2.2.0]# su - courier [courier@multik courier]$ cd /usr/src/ispmail/courier-imap-2.2.0 [courier@multik courier-imap-2.2.0]$ make clean [courier@multik courier-imap-2.2.0]$ export CPPFLAGS=-I/usr/local/ssl/include/ [courier@multik courier-imap-2.2.0]$ export LDFLAGS='-L/usr/local/ssl/lib' [courier@multik courier-imap-2.2.0]$ set|grep FL CPPFLAGS=-I/usr/local/ssl/include/ LDFLAGS=-L/usr/local/ssl/lib [courier@multik courier-imap-2.2.0]$ ./configure --enable-unicode --with-redhat --with-mysql-libs=/opt/mysql/lib/mysql --with-mysql-includes=/opt/mysql/include/mysql [courier@multik courier-imap-2.2.0]$ make [courier@multik courier-imap-2.2.0]$ exit [root@multik courier-imap-2.2.0]# make install-strip [root@multik courier-imap-2.2.0]# make install-configure Проверим, появился ли нужный файл. [root@multik root]# ls -l /usr/lib/courier-imap/bin/couriertls -rwxr-xr-x 1 root root 53168 Nov 2 18:36 /usr/lib/courier-imap/bin/couriertls Теперь запустим /usr/lib/courier-imap/share/mkimapdcert и подождем, пока он сгенерирует ключ. Этот ключ будет совершенно неправильным, но нам сейчас важно убедиться, что все в порядке. Попробуем соединиться с сервером. Mozilla сругнется на неизвестный сертификат, но почту проверит. Nov 2 19:01:02 multik imapd-ssl: LOGIN, [email protected], ip=[::ffff:127.0.0.1], protocol=IMAP Теперь сделаем сертификат известным. Заменим его своим. Просто скопируйте приватный и публичный ключи в один файл. [root@multik root]# cp /opt/apache/conf/ssl.key/server.key /usr/lib/courier-imap/share/imapd.pem cp: overwrite `/usr/lib/courier-imap/share/imapd.pem'? y [root@multik root]# cat /opt/apache/conf/ssl.crt/server.crt >> /usr/lib/courier-imap/share/imapd.pem Если хотите получить вообще абсолютно тот же по функционалу файл, то можете дополнительно выполнить следующие команды. Хотя я разницы не заметил. dd if=/dev/urandom of=/usr/lib/courier-imap/share/imapd.rand count=1 \ /usr/local/ssl/bin/openssl gendh -rand /usr/lib/courier-imap/share/imapd.rand 512 \ >>/usr/lib/courier-imap/share/imapd.pe /usr/local/ssl/bin/openssl x509 -subject -dates -fingerprint -noout -in \ /usr/lib/courier-imap/share/imapd.pem Делаем маленький скриптик, который все это дело будет запускать-останавливать и запускаем его. [root@multik root]# chkconfig --add mail [root@multik root]# chkconfig mail on [root@multik root]# chkconfig --list mail mail 0:off 1:off 2:on 3:on 4:on 5:on 6:off Теперь поправим imapd-ssl IMAP_TLS_REQUIRED=1 TLS_TRUSTCERTS=/usr/local/ssl/certs/ TLS_VERIFYPEER=PEER Когда попробуем соединиться, получим ошибку. Nov 2 19:35:27 multik imapd-ssl: couriertls: connect: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned Вспомним о том, что сертификат пользователя мы положили не просто так и обновим ссылки. [root@multik root]# /usr/local/ssl/bin/c_rehash Doing /usr/local/ssl/certs [email protected] [email protected] => 2dd0a886.0 После этого попытаемся снова присоедениться. Ошибка исчезла и в логах радующая глаз чистота. Однако, если мы попробуем поменять строчку на TLS_VERIFYPEER=REQUIREPEER То в логах получим следующую ошибку Nov 2 19:46:06 multik imapd-ssl: couriertls: accept: error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate Как я понял из объяснений и описаний, эта опция предназначена для серверов (?). В общем, как я не бился, пользовательский сертификат система видеть отказывалась. Ну не получился очень защищенный канал. Получился обычный SSL. Что тоже неплохо. Закончив разбираться с почтовой частью, обратим внимание на веб-сервер. Добавляем в apachectl следующие строки # chkconfig: 2345 95 25 # description: Apache. Правим, что бы веб-сервер по умолчанию запускался с SSL и записываем под именем apache в /etc/init.d. Затем повторяем процедуру включения автозапуска. [root@multik root]# chkconfig --add apache [root@multik root]# chkconfig apache on [root@multik root]# chkconfig --list apache apache 0:off 1:off 2:on 3:on 4:on 5:on 6:off Теперь разворачиваем SquirrelMail [root@multik ispmail]# tar jxvf squirrelmail-1.4.2.tar.bz2 Копируем его в каталог htdocs апача и конфигурируем [root@multik htdocs]# chown nobody.nobody data [root@multik htdocs]# ./Configure Для <белкомайла> необходим чистый imap, поэтому придеться включить во все инициализационные скрипты команду его запуска. /usr/lib/courier-imap/libexec/imapd.rc start Конфигурируется он легко, работает то же без проблем, поэтому мне как-то и описывать тут нечего. Вот, в общем-то, и все. Система работает, теперь ваша задача пройтись по всем конфигурационным файлам и окончательно донастроить систему. Но тут уже у каждого свои задачи, поэтому на этом месте я заканчиваю. На всякий случай я собрал все файлы, которые я редактировал, в одном месте и выложил. Думаю, для многих это будет большим подспорьем - достаточно будет раскидать файлы по нужным местам. Удачи. © 2003 Viacheslav "multik" Kaloshin <[email protected]>

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

Обсуждение [ RSS ]
  • 1, den (??), 14:51, 13/10/2005 [ответить]  
  • +/
    А пароли пользователей на поту которые хранятся в базе  mysql они просто записаны в формате plain text ?
     
     
  • 2, Nightv (?), 14:27, 19/12/2005 [^] [^^] [^^^] [ответить]  
  • +/
    > А пароли пользователей на поту которые хранятся в базе  mysql
    >они просто записаны в формате plain text ?
    >


    похоже что так :(
    я пару часов назад закончил зборку по этой статье (поимел гемора немного из-за разницы в версиях софта, которые были на момент написания статьи и то что есть сейчас)
    и вот как-раз сейчас думаю от этом вопросе.... "как зашифровать пароли?"

    Кто просвещен в этом вопросе, не сочтите за труд... помогите советом, хотябы в какую сторону копать.. (а то сам я себе кроме как могилу ничего не вырою :))

     
     
  • 3, NetMax (?), 06:51, 04/01/2006 [^] [^^] [^^^] [ответить]  
  • +/
    Они записаны в md5 по карйней мере у меня.
     

    игнорирование участников | лог модерирования

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру