SFTP-доступ с chroot и авторизацией по ключам
Когда нужно дать клиенту или подрядчику доступ к файлам сайта, но не пускать его гулять по всему серверу — используют chroot-джейл для SFTP. Пользователь видит только свой каталог, работает по ключу, а SSH-шелл ему закрыт. Настраивается штатным OpenSSH.
Содержание
Что такое chroot-джейл для SFTP
['chroot запирает пользователя в указанном каталоге: для него этот каталог становится корнем файловой системы, выше он подняться не может. В связке с internal-sftp (встроенный SFTP-сервер OpenSSH) это даёт безопасную раздачу файлов без выдачи shell.', 'Такой подход удобен на VPS, где вы сами администратор с root-доступом — например, на тарифах MAATRIX. Можно завести отдельный джейл под каждого клиента и не бояться, что подрядчик заглянет в чужие проекты, конфиги других сайтов или системные файлы. Это стандартный способ отдать доступ к статике сайта веб-мастеру или дизайнеру, не открывая ему весь сервер.', 'Механизм полностью встроен в OpenSSH: не нужны сторонние FTP-серверы вроде vsftpd или proftpd со своими конфигами и портами. Работает та же служба sshd, что уже слушает 22-й порт, а значит меньше открытых сервисов — меньше поверхность атаки.']Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS с root-доступомШаг 1. Группа и пользователь
['Создаём группу для SFTP-only пользователей и заводим пользователя без шелла:', 'sudo groupadd sftponly\nsudo useradd -m -g sftponly -s /usr/sbin/nologin client1\nsudo passwd client1 # или сразу настроим ключ ниже', 'Шелл /usr/sbin/nologin гарантирует, что интерактивной SSH-сессии не будет — только передача файлов.']
Шаг 2. Права на каталог chroot
['Ключевое требование OpenSSH: сам каталог chroot должен принадлежать root и не быть доступным на запись группе/другим. Иначе sshd откажет в соединении.', 'sudo chown root:root /home/client1\nsudo chmod 755 /home/client1\n# рабочий подкаталог, куда клиент может писать:\nsudo mkdir -p /home/client1/upload\nsudo chown client1:sftponly /home/client1/upload', 'Итог: клиент видит /home/client1 как корень, но писать может только в подкаталог upload. Требование к правам не прихоть — это защита OpenSSH от подмены пути: если бы chroot-каталог был доступен на запись пользователю, тот мог бы подсунуть в него симлинки и обойти изоляцию. Поэтому правило жёсткое: вся цепочка каталогов вплоть до chroot-корня принадлежит root и не пишется никем, кроме него.', 'Отсюда типовая схема каталогов: корень джейла (root:root, 755) не для записи, а внутри — один или несколько рабочих подкаталогов, принадлежащих клиенту. Именно в них он загружает файлы. Если клиенту нужно несколько разделов (например, upload и logs), создайте их тем же способом с владельцем-клиентом.']
Шаг 3. Конфиг sshd
['В конец /etc/ssh/sshd_config (или отдельным файлом в /etc/ssh/sshd_config.d/) добавляем блок Match для группы:', 'Match Group sftponly\n ChrootDirectory %h\n ForceCommand internal-sftp\n AllowTcpForwarding no\n X11Forwarding no\n PermitTunnel no', '%h подставляет домашний каталог пользователя. Проверяем конфиг и перезапускаем sshd:', 'sudo sshd -t && sudo systemctl restart ssh', 'Команда sshd -t обязательна: она ловит ошибки до рестарта, чтобы не потерять доступ к серверу. Ошибка в sshd_config с последующим рестартом — классический способ заблокировать себе SSH; проверка синтаксиса перед перезапуском этого не допускает. На всякий случай держите вторую открытую SSH-сессию к серверу, пока правите конфиг: если что-то пойдёт не так, вы откатите изменения через неё.', 'Директивы внутри блока Match применяются только к пользователям указанной группы. ForceCommand internal-sftp подменяет любую команду встроенным SFTP-сервером, а запреты форвардинга (AllowTcpForwarding no и др.) закрывают возможность использовать SSH-туннель в обход изоляции. Именно поэтому Match-блок ставят в самый конец конфига — всё, что идёт после него, ошибочно попадёт под условие группы.']
Шаг 4. Авторизация по ключу
['Пароли можно отключить в пользу ключей. Каталог .ssh кладём внутрь домашнего каталога клиента; важно — внутри chroot путь authorized_keys обычный:', 'sudo mkdir -p /home/client1/.ssh\nsudo nano /home/client1/.ssh/authorized_keys # вставить публичный ключ клиента\nsudo chown -R client1:sftponly /home/client1/.ssh\nsudo chmod 700 /home/client1/.ssh\nsudo chmod 600 /home/client1/.ssh/authorized_keys', 'Клиент подключается любым SFTP-клиентом (FileZilla, WinSCP) или из консоли:', 'sftp -i ~/.ssh/client1_key client1@SERVER_IP']
Частые ошибки
['- Connection closed сразу после логина — каталог ChrootDirectory принадлежит не root или имеет права шире 755. Самая частая причина.
- Клиент не может ничего загрузить — забыли подкаталог upload с владельцем-клиентом; в сам корень chroot писать нельзя.
- Match-блок стоит не в конце sshd_config — директивы после него неожиданно применяются только к группе.
- Ключ не принимается — неверные права на .ssh (нужно 700) или authorized_keys (600).
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS с root-доступомЧастые вопросы
Можно ли одному пользователю дать и SFTP, и SSH?
Тогда chroot не используют — chroot по определению закрывает шелл. Для полноценного доступа заведите обычного пользователя без Match-блока.
Как дать доступ к каталогу сайта /var/www?
Смонтируйте нужный каталог внутрь джейла через bind-mount: mount --bind /var/www/site /home/client1/site и добавьте строку в fstab.
Безопаснее ли это обычного FTP?
Да, принципиально. SFTP идёт поверх SSH с шифрованием, обычный FTP передаёт пароли и данные открытым текстом.