vsFTPd

Thank you for reading this post, don't forget to subscribe!

На теку­щий момент есть две удач­ные реа­ли­за­ции FTP-сер­ве­ра для Linux: vsFTPd и proFTPd. В дан­ной инструк­ции речь пой­дет о пер­вом, так как его акту­аль­ная вер­сия более све­жая, в то вре­мя, как послед­няя вер­сия proFTPd выпу­ще­на в 2013 году.

Установка и базовая настройка vsFTPd

Обнов­ля­ем систему:

yum update

Запус­ка­ем про­цесс установки:

yum install vsftpd

После откры­ва­ем на редак­ти­ро­ва­ние сле­ду­ю­щий файл:

vi /etc/vsftpd/vsftpd.conf

И при­во­дим его к сле­ду­ю­ще­му виду:

anonymous_enable=NO
chroot_local_user=YES

allow_writeable_chroot=YES
pasv_min_port=40900
pasv_max_port=40999

* пер­вые две строч­ки мы редак­ти­ру­ем: anonymous_enable раз­ре­ша­ет под­клю­че­ние ано­ним­ных поль­зо­ва­те­лей, поэто­му мы отклю­ча­ем такую воз­мож­ность; chroot_local_user запре­ща­ет выход за пре­де­лы домаш­ней дирек­то­рии поль­зо­ва­те­ля. Тре­тью, чет­вер­тую и пятую стро­ки мы допи­сы­ва­ем — allow_writeable_chroot раз­ре­ша­ет под­клю­че­ния поль­зо­ва­те­лю, у кото­ро­го есть пра­ва на запись в кор­не­вую дирек­то­рию; это диа­па­зон дина­ми­че­ских пор­тов, кото­рые будут исполь­зо­вать­ся vsFTPd. Дан­ный диа­па­зон важ­но ука­зы­вать, если исполь­зу­ет­ся бранд­мау­эр. Сам диа­па­зон мож­но задать любой из неза­ре­ги­стри­ро­ван­ных портов.

 

Отклю­ча­ем SELinux сле­ду­ю­щи­ми командами:

setenforce 0

sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config

* пер­вая коман­да отклю­чит SELinux, вто­рая — отклю­чит его авто­за­пуск после перезагрузки.

Добав­ля­ем пра­ви­ла в бранд­мау­эр для кор­рект­ной рабо­ты FTP-сервера:

firewall-cmd --permanent --add-port=20-21/tcp
firewall-cmd --permanent --add-port=40900-40999/tcp
firewall-cmd --reload

Раз­ре­ша­ем авто­за­пуск vsFTPd и запус­ка­ем его:

systemctl enable vsftpd
systemctl start vsftpd

По умол­ча­нию, к vsFTPd нель­зя под­клю­чить­ся с исполь­зо­ва­ни­ем учет­ной запи­си root. Поэто­му нуж­но исполь­зо­вать дру­гую поль­зо­ва­тель­скую запись или создать новую сле­ду­ю­щей командой:

useradd ftpuser -d /var/www -s /sbin/nologin

ftpuser — имя учет­ной запи­си; /var/www — домаш­няя дирек­то­рия; /sbin/nologin запре­ща­ет локаль­ный вход в систему.

Зада­ем пароль ново­му пользователю:

passwd ftpuser

Базо­вая настрой­ка закон­че­на — мож­но про­бо­вать под­клю­чать­ся к FTP-серверу.

vsFTPd через TLS

TLS поз­во­ля­ет настро­ить без­опас­ный FTP, пере­да­ча дан­ных через кото­рый осу­ществ­ля­ет­ся по зашиф­ро­ван­но­му каналу.

Для нача­ла созда­ем сертификат:

openssl req -new -x509 -days 1461 -nodes -out /etc/vsftpd/vsftpd.pem -keyout /etc/vsftpd/vsftpd.pem -subj "/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=test.test.ru/CN=test"

* в дан­ном при­ме­ре мы созда­ем само­под­пис­ный сер­ти­фи­кат на 4 года для URL test.test.ru или test. Обра­ти­те вни­ма­ние, это один файл, в кото­ром содер­жит­ся откры­тый и закры­тый ключи.

Откры­ва­ем на редак­ти­ро­ва­ние кон­фи­гу­ра­ци­он­ный файл vsFTPd:

vi /etc/vsftpd/vsftpd.conf
И допи­сы­ва­ем в него следующее:

ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=NO
force_local_logins_ssl=NO
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
rsa_cert_file=/etc/vsftpd/vsftpd.pem

* где ssl_enable раз­ре­ша­ет исполь­зо­ва­ние шиф­ро­ва­ния; allow_anon_ssl раз­ре­ша­ет исполь­зо­вать SSL ано­ним­ным поль­зо­ва­те­лям; force_local_data_ssl тре­бу­ет исполь­зо­ва­ния шиф­ро­ва­ния, и если уста­но­вить YES, кли­ен­ты без шиф­ро­ва­ния не смо­гут под­клю­чить­ся; force_local_logins_ssl так­же тре­бу­ет под­клю­че­ние по SSLssl_tlsv1 — исполь­зо­вать TLS вер­сии 1; ssl_sslv2 — исполь­зо­вать SSL вер­сии 2; ssl_sslv3 — исполь­зо­вать SSL вер­сии 3; rsa_cert_file — путь к сертификату.

Пере­за­пус­ка­ем FTP-сервер:
systemctl restart vsftpd

Гото­во.

Виртуальные пользователи

Уста­нав­ли­ва­ем пакет compat-db:

yum install compat-db

На вся­кий слу­чай, сохра­ня­ем pam файл для авто­ри­за­ции vsftpd:
mv /etc/pam.d/vsftpd /etc/pam.d/vsftpd.back

Созда­ем новый файл со сле­ду­ю­щим содержимым:
vi /etc/pam.d/vsftpd

auth required pam_userdb.so db=/etc/vsftpd/virtual_users
account required pam_userdb.so db=/etc/vsftpd/virtual_users
session required pam_loginuid.so

* где /etc/vsftpd/virtual_users — файл, в кото­ром мы будем хра­нить пользователей.

Откры­ва­ем кон­фи­гу­ра­ци­он­ный файл сер­ве­ра FTP:

vi /etc/vsftpd/vsftpd.conf

И добав­ля­ем следующее:

guest_enable=YES
guest_username=ftp
virtual_use_local_privs=YES
user_sub_token=$USER
local_root=/home/$USER

* где guest_enable раз­ре­ша­ет вир­ту­аль­ных поль­зо­ва­те­лей; guest_username — имя систем­ной учет­ной запи­си, от кото­рой рабо­таю вир­ту­аль­ные поль­зо­ва­те­ли; virtual_use_local_privs — вир­ту­аль­ные поль­зо­ва­те­ли с таки­ми же при­ви­ле­ги­я­ми, что и локаль­ные; user_sub_token — имя учет­ной запи­си хра­нить­ся в пере­мен­ной $USERlocal_root зада­ет домаш­нюю дирек­то­рию вир­ту­аль­но­му пользователю.

Созда­ем файл с вир­ту­аль­ны­ми поль­зо­ва­те­ля­ми со сле­ду­ю­щим содержимым:

vi /etc/vsftpd/virtual_users

ftp1
passwd1
ftp2
passwd2

* где ftp1 и ftp2 — логи­ны; passwd1 и passwd2 — пароли.

Сра­зу гене­ри­ру­ем из фай­ла базу:

db_load -T -t hash -f /etc/vsftpd/virtual_users /etc/vsftpd/virtual_users.db

Необ­хо­ди­мо убе­дить­ся, что для поль­зо­ва­те­лей есть соот­вет­ству­ю­щие домаш­ние директории:

mkdir /home/ftp{1,2}

И так­же у систем­ной учет­ной запи­си есть соот­вет­ству­ю­щие права:

chown -R :ftp /home/ftp{1,2}

Пере­за­пус­ка­ем сервис:

systemctl restart vsftpd

Хранение пользователей в базе данных

В каче­стве базы дан­ных мож­но исполь­зо­вать MySQL или MariaDB. В дан­ном при­ме­ре будет исполь­зо­вать­ся последняя.

Уста­нав­ли­ва­ем СУБД сле­ду­ю­щей командой:

yum install mariadb mariadb-server

Раз­ре­ша­ем авто­за­пуск и запус­ка­ем сервис:

systemctl enable mariadb
systemctl start mariadb

Зада­ем пароль для поль­зо­ва­те­ля root:

mysqladmin -u root password

Запус­ка­ем команд­ную обо­лоч­ку mariadb:

mysql -p

Созда­ем базу дан­ных и поль­зо­ва­те­ля с пра­ва­ми толь­ко на выбор­ку данных:

CREATE DATABASE vsftpd;

GRANT SELECT ON vsftpd.* TO 'vsftpd'@'localhost' IDENTIFIED BY 'passwordftp';

* где vsftpd.* раз­ре­ша­ет доступ на все таб­ли­цы базы vsftpd; 'vsftpd'@'localhost' — учет­ная запись, у кото­рой есть пра­во под­клю­чать­ся толь­ко с локаль­но­го сер­ве­ра; passwordftp — пароль для подключения.

Под­клю­ча­ем­ся к создан­ной базе и созда­ем таблицу:

USE vsftpd;

CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 30 ) NOT NULL ,
`password` VARCHAR( 50 ) NOT NULL ,
UNIQUE (`username`)
) ENGINE = MYISAM ;

Теперь доба­вим пользователя:

INSERT INTO users (username, password) VALUES('ftpm1', md5('password'));

* где ftpm1 — логин, password — пароль.

Выхо­дим из обо­лоч­ки mariadb:

> \q

Уста­нав­ли­ва­ем модуль pam_mysql:
rpm -Uvh ftp://ftp.pbone.net/mirror/archive.fedoraproject.org/fedora/linux/releases/20/Everything/x86_64/os/Packages/p/pam_mysql-0.7-0.16.rc1.fc20.x86_64.rpm

Сохра­ня­ем копию pam файла:
mv /etc/pam.d/vsftpd /etc/pam.d/vsftpd.back

Созда­ем новый и при­во­дим его к сле­ду­ю­ще­му виду:
vi /etc/pam.d/vsftpd

session optional pam_keyinit.so force revoke
auth required pam_mysql.so user=vsftpd passwd=passwordftp host=localhost db=vsftpd table=users usercolumn=username passwdcolumn=password crypt=3
account required pam_mysql.so user=vsftpd passwd=passwordftp host=localhost db=vsftpd table=users usercolumn=username passwdcolumn=password crypt=3

* где user=vsftpd passwd=passwordftp — логин и пароль для под­клю­че­ния к базе дан­ных; db=vsftpd table=users — имя создан­ной базы дан­ных и таб­ли­цы с поль­зо­ва­те­ля­ми; usercolumn=username passwdcolumn=password — назва­ние полей, из кото­рых извле­ка­ем логи­ны и паро­ли для FTP-пользователей.

Настрой­ка заве­ше­на, про­бу­ем подключиться.

Возможные проблемы

Ошибка GnuTLS -15: An unexpected TLS packet was received

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

Для реше­ния про­бле­мы вос­поль­зуй­тесь любым из способов:

  1. Уби­ра­ем пра­ва на запись для кор­не­вой дирек­то­рии, напри­мер: chmod a-w /var/www
  2. В кон­фи­гу­ра­ци­он­ном фай­ле vsftpd добав­ля­ем сле­ду­ю­щую строку:
    allow_writeable_chroot=YES

Если это не помог­ло, отклю­чи­те шиф­ро­ва­ние, заком­мен­ти­ро­вав стро­ку ssl_enable=YES. После это­го, при под­клю­че­нии будут появ­лять­ся более инфор­ма­тив­ные сообщения.

500 OOPS: vsftpd: refusing to run with writable root inside chroot()

Ошиб­ка воз­ни­ка­ет в том слу­чае, когда у учет­ной запи­си, от кото­рой идет под­клю­че­ния есть пра­ва на запись в кор­не­вую домаш­нюю дирек­то­рию. В vsFTPd, по умол­ча­нию, это при­во­дит к ошибке.

Для реше­ния про­бле­мы вос­поль­зуй­тесь любым из способов:

  1. Уби­ра­ем пра­ва на запись для кор­не­вой дирек­то­рии, напри­мер: chmod a-w /var/www
  2. В кон­фи­гу­ра­ци­он­ном фай­ле vsftpd добав­ля­ем сле­ду­ю­щую строку:
    allow_writeable_chroot=YES

500 OOPS: cannot change directory:/…

Не суще­ству­ет дирек­то­рии или нет прав на чтение.

Про­верь­те пра­виль­ность настро­ек и то, что дирек­то­рия, дей­стви­тель­но существует.

SFTP как альтернатива FTP

Если необ­хо­ди­мо разо­во пере­не­сти на сер­вер дан­ные, мож­но обой­тись про­то­ко­лом SSH File Transfer Protocol или SFTP. Все, что для это­го нуж­но — доступ по SSH и про­грам­ма кли­ент, напри­мер, WinSCP.

FTP-клиент на CentOS

Для более удоб­ной про­вер­ки настро­ек мож­но уста­но­вить FTP-кли­ент пря­мо на сер­вер и с его помо­щью выпол­нять подключения.

Для это­го выпол­ня­ем уста­нов­ку клиента:

yum install ftp

И под­клю­ча­ем­ся к наше­му сер­ве­ру командой:

ftp localhost

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

Trying ::1…
Connected to localhost (::1).
220 (vsFTPd 3.0.2)
Name (localhost:root): ftpm1
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>