У меня возникли проблемы с DNAT / SNAT после обновления до более новой версии ядра. Я использую Fedora 24 в качестве сетевого брандмауэра, и у меня есть FTP-сервер в моей локальной сети. Брандмауэр имеет общедоступные и частные IP-адреса. На сервере Fedora с ядром 4.6.5-300.fc24.x86_64 следующий набор правил iptables работает должным образом:
#!/bin/bash
modprobe iptable_nat
modprobe nf_conntrack
modprobe nf_conntrack_ftp
modprobe nf_nat_ftp
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -F
iptables -F -t nat
iptables -X
iptables -Z
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 1 > /proc/sys/net/netfilter/nf_conntrack_helper
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A PREROUTING -d $public_ip -p tcp --dport 21 -j DNAT --to-destination 192.168.0.10:2121
...
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -d 192.168.0.10 -p tcp --dport 2121 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.0.10 -p tcp --sport 2121 -j SNAT --to-source $public_ip
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -d 192.168.0.10 -p tcp --dport 2121 -j SNAT --to-source 192.168.0.1
...
Проблема возникает только тогда, когда я загружаю систему с версией ядра 4.10.10-100.fc24.x86_64 (я не знаю, затронуты ли другие версии между ними).
Эта проблема: пользователи за пределами моей локальной сети могут получить доступ к службе FTP и использовать ее в соответствии с приведенными выше правилами. Проблема затрагивает только пользователей из локальной сети, которые запускают FTP-соединение с использованием DNS-имени, которое преобразуется в публичный адрес, поэтому соединение возвращается в локальную сеть и достигает FTP-сервера. Последняя строка там, поэтому FTP-сервер не доставляет соединение напрямую клиенту.
Это влияет только на FTP-соединения и дополнительные порты, указанные в /etc/modprobe.d при загрузке модуля nf_conntrack_ftp (например, добавленное правило с портом 80 работает должным образом). Я не думаю, что rp_filter имеет к этому какое-то отношение, потому что я отключил его, и ничего не изменилось. Кроме того, с помощью iptables LOG я могу видеть, как пакеты проходят весь путь до цепочки POSTROUTING. И при запуске Wireshark на FTP-сервере я проверил и подтвердил, что ни один пакет не доходит до него.
Итак, мой вопрос: я что-то делаю не так? Есть ли новый способ сделать то, что мне нужно, в этой версии ядра? Или это может быть ошибка?
Спасибо за помощь!
Судя по отзывам об этой проблеме, кажется, что она исправлена в ядре 4.13. Как ни странно, в журнале изменений не было зарегистрировано ни одной функции, касающейся какого-либо компонента netfilter (https://kernelnewbies.org/Linux_4.13). Мой набор правил, который работал на 4.6, остановился до 4.12, и теперь он снова работает на 4.13, не изменился ни одной строчкой (кроме обновления правильного использования помощников, но он был протестирован и работал и на 4.6). Итак, загрузка на 4.13.9-200.fc26.x86_64 работает, а на 4.12.5-300.fc26.x86_64 останавливается.
Попробуй это,
echo 1 > /proc/sys/net/netfilter/nf_conntrack_helper
Это связано с журналом ядра,
nf_conntrack: automatic helper assignment is deprecated and it will be removed soon. Use the iptables CT target to attach helpers instead.
Последние ядра больше не подключают автоматически помощников по отслеживанию соединений на основе скомпилированных номеров портов. Вместо этого вам нужно добавить определенные правила в raw
table, чтобы прикрепить этих помощников. Итак, для вашего примера, я думаю, вам нужно добавить что-то вроде этого:
iptables -t raw -A PREROUTING -d $public_ip -p tcp --dport 21 -j CT --helper ftp
Это также должно позаботиться о том, чтобы вспомогательные модули загружались без явного modprobe
команды.