Все будет в изолированной сети, безопасность не проблема.
eth0 подключен к «публичной» сети. Адрес назначается DHCP.
eth1 подключен к серверу "частной сети", который предоставляет ssh, telnet, "другие" и ftp.
В этом примере у этого сервера будет фиксированный IP-адрес (192.168.1.2).
На шлюзе работает debian buster и ядро Linux 4.19.94
nft используется с NAT
Это моя конфигурация nft "шлюза":
table ip my_nat {
chain my_prerouting { type nat hook prerouting priority 0;
tcp dport { 2222 } dnat to :22 # 2222 backdoor for ssh to the gateway
tcp dport { 1-1023 } dnat to 192.168.1.2
}
chain my_postrouting {
type nat hook postrouting priority 100;
ip daddr 192.168.1.2 masquerade
}
}
Что мне нужно добавить, чтобы FTP работал
# nft add ct helper ip my_nat ftp-incoming '{ type "ftp" protocol tcp; }'
# nft add chain ip my_nat my_helpers '{ type filter hook prerouting priority 10; }'
# nft add rule ip my_nat my_helpers iif eth0 ip daddr 192.168.1.2 tcp dport 21 ct helper set ftp-incoming
# modprobe nf_nat_ftp
с более подробной информацией ниже ...
FTP - это старый протокол, который не очень удобен для брандмауэра: команды на командном канале FTP (21 / TCP) согласовывают временный порт, который будет использоваться для следующей команды передачи. Из-за этого межсетевой экран с отслеживанием состояния должен отслеживать эти команды и отвечать, чтобы временно предварительно разрешить соответствующий порт, который будет использоваться.
В Linux это обеспечивается вспомогательными модулями для конкретных протоколов, которые являются подключаемыми модулями для Conntrackподсистема Netfilter, отслеживающая соединения для NAT и межсетевого экрана с отслеживанием состояния. С FTP, когда согласование порта (в основном PORT, EPRT, PASV или EPSV) для следующей передачи было замечено на командном порту FTP, помощник добавляет кратковременную запись в специальную Conntrack стол ( ожидание conntrack table), который будет ждать следующего связанного и ожидаемого подключения к данным.
В моем ответе используется современная «безопасная» обработка, описанная в этот блог о iptables для общих слов и в столы вики и man nft
для обработки в столы который отличается от iptables.
Ядро Linux 4.7+ (включая 4.19) по умолчанию использует безопасный подход: наличие загруженного вспомогательного модуля (здесь FTP) больше не позволит ему отслеживать все пакеты, имеющие TCP-порт источника или назначения 21, до тех пор, пока не будет определен конкретный столы (или iptables) операторы говорят ему, в каком (ограниченном) случае он должен отслеживать. Это позволяет избежать ненужного использования ЦП и позволяет в любой момент изменить порт (ы) FTP для отслеживания, просто изменив несколько правил (или наборов).
Первая часть - объявить потоки, которые могут вызвать отслеживание. В столы чем в iptables. Здесь он объявлен с использованием ct helper
объект с состоянием, и фильтры для его активации должны быть выполнены после Conntrack (пока iptables требует действий, выполненных ранее). man nft
говорит:
В отличие от iptables, назначение помощника должно выполняться после завершения поиска в conntrack, например, с приоритетом ловушки по умолчанию 0.
nft add ct helper ip my_nat ftp-incoming '{ type "ftp" protocol tcp; }'
nft add chain ip my_nat my_helpers '{ type filter hook prerouting priority 10; }'
nft add rule ip my_nat my_helpers iif eth0 ip daddr 192.168.1.2 tcp dport 21 ct helper set ftp-incoming
Я выбрал ту же таблицу, но ее можно было создать в другой таблице, если объявление объекта с сохранением состояния и ссылающееся на него правило находятся в одной таблице.
Конечно, можно выбрать менее строгие правила. Замена последнего правила следующим правилом будет иметь тот же эффект, что и унаследованный режим:
nft add rule ip my_nat my_helpers tcp dport 21 ct helper set ftp-incoming
Только для справки, устаревший режим, который больше не должен использоваться, не требует приведенных выше правил, а требует только этого переключателя (и ручной загрузки соответствующего модуля ядра):
sysctl -w net.netfilter.nf_conntrack_helper=1
nf_nat_ftp
загруженМодуль ядра nf_conntrack_ftp
автоматически загружается с зависимостью, созданной ct helper ... type "ftp"
. Это не так для nf_nat_ftp
, однако необходимо также включить изменение пакетов в командном порту, когда NAT выполняется на портах потока данных.
Например, чтобы иметь модуль nf_nat_ftp
тянул всякий раз, когда nf_conntrack_ftp
загружен, файл /etc/modprobe.d/local-nat-ftp.conf
можно добавить с этим контентом:
install nf_conntrack_ftp /sbin/modprobe --ignore-install nf_conntrack_ftp; /sbin/modprobe --ignore-install nf_nat_ftp
или вместо этого просто добавьте, например, /etc/modules-load.d/local-nat-ftp.conf
с участием:
nf_nat_ftp
В любом случае, сейчас нужно выполнить эту команду, чтобы убедиться, что она загружена:
modprobe nf_nat_ftp
Вот дополнительное примечание по брандмауэру. Также могут быть правила брандмауэра с некоторыми ограничениями вместо разрешения любого нового потока, помеченного как Связанный по Conntrack.
Например, хотя вспомогательный модуль FTP обрабатывает как пассивный, так и активный режимы, если по какой-то причине кто-то хочет разрешить только пассивный режим (с подключением данных от клиента к серверу), а не «активный» ftp (подключение данных от порта источника сервера 20 к client) можно, например, использовать эти правила в части набора правил брандмауэра вместо обычных ct state established,related accept
:
ct state established accept
ct state related ct helper "ftp" iif eth0 oif eth1 tcp sport 1024-65535 accept
ct state related ct helper "ftp" drop
ct state related accept
Другой вид Связанный потоки, не связанные с FTP, остаются принятыми (или могут быть дополнительно разделены отдельно)
Здесь (в смоделированной среде) два Conntrack списки событий, измеренных на ожидание стол и Conntrack таблица с правилами OP + дополнительные правила выше с интернет-клиентом 203.0.113.101, выполняющим FTP в пассивном режиме с общедоступным IP-адресом маршрутизатора 192.0.2.2 и с помощью команды LIST после входа в систему:
# conntrack -E expect
[NEW] 300 proto=6 src=203.0.113.101 dst=192.0.2.2 sport=0 dport=37157 mask-src=0.0.0.0 mask-dst=0.0.0.0 sport=0 dport=65535 master-src=203.0.113.101 master-dst=192.0.2.2 sport=50774 dport=21 class=0 helper=ftp
[DESTROY] 300 proto=6 src=203.0.113.101 dst=192.0.2.2 sport=0 dport=37157 mask-src=0.0.0.0 mask-dst=0.0.0.0 sport=0 dport=65535 master-src=203.0.113.101 master-dst=192.0.2.2 sport=50774 dport=21 class=0 helper=ftp
одновременно:
# conntrack -E
[NEW] tcp 6 120 SYN_SENT src=203.0.113.101 dst=192.0.2.2 sport=50774 dport=21 [UNREPLIED] src=192.168.1.2 dst=192.168.1.1 sport=21 dport=50774 helper=ftp
[UPDATE] tcp 6 60 SYN_RECV src=203.0.113.101 dst=192.0.2.2 sport=50774 dport=21 src=192.168.1.2 dst=192.168.1.1 sport=21 dport=50774 helper=ftp
[UPDATE] tcp 6 432000 ESTABLISHED src=203.0.113.101 dst=192.0.2.2 sport=50774 dport=21 src=192.168.1.2 dst=192.168.1.1 sport=21 dport=50774 [ASSURED] helper=ftp
[NEW] tcp 6 120 SYN_SENT src=203.0.113.101 dst=192.0.2.2 sport=55835 dport=37157 [UNREPLIED] src=192.168.1.2 dst=192.168.1.1 sport=37157 dport=55835
[UPDATE] tcp 6 60 SYN_RECV src=203.0.113.101 dst=192.0.2.2 sport=55835 dport=37157 src=192.168.1.2 dst=192.168.1.1 sport=37157 dport=55835
[UPDATE] tcp 6 432000 ESTABLISHED src=203.0.113.101 dst=192.0.2.2 sport=55835 dport=37157 src=192.168.1.2 dst=192.168.1.1 sport=37157 dport=55835 [ASSURED]
[UPDATE] tcp 6 120 FIN_WAIT src=203.0.113.101 dst=192.0.2.2 sport=55835 dport=37157 src=192.168.1.2 dst=192.168.1.1 sport=37157 dport=55835 [ASSURED]
[UPDATE] tcp 6 30 LAST_ACK src=203.0.113.101 dst=192.0.2.2 sport=55835 dport=37157 src=192.168.1.2 dst=192.168.1.1 sport=37157 dport=55835 [ASSURED]
[UPDATE] tcp 6 120 TIME_WAIT src=203.0.113.101 dst=192.0.2.2 sport=55835 dport=37157 src=192.168.1.2 dst=192.168.1.1 sport=37157 dport=55835 [ASSURED]
Начало ожидания proto=6 src=203.0.113.101 dst=192.0.2.2 sport=0 dport=37157
сообщает, что следующее TCP-соединение от 203.0.113.101:* до 192.0.2.2:37157 будет связано (состояние Связанный) с FTP-соединением. Непосредственно не виден, но поскольку вспомогательный модуль NAT FTP также загружен, фактические данные, отправленные сервером в ответ на команду PASV / EPSV, были перехвачены и переведены, поэтому клиент подключается к 192.0.2.2 вместо 192.168.1.2, который имел бы конечно провалился на клиенте.
Несмотря на второй поток (второй НОВАЯ line), не имеющий явного правила в my_prerouting, он был успешно подключен к серверу за маршрутизатором.
если порт управления FTP зашифрован (AUTH TLS
...), то вспомогательный модуль больше не может отслеживать согласованный порт, и это не может работать. Приходится прибегать к настройке зарезервированного диапазона портов как в конфигурации FTP-сервера, так и в брандмауэре / NAT-маршрутизаторе, а также настраивать сервер так, чтобы он отправлял правильный (общедоступный) IP-адрес при согласовании вместо своего собственного. И активный режим FTP не может быть использован, если у сервера нет маршрута к Интернету (как, похоже, здесь).
придирки: приоритет предварительной маршрутизации 10 гарантирует, что даже для ядер <4.18 NAT уже выполняется для новых потоков (OP выбрал приоритет предварительной маршрутизации обработчика 0 вместо обычного -100, поскольку это редко имеет значение в nftables), поэтому использование daddr 192.168.1.2
возможно. Если приоритет был 0 (или ниже 0), возможно (не проверено) правило увидит, что первый пакет все еще не имеет NAT с общедоступным IP-адресом назначения, но перехватит следующие пакеты того же потока, поскольку они обрабатываются непосредственно Conntrack при приоритете -200. Лучше оставайтесь в безопасности и используйте 10. На самом деле это не актуально, начиная с ядра 4.18 (см. совершить ссылка в этот ожидающий патч), где приоритет NAT важен только для сравнения между несколькими цепочками nat (и позволяет смешивать NAT в устаревших iptables и nftables).