Application: OpenSSH.
Доступ владельцев к их ресурсов будем обеспечивать с помощью SFTP, функции SSH сервера OpenSSH.
Почему SSH а не старый добрый FTP? Две причины, которых достаточно для отказа от использования этого FTP-протокола как средства доступа к приватным ресурсам, вынесенным в закрытые зоны за защитными экранами: пароли, передающиеся открытым текстом и открытие нового соединения для каждого нового сеанса передачи данных. Пароли можно ещё скрыть путём шифрования контрольного соединения и сеансов передачи данных используя FTPS, но после этого пропуск трафика сервиса открывающего кучу соединений между сервером и клиентом, да ещё и шифрующего их, сквозь защитные экраны ещё более усложняется и наводит на мысль об отказе от этой суеты в пользу решения во всех смыслах более лучшего.
Справедливым было бы упомянуть о появившихся не так давно модулям реализации SFTP для FTP серверов, которые закрывают описанные выше проблемы. Но, спрашивается, зачем нам городить ещё один сервис FTP, пусть и хороший, туда, где уже есть установленный и функционирующий OpenSSH?
Наверняка сервер OpenSSH у нас уже установлен, если это не так, делаем это:
# aptitude install openssh-server openssh-client
OpenSSH заменяет собой все, что было ранее наверчено в системе для реализации работы с протоколом SSH. И это к лучшему - единое решение.
Делаем резервную копию единственного конфигурационного файла, с которым мы будем работать:
# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.dist
Для начала пробежимся по конфигурационному файлу нашего SSH сервиса на предмет обнаружения свистящих и вопиющих ошибок, приведем ряд параметров к следующему виду:
...
# принудительно указываем на использование только протокола SSH2
Protocol 2
# отключаем обратное разрешение адресов подключающихся пользователей
UseDNS no
# отключаем возможность удалённого входа для суперпользователя
PermitRootLogin no
# отключаем сессию авторизации, если в течении минуты она не прошла успешно
LoginGraceTime 60
# жёстко контролируем количество параллельных не аутентифицированных подключений к серверу. Запись параметра имеет форму "start:rate:full". В нашем случае она означает отключение с вероятностью 50% при наличии двух не аутентифицированных связей, с линейным ростом вероятности до 100% при достижении 10
MaxStartups 2:50:10
# запрещаем использование "пустых" паролей
PermitEmptyPasswords no
# запрещаем пользователю передачу своих переменных окружения
PermitUserEnvironment no
# запрещаем пользователям доступ к перенаправлению портов
GatewayPorts no
# выводим сведения о времени последнего логина пользователя после успешной авторизации
PrintLastLog yes
# отключаем вывод информационных сообщений при авторизации пользователя
PrintMotd no
# отключаем вывод информационного сообщения перед авторизацией пользователя
Banner none
# устанавливаем режим проверки права доступа пользователя к целевым объектам
StrictModes yes
# включаем сжатие трафика, у нас есть, что экономить
Compression yes
# включаем поддержку соединения посылкой контрольных пакетов
TCPKeepAlive yes
# отключаем передачу данных протокола X11, его у нас нет и не предполагается, нечего путаницу разводить
X11Forwarding no
...
# принудительно указываем на использование только протокола SSH2
Protocol 2
# отключаем обратное разрешение адресов подключающихся пользователей
UseDNS no
# отключаем возможность удалённого входа для суперпользователя
PermitRootLogin no
# отключаем сессию авторизации, если в течении минуты она не прошла успешно
LoginGraceTime 60
# жёстко контролируем количество параллельных не аутентифицированных подключений к серверу. Запись параметра имеет форму "start:rate:full". В нашем случае она означает отключение с вероятностью 50% при наличии двух не аутентифицированных связей, с линейным ростом вероятности до 100% при достижении 10
MaxStartups 2:50:10
# запрещаем использование "пустых" паролей
PermitEmptyPasswords no
# запрещаем пользователю передачу своих переменных окружения
PermitUserEnvironment no
# запрещаем пользователям доступ к перенаправлению портов
GatewayPorts no
# выводим сведения о времени последнего логина пользователя после успешной авторизации
PrintLastLog yes
# отключаем вывод информационных сообщений при авторизации пользователя
PrintMotd no
# отключаем вывод информационного сообщения перед авторизацией пользователя
Banner none
# устанавливаем режим проверки права доступа пользователя к целевым объектам
StrictModes yes
# включаем сжатие трафика, у нас есть, что экономить
Compression yes
# включаем поддержку соединения посылкой контрольных пакетов
TCPKeepAlive yes
# отключаем передачу данных протокола X11, его у нас нет и не предполагается, нечего путаницу разводить
X11Forwarding no
...
Включить SFTP в OpenSSH очень просто. В конфигурационном файле "/etc/ssh/sshd_config" применяем следующую директиву:
# Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp
Subsystem sftp internal-sftp
Перезапускаем сервис для включения нового функционала:
# /etc/init.d/ssh restart
Для того, чтобы описать в конфигурационном файле OpenSSH политику доступа владельцев ресурсов к их директориям, создаем специальную группу, в которую включаем всех владельцев ресурсов. Эта группа не будет использоваться нигде, кроме как в конфигурационном файле OpenSSH:
# groupadd www-ssh
# usermod --append --groups www-ssh u000
# usermod --append --groups www-ssh u001
# usermod --append --groups www-ssh u000
# usermod --append --groups www-ssh u001
Для регламентирования доступа добавляем в конце конфигурационного файла "/etc/ssh/sshd_config" следующую конструкцию:
....
Match Group www-ssh
AllowTcpForwarding no
ChrootDirectory /var/www/%u
ForceCommand internal-sftp
Match Group www-ssh
AllowTcpForwarding no
ChrootDirectory /var/www/%u
ForceCommand internal-sftp
Внутренний, для OpenSSH, модификатор "%u" принимает значение имени пользователя после его успешной авторизации. Учитывая то, что мы строили файловую систему таким образом, что все ресурсы пользователя расположены в директории с именем вида "/var/www/имя_пользователя", OpenSSH удерживает пользователя в пределах его корневой директории. Вот так просто и красиво мы решили вопросы доступа владельца к его файловым ресурсам.
Обращаю особое внимание на то, что конструкция "Match" должна располагаться обязательно после всех остальных определений - после неё может быть или конец файла или другая конструкция "Match". У конструкции "Match" нет определения завершения и всё, что будет ниже неё - будет воспринято как входящее в эту конструкцию.
После каждого изменения конфигурационного файла сервису необходимо дать команду перечитать конфигурационный файл (именно перечитать, а не перезапустить сервис; забавно будет, если мы дадим команду перезапустится сервису, которым в данный момент пользуемся - немедленный разрыв соединения гарантирован):
# /etc/init.d/ssh reload
Настройка SFTP-подсистемы первичного и вторичного web-серверов в общем одинаковая, однако я считаю полезным закрыть доступ владельцев ресурсов к их сайтам на вторичном сервере. Бессмысленно корректировать содержимое площадки на вторичном сервере с учётом того, что оно будет полностью замещено при очередном "зеркалировании". Потому вставим в конфигурационном файле "/etc/ssh/sshd_config" перед конструкцией "match" директиву запрещающую авторизацию пользователям входящим в группу "www-ssh":
....
DenyGroups www-ssh
....
DenyGroups www-ssh
....
Защищаем от несанкционированного доступа директорию конфигураций нашего сервиса:
# chown -R root:root /etc/ssh
# chmod -R o-rwx /etc/ssh
# chmod -R o-rwx /etc/ssh