Загрузка файлов в домашний каталог пользователя с помощью vsftpd

Published by Leave your thoughts

FTP (File Transfer Protocol) – это сетевой протокол для обмена файлами между сервером и клиентом. Поскольку FTP передаёт данные в незашифрованном виде, он считается крайне опасным; вместо него рекомендуется использовать vsftp – версию протокола, которая поддерживает шифрование данных. Многие пользователи сети Интернет предпочитают загружать данные с помощью браузера с помощью https; пользователи, имеющие навыки работы с командной строкой, обычно используют безопасные протоколы вроде scp или sFTP.

FTP часто используется для поддержки приложений и рабочих процессов со специфическими потребностями. Если ваше приложение позволяет вам выбирать протокол, выберите более современное решение, например, vsftp. Оптимизированный и высокопроизводительный протокол vsftp обеспечивает надежную защиту от уязвимостей, обнаруженных в других версиях FTP. Кроме того, он является протоколом по умолчанию для многих дистрибутивов Linux.

Данное руководство поможет настроить vsftp для загрузки файлов в домашний каталог пользователя с помощью FTP и учётных данных SSL/TLS.

Требования

  • Сервер Ubuntu 16.04 (о начальной настройке сервера можно узнать здесь).
  • Пользователь с правами sudo.

1: Установка vsftp

Обновите индекс пакетов и установите демон vsftp:

sudo apt update
sudo apt install vsftpd

После завершения установки создайте копию конфигурационного файла (так в случае ошибки вы сможете вернуться к оригинальному файлу):

sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.orig

2: Настройка брандмауэра

Для начала проверьте состояние брандмауэра и узнайте, какие сервисы он поддерживает на данный момент.

sudo ufw status
Status: active
To Action  From
-- ------  ----
OpenSSH ALLOW   Anywhere
OpenSSH (v6)   ALLOW   Anywhere (v6)

Примечание: Список правил брандмауэра может отличаться.

Как видите, в данном случае брандмауэр пропускает только трафик ssh. Нужно разблокировать трафик FTP.

Откройте порты 20 и 21 для FTP, порт 990 для TLS (который будет включен позже), диапазон пассивных портов 40000-50000:

sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 990/tcp
sudo ufw allow 40000:50000/tcp
sudo ufw status

Теперь правила брандмауэра выглядят так:

Status: active
To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
990/tcp                    ALLOW       Anywhere
20/tcp                     ALLOW       Anywhere
21/tcp                     ALLOW       Anywhere
40000:50000/tcp            ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
20/tcp (v6)                ALLOW       Anywhere (v6)
21/tcp (v6)                ALLOW       Anywhere (v6)
990/tcp (v6)               ALLOW       Anywhere (v6)
40000:50000/tcp (v6)       ALLOW       Anywhere (v6)

3: Подготовка каталога пользователя

Создайте пользователя для FTP; возможно такой пользователь у вас уже есть.

Примечание: Во время работы права существующего пользователя не будут изменяться. Однако лучше создать нового пользователя для работы FTP.

Создайте пользователя:

sudo adduser 8host

Выберите пароль нового пользователя, остальные данные можно оставить по умолчанию.

FTP гораздо безопаснее, когда пользователи ограничены определённым каталогом. vsftpd выполняет это с помощью механизма chroot jail («тюрьмы» chroot). Когда chroot включен для локальных пользователей, они по умолчанию ограничиваются домашним каталогом. Однако vsftpd не может дать пользователю права на запись в домашнем каталоге, поскольку тогда vsftpd не сможет обеспечить защиту этого каталога. Новые пользователи смогут подключаться через FTP, но существующим пользователям необходимо иметь право на запись в домашнем каталоге.

Мы не станем отнимать у пользователей этого права. Вместо этого можно создать каталог ftp для поддержки окружения chroot и каталог files для хранения файлов.

Создайте каталог ftp, установите права на него и отнимите право на запись в этом каталоге.

sudo mkdir /home/8host/ftp
sudo chown nobody:nogroup /home/8host/ftp
sudo chmod a-w /home/8host/ftp

Проверьте права на каталог:

sudo ls -la /home/8host/ftp
total 8
4 dr-xr-xr-x  2 nobody nogroup 4096 Aug 24 21:29 .
4 drwxr-xr-x 3 8host  8host   4096 Aug 24 21:29 ..

Теперь создайте каталог для хранения файлов и передайте пользователю права собственности на него.

sudo mkdir /home/8host/ftp/files
sudo chown 8host:8host /home/8host/ftp/files

Проверьте права на этот каталог:

sudo ls -la /home/8host/ftp
total 12
dr-xr-xr-x 3 nobody nogroup 4096 Aug 26 14:01 .
drwxr-xr-x 3 8host  8host   4096 Aug 26 13:59 ..
drwxr-xr-x 2 8host  8host   4096 Aug 26 14:01 files

Теперь добавьте файл test.txt, с помощью которого можно протестировать настройку.

echo "vsftpd test file" | sudo tee /home/8host/ftp/files/test.txt

4: Настройка FTP-доступа

Дайте одному пользователю с аккаунтом локальной оболочки право на FTP-подключения. Все необходимые параметры можно найти в vsftpd.conf. Откройте этот конфигурационный файл и убедитесь, что он содержит такие параметры:

sudo nano /etc/vsftpd.conf
. . .
# Allow anonymous FTP? (Disabled by default).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
local_enable=YES
. . .

Чтобы разрешить пользователям подгружать файлы, раскомментируйте write_enable:

. . .
write_enable=YES
. . .

Затем раскомментируйте chroot, чтобы заблокировать пользователям, подключившимся через FTP, доступ к файлам и каталогам вне этого дерева каталогов.

. . .
chroot_local_user=YES
. . .

Добавьте директиву user_sub_token, чтобы вставить имя пользователя в путь local_root directory. Это позволит в дальнейшем добавить новых пользователей.

user_sub_token=$USER
local_root=/home/$USER/ftp

Ограничьте диапазон портов для FTP:

pasv_min_port=40000
pasv_max_port=50000

Примечание: Этот диапазон портов был разблокирован в разделе 2. Если вы указали в файле другой диапазон, откорректируйте настройки брандмауэра.

Поскольку пользователи будут иметь доступ к FTP на индивидуальной основе, настройте FTP таким образом, чтобы доступ пользователю предоставлялся только после явного добавления в список (а не по умолчанию).

userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

Строка userlist_deny изменяет логику. Когда в ней установлено значение YES, пользователи не могут получить доступ к FTP. Значение NO даёт FTP-доступ только пользователям из списка.

Сохраните и закройте файл.

Создайте и пользователя и добавьте его в файл. Флаг –a вставит данные о пользователе в файл:

echo "8host" | sudo tee -a /etc/vsftpd.userlist

Убедитесь, что пользователь был внесён в список:

cat /etc/vsftpd.userlist
8host

Перезапустите демон, чтобы обновить настройки:

sudo systemctl restart vsftpd

5: Тестирование FTP-доступа

На данный момент FTP-доступ есть только у пользователя 8host. Протестируйте эту настройку.

Анонимным пользователям должно быть отказано в доступе. Анонимный доступ отключен. Чтобы убедиться в этом, попробуйте подключиться анонимно. Если всё работает должным образом, на экране появится:

ftp -p 203.0.113.0
Connected to 203.0.113.0.
220 (vsFTPd 3.0.3)
Name (203.0.113.0:default): anonymous
530 Permission denied.
ftp: Login failed.
ftp>

Закройте это соединение:

bye

Всем пользователям, кроме 8host, должно быть отказано в доступе. Попробуйте создать подключение как другой пользователь.

ftp -p 203.0.113.0
Connected to 203.0.113.0.
220 (vsFTPd 3.0.3)
Name (203.0.113.0:default): sudo_user
530 Permission denied.
ftp: Login failed.
ftp>

Закройте это соединение:

bye

Пользователю 8host должен иметь возможность создавать подключения, а также иметь права на чтение и запись. Попробуйте создать соединение как 8host:

ftp -p 203.0.113.0
Connected to 203.0.113.0.
220 (vsFTPd 3.0.3)
Name (203.0.113.0:default): 8host
331 Please specify the password.
Password: your_user's_password
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

Перейдите в каталог files и используйте команду get, чтобы переместить тестовый файл на локальную машину:

cd files
get test.txt
227 Entering Passive Mode (203,0,113,0,169,12).
150 Opening BINARY mode data connection for test.txt (16 bytes).
226 Transfer complete.
16 bytes received in 0.0101 seconds (1588 bytes/s)
ftp>

Теперь попробуйте выгрузить в этот каталог другой файл:

put test.txt upload.txt
227 Entering Passive Mode (203,0,113,0,164,71).
150 Ok to send data.
226 Transfer complete.
16 bytes sent in 0.000894 seconds (17897 bytes/s)

Закройте это соединение:

bye

6: Защита транзакций

FTP не шифрует передаваемые данные, в том числе и учётные данные пользователей. Это позволяет злоумышленникам перехватить их. Настройте TTL/SSL шифрование. Для начала создайте SSL-сертификат для vsftpd.

Используйте openssl, чтобы создать новый сертификат. Флаг -days указывает срок действия сертификата в днях (в данном случае сертификат действителен в течение одного года). Добавьте в команду закрытый 2048-битный RSA-ключ. Флаги -keyout и –out должны иметь одинаковые значения, чтобы ключ и сертификат были помещены в один файл.

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem

Программа запросит ваши данные. Замените условные данные в примере ниже.

Generating a 2048 bit RSA private key
............................................................................+++
...........+++
writing new private key to '/etc/ssl/private/vsftpd.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:NY
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My_Company
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

Получив сертификат, вернитесь в конфигурационный файл vsftpd.

sudo nano /etc/vsftpd.conf

В конец файла добавьте параметры ключа и закомментируйте их:

# rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
# rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

Ниже добавьте следующие строки, которые будут указывать путь к сертификату и закрытому ключу.

rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem

После этого нужно настроить поддержку SSL, чтобы защитить клиентов, у которых нет доступа к TLS-подключениям. Так вы обеспечите шифрование всего трафика, однако это может заставить FTP-пользователей изменить клиенты. В строке ssl_enable укажите значение YES.

ssl_enable=YES

Ниже добавьте следующие строки, чтобы заблокировать анонимные подключения через SSL и включить SSL для передачи данных и входа.

allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES

Теперь нужно настроить сервер для поддержки TLS, альтернативы SSL:

ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO

Ниже добавьте ещё две опции. Первая отключит повторное использование SSL, потому что это может повлиять на работу многих FTP-клиентов. Вторая установит длину ключа (128 бит и больше):

require_ssl_reuse=NO
ssl_ciphers=HIGH

Сохраните и закройте файл.

Перезапустите сервер:

sudo systemctl restart vsftpd

С этого момента вы больше не можете подключаться с помощью небезопасного клиента командной строки. Если вы попробуете сделать это, вы получите ошибку:

ftp -p 203.0.113.0
Connected to 203.0.113.0.
220 (vsFTPd 3.0.3)
Name (203.0.113.0:default): 8host
530 Non-anonymous sessions must use encryption.
ftp: Login failed.
421 Service not available, remote server has closed connection
ftp>

Теперь нужно убедиться, что клиент с поддержкой TLS может создавать соединения.

7: Тестирование TLS с помощью FileZilla

Современные FTP-клиенты могут поддерживать шифрование TLS. Попробуйте подключиться с помощью одного из таких клиентов.

Примечание: В руководстве используется FileZilla. При желании вы можете выбрать другой клиент.

Откройте FileZilla и нажмите Site Manager (слева в верхнем ряду).

В появившемся окне нажмите New Site.

В записях My Sites появится New site. Вы можете выбрать название сейчас или вернуться к этому позже (с помощью кнопки Rename).

В поле Host укажите IP-адрес. В выпадающем меню Encryption выберите Require explicit FTP over TLS. В Logon Type выберите Ask for password. В поле User введите имя пользователя FTP. Нажмите Connect.

Программа запросит пароль пользователя. Введите его и нажмите OK. Теперь соединение с сервером шифруется через TLS/SSL. На экране появятся данные сертификата.

Приняв сертификат, дважды кликните по папке files и перетащите upload.txt в левую часть экрана, чтобы убедиться, что вы можете загружать файлы.

Затем кликните правой кнопкой по локальной копии файла, переименуйте его (например, в upload-tls.txt) и перетащите его обратно в правую часть экрана, чтобы убедиться, что вы можете подгружать файлы на сервер.

8: Отключение шелл-доступа

Если ваш клиент не поддерживает TLS, вы можете повысить безопасность сервера, отключив другие методы входа. Одним из относительно простых методов является создание пользовательской оболочки.

Откройте файл ftponly:

sudo nano /bin/ftponly

Добавьте сообщение:

#!/bin/sh
echo "This account is limited to FTP access only."

Измените права, чтобы сделать файл исполняемым:

sudo chmod a+x /bin/ftponly

Откройте список валидных оболочек.

sudo nano /etc/shells

Добавьте в конец списка:

. . .
/bin/ftponly

Обновите оболочку пользователя:

sudo usermod 8host -s /bin/ftponly

Попробуйте войти как пользователь 8host:

ssh 8host@203.0.113.0

На экране появится:

This account is limited to FTP access only.
Connection to 203.0.113.0 closed.

Это значит, что пользователь не может подключаться через ssh и ограничен доступом FTP.

Tags: , , , , ,

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>