SMTP-форвардинг из CommuniGate Pro
{{ВИДЕО}}
Раздел: Интеграции (внутри книги «Установка и настройка»). Связанные разделы: Сервер SMTP, Источники писем, Правила хранения.
Назначение
Перенаправление копии SMTP-трафика из CommuniGate Pro в Клавдий для архивирования.
Клавдий выступает приёмником SMTP (роль «SMTP-сервер»); CommuniGate Pro направляет ему
копии писем с помощью скрипта resubmitter.pl и правила обработки почты.
Если Клавдий должен сам забирать почту из CommuniGate Pro по IMAP — используйте источник «IMAP» (Источники писем). Эта страница описывает push-вариант (CommuniGate → Клавдий).
Документация производителя
- CommuniGate Pro: https://doc.communigatepro.ru/russian/
- Установка на Linux
- Правила обработки почты
- Внешние фильтры (Helpers)
-
SMTP / Маршрутизатор — синтаксис
host.port._relay
- Пример подключения архиватора к CommuniGate Pro (Archiva): https://docs.archiva.ru/communigate.html
Как это работает
- Письмо попадает в очередь CommuniGate Pro и подпадает под правило
resubmitter. - Правило вызывает Helper
resubmitter.pl. Скрипт переписывает получателяuser@domain→user%domain@<адрес-Клавдия>и кладёт файл в каталогSubmitted/. - Движок доставки CommuniGate Pro берёт файл и отправляет письмо по маршруту из Router
для адреса
<адрес-Клавдия>. - Клавдий принимает письмо по SMTP, задача
smtp_collectionархивирует его по правилам хранения.
Скрипт
resubmitter.plне отправляет ничего по сети — он только переписывает получателя и кладёт файл в очередь. По сети письмо отправляет движок доставки CommuniGate Pro по маршруту из Router. Поэтому порт доставки задаётся в Router, а не в скрипте.
Сохраняются ли отправитель и получатель?
Да. Скрипт переписывает только конверт SMTP (RCPT TO: → user%domain@<адрес-Клавдия>),
а заголовки тела письма (From:, To:, Cc:) оставляет нетронутыми. Клавдий определяет
отправителя и получателя для архива именно по заголовкам тела, поэтому в архиве письмо
попадает с корректными исходными адресами (напр. user1@cgp.lab → user2@cgp.lab), а не с
подменённым конвертным адресом. Оригинальные адреса также сохраняются в дописанных скриптом
заголовках Return-Path: и Envelope-To:.
Правила хранения, фильтрующие по отправителю/получателю, работают как обычно — они опираются на адреса из заголовков, а не на конверт.
Предварительные требования
- CommuniGate Pro установлен и обрабатывает почту (есть домен, ящики, ходят письма).
- Клавдий установлен, настроен минимум по Быстрому старту: есть группа хранилищ, правило хранения, узел.
- Сетевая доступность: CommuniGate Pro может установить TCP-соединение к Клавдию на порт SMTP-слушателя.
Шаг 1. Настроить приёмник SMTP в Клавдии
- В веб-панели Клавдия откройте [Сбор почты → SMTP-сервер] (см. Сервер SMTP).
- В блоке [Глобальные настройки SMTP]:
-
Порт — порт, на котором Клавдий будет принимать трафик от CommuniGate Pro.
Если Клавдий и CommuniGate Pro на одном хосте (например, оба в
network_mode: host) — подойдёт8025(стандартный 25 может быть занят). Если порты не конфликтуют —25. -
Шифрование —
Без TLS (LAN/MX)для простейшего лаб-варианта;STARTTLSдля прод. -
Имя сервера (hostname) — напр.
klvd.local.
-
Порт — порт, на котором Клавдий будет принимать трафик от CommuniGate Pro.
Если Клавдий и CommuniGate Pro на одном хосте (например, оба в
- Нажмите [Сохранить настройки].
- Разместите слушатель на узле: [Кластер → Узлы] → узел → роль SMTP, поле
[Размещение слушателей]:
-
SMTP IP — адрес, на котором Клавдий примет трафик от CommuniGate Pro
(
0.0.0.0— все интерфейсы, или конкретный IP). -
Сети SMTP (trusted networks) — сеть CommuniGate Pro в CIDR (напр.
127.0.0.1/32если CGP на том же хосте, или192.168.1.0/24). Письма из этих сетей Клавдий принимает без SMTP-AUTH — это и нужно для форвардинга.
-
SMTP IP — адрес, на котором Клавдий примет трафик от CommuniGate Pro
(
- Убедитесь, что роль SMTP включена на узле (вкладка [Роли]).
Запомните: адрес Клавдия (IP или hostname, видимый из CommuniGate Pro) и порт SMTP-слушателя. Они понадобятся в шагах 3–4.
Шаг 2. Создать правило хранения для SMTP-писем
Клавдий хранит письма только по явным правилам (строгий режим). Без правила письмо, принятое по SMTP, будет пропущено (и зафиксировано в журнале).
- Откройте [Хранение → Правила хранения] (см. Правила хранения).
- Создайте правило, условие которого выделяет SMTP-источник:
- Источник = «Сбор из потока SMTP» (источник создаётся автоматически после первого принятого SMTP-письма; можно создать вручную в разделе [Источники]).
- Задайте действие (напр. «Хранить бессрочно» или срок) и категорию при необходимости.
Шаг 3. Разместить скрипт resubmitter.pl на сервере CommuniGate Pro
Скрипт размещается в каталоге данных CommuniGate Pro (обычно /var/CommuniGate).
-
Создайте файл
/var/CommuniGate/resubmitter.plсо содержимым из раздела «Скрипт resubmitter.pl» ниже. -
Откройте файл и в блоке
BEGIN CONFIGукажите [адрес Клавдия] (тот, что запомнили в шаге 1):my @ScannerAddresses = ( '127.0.0.1', );- Для нескольких Клавдиев (round-robin балансировка) — перечислите через запятую.
- Адрес — это IP/hostname Клавдия, видимый с сервера CommuniGate Pro. Если CGP и Клавдий
на одном хосте —
127.0.0.1. Если в одной сети — IP Клавдия в этой сети.
-
Сделайте скрипт исполняемым:
chmod +x /var/CommuniGate/resubmitter.pl -
Убедитесь, что в системе есть интерпретатор Perl (обычно есть по умолчанию):
perl -v.
Если CommuniGate Pro работает в Docker — скрипт можно положить в образ (через Dockerfile
COPY resubmitter.pl /opt/CommuniGate/resubmitter.pl) или примонтировать через volume в/var/CommuniGate/. Адрес Клавдия при этом подставляется на этапе сборки образа.
Шаг 4. Зарегистрировать Helper в CommuniGate Pro
-
Войдите в веб-интерфейс администратора CommuniGate Pro (по умолчанию
http://<сервер-CGP>:8010) какpostmaster. -
Перейдите в [Установки → Общее → Помощники (Helpers)].
-
В последней пустой строке таблицы [Фильтрация данных] заполните поля:
Поле Значение Имя программы resubmitterУровень журнала Подробности(для отладки), затемПроблемыПуть к программе /var/CommuniGate/resubmitter.plТайм-аут 60 секАвторестарт 1 сек -
Установите флажок рядом с именем
resubmitterи нажмите [Модифицировать].
Если скрипт запустился — в журнале появится строка resubmitter.pl started. Если путь неверен
или нет прав — отобразится ошибка.
Раздел официальной документации: Внешние фильтры (Helpers).
Шаг 5. Настроить маршрутизацию доставки на Клавдий (Router)
По умолчанию CommuniGate Pro доставляет почту на стандартный порт 25. Если SMTP-слушатель
Клавдия listens на другом порте (напр. 8025), добавьте запись в Router, указывающую порт.
-
В WebAdmin CommuniGate Pro откройте [Установки → Почта → Маршрутизатор].
-
Добавьте запись (синтаксис
адрес = хост.порт._relay— порт через точку перед_relay):127.0.0.1 = 127.0.0.1.8025._relay- Левая часть — адрес, который скрипт подставляет получателю (
<адрес-Клавдия>из шага 3). - Правая часть — куда доставлять:
хост.порт._relay.хост— адрес Клавдия,порт— порт SMTP-слушателя Клавдия из шага 1. - Если Клавдий слушает стандартный 25 — запись не нужна (доставка идёт на 25 по умолчанию),
но можно задать явно:
127.0.0.1 = 127.0.0.1._relay.
- Левая часть — адрес, который скрипт подставляет получателю (
-
Нажмите [Обновить конфигурацию] (или [Модифицировать]).
Документация по синтаксису: SMTP / Router. Запись
host.port._relayотключает MX-разрешение и доставляет напрямую наhost:port.
Шаг 6. Создать правило обработки почты (Rule)
Правило вызывает Helper resubmitter для писем, которые нужно архивировать.
-
В WebAdmin CommuniGate Pro откройте [Установки → Почта → Правила] (общесерверные правила).
-
Создайте новое правило с именем
resubmitterи нажмите [Изменить]. -
Задайте условия (чтобы правило применялось ко всем локальным письмам, но не зацикливалось на обратной доставке в Клавдий):
Данные Операция Параметр Любой Маршрут is LOCAL*Submit Address not in SMTP[<адрес-Клавдия>*]Submit Address is not PIPE*-
LOCAL*— письма, адресованные локальным ящикам CommuniGate Pro. -
not in SMTP[<адрес-Клавдия>*]— исключает письма, которые уже идут от/к Клавдию (предотвращает цикл). -
<адрес-Клавдия>— тот же адрес, что в шаге 3 (напр.127.0.0.1).
-
-
Задайте действие:
Действие Параметр Внешний Фильтр resubmitter -
Сохраните правило и убедитесь, что оно включено (стоит первым или выше правил, останавливающих обработку).
Раздел документации: Правила обработки почты. Действие «Внешний Фильтр» доступно только в общесерверных правилах.
Шаг 7. Проверить
- Через веб-почту CommuniGate Pro (или почтовый клиент) отправьте письмо
user1@<домен-CGP>→user2@<домен-CGP>с темойcgp-klvd-push-001. - В CommuniGate Pro проверьте журнал Helper:
- Файл
SystemLogs/<год>-<месяц>-<день>_resubmitter.logв каталоге данных CGP. - Должна быть строка
done ... transferedдля отправленного письма.
- Файл
- В Клавдии:
- [Клавдий → Обзор] → блок [Системные метрики] → строки «SMTP-сервер» / «Приём SMTP»: обработано +1.
-
Задачи — задача
smtp_collectionвыполнилась без ошибок. -
Архив — письмо
cgp-klvd-push-001появилось (если правило хранения из шага 2 подходит; иначе — в журнале запись о пропуске письма, и нужно скорректировать правило).
- При проблемах — см. Обслуживание → Диагностика
и Коды ошибок (коды
#ERROR_KLVD_SMTP_*).
Диагностика типовых проблем
| Симптом | Вероятная причина | Действие |
|---|---|---|
В журнале CGP resubmitter.log пусто |
Правило не срабатывает | Проверить условия правила (особенно LOCAL* и фильтр по Submit Address); поднять уровень журнала CGP «Установка в Очередь» до «Подробности» |
resubmitter.log: REJECTED can't create ...tmp |
Нет прав на запись в Submitted/ |
Проверить права на /var/CommuniGate/Submitted/ (владелец — процесс CGP) |
Письмо доходит до .sub, но не доставляется в Клавдий |
Неверный Router / порт / сеть | Проверить запись Router (шаг 5); убедиться, что CGP может открыть TCP к <адрес-Клавдия>:<порт> |
| Клавдий принимает SMTP, но письмо не в архиве | Нет правила хранения (шаг 2) | Создать правило для SMTP-источника; проверить журнал Клавдия на skip |
| Цикл: письмо гоняется CGP↔Клавдий | Не настроен фильтр not in SMTP[<адрес-Клавдия>*] |
Добавить/скорректировать условие в шаге 6 |
bind() failed в Клавдии на порту 25 |
Порт 25 занят другим MTA | Перенести SMTP-слушатель Клавдия на другой порт (шаг 1) и обновить Router (шаг 5) |
Скрипт resubmitter.pl
Ниже — полный текст скрипта. Скопируйте в /var/CommuniGate/resubmitter.pl, подставьте адрес
Клавдия в @ScannerAddresses (шаг 3), сделайте исполняемым.
#!/usr/bin/perl -w
# script: resubmitter.pl
#
# howto:
# Invoke from CommuniGate Pro Rule, such as:
# Data:
# [Any Route] [is] 'LOCAL*'
# [Submit Address] [not in] 'SMTP [80.69.98.241*,SMTP [80.69.98.242*'
# [Submit Address] [is not] 'PIPE*'
# Action:
# [ExternalFilter] [resubmitter]
use strict;
use POSIX qw(strftime);
## BEGIN CONFIG
# Here you specify the scanner IPs or hostnames
# You can specify one or multiple names for round-robin load balancing
my @ScannerAddresses = (
'127.0.0.1', # ← адрес Клавдия (видимый с сервера CommuniGate Pro)
);
my $verbose = 1; # debug option
my $quitCounter = 0; # if >0, feed this number then quit
my $SubmittedDir= "Submitted";
## END CONFIG
$| = 1;
myLog("* resubmitter.pl started");
print "* resubmitter.pl started.\n";
my $msgCounter=0;
my $scannerCounter=0;
while(<STDIN>) {
chomp;
my ($prefix,$command,@args) = split(/ /);
myLog("Cmd: $_") if $verbose;
if($command eq 'INTF') {
print "$prefix INTF 3\n";
} elsif($command eq 'QUIT') {
myLog("QUIT command received");
print "$prefix OK\n";
last;
} elsif($command eq 'KEY') {
myLog("KEY command received") if $verbose;
print "$prefix OK\n";
} elsif($command eq 'FILE') {
processFILE($prefix,$args[0]);
} else {
print "$prefix ERROR unexpected command: $command\n";
myLog("Error: unexpected command: $command") if $verbose;
}
if($quitCounter>0) {
if(--$quitCounter==0) {
print "* time to quit and to be restarted\n";
myLog("* time to quit and to be restarted") if $verbose;
last;
}
}
}
print "* stopping the resubmitter plugin\n";
myLog("* stopping the plugin");
exit(0);
# Subs
sub processFILE {
my ($prefix,$fileName) = @_;
myLog("processing: $prefix FILE $fileName");
unless( open (FILE,"$fileName")) {
print qq/$prefix REJECTED can't open $fileName: $!\n/;
myLog("ERROR: REJECTED: can't open $fileName: $!");
return undef;
}
my $returnPath="";
my @recipients;
while(<FILE>) {
chomp;
last if($_ eq '');
my $address=(/\<(.*?)\>/)[0];
if(/^P/) {
$returnPath=$address;
myLog("returnPath: $returnPath") if $verbose;
}
elsif(/^R/) {
$address =~ s/\@/\%/g;
$address.='@'.$ScannerAddresses[$scannerCounter];
myLog("recipient: $address") if $verbose;
push(@recipients,$address);
}
}
$scannerCounter=0 if(++$scannerCounter>=scalar(@ScannerAddresses));
$fileName=~/(\d+)\./;
my $subFileName=$SubmittedDir.'/'.$1;
myLog("Submitted file name: $subFileName") if $verbose;
unless( open(WFILE,">$subFileName.tmp")) {
print qq/$prefix REJECTED can't create $subFileName.tmp: $!\n/;
myLog("ERROR: REJECTED: can't create $subFileName.tmp: $!");
close(FILE);
return undef;
}
print WFILE "Return-Path: <$returnPath>\n";
#print WFILE "Envelope-To: ".join(",",@recipients)."\n";
my $line='Envelope-To: ';
for(my $idx=0;$idx<@recipients;$idx++) {
$line.=$recipients[$idx];
$line.="," if($idx<@recipients-1);
if(length($line)>900) {
print WFILE "$line\n";
$line=' ';
}
}
if(length($line)>2) {
print WFILE "$line\n";
}
while(<FILE>) {
next if(/^Envelope-to:/i);
print WFILE $_;
}
close(WFILE);
close(FILE);
unless( rename("$subFileName.tmp","$subFileName.sub") ) {
print qq/$prefix REJECTED can't rename open $subFileName.tmp to $subFileName.sub: $!\n/;
myLog("ERROR: REJECTED: can't rename open $subFileName.tmp to $subFileName.sub: $!");
unlink("$subFileName.tmp");
return undef;
}
myLog("done $prefix $fileName, transfered");
print qq/$prefix OK\n/;
undef;
}
sub myLog {
my ($data)=@_;
$data =~ s/[\015\012]//g;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my $fName=sprintf("SystemLogs/%04d-%02d-%02d_resubmitter.log",$year+1900,$mon+1,$mday);
my $tmstr=sprintf("%02d:%02d:%02d",$hour,$min,$sec);
unless (open LOG,">>$fName") {
print "* can't append to $fName: $!\n";
return;
}
# LOG->autoflush(1);
print LOG "$tmstr $data\n";
close LOG;
}
__END__
См. также
- Сервер SMTP — встроенный приёмник Клавдия (настройка порта, TLS, trusted networks).
- Источники писем — IMAP/EWS как альтернатива форвардингу.
- Правила хранения — без правила SMTP-письма не сохраняются.
-
Коды ошибок — расшифровка
#ERROR_KLVD_SMTP_*. - HTTP API и Swagger — программное управление Клавдием.
Навигация по книге
- Следующая статья: Доступ к HTTP API и Swagger