Доступ к FTP-серверу за NAT
01.03.2020
Теги: FTP • Linux • Ubuntu • Конфигурация • ЛокальнаяСеть • Настройка • Сервер
Протокол FTP является старейшим сетевым протоколом (создан в 1971 году), но, тем не менее, широко используется по сей день. Важной особенностью протокола является то, что он использует несколько соединений: одно для управляющих команд, остальные для данных. Причем соединений для передачи данных может открываться несколько.
В зависимости от способа установления соединения для передачи данных различают активный и пассивный режимы работы FTP. В активном режиме сервер сам устанавливает соединение передачи данных к клиенту, в пассивном наоборот.
Активный режим
В активном режиме клиент устанавливает управляющее соединение на порт 21
сервера и передает специальную команду PORT
, в которой указывает свой адрес и порт для передачи данных. Получив данную команду, сервер устанавливает соединение с 20 порта на указанный в команде порт клиента.
Тут сразу виден недостаток данного метода: для работы в активном режиме клиенту требуется выделенный IP-адрес. Также определенные сложности будут возникать при нахождении клиента за брандмауэром или NAT-ом.
Пассивный режим
В пассивном режиме клиент устанавливает управляющее соединение на порт 21
сервера и передает специальную команду PASV
. В ответ сервер передает адрес и порт, на который следует устанавливать соединение для передачи данных. Получив эту информацию, клиент устанавливает подключение к серверу и начинает передачу данных.
Как видим, в пассивном режиме все соединения инициирует клиент и поэтому к нему нет никаких требований, он может находиться за NAT и брандмауэром, а также не иметь выделенного IP-адреса. Поэтому на сегодняшний день основным режимом работы FTP является пассивный.
FTP сервер за NAT
У меня дома компьютер с установленной Windows 10 и VirtualBox. Давайте создадим несколько виртуальных машин: router
, pc-1
, pc-2
, ftp-server
и web-server
(будет играть роль FTP-клиента). У виртуальной машины router
два сетевых интерфейса:
enp0s3
(сетевой мост) — смотрит в домашнюю сеть, получает ip-адрес192.168.110.8
от роутера Keenetic Airenp0s8
(виртуальная сеть) — смотрит в одну сеть с виртуальными машинамиpc-1
,pc-2
иftp-server
Виртуальная машина router
обеспечивает выход в интренет для pc-1
, pc-2
и ftp-server
. Все это более подробно можно прочитать здесь. А если совсем коротко, то тогда так
$ sudo nano /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
$ sudo sysctl -p net.ipv4.ip_forward = 1
$ sudo iptables -t nat -A POSTROUTING -o enp0s3 -j SNAT --to-source 192.168.110.8 # SNAT для enp0s3 $ sudo iptables-save > /etc/iptables/rules.v4 # должен быть установлен пакет iptables-persistent
Давайте установим на виртуальную машину ftp-server
FTP-сервер vsftpd
:
$ sudo apt install vsftpd
Про настройки подробно рассказывать не буду (подробнее можно прочитать здесь), упомяну только важные для нас:
pasv_enable=NO
— используется только активный режимpasv_enable=YES
— можно использовать пассивный режимpasv_address=XXX.XXX.XXX.XXX
— этот ip-адрес сервер будет передавать клиенту вместо своего в ответ наPASV
pasv_min_port
иpasv_max_port
— сервер будет отправлять клиенту порт из этого диапазона в ответ наPASV
$ sudo nano /etc/vsftpd.conf
# Слушать и обрабатывать входящие соединения listen=YES # Запретить доступ для анонимных пользователей anonymous_enable=NO # Использовать для авторизации учётные записи пользователей local_enable=YES # Разрешить изменения файловой системы (запись и удаление файлов) write_enable=YES # Маска для вновь создаваемых файлов и директорий local_umask=022 # Запретить пользователям выходить за пределы домашнего каталога chroot_local_user=YES # Разрешить запись в домашний каталог (иначе будет ошибка) allow_writeable_chroot=YES # Показывать скрытые файлы, которые начинаются с точки force_dot_files=NO # При выводе списка файлов показывать локальное время, а не GMT use_localtime=YES # Записывать в /var/log/vsftpd.log данные о скачиваниях и загрузках xferlog_enable=YES # Включить поддержку ASCII для замены символов переноса строки ascii_upload_enable=YES ascii_download_enable=YES # Использовать кодировку UTF-8 при работе с файловой системой utf8_filesystem=YES # Разрешить использование пассивного режима pasv_enable=NO # Диапазон портов для работы FTP-сервера в пассивном режиме #pasv_min_port=60000 #pasv_max_port=60100 # Передавать клиенту этот ip-адрес вместо своего в ответ на PASV #pasv_address=192.168.110.8
$ sudo systemctl restart vsftpd.service
Теперь на виртуальной машине router
настроим перенаправление пакетов, которые приходят на внешней интерфейс enp0s3
, порт 21
— это управляющее соединение от клиента к серверу:
$ sudo iptables -t nat -A PREROUTING -i enp0s3 -p tcp --dport 21 \ > -j DNAT --to-destination 192.168.30.254 # управляющее соединение, активный и пассивный режим
И будем перенаправлять пакеты, которые приходят на внешней интерфейс enp0s3
, порт 60000-60100
, при работе в пассивном режиме — это соединение от клиента к серверу для передачи данных:
$ sudo iptables -t nat -A PREROUTING -i enp0s3 -p tcp --dport 60000:60100 \ > -j DNAT --to-destination 192.168.30.254:60000-60100 # для передачи данных, пассивный режим
Сохраняем новые правила, чтобы они применились после перезагрузки:
$ sudo iptables-save > /etc/iptables/rules.v4
Активный режим
В реальной ситуации FTP-клиент и маршрутизатор должны иметь белые ip-адреса. Но мы здесь моделируем ситуацию, как будто бы у них белые ip-адреса. Просто потому, что у нас маршртузатор и FTP-клиент находятся в одной сети 192.168.110.0/24
и видят друг друга. Когда FTP-клиент устанавливает управляющее соединение с FTP-сервером — он отправляет пакеты на внешний интерфейс маршрутизатора, на порт 21. А маршрутизатор отправляет эти пакеты внутрь сети 192.168.30.0/24
— на ip-адрес 192.168.30.254
FTP-сервера (DNAT, первое правило).
Вроде все готово для испытаний, файл конфигурации FTP-сервера разрешает использовать только активный режим. Пробуем из сети 192.168.110.0/24
подключиться к FTP-серверу за NAT с виртуальной машины web-server
(ip-адрес 192.168.110.12
).
$ ftp > open 192.168.110.8 Connected to 192.168.110.8. 220 (vsFTPd 3.0.3) Name (192.168.110.8:evgeniy): evgeniy 331 Please specify the password. Password: пароль 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. > pwd 257 "/" is the current directory > dir 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxrwx--- 1 0 999 0 Feb 28 13:59 share drwx------ 2 1000 1000 4096 Feb 24 14:53 test 226 Directory send OK. > exit 221 Goodbye.
Сервер получил от клиента команду PORT
и успешно ее обработал — PORT command successful
. Сервер устанавливает соединение с 20 порта на указанный в команде PORT
ip-адрес и порт клиента и отправляет листинг директории. Адрес клиента — это 192.168.110.12
, сервер отправит данные в шлюз 192.168.30.1
(по дефолтному маршруту), маршрутизатор перебросит пакеты с интерфейса enp0s8
на enp0s3
и отправит дальше — FTP-клиенту web-server
.
Пассивный режим
Теперь изменим настройки сервера, чтобы разрешить работу в пассивном режиме:
$ sudo nano /etc/vsftpd.conf
# Слушать и обрабатывать входящие соединения listen=YES # Запретить доступ для анонимных пользователей anonymous_enable=NO # Использовать для авторизации учётные записи пользователей local_enable=YES # Разрешить изменения файловой системы (запись и удаление файлов) write_enable=YES # Маска для вновь создаваемых файлов и директорий local_umask=022 # Запретить пользователям выходить за пределы домашнего каталога chroot_local_user=YES # Разрешить запись в домашний каталог (иначе будет ошибка) allow_writeable_chroot=YES # Показывать скрытые файлы, которые начинаются с точки force_dot_files=NO # При выводе списка файлов показывать локальное время use_localtime=YES # Записывать в /var/log/vsftpd.log данные о скачиваниях и загрузках xferlog_enable=YES # Включить поддержку ASCII для замены символов переноса строки ascii_upload_enable=YES ascii_download_enable=YES # Использовать кодировку UTF-8 при работе с файловой системой utf8_filesystem=YES # Разрешить использование пассивного режима pasv_enable=YES # Диапазон портов для работы FTP-сервера в пассивном режиме pasv_min_port=60000 pasv_max_port=60100 # Передавать клиенту этот ip-адрес вместо своего в ответ на PASV pasv_address=192.168.110.8
$ sudo systemctl restart vsftpd.service
Пробуем подключиться к серверу
$ ftp > open 192.168.110.8 Connected to 192.168.110.8. 220 (vsFTPd 3.0.3) Name (192.168.110.8:evgeniy): evgeniy 331 Please specify the password. Password: пароль 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. > passive Passive mode on. > dir 227 Entering Passive Mode (192,168,110,8,234,149). 150 Here comes the directory listing. drwxrwx--- 1 0 999 0 Feb 28 13:59 share drwx------ 2 1000 1000 4096 Feb 24 14:53 test 226 Directory send OK. > exit 221 Goodbye.
После команды passive
(PASV
, пассивный режим), сервер сообщает клиенту ip-адрес 192.168.110.8
из директивы pasv_address
(вместо своего 192.168.30.254
) и порт — 60053
(порт вычисляется как 234*256+149=60053
). А клиент устанавливает еще одно соединение с сервером — уже для передачи данных.
Тут важно то, что FTP-сервер сообщает FTP-клиенту не свой серый ip-адрес, а белый ip-адрес внешнего интерфейса шлюза (который на самом деле серый, но мы только моделируем реальную ситуацию). И сообщает порт из диапазона 60000-60100, который мы задали в настройках FTP-сервера. FTP-клиент отправляет пакеты с данными на белый ip-адрес маршрутизатора (который на самом деле серый), на порт 60053
. А маршрутизатор отправляет эти пакеты внутрь сети 192.168.30.0/24
— на ip-адрес 192.168.30.254
FTP-сервера (DNAT, второе правило).
- Установка WireGuard на Ubuntu 20.04 LTS. Часть вторая из двух
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 12 из 12
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 11 из 12
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 10 из 12
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 9 из 12
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 8 из 12
- Установка OpenVPN на Ubuntu 18.04 LTS. Часть 7 из 12
Поиск: Linux • Ubuntu • FTP • Конфигурация • Настройка • Сервер • iptables • Активный режим • Пассивный режим • Порт • NAT • Локальная сеть