MAATRIX / Блог / SFTP-доступ с chroot и авторизацией по ключам

SFTP-доступ с chroot и авторизацией по ключам

SFTP-доступ с chroot и ключами: изоляция пользователей
Блог MAATRIX · 2026-07-07

Когда нужно дать клиенту или подрядчику доступ к файлам сайта, но не пускать его гулять по всему серверу — используют chroot-джейл для SFTP. Пользователь видит только свой каталог, работает по ключу, а SSH-шелл ему закрыт. Настраивается штатным OpenSSH.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое 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
sudo useradd -m -g sftponly -s /usr/sbin/nologin client1
sudo passwd client1   # или сразу настроим ключ ниже

Шелл /usr/sbin/nologin гарантирует, что интерактивной SSH-сессии не будет — только передача файлов.

Шаг 2. Права на каталог chroot

Ключевое требование OpenSSH: сам каталог chroot должен принадлежать root и не быть доступным на запись группе/другим. Иначе sshd откажет в соединении.

sudo chown root:root /home/client1
sudo chmod 755 /home/client1
# рабочий подкаталог, куда клиент может писать:
sudo mkdir -p /home/client1/upload
sudo 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
    ChrootDirectory %h
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
    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
sudo nano /home/client1/.ssh/authorized_keys   # вставить публичный ключ клиента
sudo chown -R client1:sftponly /home/client1/.ssh
sudo chmod 700 /home/client1/.ssh
sudo 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-доступом

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

Можно ли одному пользователю дать и SFTP, и SSH?

Тогда chroot не используют — chroot по определению закрывает шелл. Для полноценного доступа заведите обычного пользователя без Match-блока.

Как дать доступ к каталогу сайта /var/www?

Смонтируйте нужный каталог внутрь джейла через bind-mount: mount --bind /var/www/site /home/client1/site и добавьте строку в fstab.

Безопаснее ли это обычного FTP?

Да, принципиально. SFTP идёт поверх SSH с шифрованием, обычный FTP передаёт пароли и данные открытым текстом.