Возникла необходимость настроить vsFTPd так, чтобы, во-первых, быстро, удобно и безопасно скачивать файлы с определённой компактной директории сервера и только с неё, а во-вторых, чтобы при этом локальные (и тем паче, анонимные) пользователи не имели полноценного доступа к серверу по ftp. Для этих целей подходит концепция т.н. виртуальных пользователей, с которыми vsftpd, что стоит на Ubuntu (версия Xenial 16.04 LTS — в данном случае не столь важно) по умолчанию, работать умеет.
В общем, задача практически тривиальная. За некоторыми но.
Во-первых, мануал с help.ubuntu.com показался не совсем адекватным и удобным. Вместо чего лично мне прекрасно подошла инструкция, выложенная пользователем на askubuntu.com. Там, как мне показалось, используется ряд интересных находок, и, чтобы не потерялось (фиксирую для себя, но мало ли какому гостю с бескрайних просторов интернета тоже сгодится 🙂), напишу свой метод настройки vsftpd, во многом основываясь на ней.
Второе «но»: vsftpd «из коробки» никак не получилось заставить работать с кириллицей (кириллическими именами файлов и директорий), однако для моей задачи оно было не столь принципиально. Вроде бы можно найти какие-то форки, которые можно собрать из исходников, но, повторюсь, конкретно в моём случае это overkill.
1. Итак, устанавливаем vsftpd, если он ещё не в системе:
~$ sudo apt install vsftpd
2. Редактируем основной конфигурационный файл. Кстати, я не сторонник вычищать всё содержимое и заменять на новое, так что иду по пути редактирования уже существующих строк:
~$ sudo vim /etc/vsftpd.conf
Вначале файла ищем и меняем параметры таким образом:
listen=YES
listen_ipv6=NO
anonymous_enable=NO
local_enable=YES
Ближе к секции chroot_local_user, что ближе к концу:
chroot_local_user=YES
pam_service_name=vsftpd # - эта же строка есть в конце файла конфига, сразу не заметил, но работает и с дублированием
local_root=/home/some/interchange/folder
allow_writeable_chroot=YES
hide_ids=YES
#user_config_dir=/etc/vsftpd_user_conf - это, видимо, для дополнительных/специфических конфигов виртуальных юзеров, хранящихся здесь в файлах с именем каждого такого юзера (в частности, можно установить local_root= для каждого), я не использовал
guest_enable=YES
virtual_use_local_privs=YES
nopriv_user=vsftpd
guest_username=vsftpd
3. Теперь нужно создать этого «кастрированного» системного юзера с именем vsftpd:
~$ sudo useradd --home /home/vsftpd --gid nogroup -m --shell /bin/false vsftpd
(Устанавливаем, если нужно, специальные права на эту директорию для внешнего доступа/обмена:
~$ sudo chown vsftpd:nogroup /home/some/interchange/folder
)
4. Теперь нужно создать, собственно, виртуального юзера(-ов), с помощью которого и будем залогиниваться на сервер по ftp.
4а. Ищем файл /etc/pam.d/vsftpd:
~$ sudo vim /etc/pam.d/vsftpd
содержимое которого полностью заменяем на:
auth required pam_pwdfile.so pwdfile /etc/vsftpd/ftpd.passwd
account required pam_permit.so
Для того, чтобы заработала аутентификация из текстового файла (в данном случае, /etc/vsftpd/ftpd.passwd), надо установить специальный PAM-модуль (по умолчанию не стоял):
~$ sudo apt install libpam-pwdfile
4b. Далее создадим папку и файл с нужным юзером(-ами) и паролем(-ями). Пусть имя для первого — userftp1:
~$ sudo mkdir /etc/vsftpd
~$ sudo htpasswd -cd /etc/vsftpd/ftpd.passwd userftp1
параметр c — это create, и если файл уже есть, можно опустить.
d — игнорирование CRYPT, без этого параметра не сработало, юзер не залогинивался. Ограничение на максимальное кол-во символов в пароле — 8. Чтобы его избежать, можно вот так вывернуться, указав пароль текстом в явном виде (пусть будет «pass-for-userftp1»):
~$ sudo htpasswd -pb /etc/vsftpd/ftpd.passwd userftp1 $(openssl passwd -1 -noverify pass-for-userftp1)
5. Ну и перезапустим демона:
~$ sudo systemctl restart vsftpd
Пробуем залогиниться, предварительно пробросив на шлюзе 21-й порт (незащищённое соединение). Локально можно вот так проверить:
~$ ftp localhost
6. Удобство виртуальных пользователей ещё и в том, что их удобно штамповать по мере надобности:
~$ sudo htpasswd -d /etc/vsftpd/ftpd.passwd userftp2
~$ sudo htpasswd -d /etc/vsftpd/ftpd.passwd userftp3
и т.д.
А также удалять ненужные:
~$ sudo htpasswd -D /etc/vsftpd/ftpd.passwd userftp2
(Не забывая перезапускать демона vsftpd.)
7. Всё бы ничего, но по современным стандартам безопасности оставлять соединение незащищённым не комильфо, хотя это и удобно. Поэтому генерируем сертификат и приватный ключ:
~$ sudo openssl req -x509 -nodes -days 1825 -newkey rsa:2048 -keyout /etc/vsftpd/vsftpd.key -out /etc/vsftpd/vsftpd.crt
И вернёмся к редактированию vsftpd.conf, пролистывая файл ближе к концу:
~$ sudo vim /etc/vsftpd.conf
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
#ssl_tlsv1_1=YES
#ssl_tlsv1_2=YES
#ssl_tlsv1=NO
#ssl_sslv2=NO
#ssl_sslv3=NO
#require_ssl_reuse=YES
#ssl_ciphers=HIGH
rsa_cert_file=/etc/vsftpd/vsftpd.crt
rsa_private_key_file=/etc/vsftpd/vsftpd.key
pasv_min_port=9019
pasv_max_port=9044
(В принципе, можно дополнительно поиграться с ssl_tlsv1_2=YES, ssl_ciphers=HIGH и прочим, но у меня завелось с закомментированными строками, в представленном выше виде.)
Последние две строки — это произвольный (в рамках разумного и незанятого другими сервисами и демонами) диапазон портов для пассивного режима работы ftp. Пробрасывается этот диапазон извне (пускай с условного адреса 8.8.8.8) на локальный сервер (пусть адрес будет 192.168.1.100) достаточно просто:
~# iptables -t nat -I PREROUTING -s 8.8.8.8 -p tcp --dport 9019:9044 -j DNAT --to 192.168.1.100:9019-9044
Но я сделал ещё проще: pasv_min_port и pasv_max_port у меня — один и тот же порт 🙂 Само собой, этот порт не занят ничем иным.
Voilà, всё работает. 🙂
P.S. Горький (ну, горьковатый) привкус только оттого, что с кириллическими названиями файлов, увы, промблема: они в ftp-клиенте отображаются кракозябрами и не скачиваются. Может, для этих целей подойдёт другой FTP-сервер?
Внимание! Администрация сайта adlersky.top не имеет отношения и не несёт никакой ответственности за публикуемые ниже, т.е. под оригинальными записями и внизу страниц сайта, комментарии, не отвечает за их содержание. Все права на комментарии (и всё бремя ответственности за публикацию) принадлежат их авторам.