FTP можно пользоваться одним из двух способов: пассивным или активным. Как правило, выбор активного или пассивного делается для того, чтобы определить, есть ли у кого-то проблем с firewall'ом.
При активном FTP, когда пользователь подключается к удаленному FTP-серверу и запрашивает информацию или файл, FTP-сервер устанавливает новое соединение с клиентом для передачи запрошенных данных. Это называется data connection (подключением к данным). Для начала FTP-клиент выбирает случайный порт для приема соединения, для передачи данных. Клиент отправляет номер выбранного порта FTP-серверу и ожидает входящее соединение на нем. Затем FTP-сервер создает новое соединение на этот порт клиента и начинает передачу данных. Это проблема для пользователей, пытающихся получить доступ к FTP-серверам из-за шлюза NAT. Из-за того, что используется NAT, FTP-сервер создает новое соединение к внешнему адресу, который принадлежит не клиенту, а NAT, и порту, который выбрал клиент для передачи данных. NAT получит запрос, но, поскольку у него нет информации о сопоставлении в своей таблице состояний о выбранном клиентом порте, он отбросит пакет от FTP-сервера, т.е. ответный пакет от сервера клиент не получит.
В пассивном режиме FTP (режим, используемый по умолчанию в клиенте
ftp(1) в OpenBSD), клиент
запрашивает, чтобы сервер выбирал случайный порт для передачи данных.
Сервер сообщает клиенту выбранный порт, а клиент подключается к этому порту.
К сожалению, это не всегда возможно или желательно из-за возможностей Firewall-a
перед FTP-сервером, блокирующего входящие подключение для передачи данных.
Чтобы использовать активный режим FTP, используйте флаг -A
для
ftp
, или установите для пассивного режима значение "off",
введя команду «passive off
» в приглашении "ftp>
".
PF предлагает решение этой ситуации, перенаправляя FTP-трафик, через FTP прокси-сервер. Этот процесс используется, чтобы перенаправлять FTP-трафик через NAT firewall, путем активного добавления необходимых правил в PF и удаления их, когда это делается через систему привязки. FTP прокси-сервер, используемый PF: ftp-proxy(8).
Чтобы активировать его, используйте что-то подобное в начале файла с правилами
pf.conf
:
pass in quick on $int_if inet proto tcp to port 21 divert-to 127.0.0.1 port 8021Это перенаправляет FTP-трафик от клиентов к программе ftp-proxy, которая прослушивает порт 8021 сервера.
Также нужна привязка/якорь/anchor в разделе правил:
anchor "ftp-proxy/*"Прокси-сервер должен быть запущен, и добавлен в автозапуск в OpenBSD.
# rcctl enable ftpproxy # rcctl start ftpproxyДля поддержки подключений в активном режиме от определенных (суетливых) клиентов, может потребоваться флаг
-r
.
pass in on egress proto tcp to port 21 pass in on egress proto tcp to port > 49151При желании этот диапазон портов можно расширить. В случае ftpd(8), это выполняется с использованием переменных sysctl(8)
net.inet.ip.porthifirst
и net.inet.ip.porthilast
.
ftp-proxy может быть запущен в режиме, который заставляет его перенаправлять все FTP-соединения на конкретный FTP-сервер. Прокси-сервер будет настроен на прослушивание порта 21 firewall-а, и перенаправить все подключения к внутреннему серверу.
# rcctl set ftpproxy flags -R 10.10.10.1 -p 21 -b 192.168.0.1Здесь 10.10.10.1 - это IP-адрес фактического FTP-сервера, 21 - это порт ftp-proxy, который будет прослушивать, а 192.168.0.1 - это адрес на firewall, к которому будет привязан прокси.
Теперь о правилах pf.conf
:
ext_ip = "192.168.0.1" ftp_ip = "10.10.10.1" match out on egress inet from $int_if nat-to (egress) anchor "ftp-proxy/*" pass in on egress inet proto tcp to $ext_ip port 21 pass out on $int_if inet proto tcp to $ftp_ip port 21 user _ftp_proxyЗдесь входящее соединение на порт 21 разрешено на внешнем интерфейсе, а также соответствующее исходящее соединение с FTP-сервером. Дополнение
user _ftp_proxy
к правилу исходящего трафика
гарантирует, что разрешены будут только соединения, инициированные ftp-proxy.
tftp-proxy настраивается почти так же, как ftp-proxy. Смотри FTP-клиент за Firewall-ом.
match out on egress inet from $int_if nat-to (egress) anchor "tftp-proxy/*" pass in quick on $int_if inet proto udp from $lan to port tftp \ divert-to 127.0.0.1 port 6969 pass out quick on $ext_if inet proto udp from $lan to port tftp \ group _tftp_proxy divert-replyПриведенные выше правила разрешают исходящий трафик TFTP из внутренней сети к TFTP-серверу во внешней сети.
Последний шаг - добавить в автозапуск и запустить tftp-proxy.
# rcctl enable tftpproxy # rcctl start tftpproxy