nft config, чтобы сделать общедоступным локальный FTP-сервер с NAT
Все будет в изолированной сети, безопасность не проблема.
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 работал
Ответы
TL; DR
# 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 ), которая будет дождитесь следующего связанного и ожидаемого подключения для передачи данных.
В моем ответе используется современная «безопасная» обработка, описанная в этом блоге об iptables для общих целей и в wiki nftables, а также man nft
для обработки в nftables, которая отличается от iptables .
Безопасное использование правил helper и nftables
Ядро Linux 4.7+ (включая 4.19) по умолчанию использует безопасный подход: загруженный вспомогательный модуль (здесь FTP) больше не позволяет ему отслеживать все пакеты, имеющие TCP-порт источника или назначения 21, до тех пор, пока не будут определены определенные nftables (или iptables). ) операторы говорят ему, в каком (ограниченном) случае он должен отслеживать. Это позволяет избежать ненужного использования ЦП и позволяет в любой момент изменить порт (ы) FTP для отслеживания, просто изменив несколько правил (или наборов).
Первая часть - объявить потоки, которые могут вызвать отслеживание. В nftables это обрабатывается иначе, чем в 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
О межсетевом экране
Вот дополнительное примечание по брандмауэру. Там также может быть межсетевой экран правила с некоторыми ограничениями , вместо того , чтобы позволить любой новый поток помечены как связанные с помощью трассировщика .
Например, хотя вспомогательный модуль 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.0.1. 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, который имел бы конечно провалился на клиенте.
Несмотря на то, что второй поток (вторая строка NEW ) не имеет явного правила в my_prerouting , он был успешно применен DNAT к серверу за маршрутизатором.
Примечания
если порт управления 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).
После некоторых проб и ошибок я получил следующий файл nftables.conf. Он работает по назначению и поддерживает NAT в обоих направлениях, а также экспортирует все, кроме одного порта на моем сервере, в «общедоступную» сеть. Порт 2222 по-прежнему используется как «бэкдор» для шлюза, который будет использован, если мне когда-нибудь понадобится снова получить к нему доступ :-)
table ip my_nat {
ct helper ftp-incoming {
type "ftp" protocol tcp
l3proto ip
}
chain my_prerouting {
type nat hook prerouting priority 0; policy accept;
iifname "eth0" tcp dport { 2222 } dnat to :ssh
iifname "eth0" tcp dport { 1-2221, 2223-65535 } dnat to 192.168.0.2
}
chain my_postrouting {
type nat hook postrouting priority 100; policy accept;
ip daddr 192.168.0.2 masquerade
oifname "eth0" masquerade
}
chain my_helpers {
type filter hook prerouting priority 10; policy accept;
iif "eth0" ip daddr 192.168.0.2 tcp dport ftp ct helper set "ftp-incoming"
}
}