Когда на одном сервере нужно выдать безопасный файловый доступ нескольким пользователям или подрядчикам, базовый SSH со свободной оболочкой — слишком широкие права. Правильная практика — SFTP‑доступ, ограниченный chroot
, с внятными правами, группами и квотами, чтобы исключить выход за пределы каталога проекта и переполнение диска. В этом руководстве соберём продакшен‑конфигурацию на OpenSSH, рассмотрим схемы каталогов, настройки internal-sftp
, квоты для ext4 и XFS, а также диагностику типичных ошибок. Если сервера ещё нет — поднимите всё на нашем VDS.
Модель угроз и архитектура решения
Наша цель — выдать пользователям только SFTP (без интерактивного shell и без SCP), изолировать их внутри проектного каталога, обеспечить корректные права записи, а также гарантировать, что ни один пользователь не сможет занять весь диск. Добавим минимально необходимый журналинг и проверки.
Ключевые ограничения безопасности: родительские каталоги
chroot
должны принадлежатьroot
и быть недоступны на запись пользователям; вход — только черезinternal-sftp
; отключаем TCP/X11‑прокси, ограничиваем сессии и старт соединений.
Схема каталогов и права
Надежная и удобная схема для множества пользователей на одном сервере:
/sftp
— базовый корень для всех SFTP‑пользователей (владение root:root
, права 755
).
/sftp/%u
— персональный корень пользователя, подменяется на его login
(root:root
, права 755
), используется как ChrootDirectory
.
/sftp/%u/data
— рабочая папка, куда пользователь может писать (владение %u:sftpusers
, права 750
или 770
в зависимости от модели доступа).
Почему нельзя дать права на запись корню chroot? OpenSSH требует, чтобы
ChrootDirectory
и все его родители были непишущими для пользователя (владениеroot
, безw
). Поэтому запись переносится в подкаталог вродеdata
.
Подготовка: группа, каталоги, пользователи
Создаём сервисную группу
groupadd sftpusers
Готовим базовую директорию
mkdir -p /sftp
chown root:root /sftp
chmod 755 /sftp
Добавляем первого пользователя
useradd -g sftpusers -G sftpusers -d /sftp/alice -s /usr/sbin/nologin alice
# при необходимости пароль (или используйте ключи)
passwd alice
# создаём структуру chroot и рабочую папку
mkdir -p /sftp/alice/data
chown root:root /sftp/alice
chmod 755 /sftp/alice
chown alice:sftpusers /sftp/alice/data
chmod 750 /sftp/alice/data
Оболочка
/usr/sbin/nologin
не даст интерактивный shell. Доступ будет только через SFTP, если мы принудим его на уровне OpenSSH.
OpenSSH: включаем internal-sftp, chroot и запреты
Правим конфигурацию /etc/ssh/sshd_config
:
# Включаем встроенную реализацию SFTP (не требует внешнего бинарника)
Subsystem sftp internal-sftp
# Жёсткая политика для группы sftpusers
Match Group sftpusers
ChrootDirectory /sftp/%u
ForceCommand internal-sftp -u 0027 -d data
AllowTCPForwarding no
X11Forwarding no
PermitTunnel no
PasswordAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile /etc/ssh/authorized_keys/%u
Разбор ключевых строк:
Subsystem sftp internal-sftp
— используем встроенный сервер SFTP, без внешнегоsftp-server
.Match Group sftpusers
— правила применяются только к нашим SFTP‑пользователям.ChrootDirectory /sftp/%u
— изолируем каждого внутри персонального корня.ForceCommand internal-sftp -u 0027 -d data
— принудительно SFTP, задаем умаску0027
(файлы 640, каталоги 750) и стартовый каталогdata
.AllowTCPForwarding/X11Forwarding/PermitTunnel no
— обрезаем боковые каналы.AuthorizedKeysFile
указывает центральное расположение ключей, чтобы не сталкиваться с ограничениямиchroot
на права.
Создайте каталог под ключи и назначьте права:
mkdir -p /etc/ssh/authorized_keys
chown root:root /etc/ssh/authorized_keys
chmod 755 /etc/ssh/authorized_keys
Добавьте файл ключа для пользователя:
install -m 600 -o alice -g sftpusers /dev/null /etc/ssh/authorized_keys/alice
# затем вставьте публичный ключ в этот файл удобным редактором
Проверяем конфигурацию и перезапускаем SSH:
sshd -t
systemctl reload sshd
# или
systemctl restart sshd
Если вы предпочитаете хранить
authorized_keys
в домашнем каталоге, убедитесь, что путь к нему удовлетворяет строгим требованиям OpenSSH по владению и правам. Централизованный путь часто проще.

Квоты на диске: ext4 и XFS
Квоты ограничивают место на файловой системе, чтобы один аккаунт не забрал всё пространство. Конфигурация зависит от файловой системы.
ext4: usrquota/grpquota
- Включите квоты в
/etc/fstab
для соответствующего раздела (например/
или отдельный/srv
):
# пример: для / на /dev/sda2
UUID=... / ext4 defaults,usrquota,grpquota 0 1
- Примонтируйте раздел с новыми опциями:
mount -o remount /
- Инициализируйте и включите квоты:
quotacheck -cum /
quotaon /
- Задайте лимит пользователю:
# мягкий/жесткий порог: 2G/2.2G; иноды не ограничиваем (0)
setquota -u alice 2G 2.2G 0 0 /
# проверить
quota -u alice
XFS: xfs_quota
Для XFS опции квот включаются при монтировании. Проверьте /etc/fstab
— должна быть uquota
или prjquota
для проектных квот.
# remount раздела с квотами (пример для /srv)
mount -o remount,uquota /srv
# установить лимит для пользователя
xfs_quota -x -c "limit bsoft=2g bhard=2200m alice" /srv
# посмотреть текущие лимиты
xfs_quota -x -c "report -u" /srv
Практика: держите каталоги SFTP на отдельном разделе. Это упростит квоты, снимет риски упереться в inode‑лимиты системного раздела и облегчит бэкапы/миграции. Про перенос без простоя читайте в материале о миграции без простоя.
Права, umask и совместная работа
Мы задали умаску 0027
для internal-sftp
: файлы — 640, каталоги — 750. Это убирает лишние «другие» права и оставляет доступ группе. Если нескольким пользователям нужна запись в один проект, используйте одну группу (например sftp-proj
), добавляйте людей в неё, а каталог проекта делайте 770
.
groupadd sftp-proj
usermod -aG sftp-proj alice
usermod -aG sftp-proj bob
chgrp -R sftp-proj /sftp/alice/data
chmod 2770 /sftp/alice/data
Бит 2
в правах каталога (2xxx
) — это setgid
, он заставляет новые файлы наследовать группу каталога, что удобно для командной работы.
ACL для «чтения вебом»
Если сайт деплоится из SFTP‑каталога и веб‑процессу нужен доступ на чтение, добавьте ACL‑правило на пользователя или группу веб‑сервера:
setfacl -R -m u:www-data:rx /sftp/alice/data
setfacl -R -m d:u:www-data:rx /sftp/alice/data
ACL удобны, когда обычных режимов недостаточно. Следите, чтобы маска ACL не отрезала нужные биты.
Укрепление SSH: минимум атакуемой поверхности
- Ограничьте список пользователей/групп:
AllowGroups sftpusers
и, при необходимости,AllowUsers
. - Снизьте шум брутфорса:
MaxStartups 10:30:60
,LoginGraceTime 20
,MaxSessions 2
. - Отключите неиспользуемые методы: если всё на ключах, переведите
PasswordAuthentication no
. - Firewall: открывайте только нужный порт SSH, ограничьте по адресам, где возможно.
- Fail2ban: тюрьма по
sshd
с агрессивными тайм‑аутами.
SELinux/AppArmor
На системах с SELinux убедитесь, что контексты на /sftp
корректны. Для записи внутри chroot иногда требуется включить соответствующий boolean или настроить контексты:
# пример для RHEL/CentOS, если используете домашние каталоги
setsebool -P ssh_chroot_rw_homedirs on
# или пометьте путь корректным типом (проверьте через seinfo/semanage)
restorecon -R /sftp
Для AppArmor проверьте профиль sshd
, чтобы он позволял chroot в /sftp
.
Проверка: что и как тестировать
Подключение с клиента и проверка ограничений:
# подробный режим, свой порт
sftp -vvv -P 22 alice@server
# проверить, что мы в data, создать файл, проверить права
put README.txt
ls -la
# попытка выйти выше chroot должна провалиться
cd /
cd ..
Журналы на сервере:
journalctl -u sshd -e
# или, если системные логи в отдельном файле
grep -i sftp /var/log/auth.log
Типичные ошибки и решения
- subsystem request for sftp failed — не задан
Subsystem sftp internal-sftp
или конфликтует старая строка. Проверьтеsshd_config
. - bad ownership or modes for chroot directory — любой родительский каталог chroot должен быть
root:root
и без права записи. Проверьте/sftp
и/sftp/%u
. - Connection closed сразу после входа — часто виновата неправильная
ChrootDirectory
, недоступный стартовый каталог-d data
или права наauthorized_keys
. - Permission denied при загрузке файлов — проверьте владельца и права
/sftp/%u/data
, а также умаску. При совместной работе нуженsetgid
и общая группа. - Квоты «не работают» — не включены опции монтирования (
usrquota
/uquota
), не запущеныquotaon
, раздел другой, чем вы ограничиваете, или иноды закончились раньше байтов.
Обслуживание и масштабирование
Для массового создания аккаунтов приготовьте скрипт, который добавляет пользователя, создаёт структуру каталогов и задаёт квоты. Примерные шаги:
- Создать пользователя с неинтерактивной оболочкой и в нужных группах.
- Создать
/sftp/%u
, назначитьroot:root
, права755
. - Создать
/sftp/%u/data
, назначить владельца пользователю, права750
или770
и, при необходимости,setgid
. - Вписать публичный ключ в
/etc/ssh/authorized_keys/%u
(или воспользоваться централизованным управлением ключами). - Назначить квоты в соответствии с планом.
- Прогнать smoke‑тест SFTP.
Если хотите упростить рутину, рассмотрите панели администрирования; сравнение вариантов — в материале о панелях для VDS.
Расширения: проектные квоты и policy‑подход
На XFS можно использовать проектные квоты (prjquota), чтобы ограничивать не пользователей, а каталоги проекта. Это удобно, когда над одним деревом работает несколько аккаунтов. На ext4 похожего механизма нет, но можно имитировать через выделенные разделы.
Для управления доступом применяйте понятные политики: «пользователь‑проект‑квота‑группа‑роль». Документируйте права, умаску и процесс запроса доступа. Это снижает случайные нарушения и ускоряет онбординг.
Итог
Конфигурация SFTP‑изоляции на OpenSSH с chroot
— это не «магия», а набор чётких правил: родительские каталоги под root
, запись только в рабочие подпапки, принудительный internal-sftp
с подходящей umask
, централизованные ключи, отключение лишних возможностей SSH и квоты на файловой системе. Следуя описанной последовательности, вы выдадите безопасный доступ подрядчикам и команде без риска утечки данных или внезапного переполнения диска.