# Організація багатокористувацького файло-обмінника на базі FTP / vsftpd У попередньому матеріалі, я описував свій досвід з організації гостьового FTP сервера для доступу до файлів на читання: => setup-anonymous-ftp-server.gmi Організація гостьового сервера FTP Утім, довго планував організувати саме соціальний, інтерактивний інстанс в дусі колишніх локалок: де unix-юзери можуть не тільки завантажувати цікавий для них контент, але й відвантажувати свій, не заважаючи при цьому іншим користувачам сервера. Звісно, можна дозволити анонімний доступ на запис і закрити питання, але чесно кажучи займатись модерацією - в мене часу і бажання немає, натомість надаватиму створений обліковий запис тим, хто погоджується з умовами сервера або запрошений по інвайту. ## Встановлення vsftpd vsftpd - це мабуть найвідоміший, перевірений часом сервер FTP, довкола якого написано чимало гайдів і зокрема - даний матеріал. Встановити сервер найпростіше з репозиторію: ``` bash apt install vsftpd ``` ## Налаштування Мій сервер працюватиме на дві локальні IPv6 мережі: => https://github.com/threefoldtech/mycelium Mycelium => https://yggdrasil-network.github.io Yggdrasil Ці мережі дозволяють легко організувати безкоштовний статичний IP за NAT в діапазонах 0400::/7 і 0200::/7 відповідно. Також, обом мережам - властиве шифрування трафіку з коробки, тому мій приклад налаштувань не міститиме само-підписаних сертифікатів TLS для авторизації користувачів засобами FTPs. Такий сертифікат можна додати тільки у випадку, якщо ви остерігаєтесь колізії приватних ключів Yggdrasil та Mycelium і підміни цільового сервера через несанкціонований "мульти-хоумінг", що мало ймовірно та у даному випадку не критично. Я також лишу гостьовий (анонімний) доступ до сервера FTP на читання усім охочим, але з певними лімітами: зокрема - по швидкості каналу. ### Створення користувачів Реєстрація нових користувачів поки буде відбуватися вручну, можливо згодом створю Веб-інтерфейс зі скриптом на бекенді. ``` bash useradd -m ps passwd ps ``` ### Користувацькі налаштування vsftpd Без цього пункту можна обійтись, але я хочу мати окремі конфіги на доданих користувачів: наприклад, щоб мати можливість збільшувати для них персональні квоти. Щоб застосувати вибіркову конфігурацію на користувача, потрібно підготувати для цього теку: ``` bash mkdir -p /etc/vsftpd/user_config_dir ``` До неї, у разі потреби, додамо файл назва якого відповідатиме юзернейму системи: ``` bash /etc/vsftpd/user_config_dir/ps ``` * і запишемо туди потрібний нам оверврайт опції: наприклад `local_root` Поки що, я не додаю жодних вибіркових опцій; цей рецепт на майбутнє. Кроками нижче - буде лише оголошено цей шлях в опції `user_config_dir`, в глобальному файлі конфігурації `/etc/vsftpd.conf`. ### Організація спільного сховища Оскільки я хочу зробити сервер соціальним, `local_root` в мене буде спільним на читання для всіх користувачів і гостей FTP: до нього будуть додаватись каталоги зареєстрованих користувачів (до яких вони зможуть писати) а також ці каталоги зможуть читати інші користувачі, включно з анонами (але писати туди - останні не зможуть). Таким чином, підготуймо одну спільну кореневу теку для `anon_root` і `local_root`: ``` bash mkdir -p /path/to/ftp_root ``` І окрему теку для користувача @ps з відповідними правами на читання: ``` bash mkdir /path/to/ftp_root/ps chown ps:ps /path/to/ftp_root/ps chmod 0644 /path/to/ftp_root/ps ``` * щодо прав на вміст, згодом звернемо увагу на опцію `local_umask` ### Обмеження авторизації по білому списку Створимо ще один файл, в якому вкажемо явно створеного користувача, а також "аноніма" для можливості авторизації по білому списку (наш глобальний конфіг vsftpd використовуватиме `userlist_enable=YES`, а цей файл - ми підключимо згодом через `userlist_file`) ``` /etc/vsftpd.userlist anonymous ps ``` * `anonymous` - гостьовий псевдо-користувач, без нього анон не зможе підключитись! * `ps` - доданий користувач, інші облікові записи додаємо по одному на рядок Якщо не вказувати білий список, то на FTP сервері можна буде залогінитись будь яким системним користувачем, включно з таким, до якого не було вказано пароль. ### Блокування брутфорсу засобами fail2ban В контексті попереднього пункту, буде корисним поставити fail2ban - утиліту, яка блокуватиме клієнтський хост при введенні таким не правильної пари логін/пароль. Адже підбираючи пароль до користувачів `/etc/vsftpd.userlist` можна так само підібрати пароль до SSH (якщо 22 порт відкритий і використовується авторизація паролем) ``` bash apt install fail2ban ``` Підтримка vsftpd в fail2ban є з коробки, я тільки вручну додав опцію: ``` /etc/fail2ban/jail.conf [vsftpd] # .. enabled = true ``` * тут можна вказати кастомний шлях журналу, якщо він у вас відрізняється Правила фільтрації для журналу vsftpd задаються у файлі: ``` /etc/fail2ban/filter.d/vsftpd.conf #failregex = .. ``` * я лишив стандартні - в мене вони працюють Користуючись fail2ban, важливо вказати в глобальній конфігурації (vsftpd.conf) опцію `dual_log_enable=YES`! Після запуску сервера, варто особисто перевірити роботу блокування, вказавши завідомо неправильний пароль: після n-ї спроби (налаштовується в конфігурації fail2ban) в FTP клієнті замість коду 530 має бути повідомлення вигляду: > Connection attempt failed with "ECONNREFUSED - Connection refused by server". ### Глобальна конфігурація vsftpd Нарешті, коли все підготовлено, можемо приступити до налаштування глобального файлу конфігурації. Тут лишу коментарі до деяких опцій, з іншими - можна ознайомитись в офіційній документації для вашої версії vsftpd. ``` /etc/vsftpd.conf # налаштування підключення # ------------------------ # вимикаю IPv4 # сервер не доступний для Інтернет/IPv4 - цей сокет мені не потрібен listen=NO # вмикаю IPv6 # буде доступний для IPv6 мереж Mycelium і Yggdrasil listen_ipv6=YES # Yggdrasil та Mycelium мають end-to-end шифрування, тому вимикаю ssl_enable=NO # вимагати підключення на канонічний 20 порт connect_from_port_20=YES # налаштування пасивного режиму сервера - ці порти повинні бути доступними (по діапазону) в фаєрвол! pasv_enable=YES pasv_max_port=10100 pasv_min_port=10000 #pasv_addr_resolve=NO #pasv_address= # файл для журналів use_localtime=YES xferlog_enable=YES xferlog_std_format=NO vsftpd_log_file=/var/log/vsftpd.log # дана опція використовується для коректної роботи fail2ban! dual_log_enable=YES # налаштування анонімного режиму # ------------------------------ # дозволити гостьовий (анонімний) доступ anonymous_enable=YES # заборонити анонам відвантаження файлів на сервер anon_upload_enable=NO # заборонити анонам створення тек на сервері anon_mkdir_write_enable=NO # обмеження швидкості для анонімних користувачів до 128 KiB/s anon_max_rate=131072 # це коренева тека для анонімних юзерів, # сюди будуть залінковуватись теки користувачів anon_root=/path/to/ftp_root # налаштування користувацького режиму # ----------------------------------- # дозволити авторизацію локальних користувачів local_enable=YES # дозволити запис (для авторизованих користувачів) write_enable=YES # стандартна маска для сутностей файлової системи local_umask=022 # обмеження швидкості для зареєстрованих користувачів - відсутні local_max_rate=0 # в рамках цієї "соціальної" збірки, така само коренева локація й для окремих користувачів # для них було створено підтеки з відповідними правами local_root=/path/to/ftp_root # шлях до теки з користувацькими конфігами (якщо такі використовуються) user_config_dir=/etc/vsftpd/user_config_dir/ # безпека # ------- # ізолюємо користувачів у їх домашніх теках (вказаних в `chroot_list_file`) chroot_local_user=YES chroot_list_enable=NO secure_chroot_dir=/var/run/vsftpd/empty allow_writeable_chroot=YES # активуємо "білий" список дозволених користувачів, який ми створили раніше userlist_enable=YES userlist_file=/etc/vsftpd.userlist userlist_deny=NO # дозволяю для зручності навігації в клієнті FTP dirmessage_enable=YES # я вважаю, що ховати "приховані" файли (що починаються з крапки) сенсу немає, # бо доступ до них буде все одно, але про них можна забути і додати випадково. # * якщо потрібно обмежити доступ по масці - дивіться опції типу `deny_file`. force_dot_files=YES ``` ### Фаєрвол Мій приклад ufw/iptables для конфігурації вище: ``` bash # mycelium ufw allow from 0400::/7 to 505:6847:c778:61a1:5c6d:e802:d291:8191 port 20,21,10000:10100 proto tcp # yggdrasil ufw allow from 0200::/7 to 202:68d0:f0d5:b88d:1d1a:555e:2f6b:3148 port 20,21,10000:10100 proto tcp ``` Можна дозволити порти 20, 21, 10000-10100 для всіх мереж: ``` bash ufw allow 20/tcp ufw allow 21/tcp ufw allow 10000:10100/tcp ``` ## Запуск * `systemctl restart vsftpd` - застосовуємо конфігурацію перезапуском сервера * `systemctl enable vsftpd` - автозапуск сервера при старті системи * `systemctl status vsftpd` - перевіряємо статус, після чого можна підключатися ## Посилання => duplo.gmi Дупло: соціальна мережа в форматі FTP => https://devzone.org.ua/post/orhanizatsiia-bahatokorystuvatskoho-servera-ftp-na-bazi-vsftpd Веб-версія цієї публікації з коментарями на DevZone ### Дивіться також => setup-anonymous-ftp-server.gmi Організація гостьового сервера FTP => yggdrasil-is-network-with-distributed-routing.gmi Yggdrasil - мережа з децентралізованою маршрутизацією => fail2ban-startup-failure-fix-on-debian-12.gmi Виправлення помилки запуску fail2ban в Debian 12