Часто в резюме, в графе профессиональные навыки, встречаю упоминания FTP серверов, например:
Навыки: Опыт работы в компании с более 150 пользователей Установка, настройка и администрирование Debian, Ubuntu ... ... ... Администрирование ftp сервера: vsftpd
Не знаю как кто относится к подобным фразам, но у меня они вызывают лишь улыбку. Но в случае с profptd, особенно зная его широкий функционал, я бы сказал, что его смело можно указывать в резюме, если речь конечно не о типовой конфигурации - тривиальная настройка ftp сервера.
Итак, что же такое proftpd? Как я уже говорил выше, пожалуй один из самых «мощных» и продвинутых ftp серверов. Правда у этой медали есть и обратная сторона - в нем чаще, чем в других ftp серверах находят уязвимости. Поэтому, если вы используете его на боевых серверах, то необходимо следить за обновлениями.
ProFTPd — FTP-сервер для Linux и UNIX-подобных операционных систем. ProFTPd использует один конфигурационный файл proftpd.conf. Сам сервер может быть настроен для работы нескольких виртуальных хостов, также поддерживает chroot и IPv6. Может быть запущен в виде отдельного сервера (демона) или в составе суперсервера xinetd.
Ниже перечислю наиболее значимый функционал
Итак, почему я назвал статью нестандартная настройка? Потому что у нас ftp сервер по сути будет выполнять 3 функции
У нас будет 4 виртуальных хоста со следующими настройками:
Установить сам proftpd вы можете любым удобным для вас способом, но в CentOS 6 к сожалению в репозитариях идет старая версия 1.3.3g-4.el6, к тому же в ней нет поддержки TLS. Но это не проблема, в составе тарбола самого proftpd идет spec файл, так что все, что нам нужно - это собрать пакет с нужными нам опциями.
# wget ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.5a.tar.gz # rpmbuild -ta --target=x86_64 --with ldap --with mysql --with pcre --with ssl --with wrap proftpd-1.3.5.tar.gz Building target platforms: x86_64 Building for target x86_64 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.HmqOvI + umask 022 + cd /root/rpmbuild/BUILD + cd /root/rpmbuild/BUILD + rm -rf proftpd-1.3.4e + /bin/tar -xf - ... ... ... Wrote: /root/rpmbuild/SRPMS/proftpd-1.3.5-0.1.a.el6.src.rpm Wrote: /root/rpmbuild/RPMS/x86_64/proftpd-1.3.5-0.1.a.el6.x86_64.rpm Wrote: /root/rpmbuild/RPMS/x86_64/proftpd-ldap-1.3.5-0.1.a.el6.x86_64.rpm Wrote: /root/rpmbuild/RPMS/x86_64/proftpd-mysql-1.3.5-0.1.a.el6.x86_64.rpm Wrote: /root/rpmbuild/RPMS/x86_64/proftpd-wrap-1.3.5-0.1.a.el6.x86_64.rpm Wrote: /root/rpmbuild/RPMS/x86_64/proftpd-devel-1.3.5-0.1.a.el6.x86_64.rpm Wrote: /root/rpmbuild/RPMS/x86_64/proftpd-utils-1.3.5-0.1.a.el6.x86_64.rpm Wrote: /root/rpmbuild/RPMS/x86_64/proftpd-debuginfo-1.3.5-0.1.a.el6.x86_64.rpm Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.1ngMCo + umask 022 + cd /root/rpmbuild/BUILD + cd proftpd-1.3.5a + rm -rf /root/rpmbuild/BUILDROOT/proftpd-1.3.5-0.1.a.el6.x86_64 + rm -rf /root/rpmbuild/BUILD/proftpd-1.3.5 + exit 0
После этого ставим сам proftpd
# cd /root/rpmbuild/RPMS/x86_64/ # rpm -ivh proftpd-1.3.5-0.1.a.el6.x86_64.rpm proftpd-utils-1.3.5-0.1.a.el6.x86_64.rpm proftpd-ldap-1.3.5-0.1.a.el6.x86_64.rpm
Остальные пакеты, а именно
необходимо будет доустановить по мере необходимости. А теперь переходим к самому интересному, настройкой proftpd, а именно к редактированию файла /etc/proftpd.conf.
Несколько комментариев к данному файлу. Все, что касается описания виртуальных хостов и их характеристик я специально вынес в отдельные файлы, которые располагаются в /etc/proftpd/conf.d/. Это сделано специально, чтобы основной конфигурационный файл было удобно читать и он не загромождался описанием виртуальных хостов. Примерно также принято делать и в apache/nginx. Т.е. здесь мы описываем глобальные переменные и поведение сервера в целом, а уже в конкретном виртуальном хосте - конкретизируем эти требования.
ServerAdmin root@localhost ServerType standalone AccessGrantMsg "User %u logged in." # Загружаем необходимые модули LoadModule mod_auth_pam.c LoadModule mod_ldap.c LoadModule mod_sftp.c LoadModule mod_tls.c LoadModule mod_rewrite.c <IfModule mod_auth_pam.c> AuthPAMConfig proftpd </IfModule> # Указываем какие версии протокола можно использовать при шифровании канала в ftps режиме <IfModule mod_tls.c> # TLSv1.1 TLSv1.2 будет работать только в 1.3.5+. В 1.3.4 можно указывать только TLSv1 TLSProtocol TLSv1 TLSv1.1 TLSv1.2 </IfModule> # Отключаем сервер по умолчанию (default server) DefaultServer off Port 0 # Задаем маску по умолчанию Umask 022 # Задаем режим отображения содержимого директорий ListOptions "-a" # Включаем поддержку докачки и дозагрузки файлов AllowRetrieveRestart on AllowStoreRestart on # Максимальное количество дочерних процессов. Так же ограничивает кол-во одновременных соединений MaxInstances 20 # Пользователь и группа, от которых работает proftpd User nobody Group nobody # Включаем использование sendfile() функциональности, что снижает затраты на ресурсы, # но его включение нарушает отображение статистики в таких утилитах как ftptop и ftpwho UseSendfile yes # Путь к служебному файлу Scoreboard, который используется для хранения т.н. "scoreboard" информации, # например, для корректной обработки MaxClients ScoreboardFile /var/run/proftpd.score # Задаем временную зону, соответствующую настройкам сервера TimesGMT off SetEnv TZ :/etc/localtime # Отключаем проверку reverse DNS записей и Ident UseReverseDNS off IdentLookups off # Ограничиваем максимальный размер загружаемого файла. MaxStoreFileSize 512 Mb # Включаем поддержку более безопасной загрузки файлов. Вначале файл загружается с именем .in.filename.ext # И только после успешной и полной загрузки он переименовывается в filename.ext. Позволяет избежать проблем # частичной загрузки файлов, а так же случаев, когда частично загруженный файл начинает использоваться системой HiddenStores on # Подключаем необходимый виртуальный хост, если в /etc/sysconfig/proftpd есть соответствующая директива # например для включение VHOST1_21 добавляем PROFTPD_OPTIONS="-DVHOST1_21" <IfDefine VHOST1_21> Include /etc/proftpd/conf.d/vhost1_default_21.conf </IfDefine> <IfDefine VHOST2_2121> Include /etc/proftpd/conf.d/vhost2_2121.conf </IfDefine> <IfDefine VHOST3_3333> Include /etc/proftpd/conf.d/vhost3_3333.conf </IfDefine> <IfDefine VHOST4_4444> Include /etc/proftpd/conf.d/vhost4_4444.conf </IfDefine> # Глобальные переменные <Global> RequireValidShell off AllowOverwrite yes DenyFilter \*.*/ <Limit SITE_CHMOD> DenyAll </Limit> </Global> # Включаем логирование LogFormat default "%h %l %u %t \"%r\" %s %b" LogFormat auth "%v [%P] %h %t \"%r\" %s" ExtendedLog /var/log/proftpd/access.log read,write
Ниже привожу содержимое /etc/sysconfig/proftpd
# cat /etc/sysconfig/proftpd PROFTPD_OPTIONS="-DVHOST1_21 -DVHOST2_2121 -DVHOST3_3333 -DVHOST4_4444"
А теперь опишем первый виртуальный хост. Так как это будет чистый ftp и использоваться он будет только одной программой, то нет смысла заводить системного пользователя. Вместо этого мы будем использовать виртуальных пользователей. Данные о самом пользователе будут храниться в обычном текстовом файле.
# ftpasswd --passwd --file /etc/proftpd/virtual_users.passwd --sha512 --gid 99 --uid 99 --shell /sbin/nologin --name screen --home /vhosts/screen.example.net ftpasswd: using alternate file: /etc/proftpd/virtual_users.passwd ftpasswd: creating passwd entry for user screen Password: Re-type password: ftpasswd: entry created
В результате у нас получится файл с примерно таким содержимым
# cat /etc/proftpd/virtual_users.passwd screen:$6$Vs7rWzTNHOp4JNCW$bvB7i5bd.t.lVEhXmn5J/0/LbtKcX6bMV352t4jULazNpZLhbjqNjR/zxx8Fzjuse83lgplE7PFR9mjzVJHGw1:99:99::/vhosts/screen.example.net:/sbin/nologin
### # /etc/proftpd/conf.d/vhost1_default_21.conf ### <VirtualHost screen.example.net> # Задаем общие настройки виртуального хоста ServerName "FTP: Screenshots." DefaultRoot ~ DefaultServer on Umask 002 Port 21 # Задаем поддержку только FTP протокола. На момент написания статьи 26.02.2016 proftpd # поддерживал следующие протоколы - ftp/ftps/sftp/scp(mod_sftp) Protocols ftp # Разрешаем аутентификацию только через модуль mod_auth_file, который является авторитативным. # Так как ProFTPD обрабатывает модули в порядке их указания, то добавление * в конце имени модуля # говорит о том, что поиск стоит прекратить, так как ответ данного модуля "заслуживает доверие" AuthOrder mod_auth_file.c* # А здесь мы указываем путь к файлу, который мы создали перед этим. Именно на основании его содержимого # и будет производиться аутентификация. Так же задаем дополнительное ограничение, домашний каталог # пользователя должен быть /vhosts/screen.example.net/. Так же можно ограничить и имя пользователя AuthUserFile /etc/proftpd/virtual_users.passwd home ^/vhosts/screen.example.net$ # Разрешаем вход только пользователю screen <Limit LOGIN> AllowUser screen DenyAll </Limit> # В целях безопасности запрещаем удаление или переименование файлов, только upload и download <Directory /vhosts/screen.example.net/*> <Limit DELE RMD XRMD RNFR RNTO> DenyAll </Limit> </Directory> </VirtualHost>
Второй виртуальный хост используется разработчиками, для тестирования различных CMS. Тут как бы все просто.
### # /etc/proftpd/conf.d/vhost2_2121.conf ### <VirtualHost sftp.example.net> # Задаем общие настройки виртуального хоста ServerName "SFTP: Staging." DefaultRoot ~ Umask 002 Port 2121 # Полностью сбрасываем все привилегии root, как только пользователь прошел аутентификацию # Данная опция будет работать, только если номер порта > 1024 RootRevoke on # Задаем поддержку только FTP протокола. На момент написания статьи 26.02.2016 proftpd # поддерживал следующие протоколы - ftp/ftps/sftp/scp(mod_sftp) Protocols sftp # Разрешаем аутентификацию только через модуль mod_auth_unix, который является авторитативным. # Т.е. будут использоваться системные пользователи AuthOrder mod_auth_unix.c* # Включаем модуль sftp <IfModule mod_sftp.c> SFTPEngine on SFTPLog /var/log/proftpd/sftp.log SFTPHostKey /etc/ssh/ssh_host_rsa_key SFTPHostKey /etc/ssh/ssh_host_dsa_key SFTPAuthMethods password SFTPCompression delayed </IfModule> </VirtualHost>
И на последок я оставил, пожалуй, «сложный» виртуальный хост. Он используется front-end разработчиками для проверки SSI (Server Side Includes). Для того, чтобы на сервере был порядок и было понятно, кто и какой проект загрузил, то я решил использовать существующую базу LDAP. Что очень удобно, так как позволяет заходить пользователю с уже имеющимися доменными учетными данными. Но так, как сам по себе ftp протокол никак не защищен, то мы будем использовать шифрование - FTPS. Но почему же тогда не использовать sftp? Тут чисто технические ограничения - пользователям удобно, когда папка на FTP сервере монтируется как сетевой диск. В случае с sftp протоколом я не смог найти нормальной и бесплатной программы, которая поддерживала бы монтирование сетевого диска с удаленного сервера по sftp протоколу. Если вы такую знаете - буду рад услышать.
У FTPS есть два режима работы - explicit и implicit. Если производить аналогии с smtp, то в первом случае мы будем использовать некий аналог starttls, чтобы указать серверу, что необходимо шифрование. Во втором случае мы явно должны установить шифрованный тунель и лишь потом производить любой обмен данными. Для включения implicit режима в TLSOptions необходимо добавить UseImplicitSSL.
FileZilla: Explicit FTP
ftpes://user:[email protected]:port/
Command line: Explicit FTP
# openssl s_client -connect ip.add.re.ss:port -starttls ftp
FileZilla: Implicit FTP
ftps://user:[email protected]:port/
Command line: Implicit FTP
# openssl s_client -connect ip.add.re.ss:port
Однозначно сложно сказать, какой из режимов лучше использовать. Тут придется пробовать, многое будет зависеть от ftp клиентов, но implicit режим считается устаревшим.
### # /etc/proftpd/conf.d/vhost3_3333.conf ### <VirtualHost ftps.example.net> # Задаем общие настройки виртуального хоста ServerName "FTPES: SSI." DefaultRoot ~ Umask 002 Port 3333 # Полностью сбрасываем все привилегии root, как только пользователь прошел аутентификацию # Данная опция будет работать, только если номер порта > 1024 RootRevoke on # Задаем поддержку только FTP протокола. На момент написания статьи 26.02.2016 proftpd # поддерживал следующие протоколы - ftp/ftps/sftp/scp(mod_sftp) Protocols ftps # Разрешаем аутентификацию только через модуль mod_ldap, который является авторитативным. # Т.е. будут использоваться пользователи из LDAP каталога AuthOrder mod_ldap.c* # Включаем шифрование <IfModule mod_tls.c> # Включаем поддержку TLS TLSEngine on TLSLog /var/log/proftpd/tls.log # Требуем обязательного шифрования канала данных и управляющего канала TLSRequired on # Другие опция нашего шифрования TLSOptions NoCertRequest EnableDiags NoSessionReuseRequired # указываем сертификат и ключ TLSRSACertificateFile /etc/pki/proftpd/ftps.example.net.crt TLSRSACertificateKeyFile /etc/pki/proftpd/ftps.example.net.key TLSCipherSuite kEECDH+AES128:kEECDH:kEDH:-3DES:kRSA+AES128:kEDH+3DES:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv2 </IfModule> # Включаем поддержку LDAP <IfModule mod_ldap.c> # Задаем адрес LDAP сервера, а так же где и как искать пользователей LDAPServer 127.0.0.1:389 LDAPProtocolVersion 3 LDAPAuthBinds on LDAPBindDN "uid=ldap_reader,ou=System,ou=users,dc=example,dc=net" "7654321" LDAPUsers ou=users,dc=example,dc=net "(&(uid=%u)(objectclass=posixAccount))" LDAPGroups ou=groups,dc=example,dc=net # Задаем, чтобы у всех аутентифицированных пользователей LDAP был одинаковый uid/gid LDAPForceDefaultUID on LDAPForceDefaultGID on # 99/99 - nobody/nobody LDAPDefaultUID 99 LDAPDefaultGID 99 # Указываем автоматически создавать домашнюю папку для пользователя. Задаем права и владельца CreateHome on 0775 skel /etc/skel/empty dirmode 0775 uid 99 gid 99 LDAPGenerateHomedir on 0775 LDAPGenerateHomedirPrefix /vhosts/ssi.example.net LDAPForceGeneratedHomedir on </IfModule> </VirtualHost>
Так как пользователей в LDAP более 500, то функция автоматического создания home директории при первом заходе - очень удобная и сильно облегчает жизнь администратору.
На днях попался интересный вопрос на ServerFault. В котором человек спрашивал про возможность использовать sftp сервис, проходить аутентификацию с помощью открытых ключей и при этом, чтобы не было необходимости для каждого пользователя создавать учетную запись, даже виртуальную. При этом нужно сделать так, чтобы пользователи видели только свои данные и не имели доступа к данным друг друга.
Даже казалось бы такой сложный и «странный» сервис можно настроить средствами ProFTPD. За этого я его и люблю и мирюсь с относительно частыми проблемами безопасности. Это как раз тот случай, когда за функционал приходится платить.
### # /etc/proftpd/conf.d/vhost4_4444.conf ### <VirtualHost backup.example.net> ServerName "SFTP: Backup server. Public key auth only!" DefaultRoot ~ Umask 002 Port 4444 # Задаем поддержку только SFTP протокола. На момент написания статьи 26.02.2016 proftpd # поддерживал следующие протоколы - ftp/ftps/sftp/scp(mod_sftp) Protocols sftp # Разрешаем аутентификацию только через модуль mod_auth_file, который является авторитативным. # Так как ProFTPD обрабатывает модули в порядке их указания, то добавление * в конце имени модуля # говорит о том, что поиск стоит прекратить, так как ответ данного модуля "заслуживает доверие" AuthOrder mod_auth_file.c* RootRevoke on # Включаем модуль sftp <IfModule mod_sftp.c> SFTPEngine on SFTPLog /var/log/proftpd/sftp.log SFTPHostKey /etc/ssh/ssh_host_rsa_key SFTPHostKey /etc/ssh/ssh_host_dsa_key # Путь к файлу с DH параметрами (Diffie-Hellman) SFTPDHParamFile /etc/pki/proftpd/dhparam_2048.pem # Здесь у нас будут храниться открытые ключи пользователей в формате RFC4716 SFTPAuthorizedUserKeys file:/etc/proftpd/sftp_authorized_keys # Здесь мы описываем нашего единственного пользователя AuthUserFile /etc/proftpd/sftp_users.passwd home ^/vhosts/backup/ SFTPCompression delayed # Разрешаем проходить аутентификацию только по открытому ключу SFTPAuthMethods publickey # Настраиваем автоматическое создание домашней папки CreateHome on 0700 dirmode 0700 uid 99 gid 99 # А здесь собственно и происходит весь трюк. С помощью mod rewrite правила мы динамически # задаем домашнюю директорию для пользователя. Таким образом нет необходимости создавать # запись в файле sftp_users.passwd для каждого пользователя. Достаточно лишь добавить его # открытый ключ в файл sftp_authorized_keys. <IfModule mod_rewrite.c> # Включаем возможность перезаписи домашней директории RewriteHome on # Включаем поддержку mod rewrite RewriteEngine on # Подробный лог файл, в котором будут отображаться все шаги перезаписи. # Очень удобно при поиске ошибок. RewriteLog /var/log/proftpd/rewrite.log # Задаем условие, при котором будет срабатывать наше правило. Я, думаю, # вы заметили, что директивы аналогичны mod rewrite с apache. # %m - будет заменена на FTP команду. В нашем случае, нас интересует REWRITE_HOME RewriteCondition %m REWRITE_HOME # Собственно производим замену. # %U - имя пользователя, которое было использовано в FTP команде user RewriteRule (.*) /vhosts/backup/%U </IfModule> </IfModule> </VirtualHost>
Конвертируем открытый ключ в формат RFC4716
# ssh-keygen -e -f user1.public.key >> /etc/proftpd/sftp_authorized_keys # ssh-keygen -e -f user2.public.key >> /etc/proftpd/sftp_authorized_keys
В файле /etc/proftpd/sftp_authorized_keys обязательно должна быть новая строка в конце файла! Иначе при попытке аутентификации вы будете получать
2016-02-26 14:27:44,050 mod_sftp/0.9.9[20427]: line too long (29) on line 13 of '/etc/proftpd/sftp_authorized_keys' 2016-02-26 14:27:44,050 mod_sftp/0.9.9[20427]: Make sure that '/etc/proftpd/sftp_authorized_keys' is a RFC4716 formatted key 2016-02-26 14:27:44,050 mod_sftp/0.9.9[20427]: error comparing keys from '/etc/proftpd/sftp_authorized_keys': Invalid argument 2016-02-26 14:27:44,051 mod_sftp/0.9.9[20427]: sending userauth failure; remaining userauth methods: publickey 2016-02-26 14:27:44,052 mod_sftp/0.9.9[20427]: client at 192.168.1.2 sent SSH_DISCONNECT message: No supported authentication methods available (No other authentication mechanisms available)
Генерируем файл с DH параметрами
# mkdir /etc/pki/proftpd/ # openssl dhparam -out /etc/pki/proftpd/dhparam_2048.pem 2048
Создаем нашего единственного виртуального пользователя
# ftpasswd --passwd --file /etc/proftpd/sftp_users.passwd --sha512 --gid 99 --uid 99 --shell /sbin/nologin --name user1 --home /vhosts/backup
Думаю очевидно, что такое 99. Но в принципе вам никто не запрещает создать специального пользователя для этих целей.
# id nobody uid=99(nobody) gid=99(nobody) groups=99(nobody)
Создаем корневую папку и выставляем права
# mkdir -p /vhosts/backup/ # chmod -R 700 /vhosts/backup/ # chown -R nobody:nobody /vhosts/backup/
Ну и заключительная часть - тестирование. А как же без него! Как мы помним, на 21 порту у нас запущен обычный FTP сервер с аутентификацией с поддержкой виртуальных пользователей, данные которых хранятся в обычном текстовом файле. Так же у пользователя мы убрали возможность удалять или переименовывать файлы. Проверим наши настройки.
# ftp 192.168.127.1 21 Connected to 192.168.127.1 (192.168.127.1). 220 ProFTPD 1.3.5 Server (FTP: Screenshots.) [::ffff:192.168.127.1] Name (192.168.127.1:root): screen 331 Password required for screen Password: ******* 230 User screen logged in Remote system type is UNIX. Using binary mode to transfer files. ftp> ls 227 Entering Passive Mode (192,168,127,1,137,204). 150 Opening ASCII mode data connection for file list 226 Transfer complete ftp> put smart.txt local: smart.txt remote: smart.txt 227 Entering Passive Mode (192,168,127,1,144,162). 150 Opening BINARY mode data connection for smart.txt 226 Transfer complete 588 bytes sent in 1.8e-05 secs (32666.67 Kbytes/sec) ftp> ls 227 Entering Passive Mode (192,168,127,1,230,34). 150 Opening ASCII mode data connection for file list -rw-rw-r-- 1 nobody nobody 588 Apr 7 11:38 smart.txt 226 Transfer complete ftp> delete smart.txt 550 smart.txt: Operation not permitted ftp> rename smart.txt temp.txt 550 smart.txt: Operation not permitted ftp> quit 221 Goodbye.
Как видно, все работает именно так, как мы и планировали. Если запустить proftpd в режиме отладки, смотри ниже, то мы увидим следующие строки
2015-04-07 07:38:39,347 ftp.example.net proftpd[9621] 192.168.127.1 (192.168.127.2[192.168.127.2]): user 'screen' authenticated by mod_auth_file.c 2015-04-07 07:38:39,347 ftp.example.net proftpd[9621] 192.168.127.1 (192.168.127.2[192.168.127.2]): Preparing to chroot to directory '/vhosts/screen.example.net' 2015-04-07 07:38:39,347 ftp.example.net proftpd[9621] 192.168.127.1 (192.168.127.2[192.168.127.2]): Environment successfully chroot()ed ... ... ... 2015-04-07 07:49:36,807 ftp.example.net proftpd[9770] 192.168.127.1 (192.168.127.2[192.168.127.2]): deleting '/smart.txt' denied by <Limit> configuration 2015-04-07 07:49:36,807 ftp.example.net proftpd[9770] 192.168.127.1 (192.168.127.2[192.168.127.2]): dispatching LOG_CMD_ERR command 'DELE smart.txt' to mod_log
При этом, если мы попробуем зайти под любым другим пользователем, даже который есть в файле /etc/proftpd/virtual_users.passwd, то в логах мы увидим подобные строки
2015-04-07 07:55:07,636 ftp.example.net proftpd[9843] 192.168.127.1 (192.168.127.2[192.168.127.2]): USER borodach (Login failed): Limit access denies login
Теперь проверяем второй виртуальный хост, который работает по sftp протоколу
# sftp -oPort=2121 [email protected] Connecting to 192.168.127.1... [email protected]'s password: sftp> lpwd Local working directory: /home/borodach sftp> pwd Remote working directory: / sftp> put ./smart.txt Uploading ./smart.txt to /smart.txt ./smart.txt 100% 588 0.6KB/s 00:00 sftp> ls smart.txt sftp> rm smart.txt Removing /smart.txt sftp> quit
Думаю, тут все предельно просто и ясно. Для удобства быстрого доступа пользователей через FileZilla, в описании проекта я генерирую ссылку быстрого доступа, которая имеет следующий вид:
sftp://borodach:[email protected]:2121/
Если же вам необходимо проверить аутентификацию по публичному ключу, то необходимо использовать следующую команду
# sftp -oPort=2121 -oIdentityFile=borodach_private.key [email protected]
И последний виртуальный хост - FTPS (explicit). Строка быстрого подключения для FileZilla будет выглядеть
ftpes://borodach:[email protected]:3333/
Из командной строки можно проверить с помощью openssl
# openssl s_client -tls1_2 -starttls ftp -connect 192.168.127.1:3333 CONNECTED(00000003) depth=0 description = 82pjOgKm8a9O4NG0, C = UA, CN = test.example.net, emailAddress = [email protected] verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 description = 82pj4NG0OgKm8a9O, C = UA, CN = test.example.net, emailAddress = [email protected] verify error:num=27:certificate not trusted verify return:1 depth=0 description = 82pjOgKm8a9O4NG0, C = UA, CN = test.example.net, emailAddress = [email protected] verify error:num=21:unable to verify the first certificate verify return:1 --- Certificate chain 0 s:/description=82pjOgKm8a9O4NG0/C=UA/CN=test.example.net/[email protected] i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA --- ... ... ... --- No client certificate CA names sent Server Temp Key: ECDH, prime256v1, 256 bits --- SSL handshake has read 2711 bytes and written 385 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384 Server public key is 4096 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES256-GCM-SHA384 Session-ID: 26369EB0834724AB1491D64F2890DF4F360DE45468D9617808B794A7E8347195 Session-ID-ctx: Master-Key: A37FEAE590ABD42CD731AFC4D4799D706C9238E974DF0CF30A14D7A02FB2CB972F221DA07894BAC14CEF8249A16BF580 Key-Arg : None Krb5 Principal: None PSK identity: None PSK identity hint: None Start Time: 1428414903 Timeout : 7200 (sec) Verify return code: 21 (unable to verify the first certificate) --- 220 ProFTPD 1.3.5 Server (FTPES: SSI.) [::ffff:192.168.127.1] user borodach 331 Password required for borodach pass 7654321 230 User borodach logged in quit 221 Goodbye. read:errno=0
В режиме отладки обращаем внимание не следующие строчки
2015-04-07 09:51:32,215 ftp.example.net proftpd[11484] 192.168.127.1 (192.168.127.2[192.168.127.2]): user 'borodach' authenticated by mod_ldap.c 2015-04-07 09:51:32,215 ftp.example.net proftpd[11484] 192.168.127.1 (192.168.127.2[192.168.127.2]): creating home directory '/vhosts/ssi.example.net/borodach' for user 'borodach' 2015-04-07 09:51:32,215 ftp.example.net proftpd[11484] 192.168.127.1 (192.168.127.2[192.168.127.2]): CreateHome: '/' already exists 2015-04-07 09:51:32,215 ftp.example.net proftpd[11484] 192.168.127.1 (192.168.127.2[192.168.127.2]): CreateHome: '/vhosts' already exists 2015-04-07 09:51:32,215 ftp.example.net proftpd[11484] 192.168.127.1 (192.168.127.2[192.168.127.2]): CreateHome: '/vhosts/ssi.example.net' already exists 2015-04-07 09:51:32,215 ftp.example.net proftpd[11484] 192.168.127.1 (192.168.127.2[192.168.127.2]): CreateHome: directory '/vhosts/ssi.example.net/borodach' created 2015-04-07 09:51:32,215 ftp.example.net proftpd[11484] 192.168.127.1 (192.168.127.2[192.168.127.2]): home directory '/vhosts/ssi.example.net/borodach' created 2015-04-07 09:51:32,215 ftp.example.net proftpd[11484] 192.168.127.1 (192.168.127.2[192.168.127.2]): CreateHome: copying skel files from '/etc/skel/empty' into '/vhosts/ssi.example.net/borodach'
Для тестирование нашего последнего виртуального хоста лучше использовать FileZilla или любой другой клиент с поддержкой SFTP протокола. Итак, подключаемся с ключом первого пользователя.
2016-02-26 14:57:36,758 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): creating home directory '/vhosts/backup/user1' for user 'user1' 2016-02-26 14:57:36,758 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): CreateHome: '/' already exists 2016-02-26 14:57:36,758 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): CreateHome: '/vhosts' already exists 2016-02-26 14:57:36,758 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): CreateHome: '/vhosts/backup' already exists 2016-02-26 14:57:36,759 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): home directory '/vhosts/backup/user1' created 2016-02-26 14:57:36,759 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): Preparing to chroot to directory '/vhosts/backup/user1' 2016-02-26 14:57:36,759 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): Environment successfully chroot()ed 2016-02-26 14:57:36,759 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): USER user1: Login successful 2016-02-26 14:57:36,759 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): RootRevoke in effect, dropped root privs 2016-02-26 14:57:36,759 backup.example.net proftpd[20481] 192.168.1.6 (192.168.1.2[192.168.1.2]): USER user1: Login successful.
И вот что при этом будет в файле rewrite.log
2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst_vars(): replacing variable '%m' with 'REWRITE_HOME' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst(): var subst'd pattern: 'REWRITE_HOME' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_parse_map_str(): parsing 'REWRITE_HOME' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst(): maps subst'd pattern: 'REWRITE_HOME' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst(): env subst'd pattern: 'REWRITE_HOME' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_match_cond: subst'd cond: 'REWRITE_HOME' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_match_cond(): checking regex cond against 'REWRITE_HOME' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_fixup(): condition met 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_fixup(): executing RewriteRule 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst(): original pattern: '/vhosts/backup/%U' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst(): rule backref subst'd pattern: '/vhosts/backup/%U' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst(): pattern '/vhosts/backup/%U' had no cond backrefs 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst_vars(): replacing variable '%U' with 'user1' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst(): var subst'd pattern: '/vhosts/backup/user1' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_parse_map_str(): parsing '/vhosts/backup/user1' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst(): maps subst'd pattern: '/vhosts/backup/user1' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_subst(): env subst'd pattern: '/vhosts/backup/user1' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrite_fixup(): REWRITE_HOME arg now '/vhosts/backup/user1' 2016-02-26 14:57:36,759 mod_rewrite/0.9[20481]: rewrote home to be '/vhosts/backup/user1'
При подключении с ключом второго пользователя картина будет аналогичная, за исключением того, что rewrite будет сделан в папку /vhosts/backup/user2
2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_match_cond(): checking regex cond against 'REWRITE_HOME' 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_fixup(): condition met 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_fixup(): executing RewriteRule 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_subst(): original pattern: '/vhosts/backup/%U' 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_subst(): rule backref subst'd pattern: '/vhosts/backup/%U' 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_subst(): pattern '/vhosts/backup/%U' had no cond backrefs 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_subst_vars(): replacing variable '%U' with 'user2' 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_subst(): var subst'd pattern: '/vhosts/backup/user2' 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_parse_map_str(): parsing '/vhosts/backup/user2' 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_subst(): maps subst'd pattern: '/vhosts/backup/user2' 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_subst(): env subst'd pattern: '/vhosts/backup/user2' 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: rewrite_fixup(): REWRITE_HOME arg now '/vhosts/backup/user2' 2016-02-26 15:03:49,786 mod_rewrite/0.9[20496]: home directory '/vhosts/backup/user2' not changed by RewriteHome
В proftpd реализован удобный режим отладки, так что если у вас что либо не работает, или сам демон не запускается, то советую запускать в режиме отладки, примерно таким образом
# proftpd -n -d 3 -DVHOST1_21 2015-04-07 06:27:25,490 ftp.example.net proftpd[8588]: using PCRE 7.8 2008-09-05 2015-04-07 06:27:25,494 ftp.example.net proftpd[8588]: mod_ldap/2.9.4: compiled using LDAP vendor 'OpenLDAP', LDAP API version 3001 2015-04-07 06:27:25,494 ftp.example.net proftpd[8588]: mod_sftp/0.9.9: using OpenSSL 1.0.1e-fips 11 Feb 2013 2015-04-07 06:27:25,495 ftp.example.net proftpd[8588]: mod_tls/2.6: using OpenSSL 1.0.1e-fips 11 Feb 2013 2015-04-07 06:27:25,498 ftp.example.net proftpd[8588]: <IfModule>: using 'mod_auth_pam.c' section at line 27 2015-04-07 06:27:25,498 ftp.example.net proftpd[8588]: <IfModule>: using 'mod_tls.c' section at line 31 2015-04-07 06:27:25,498 ftp.example.net proftpd[8588]: <IfDefine>: using 'VHOST1_21' section at line 73 2015-04-07 06:27:26,194 ftp.example.net proftpd[8588]: <Directory /vhosts/screen.example.net/*>: adding section for resolved path '/vhosts/screen.example.net/*' 2015-04-07 06:27:26,687 ftp.example.net proftpd[8588]: <IfDefine>: skipping 'VHOST2_2121' section at line 77 2015-04-07 06:27:26,687 ftp.example.net proftpd[8588]: <IfDefine>: skipping 'VHOST3_3333' section at line 81 2015-04-07 06:27:26,835 ftp.example.net proftpd[8588] 192.168.127.1: set core resource limits for daemon 2015-04-07 06:27:26,835 ftp.example.net proftpd[8588] 192.168.127.1: ProFTPD 1.3.5 (stable) (built Mon Apr 6 2015 02:25:07 EDT) standalone mode STARTUP
Из вывода видно, что, так как мы не указали -DVHOST2_2121 и -DVHOST3_3333, то соответствующие секции виртуальных хостов были пропущены «skipping» и соответственно эти виртуальные хосты не будут работать.
Если вам не хватает 3го уровня информативности, т.е. не видно причину ошибки, то можно увеличить уровень информативности вплоть до 10.