devzone.org.ua/post/orhanizatsiia-bahatokorystuvatskoho-servera-ftp-na-bazi-vsftpd.md

220 lines
No EOL
13 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Організація соціального сервера FTP на базі vsftpd
У попередньому [матеріалі](https://devzone.org.ua/post/orhanizatsiia-hostyovoho-servera-ftp), я описував свій досвід з організації **гостьового** FTP сервера для доступу до файлів на читання. Утім, довго планував організувати саме соціальний, інтерактивний інстанс в дусі колишніх локалок: де unix-юзери можуть не тільки завантажувати цікавий для них контент, але й відвантажувати свій, не заважаючи при цьому іншим користувачам сервера.
*Звісно, можна дозволити анонімний доступ на запис і закрити питання, але чесно кажучи займатись модерацією - в мене часу і бажання немає, натомість надаватиму створений обліковий запис тим, хто погоджується з умовами сервера або запрошений по інвайту.*
## Встановлення vsftpd
[vsftpd](https://en.wikipedia.org/wiki/Vsftpd) - це мабуть найвідоміший, перевірений часом сервер FTP, довкола якого написано чимало гайдів і зокрема - даний матеріал.
Встановити сервер найпростіше з репозиторію:
``` bash
apt install vsftpd
```
## Налаштування
Мій сервер працюватиме на дві локальні IPv6 мережі:
* [Mycelium](https://github.com/threefoldtech/mycelium)
* [Yggdrasil](https://yggdrasil-network.github.io) (див. також: [Yggdrasil - мережа з децентралізованим роутингом](https://devzone.org.ua/post/yggdrasil-mereza-z-detsentralizovanym-routynhom))
Ці мережі дозволяють легко організувати безкоштовний статичний 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](https://en.wikipedia.org/wiki/Fail2ban), але захист від [брутфорсу](https://uk.wikipedia.org/wiki/Пошук_грубою_силою) - це окрема історія.
### Глобальна конфігурація 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
# налаштування анонімного режиму
# ------------------------------
# дозволити гостьовий (анонімний) доступ
anonymous_enable=YES
# заборонити анонам відвантаження файлів на сервер
anon_upload_enable=NO
# заборонити анонам створення тек на сервері
anon_mkdir_write_enable=NO
# обмеження швидкості для анонімних користувачів до 128KiB/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
# шлях до користувацького конфігу, де ми вказуємо `local_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 proto tcp
ufw allow from 0400::/7 to 505:6847:c778:61a1:5c6d:e802:d291:8191 port 21 proto tcp
ufw allow from 0400::/7 to 505:6847:c778:61a1:5c6d:e802:d291:8191 port 10000:10100 proto tcp
# yggdrasil
ufw allow from 0200::/7 to 202:68d0:f0d5:b88d:1d1a:555e:2f6b:3148 port 20 proto tcp
ufw allow from 0200::/7 to 202:68d0:f0d5:b88d:1d1a:555e:2f6b:3148 port 21 proto tcp
ufw allow from 0200::/7 to 202:68d0:f0d5:b88d:1d1a:555e:2f6b:3148 port 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` - перевіряємо статус, після чого можна підключатися
## Посилання
Гостьовий (анонімний) доступ до серверу з прикладу вище - доступний за локальними адресами:
* `ftp://[505:6847:c778:61a1:5c6d:e802:d291:8191]:21` - Mycelium
* `ftp://[202:68d0:f0d5:b88d:1d1a:555e:2f6b:3148]:21` - Yggdrasil