Пусть распространяемые файлы будут располагаться в директории "/var/lib/share/files/", а "торрент"-файлы в директории "/var/lib/share/torrents/".
# mkdir -p /var/lib/share/files
# mkdir -p /var/lib/share/torrents
# mkdir -p /var/lib/share/torrents
Создаём группу для пользователей - операторов сервисов:
# groupadd share-users
Создаем первый (условно) аккаунт пользователя - оператора сервиса:
# useradd --shell /bin/false --home-dir /var/lib/share --gid share-users share-operator
Явно добавляем пользователя share-operator в группу share-users, чтобы после для группы сделать разрешение на работу с ресурсами:
# usermod --append --groups share-users share-operator
Применяем пользователю пароль:
# passwd share-operator
Указываем собственником корневой директории нашего хранилища суперпользователя (это необходимо для корректной работы встроенного в OpenSSH SFTP-сервера):
# chown root:share-users /var/lib/share
# chmod g-w /var/lib/share
# chmod o-rw /var/lib/share
# chmod g-w /var/lib/share
# chmod o-rw /var/lib/share
Объявляем группу операторов собственником директории и дочерних объектов файлового хранилища:
# chown -R root:share-users /var/lib/share
Уточняем права доступа:
# chmod -R o-rw /var/lib/share
# chmod -R ug+rwx /var/lib/share/files
# chmod -R g-w /var/lib/share/torrents
# chmod -R ug+rwx /var/lib/share/files
# chmod -R g-w /var/lib/share/torrents
В итоге должно получится что-то вроде такого, подвешенного за корни, файлового дерева:
share (-R root:share-users; rwx:rx:x)
|
+ files (-R root:share-users; rwx:rwx:x)
|
+ torrents (-R root:share-users; rwx:rx:x)
|
+ files (-R root:share-users; rwx:rwx:x)
|
+ torrents (-R root:share-users; rwx:rx:x)
Доступ операторов непосредственно к хранилищу файлам будем обеспечивать с помощью SFTP, функции SSH сервера 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
Для регламентирования доступа добавляем в конце конфигурационного файла "/etc/ssh/sshd_config" следующую конструкцию:
....
Match Group share-users
AllowTcpForwarding no
ForceCommand internal-sftp
ChrootDirectory /var/lib/share
Match Group share-users
AllowTcpForwarding no
ForceCommand internal-sftp
ChrootDirectory /var/lib/share
Обращаю особое внимание на то, что конструкция "Match" должна располагаться обязательно после всех остальных определений - после неё может быть или конец файла или другая конструкция "Match". У конструкции "Match" нет определения завершения и всё, что будет ниже неё - будет воспринято как входящее в эту конструкцию.
После каждого изменения конфигурационного файла сервису необходимо дать команду перечитать конфигурационный файл (именно перечитать, а не перезапустить сервис; забавно будет, если мы дадим команду перезапустится сервису, которым в данный момент пользуемся - немедленный разрыв соединения гарантирован):
# /etc/init.d/ssh reload
Теперь оператор сможет размещать в директории "/var/lib/share/files" распространяемые файлы путём элементарного копирования. Доступ на чтение к директории хранения "торрент"-файлов "/var/lib/share/torrents" ему даём на тот случай, если будет необходимо локализовать возможные проблемы с автоматическим управлением "торрент"-файлами.
Последний, и очень важный нюанс в том, что сервис авторизации PAM, используемый OpenSSH (который, в свою очередь запускает встроенный SFTP), задаёт в переменных окружения подключающегося пользователя значение "umask" равное системному (как правило, в Linux Debian: 0022), то есть, лишает одногрупников доступа на запись к загруженным файлам. А нам как раз требуется обеспечить возможность записи группе "share-users", чтобы возможные ошибки одного сотрудника мог исправить его коллега.
Сервис PAM позволяет задать особые параметры для подключающихся пользователей, в том числе и значение "umask", с помощью модуля "pam_umask.so". Для этого добавим соответствующее указание в конфигурационный файл PAM, описывающий особенности работы с OpenSSH, в самый конец файла, до перехода к обработки иных внешних включений:
# cat /etc/pam.d/sshd
....
# Overriding the "umask" for user-created files
session optional pam_umask.so umask=0007
# Standard Un*x password updating.
@include common-password
# Overriding the "umask" for user-created files
session optional pam_umask.so umask=0007
# Standard Un*x password updating.
@include common-password
Вообще-то, красивее значение "umask" менять с помощью "POSIX ACLs" в части, применимой к файловым системам, но - это уже отдельная песня.