LINUX.ORG.RU
решено ФорумAdmin

iptables: почтовый сервер за nat

 , ,


0

1

Здравствуйте! Перенес почтовый сервер за nat. Стоял какое-то время бытовой роутер. Пробросил порты почты - все работало. Заменил роутер на debian. Пробросил порты. Извне почта работает. Внутри локальной сети клиенты получают сообщение «В соединении отказано». Крутил различные варианты SNAT с подменой адреса, но толку ноль. Наверно я чего-то не понимаю. Подскажите кто чем может. Спасибо!

#!/bin/sh
$IPT -t nat -A PREROUTING -p tcp -i $WAN --dport 993 -j DNAT --to 192.168.0.87:993
$IPT -t nat -A PREROUTING -p tcp -i $WAN --dport 465 -j DNAT --to 192.168.0.87:465
$IPT -t nat -A PREROUTING -p tcp -i $WAN --dport 25 -j DNAT --to 192.168.0.87:25
$IPT -t nat -A PREROUTING -p tcp -i $WAN --dport 587 -j DNAT --to 192.168.0.87:587
$IPT -t nat -A PREROUTING -p tcp -i $WAN --dport 143 -j DNAT --to 192.168.0.87:143
$IPT -t nat -A POSTROUTING -o $WAN -j MASQUERADE
$IPT -A FORWARD -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -m state --state INVALID -j DROP
$IPT -A FORWARD -i $WAN -d 192.168.0.0/24 -j ACCEPT
$IPT -A FORWARD -i $LAN -o $WAN -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -i $LAN -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPT -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -m state --state INVALID -j DROP
$IPT -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A INPUT -p tcp -m tcp --tcp-flags FIN,ACK FIN -j DROP



Ответ на: комментарий от targitaj

да, на доменное имя. Телнетом и traceroute проверял. Коннекты из локалки идут на публичный адрес.

kerby
() автор топика
Ответ на: комментарий от kerby

читай по ссылке, там всё типовое

правило для клиентов снаружи
правило для клиентов изнутри
правило для обращения с самого шлюза

и не забудь forward разрешить

targitaj ★★★★★
()
Ответ на: комментарий от targitaj

Я это пробовал. Все вариации с SNAT, которые выдавал google. Либо интернет отваливался, либо ничего не менялось.

kerby
() автор топика
Ответ на: комментарий от kerby

Внимание и еще раз внимание. Скорее всего, где-то в условиях ошибся. Лично я пользуюсь наработками камрада https://www.frozentux.net/documents/iptables-tutorial/ (у меня, правда, уже довольно сильно от его болванки уехало) и для forward-preroute почти не используется условие "-i".

targitaj ★★★★★
()
Ответ на: комментарий от targitaj

Правила поменял, но чтобы проверить, нужно роутер переподключать. Я отпишусь о результатах.

kerby
() автор топика
Ответ на: комментарий от kerby

да, на доменное имя.

Я лет 10 назад подобную проблему решил заведением внутренней и внешней зон в Bind. Так что изнутри доменное имя разрешается в локальный адрес, а снаружи в публичный.

Serge10 ★★★★★
()
Ответ на: комментарий от targitaj

Нет, не помогло. Теперь ошибка другая - не получен отклик за отведенное время, соединение не установлено.

kerby
() автор топика
Ответ на: комментарий от Serge10

Я так понял, что в моем случае (dnsmasq) достаточно в /etc/hosts прописать доменное имя и внутренний ip почтового сервера. Тогда dnsmasq все внутренние запросы на домен перешлет к локальному почтовому серверу. А извне сети все останется без изменений. Т.е. работать тоже будет. Так?

kerby
() автор топика
Ответ на: комментарий от kerby

В качестве dns у меня dnsmasq. Может можно и его подкрутить как-то?

Легче легкого, одна строка в конфиге address=/hostname/ip

anc ★★★★★
()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от kerby

Нет, не помогло. Теперь ошибка другая - не получен отклик за отведенное время, соединение не установлено.

Показывайте что делали.

anc ★★★★★
()
Ответ на: комментарий от anc

Первоначальный вариант правил в заголовке. А потом делал в соответствии с этим:

Изнутри ходишь на public адрес? Это классическая ситуация,вот типа похожая задача https://sysadmin.ru/articles/probros-portov-v-lokalnuyu-set-s-pomoshhyu-iptables (первое из поиска)

Само собой, вместо 80 порта использовал порты почтового сервера. Только при таком варианте возникала ошибка подключения по таймауту, а при первоначальном варианте Отказано в доступе. Если подключаться снаружи то все работает. Не работает только в локальной сети. Если на клиентской машине в hosts прописать домен и локальный ip почтового, то тоже работает.

kerby
() автор топика
Ответ на: комментарий от anc

Ну вот практически полный скрипт правил.

#!/bin/sh
### MailServer ###
MAIL_IP=192.168.0.87
MAIL_PORTS="993 465 25 587 143"

IPT=`which iptables`

WAN=enp4s0
WAN_IP=123.123.123.123
LAN=enp1s0
LAN_IP_RANGE=192.168.0.0/24

$IPT -F
$IPT -F -t nat
$IPT -F -t mangle
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X

$IPT -P INPUT DROP
$IPT -P OUTPUT DROP #пробовал и с ACCEPT
$IPT -P FORWARD DROP

for PORT in $MAIL_PORTS
        do
        $IPT -t nat -A PREROUTING --dst $WAN_IP -p tcp --dport $PORT -j DNAT --to-destination $MAIL_IP
        $IPT -t nat -A POSTROUTING --dst $MAIL_IP -p tcp --dport $PORT -j SNAT --to-source $WAN_IP
        $IPT -t nat -A OUTPUT --dst $WAN_IP -p tcp --dport $PORT -j DNAT --to-destination $MAIL_IP
done

$IPT -t nat -A POSTROUTING -o $WAN -j MASQUERADE

$IPT -A FORWARD -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -m state --state INVALID -j DROP
$IPT -A FORWARD -i $WAN -d 192.168.0.0/24 -j ACCEPT
$IPT -A FORWARD -i $LAN -o $WAN -j ACCEPT

$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -i $LAN -j ACCEPT

$IPT -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

$IPT -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPT -A INPUT -m state --state INVALID -j DROP

$IPT -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

$IPT -A INPUT -p tcp -m tcp --tcp-flags FIN,ACK FIN -j DROP

$IPT -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP

$IPT -A INPUT -p tcp -m osf --genre NMAP -j DROP
$IPT -A INPUT -m psd -j DROP

$IPT -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP

kerby
() автор топика
Ответ на: комментарий от kerby

Правила для FORWARD не хватает $IPT -A FORWARD -i $LAN -o $LAN -j ACCEPT у вас входящий и исходящий интерфейс одинаковые.

PS По ссылке которую привели, предлагают в правиле snat заменять исходящий адрес на 123.123.123.123, как вы и сделали. В конкретной схеме вроде ничего плохого нет. Но все-таки мне что-то не нравиться, хотя сходу не могу придумать в чем минус. Как по мне, логичнее в snat исходящий адрес менять на IP исходящего интерфейса (предположим что у роутера на enp1s0 IP 192.168.0.1, вот его и использовать $IPT -t nat -A POSTROUTING –dst $MAIL_IP -p tcp –dport $PORT -j SNAT –to-source 192.168.0.1)

PSS Не в тему, а вот это правило $IPT -A FORWARD -i $WAN -d 192.168.0.0/24 -j ACCEPT у вас специально?

anc ★★★★★
()
Ответ на: комментарий от anc

$IPT -A FORWARD -i $LAN -o $LAN -j ACCEPT

Здесь нет никакой ошибки? Это правило разрешает форвард пакетов из LAN в LAN?

kerby
() автор топика
Ответ на: комментарий от kerby

Я так понял, что в моем случае (dnsmasq) достаточно в /etc/hosts прописать доменное имя и внутренний ip почтового сервера.

Так это придется на каждом локальном клиенте прописывать. IMHO, не самый удобный вариант. Лучше DNS нормально настроить.

В качестве dns у меня dnsmasq. Может можно и его подкрутить как-то?

Можно, конечно. См. тут, например.

Serge10 ★★★★★
()
Последнее исправление: Serge10 (всего исправлений: 1)
Ответ на: комментарий от Serge10

Не, судя по той ссылке,

Можно, конечно. См. тут, например.

я прав. Нужно в /etc/hosts на шлюзе прописать доменное имя и локальный ip почтового сервера. Dnsmasq все запросы на домен внутри сети отправит прямо на локальный почтовый сервер.

kerby
() автор топика
Ответ на: комментарий от kerby

Нет. У вас именно так и есть. Собстно я об этом написал:

у вас входящий и исходящий интерфейс одинаковые

anc ★★★★★
()
Ответ на: комментарий от kerby

И еще немного критики. Увеличение кол-ва правил никогда положительно не сказывалось на производительности. Вот «это»:

for PORT in $MAIL_PORTS...

решается

$IPT -t nat -A PREROUTING --dst $WAN_IP -p tcp -m multiport --dports 993,465,25,587,143 -j DNAT --to-destination $MAIL_IP

anc ★★★★★
()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от anc

Учту. Спасибо за конструктивную критику.

kerby
() автор топика
Ответ на: комментарий от anc

я уже пробовал и tcpdump и даже wireshark. Правда так ничего и понял, но хотя бы попробовал.) Dnsmasq у меня hosts читает, если до конца недели не разберусь с правилами, пропишу домен в hosts.

kerby
() автор топика
Ответ на: комментарий от kerby

я уже пробовал и tcpdump и даже wireshark. Правда так ничего и понял

Если трафик на 143-й порт не большой, то можно так:
На роутере
tcpdump -n -i enp1s0 'tcp and port 143 and (host 192.168.0.87 or host 123.123.123.123 or host IP-почтового-клиента-в-локалке )'
На почтовом сервере так же, только имя интерфейса поменяйте на тот на котором ip 192.168.0.87
С клиента telnet 123.123.123.123 143
И смотрите что происходит с адресами пакетов. Долетают/улетают ли пакеты.

Dnsmasq у меня hosts читает, если до конца недели не разберусь с правилами, пропишу домен в hosts.

С целом решение с dns лучше, не надо лишним nat-ом роутер нагружать.
У него возможна проблема, в случае если у клиента локалки прописан какой-то другой dns, например 8.8.8.8, но это так же решаемо. Если такое не допустимо, решается волшебными люлями. Если допустимо, то возвращаемся к варианту dnat *:53 на dns локалки.

anc ★★★★★
()
Ответ на: комментарий от kerby

У меня именно так (hosts) и сделано. Все работает. И никакой мороки с iptables. Причем уже не один почтовый сервер так делаю. В локальной сети у хостов назначен мой DNS (dnsmasq), а он читает hosts.

funky
()
Ответ на: комментарий от anc

Прописал домен в dnsmasq. Работает. Тему закрываю. Решение хорошее, но не очень. Легкий осадочек непобеды над iptables остался))

kerby
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.