Ключевые слова:mail, postfix, spam, imap, virus, spamassassin, (найти похожие документы)
From: Sergey Levashev (aka Chek) <chek@alt.ru.>
Newsgroups: email
Date: Mon, 20 Oct 2005 14:31:37 +0000 (UTC)
Subject: Установка и настройка почтовой системы на базе Posfix
Posfix + PostgreSQL + Courier-Authlib + Courier-Imap + SqWebMail +
Maildrop + ClamAV + SpamAssassin + AWStats.
Вторая редакция. В которой Винни-пух... зачитался. В которой я
постараюсь учесть все спасибы, замечания и конструктивную критику
читателей.
- Postfix (http://postfix.org) - MTA
- PostgreSQL (http://postgresql.org) - БД
- Courier-Authlib (http://www.courier-mta.org) - Демон и библиотека аутентификации
- Courier-Imap (тамже) - IMAP и POP демон
- Maildrop (тамже) - MDA
- SqWebMail (тамже) - Веб-интерфейс для работы с почтовыми ящиками
- ClamAV (http://www.clamav.net/) - Фриварный антивирус
- SpamAssassin (http://spamassassin.apache.org/) - Убийца и маркировщик спама
- AWStats (http://awstats.sourceforge.net/) - Генератор статистики.
Преамбула
После двух недель блуждания по далёким серверам и надоедания гуглу
вопросом как связать постгрю с сендмейлом без перестройки формата базы я
нашел патчик для связки с базой. http://blue-labs.org/software/sm-pgsql/
Принцип работы не понравился.
Это было тогда, а сейчас есть сервер на базе postfix'a с довольно таки
разросшейся базой пользователей, соответственно и возросшимся потоком
спама. Я уже было начал материться благим матом, но потом вспомнил про
такой замечательный сайт www.faqs.org который ни раз меня выручал ибо
там можно покурить замечательные маны, которые из-за содержания
тетраэрфэцэола называют RFC.
Помимо RFC 822, который многние горе-админы забывают читать, там есть
RFC 1123 (очень полезный документ) и 2505. Последний должен быть более
интересен администраторам небольших компаний т.к. на крупных серверах
идёт большой поток деловой корреспонденции с криво настроенных серверов.
Я долго матерился, когда посмотрел что у меня помимо спама начало
зарезаться на сервере.
Например, сервер одной туристической фирмы (не будем называть его имени)
в хело мне выдал domain.tld, после чего был успешно послан по старой
дороге.
В прошлой статье я специально не привязывал процесс установки ПО к
платформам, ссылаясь на документацию.
Объясняю почему так. Мне неприятно читать статьи по типу "Ставим ЭТО на
ЭТО (версия прилагается)".
Особенно когда ещё приводятся скрипты под эту платформу. Бросаешь это
чтиво и начинаешь изучать INSTALL и README,который есть в любой софтине.
Администратор всёравно знает как ставить софт на администрируемую им
платформу, поэтому чтоб не толочь воду в ступе лучше описать подводные
камни, которые обязательно встретятся. Это моё мнение, я не хочу
огорчить, расстроить или оскорбить авторов таких статей.
И всё же. Весь перечисленный софт есть в rpm, портежах Генты и портах
FreeBSD за исключением AWStats. Я бы был признателен администраторам,
которые приведут startup скрипты и замечания по установке для платформ
на которые нет собранных пакетов вышеперечисленного ПО.
Итак, постараемся исправить сложившуюся ситуацию и описать процесс
установки с нуля.
Что нам нужно.
Для начала надо завести на ДНСе запись типа A с именем нашего будущего
сервера и указываем в нашем домене MX на наш будущий почтовый сервер.
Потом добавляем в обратную зону PTR на наше имя. Обязательно к
исполнению и обжалованию не подлежит, если не хотим проблем с отправкой
почты на другие сервера.
Устанавливаем PostgreSQL, заводим пользователя, разрешаем ему стучаться
в базу. Если сложно читать документацию, постовляемую с посгрей -
воспользуйтесь поиском.
Кратко от FDS:
# su postgres
bash-3.00$ createuser test
Разрешить новому пользователю создавать базы? (y/n) n
Разрешить новому пользователю создавать пользователей? (y/n) n
CREATE USER
bash-3.00$ createdb postfix
CREATE DATABASE
bash-3.00$
bash-3.00$ psql postfix
Добро пожаловать в psql 7.4.8 - Интерактивный Терминал PostgreSQL.
Наберите: \copyright для условий распространения
\h для подсказки по SQL командам
\? для подсказки по внутренним slash-командам (\команда)
\g или ";" для завершения и выполнения запроса
\q для выхода
postfix=#grant all on database postfix to test;
GRANT
postfix=#\q
летим в каталог /var/lib/pgsql/data/pg_hda.conf
пишем
host postfix test 10.0.0.1/32 trust
где 10.0.0.1 это ip mail server-а
Собственно о формате БД. Для virtual_mailbox_maps нужно два поля: имени
пользователя с доменом и пути до ящика. При использовании maildrop,
который использует courier-authlib для получения пути до ящика, второе
поле необязательно. Для courier-authlib нужно имя пользователя, пароль
(открытый или хэшированный в MD5), путь до ящика, владельца и группу
владельца ящика, квоту, полное имя пользователя, дополнительные
параметры, которые указываются через запятую в одном поле.
По поводу квоты. Это очень призрачный параметр у курьера. Смысла его
использования я до сих пор не понял т.к. почта всё равно принимается
MTA.
Параметрам main.cf postfix'a virtual_uid_maps и virtual_gid_maps,
которые отвечают за владельца и группу почтовых ящиков, мы установим
статическое значение - uid и gid пользователя vmail, которого надо
завести на системе. Соответственно теже значения должны отдаваться
courir-authlib'у.
Для примера возмём таблицу mailusers на БД mail:
login varchar(50) unique, pass varchar(50), path varchar(100), fullname varchar(50)
login - имя пользователя с доменом, pass - некриптованый пароль, path - путь до ящика,
fullname - полное имя пользователя.
Этого хватит. Остальное мы зададим в запросе.
Устанавливаем Courier-Authlib и модуль для работы с постгресом. Для
rpm-based - courier-authlib и courier-authlib-pgsql.
В /etc/authlib/authdaemonrc пишем:
authmodulelist="authpgsql"
daemons=5
DEBUG_LOGIN=0
DEFAULTOPTIONS=""
В /etc/authlib/authpgsqlrc пишем:
PGSQL_HOST хост.где.находится.база
PGSQL_PORT 5432
PGSQL_USERNAME имя
PGSQL_PASSWORD пароль
PGSQL_DATABASE база данных с пользователями и их паролями
PGSQL_SELECT_CLAUSE SELECT login as username,'' as cryptpw, \
pass as clearpw,506 as uid, \
506 as gid,'/mailboxes/'||substring(c.login from 1 for 1)||'/'||c.login as home,\
'' as maildir, \
30 as quota,fullname, \
'disableimap' as options \
where login = '$(local_part)'||'@'||'$(domain)';
#'/mailboxes/'||substring(c.login from 1 for 1)||'/'||c.login as home -- пользовательские ящики с путями /mailboxes/первая_буква_логина/логин
# просто мне так больше нравится.
#gid 506 и uid 506 - пользователь vmail, которому будет принадлежать вся почта
Читаем документацию. Запускаем.
Затем устанавливаем Courier-Imap и Maildrop.
в /etc/maildroprc пишем:
`test -f $HOME/.mailfilter`
if ( $RETURNCODE == 0 )
{
include '.mailfilter'
if ( $QUIT )
REASON="users's filter"
}
to 'Maildir/.'
Это нужно для того, чтобы в директории ящика пользователя при
необходимости можно было создать индивидуальные правила в файлике
.mailfilter
Устанавливаем SpamAssassin 3.1.0
Читаем документацию, устанавливаем все необходимые перловые модули и DCC.
Razor2 не является открытым - не используем.
Если нет startup скрипта, можете воспользоваться нижеприведённым
spamd.rc
#!/bin/sh
case "$1" in
start)
spamd -d -u clamav -m 7 -x '--virtual-config-dir=/mailboxes_conf/%u' --max-conn-per-child=5 -r /home/clamav/spamd.pid
;;
stop)
kill `cat /home/clamav/spamd.pid`
;;
restart)
$0 stop
$0 start
;;
esac
--virtual-config-dir=/mailboxes_conf/%u используется для создания
индивидуальных настроек. spamd будет работать от пользователя clamav.
Подробности в документации.
Правим файлы /etc/mail/spamassassin/v310.pre и init.pre на свой вкус и
цвет. Ниже приведу свои настройки.
init.pre
loadplugin Mail::SpamAssassin::Plugin::RelayCountry
loadplugin Mail::SpamAssassin::Plugin::URIDNSBL
loadplugin Mail::SpamAssassin::Plugin::Hashcash
v310.pre
loadplugin Mail::SpamAssassin::Plugin::DCC
loadplugin Mail::SpamAssassin::Plugin::AutoLearnThreshold
loadplugin Mail::SpamAssassin::Plugin::WhiteListSubject
loadplugin Mail::SpamAssassin::Plugin::DomainKeys
loadplugin Mail::SpamAssassin::Plugin::MIMEHeader
loadplugin Mail::SpamAssassin::Plugin::ReplaceTags
В local.cf находятся настройки по выставлению баллов, "белые" листы и
всё остальное, что влияет на определение спама.
Приведу свои настройки.
report_contact [email protected]
rewrite_subject 1
report_safe 0
whitelist_from *@otherdomain.ru ............
trusted_networks xxx.xxx.xxx
lang ru
ok_languages ru en
ok_locales ru en
rewrite_header Subject SPAM(_SCORE_)
bayes_path /etc/mail/spamassassin/bayes
bayes_auto_learn 0
bayes_min_ham_num 10
bayes_min_spam_num 10
auto_learn 0
use_auto_whitelist 0
use_razor2 1
use_dcc 1
skip_rbl_checks 1
score FROM_ILLEGAL_CHARS 0.5
score HEAD_ILLEGAL_CHARS 0.5
score SUBJ_ILLEGAL_CHARS 1.0
score HTML_FONTCOLOR_RED 3.0
score MIME_HTML_ONLY 2.0
score HTML_FONT_BIG 1.5
score BAYES_99 3
score RCVD_IN_NJABL_DUL 5.5
score URIBL_SBL 3
score RCVD_IN_SORBS_DUL 6.2
score RCVD_IN_XBL 8.1
score DNS_FROM_AHBL_RHSBL 8.1
score RAZOR2_CHECK 8.7
score DNS_FROM_RFC_ABUSE 6.5
required_hits 7
Потом подсовываем sa-learn писем 300-400 spam'a и 300-400 ham'a.
Подробности по [[code]]sa-learn --help[[/code]] Если попалась
корреспонденция в idx (формат аутлука), то в mailbox можно перегнать
перловым скриптом mbx2mbox (ищем в гугле).
В данной конфигурации проскакивает 3% спама на мой ящик, жалоб от
пользователей не было.
ClamAV
Заводим пользователя clamav, создаём директорию /var/clamav/{log,tmp} и
назначаем владельцем clamav Читаем документацию. Думаем. Устанавливаем.
Правим /usr/local/etc/clamd.conf:
LogFile /var/clamav/clamav.log
LogFileMaxSize 2M
LogTime
LogClean
LogSyslog
LogFacility LOG_MAIL
LogVerbose
PidFile /var/clamav/clamd.pid
TemporaryDirectory /var/clamav/tmp
DatabaseDirectory /var/clamav
LocalSocket /var/clamav/clamd.sock
FixStaleSocket
MaxConnectionQueueLength 30
StreamMaxLength 400k
MaxThreads 100
IdleTimeout 5
SelfCheck 100
User clamav
ScanHTML
ScanArchive
ScanRAR
ArchiveMaxFileSize 400k
startup скрипт clamd
#!/bin/sh
case "$1" in
start)
/usr/local/sbin/clamd
;;
stop)
# kill `cat /var/clamav/clmilter.pid`
;;
restart)
$0 stop
sleep 2
$0 start
;;
esac
Правим /usr/local/etc/freshclam.conf:
DatabaseDirectory /var/clamav
UpdateLogFile /var/clamav/freshclam.log
PidFile /var/clamav/freshclam.pid
DatabaseOwner clamav
DatabaseMirror database.clamav.net
Checks 24
startup скрипт freshclamd
#!/bin/sh
case "$1" in
start)
/usr/local/bin/freshclam -d
;;
stop)
kill `cat /var/clamav/freshclam.pid`
;;
restart)
$0 stop
$0 start
;;
esac
Переходим к самому интересному.
Postfix
Читаем документацию, из неё видим:
For example:
% make tidy
% make -f Makefile.init makefiles \
'CCARGS=-DHAS_PGSQL -I/usr/local/include/pgsql' \
'AUXLIBS=-L/usr/local/lib -lpq'
Then just run 'make'.
собираем, устанавливаем. Заводим пользователя vmail. О том как связать
postfix и clamav через clamsmtpd читаем
http://www.nixp.ru/cgi-bin/go.pl?q=articles;a=clamav_postfix
конфигурация clamsmtpd.conf
OutAddress: 10026
Listen: 127.0.0.1:10025
ClamAddress: /var/clamav/clamd.sock
TempDirectory: /tmp
User: clamav
В /etc/postfix/access разрешаем хостам отправлять почту через нас
Перенаправляем всю почту на наш хост в виртуал, правим /etc/postfix/transport:
то.что.указано.в.myhostname virtual:
Опять же мне так больше нравится. Теперь нет локальных пользователей.
Не забудем поправить myorigin на наш домен.
В /etc/postfix/virtual у нас теперь алиасы виртуальных пользователей,
alias_maps и alias_database не возымеют над виртуальными пользователями
никакой власти, а локальных у нас теперь нет.
/etc/postfix/main.cf:
soft_bounce=no
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
mail_owner = postfix
myhostname = сервер.домен.ru
inet_interfaces = all
myorigin = домен.ru
mydestination = $myhostname
mynetworks = hash:/etc/postfix/access, cidr:/etc/postfix/access.cidr
#cidr нужен чтоб разрешать сети по маскам так как в хеше это невозможно
mynetworks_style = subnet
in_flow_delay = 1s
content_filter = scan:127.0.0.1:10025
receive_override_options = no_address_mappings
#Про это мы уже где-то читали...
smtpd_client_restrictions =
check_client_access hash:/etc/postfix/access,
permit_mynetworks,
# reject_unknown_client, я уже писал выше про кривую настройку некоторых серверов, поэтому не используем
reject_rhsbl_client sbl-xbl.spamhaus.org,
reject_rhsbl_client bl.spamcop.net,
reject_rhsbl_client combined.njabl.org,
reject_rbl_client sbl-xbl.spamhaus.org,
reject_rbl_client bl.spamcop.net,
reject_rbl_client combined.njabl.org,
check_client_access regexp:/etc/postfix/client_check.pcre
smtpd_helo_restrictions =
permit_mynetworks,
reject_non_fqdn_hostname,
reject_invalid_hostname
smtpd_sender_restrictions =
permit_mynetworks,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
reject_rhsbl_sender bl.spamcop.net,
reject_rhsbl_sender combined.njabl.org,
reject_rhsbl_sender sbl-xbl.spamhaus.org
smtpd_recipient_restrictions =
check_recipient_access hash:/etc/postfix/disabled_users,
check_recipient_access hash:/etc/postfix/access,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
permit_mynetworks,
reject_unlisted_recipient,
reject_unauth_destination
smtpd_etrn_restrictions =
check_etrn_access hash:/etc/postfix/access,
reject
smtpd_delay_reject = yes
bounce_size_limit = 10000
max_use = 10
smtpd_helo_required = yes
maildrop_destination_recipient_limit = 1
smtpd_recipient_limit = 30
smtpd_client_message_rate_limit = 0
smtpd_client_connection_count_limit = 0
virtual_alias_maps = hash:/etc/postfix/virtual
transport_maps = hash:/etc/postfix/transport
virtual_mailbox_domains = тут пару-тройку наших доменов, исключая mydestination
virtual_mailbox_base = /mailboxes
virtual_transport = maildrop
virtual_mailbox_maps = pgsql:/etc/postfix/mailbox.pgsql
virtual_uid_maps = static:506
#пользователь vmail
default_process_limit = 200
virtual_gid_maps = static:506
virtual_mailbox_limit = 51200000
#с maildrop не работает
#пока не нашел универсальное решение проблемы размера ящика
message_size_limit = 5120000
disable_vrfy_command = yes
bounce_queue_lifetime = 5d
alias_maps = hash:/etc/postfix/aliases
alias_database = hash:/etc/postfix/aliases
Теперь подробнее о файлах /etc/postfix/mailbox.pgsql и
/etc/postfix/client_check.pcre В /etc/postfix/mailbox.pgsql мы указываем
посфиксу каким макаром искать пользователя в БД
hosts = адрес машины с БД
user = владелец БД
password = соответственно пароль
dbname = mail #то, что приводили для примера
query = SELECT substring(c.login from 1 for 1)||'/'||c.login||'/Maildir/' from mailusers where login = '%u'||'@'||'%d';
Таким образом наличие пути говорит о наличии ящика на сервере.
В /etc/postfix/client_check.pcre зафильтруем всякие adsl'и и диалапы с
кабельным ТВ откуда не идёт ничего хорошего (исходный вариант нашел на
опеннете)
/(modem|dia(l|lup)|dialin|dsl|p[cp]p|cable|catv|poo(l|les)|dhcp|client|customer|user|[0-9]{6,})(-|\.|[0-9])/ 550 Are you spamer?
/([0-9]{,4}\-[0-9]{,4}\-[0-9]{,4}\-[0-9]{,4})/ 550 Are you spamer?
/([0-9]{,4}\.[0-9]{,4}\.[0-9]{,4}\.[0-9]{,4}.{4,})/ 550 Are you spamer? If you think that the system is mistaken, please report details to [email protected]
Т.к. maildrop не умеет автоматом создавать директорию ящика, придётся его этому обучить.
В master.cf правим:
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
на
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/etc/postfix/test -d ${recipient}
/etc/postfix/test
#!/bin/bash
if ! test -d /mailboxes/${2:0:1}/$2; then
mkdir /mailboxes/${2:0:1}/$2 && /usr/local/bin/maildirmake /mailboxes/${2:0:1}/$2/Maildir ;
fi
/usr/local/bin/maildrop $@
exit $?
делаем его исполняемым
Выполняем
mkdir /mailboxes/{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z} && chown vmail.vmail -R /mailboxes
SpamAssassin можно теперь сделать индивидуально или глобально, также
пользователи могут иметь свои white и black листы (читаем документацию)
для глобальной проверки почты spamassassin'om в /etc/maildroprc
Добавляем в начало:
if ( $SIZE < 256000 ) # Filter if message is less than 250k
{
log " running message through spamc"
exception {
xfilter '/usr/bin/spamc -u $LOGNAME'
}
}
#Если хотим, чтобы спам зарезался на месте:
if ( /^X-Spam-Status: *Yes/)
{
to "/dev/null"
}
Для проверки индивидуально - делаем тоже самое в файле
/mailboxes/firs_char_of_user/user/.maildroprc Если хотим сделать
красивее, то создаём файлик /mailboxes/scheck, в него пишем:
if ( $SIZE < 256000 ) # Filter if message is less than 250k
{
log " running message through spamc"
exception {
xfilter '/usr/bin/spamc -u $LOGNAME'
}
}
Создаём файлик /mailboxes/sdrop:
if ( /^X-Spam-Status: *Yes/)
{
to "/dev/null"
}
И теперь .maildroprc будет выглядеть:
#для проверки
include '/mailboxes/scheck'
#для удаления спама
include '/mailboxes/sdrop'
Для первого раза чтобы проверить свой почтовый ящик, нужно сначало
отправить себе письмо.
Об AWStats
Вобщем, он доступен в rpm. С ним идёт вся необходимая документация.
Об SqWebMail
Ставится с полпинка. Есть русский перевод, искать в гугле.
На последок.
Читаем RFC 822, 2505.
Буду признателен за замечания, добавления и исправления.
Месяц -- не срок. Поверь мне, бывает. У немцев часто бывает. крупная контора, ОченьКрупняКонтора, и тем не менее адрес их почтового кэйта 333-333-333-333-mailgate.big-gmbh.de. и достучаться чтобы отправит абъюз они не смогут. Как вариант завести на провайдере алиас для этих целей.
да, действительно попалось одно..... и второе, что не есть хорошо
решение свелось к удалению этой фильтрации и создание проверки на существование отправителя. И заработало не хуже =) Полтора месяца - полёт нормальный.
Вчера поставил проверку SPF. Дней через несколько выложу новую редакцию статьи.
Как-то странно. В начале ссылка на RFC. Хорошо. Высокий клас. Стандарт. Не нравятся ламеры. Согласились - зачем тогда детализация статьи ?
> Oъясняю почему так. Мне неприятно читать
> статьи по типу "Ставим ЭТО на
> ЭТО (версия прилагается)".
Зачем тогда раздел "Что нам нужно." - админ и так знает все что нужно. Там идет детализация что такое IN A - не для ламеров ли ?
Если уже такого класса текст - то снизойди до одного уровна - дай ПРИМЕРЫ ВСЕХ ФАЙЛОВ КОНФИГУРАЦИИ MTA В ПОЛНОМ СООТВЕТСТВИИ С RFC 2505 (rfc2505) - Anti-Spam Recommendations for SMTP MTAs. Пялить пальцы можно долго и упорно. Толку с этого - ноль.
>Как-то странно. В начале ссылка на RFC. Хорошо. Высокий клас. Стандарт. Не нравятся ламеры. Согласились - зачем тогда детализация статьи ?
Тебе оно мешает? Под дулом автомата заставили читать?
>Если уже такого класса текст - то снизойди до одного уровна - дай ПРИМЕРЫ ВСЕХ ФАЙЛОВ КОНФИГУРАЦИИ MTA В ПОЛНОМ СООТВЕТСТВИИ С RFC 2505 (rfc2505) - Anti-Spam Recommendations for SMTP MTAs.
Читай вступление глазами.
Можешь лучше? Действуй!!
Пробовал на Debian linux.
Стоит postgresql 8.0.4.
Нужно править конфиг (возможно, и для 7-й версии).
в authpgsqlrc нет отношения c - добавить
'disableimap' as options \
from mailusers c \
where login = '$(local_part)'||'@'||'$(domain)';
В /etc/postfix/mailbox.pgsql
Поправить отношение c. Т.е. должно быть:
query = SELECT substring(c.login from 1 for 1)||'/'||c.login||'/Maildir/' from mailusers c where login = '%u'||'@'||'%d';
postfix=> SELECT login as username,'' as cryptpw,pass as clearpw,506 as uid,506 as gid,'/mailboxes/'||substring(c.login from 1 for 1)||'/'||c.login as home,'' as maildir,30 as quota,fullname,'disableimap' as options from mailusers c where login = 'vvvua'||'@'||'mydomain.ltd';
username | cryptpw | clearpw | uid | gid | home | maildir | quota | fullname | options
------------------------+---------+-----------+-----+-----+-------------------------------------+---------+-------+----------+-------------
vvvua@mydomain.ltd | | testpass | 506 | 506 | /mailboxes/v/vvvua@mydomain.ltd | |
30 | VS | disableimap
(1 запись)
моя ошибка
у меня выборка из двух таблиц идёт, когда переписывал запрос, не учёл
тогда
query = SELECT substring(login from 1 for 1)||'/'||login||'/Maildir/' from mailusers where login = '%u'||'@'||'%d';
authlib
SELECT login as username,'' as cryptpw, \
pass as clearpw,506 as uid, \
506 as gid,'/mailboxes/'||substring(login from 1 for 1)||'/'||login as home,\
'' as maildir, \
30 as quota,fullname, \
'disableimap' as options \
where login = '$(local_part)'||'@'||'$(domain)';
Если опять не ошибаюсь
действительно, недочет
вот правильные запросы
mailbox.pgsql
SELECT substring(login from 1 for 1)||'/'||login||'/Maildir/' as path from mailusers where login = '%u||'@'||'%d'
authlib
SELECT login as username,'' as cryptpw,506 as gid,'/mailboxes/'||substring(login from 1 for 1)||'/'||login as home,'' as maildir,30 as quota,fullname,'disableimap' as options from mailusers where login = '$(local_part)'||'@'||'$(domain)';
>жаль что opennet не поддерживает wiki, максим 4 дня не отвечает уже
Над каждой статьей есть ссылка "правка", там wiki-подобный интерфейс для исправления статей. Правки внесенные через ту форму появляются на сайте через несколько часов.
Исправления статьи вы прислали по email, соответственно требуется полное переформатирование текста в формат статей opennet, что делается при наличии свободного врмени.
Так я же привел правильные. У меня с ними работало. (Или не должно было? :) тестовая системка ведь была.)
Пока не начал дальше ковырять на предмет авторизации на отсылку.