
FTP в открытом виде передаёт логины, пароли и данные в plaintext - любой в той же сети видит всё. FTPS (FTP over TLS) шифрует соединение. В сочетании с виртуальными пользователями, ограниченными chroot, vsftpd становится приемлемым выбором для задач, где SFTP недоступен.
В статье установим vsftpd на Ubuntu 24.04, настроим TLS, создадим виртуальных пользователей через PAM и разберём отличия FTP/FTPS/SFTP.
FTP, FTPS и SFTP: в чём разница
FTP (File Transfer Protocol, порты 21/20) - передаёт данные открытым текстом. Использовать без TLS в 2026 году нельзя.
FTPS (FTP Secure, порты 21 для explicit, 990 для implicit) - FTP с шифрованием TLS/SSL. Два режима:
Explicit FTPS: клиент подключается на порт 21, затем командой
AUTH TLSпереходит на зашифрованное соединениеImplicit FTPS: соединение сразу зашифровано, порт 990
SFTP (SSH File Transfer Protocol, порт 22) - не является FTP. Это отдельный протокол поверх SSH. Встроен в OpenSSH, не требует vsftpd. Если задача - безопасная передача файлов, SFTP проще и надёжнее FTPS.
vsftpd поддерживает FTPS. SFTP - это openssh-server.
Установка vsftpd
sudo apt update
sudo apt install -y vsftpd libpam-pwdfile apache2-utilslibpam-pwdfile- PAM-модуль для аутентификации через htpasswd-файлыapache2-utils- содержитhtpasswdдля создания файлов паролей
Проверьте версию:
vsftpd -v
# vsftpd: version 3.0.5
Создайте резервную копию стандартного конфига:
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.orig

Создание TLS-сертификата
Для production используйте Let's Encrypt:
sudo apt install -y certbot
sudo certbot certonly --standalone -d ftp.example.com
Сертификаты будут в /etc/letsencrypt/live/ftp.example.com/.
Для локального использования - самоподписанный сертификат:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/vsftpd.key \
-out /etc/ssl/certs/vsftpd.pem \
-subj "/C=UA/ST=Kyiv/L=Kyiv/O=MyCompany/CN=ftp.example.com"
sudo chmod 600 /etc/ssl/private/vsftpd.key
sudo chmod 644 /etc/ssl/certs/vsftpd.pemКонфигурация vsftpd с TLS
Полностью замените /etc/vsftpd.conf:
sudo nano /etc/vsftpd.conf
# Основные настройки
listen=YES
listen_ipv6=NO
anonymous_enable=NO
local_enable=YES
write_enable=YES
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
# Виртуальные пользователи
virtual_use_local_privs=YES
pam_service_name=vsftpd_virtual
guest_enable=YES
guest_username=ftpuser
# Chroot - заключить пользователей в их домашние директории
chroot_local_user=YES
allow_writeable_chroot=YES
user_sub_token=$USER
local_root=/srv/ftp/$USER
# Пассивный режим - важно для работы за NAT/firewall
pasv_enable=YES
pasv_min_port=40000
pasv_max_port=40100
pasv_address=YOUR_SERVER_IP
# TLS
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH
rsa_cert_file=/etc/ssl/certs/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.key
# Логирование
log_ftp_protocol=YES
vsftpd_log_file=/var/log/vsftpd.log
Параметры:
chroot_local_user=YES - пользователь видит только свою директорию как корень (/). Не может выйти за её пределы.
allow_writeable_chroot=YES - разрешает запись в chroot-директорию. По умолчанию запрещено из соображений безопасности; если директория не принадлежит root, включайте осознанно.
pasv_min_port=40000 и pasv_max_port=40100 - диапазон портов для пассивного режима. Эти порты нужно открыть в firewall.
force_local_data_ssl=YES и force_local_logins_ssl=YES - запрещают подключение без TLS.
require_ssl_reuse=NO - некоторые клиенты (FileZilla) не поддерживают переиспользование SSL-сессии. Отключение решает проблему с подключением.
Создание системного пользователя ftpuser
Все виртуальные пользователи будут работать от имени одного системного пользователя ftpuser:
sudo useradd --no-create-home --shell /bin/false --home /srv/ftp ftpuser
sudo mkdir -p /srv/ftp
sudo chown root:root /srv/ftpДиректория /srv/ftp принадлежит root - это требование vsftpd при включённом chroot.
Виртуальные пользователи через PAM
Создание файла паролей
# Создать файл с первым пользователем
sudo htpasswd -c /etc/vsftpd/virtual_users admin
# Добавить следующих пользователей
sudo htpasswd /etc/vsftpd/virtual_users alice
sudo htpasswd /etc/vsftpd/virtual_users bob
sudo mkdir -p /etc/vsftpd
sudo chmod 640 /etc/vsftpd/virtual_users
sudo chown root:root /etc/vsftpd/virtual_usershtpasswd создаёт файл с хешированными паролями (MD5 или bcrypt).
Настройка PAM
Создайте /etc/pam.d/vsftpd_virtual:
auth required pam_pwdfile.so pwdfile=/etc/vsftpd/virtual_users
account required pam_permit.soПроверьте, что стандартный /etc/pam.d/vsftpd не конфликтует - он используется для системных пользователей.

Создание домашних директорий для пользователей
sudo mkdir -p /srv/ftp/admin /srv/ftp/alice /srv/ftp/bob
sudo chown ftpuser:ftpuser /srv/ftp/admin /srv/ftp/alice /srv/ftp/bob
sudo chmod 750 /srv/ftp/admin /srv/ftp/alice /srv/ftp/bob
Структура:
/srv/ftp/
├── admin/ ← chroot для пользователя admin
├── alice/ ← chroot для alice
└── bob/ ← chroot для bobКаждый пользователь видит только свою директорию как /.
Запуск vsftpd
sudo systemctl restart vsftpd
sudo systemctl enable vsftpd
sudo systemctl status vsftpdНастройка firewall
# UFW
sudo ufw allow 21/tcp comment "FTP"
sudo ufw allow 990/tcp comment "FTPS Implicit"
sudo ufw allow 40000:40100/tcp comment "FTP Passive"
# iptables
sudo iptables -A INPUT -p tcp --dport 21 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 990 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 40000:40100 -j ACCEPTТестирование через curl
# Листинг директории
curl -v --user "admin:password" "ftps://ftp.example.com/" --ssl-reqd -k
# Загрузка файла
curl -v --user "admin:password" "ftps://ftp.example.com/" \
--ssl-reqd -k \
--upload-file /tmp/test.txt
# Скачивание
curl --user "admin:password" "ftps://ftp.example.com/test.txt" \
--ssl-reqd -k \
-o /tmp/downloaded.txtФлаг -k отключает проверку сертификата (для самоподписанного). В production уберите его.

Ограничение по IP через tcp_wrappers или hosts.allow
Дополнительная защита через /etc/hosts.allow:
vsftpd: 192.168.1.0/24 10.0.0.0/8
И /etc/hosts.deny:
vsftpd: ALL
Разрешаем только указанные сети, блокируем остальных.
Изоляция пользователей по доступу
Если нужно дать пользователю только read-only доступ, создайте для него отдельный конфиг в /etc/vsftpd/user_conf/:
sudo mkdir -p /etc/vsftpd/user_conf
Добавьте в vsftpd.conf:
user_config_dir=/etc/vsftpd/user_conf
Создайте /etc/vsftpd/user_conf/readonly_user:
write_enable=NOvsftpd применит этот конфиг при подключении пользователя readonly_user.
Итог
vsftpd с TLS и виртуальными пользователями - рабочее решение для задач передачи файлов, где клиент не поддерживает SFTP. Ключевые моменты: force_local_logins_ssl=YES запрещает подключение без TLS, chroot_local_user=YES изолирует пользователей, pasv_min_port/pasv_max_port упрощают настройку firewall.
Если у вас нет жёстких требований к FTP-протоколу, предпочтите SFTP через OpenSSH - он работает через единый порт 22 без дополнительного ПО.