- Linux: Setup Restricted SFTP Server with OpenSSH, Chroot Jail, and File Permissions
- 1. Create SFTP users
- 2. Create SFTP locations
- 3. Setup Passwordless Login with SSH Keys
- 4. Setup SFTP Server
- 5. Verify SFTP Access
- Troubleshooting Guide
- For permission issues
- For network issues
- 👉 Any questions? Please comment below.
- Настройка домашнего каталога SFTP или SSH Chroot
- 1. Настройка SSH
- 2. Создание пользователя и группы
- Создание пользователя
- Создание группы
- 3. Выставление прав на каталог
- Проверка и решение проблем
- Lshell как альтернатива chroot ssh
Linux: Setup Restricted SFTP Server with OpenSSH, Chroot Jail, and File Permissions
SFTP (SSH File Transfer Protocol) implements FTP commands that can be used over SSH protocol and is more secure than general file transfer protocols like FTP/FTPS.
By following this tutorial, you will be able to setup a Linux server with the following restrictions:
- Users can connect to your server only via SFTP (SSH shell access is disabled).
- Users can access only a specific file location on your server (Irrelevant directories are hidden using Chroot Jail).
- Users have limited read-write file permissions (File permissions are strictly managed).
- Users must have a private key to connect to your server (Password-based login is disabled).
- Users can use only general SFTP commands (Interactive shell access is disabled).
- Users cannot have elevated privileges (No sudo commands).
1. Create SFTP users
1.1 Create a common user group for SFTP only users.
1.2 Create a new user (say pfops_user ) with preferred values for the below flags.
$ sudo useradd -g sftp_users -m -d /home/pfops_user -c "Platform Ops User (SFTP Only)" -s /sbin/nologin pfops_user
If the user is already existing in the system, use usermod with the below flags.
$ sudo usermod -aG sftp_users -s /sbin/nologin pfops_user
- -g : specify user’s initial login group
- -m : with useradd , create user’s home directory if it does not exist; with usermod , move the current home content to new location
- -d : specify user’s home directory
- -s : specify user’s login shell
- -c : specify meaningful comment
- -aG : append user to another group (no harm to existing supplementary group memberships)
- -G : specify user’s supplementary groups (existing supplementary group memberships will be lost)
- -e : specify an expire date (format: YYYY-MM-DD ) on which the user account will be disabled
$ id pfops_user uid=1001(pfops_user) gid=1001(sftp_users) groups=1001(sftp_users)
2. Create SFTP locations
2.1 Create a separate root-level directory for storing SFTP data (Benefit: you can move content in this directory to a separate disk mount at any time. This is a best practice to compensate when servers run out of disk space in the future).
NOTE: My suggestion is to create multiple directories specific to each SFTP user inside /sftp_data directory, so that you can manage them easily.
$ tree /sftp_data -d -L 2 /sftp_data ├── pfops_user │ ├── archive │ ├── docker_images │ ├── kubernetes_configs │ └── releases ├── pfops2 │ ├── archive │ ├── bash_scripts │ ├── maven_dependencies │ ├── releases │── pfops3 │ ├── . │ └── .
2.2 Create a SFTP location for the user.
$ sudo mkdir -p /sftp_data/pfops_user
2.3 Make sure that this location is owned by root .
$ sudo chown root:root /sftp_data/pfops_user
2.4 Create sub directories as you wish.
$ sudo mkdir -p /sftp_data/pfops_user/releases
NOTE: User can only read these content since the owner is set to root:root .
In case if you need to provide some write permissions (say user needs to upload or modify files in your server via SFTP), you need to create a separate directory and transfer its ownership to user.
$ sudo mkdir -p /sftp_data/pfops_user/uploads $ sudo chown pfops_user /sftp_data/pfops_user/uploads
3. Setup Passwordless Login with SSH Keys
3.1 On client machine, generate RSA private and public key pairs.
$ ssh-keygen -t rsa -b 4096 -N '' -C "pfops_user@SFTP_HOST" -f id_rsa_pfops_user $ mv id_rsa_pfops_user ~/.ssh/ $ chmod 644 ~/.ssh/id_rsa_pfops_user
3.2 On client machine, extract the public key that starts with ssh-rsa AAAA… .
3.3 On SFTP Server, append that extracted public key to /home/pfops_user/.ssh/authorized_keys file.
$ sudo vi /home/pfops_user/.ssh/authorized_keys $ sudo cat /home/pfops_user/.ssh/authorized_keys . ssh-rsa AAAA. pfops_user@SFTP_HOST .
$ sudo chown root:root /home/pfops_user $ sudo chown pfops_user:sftp_users /home/pfops_user/.ssh $ sudo chown pfops_user:sftp_users /home/pfops_user/.ssh/authorized_keys $ sudo chmod 700 /home/pfops_user/.ssh $ sudo chmod 600 /home/pfops_user/.ssh/authorized_keys
4. Setup SFTP Server
4.1 Install OpenSSH Server.
// for RHEL/CentOS $ sudo yum install -y openssh-server openssh-clients // for Ubuntu/Debian $ sudo apt update -y && sudo apt install openssh-server -y
$ systemctl start sshd $ systemctl enable sshd $ systemctl status sshd
4.3 Configure SFTP settings.
$ cp /etc/ssh/sshd_config ~/sshd_config_BACKUP $ sudo vi /etc/ssh/sshd_config // comment out current `Subsystem` setting and add internal-sftp to enable SFTP (see below) #Subsystem sftp /usr/lib/openssh/sftp-server Subsystem sftp internal-sftp // append group/user specific settings at the end of file (this will override default settings) // [option 1] to apply for the entire group Match Group sftp_users X11Forwarding no AllowTcpForwarding no ChrootDirectory /sftp_data/%u ForceCommand internal-sftp PasswordAuthentication no // [option 2] to apply only for the user Match User pfops_user X11Forwarding no AllowTcpForwarding no ChrootDirectory /sftp_data/%u ForceCommand internal-sftp PasswordAuthentication no
- X11Forwarding : specify whether to enable X11
- AllowTcpForwarding : specify whether to allow TCP forwarding
- ChrootDirectory : specify a custom location to chroot (change root level) after authentication. ( %u : username, %h : user’s home directory)
- ForceCommand : force to use commands supplied by a specific service, ignoring any command supplied by the client and ~/.ssh/rc if present
- PasswordAuthentication : specify whether to allow password-based authentication (set no to disable it and enforce key-based authentication at all times)
4.4 Restart SSH service for changes to take place.
$ sudo systemctl restart ssh
5. Verify SFTP Access
Do these steps in your client machine.
5.1 Try SSH login. This must fail.
$ ssh -i ~/.ssh/id_rsa_pfops_user pfops_user@SFTP_HOST
5.2 Try SFTP login. This must be successful.
$ sftp -i ~/.ssh/id_rsa_pfops_user pfops_user@SFTP_HOST
5.3 If specifying private key every time seems troublesome, add private key location to local SSH configs, so that you don’t need to mention it again.
$ vi ~/.ssh/config Host server SFTP_HOST Port 22 User pfops_user HostName SFTP_HOST IdentityFile ~/.ssh/id_rsa_pfops_user LogLevel QUIET
- LogLevel : set log levels only if you need to troubleshoot connection issues (possible values: DEBUG1 , DEBUG2 , DEBUG4 )
Troubleshooting Guide
⚠️ If it fails to connect over SFTP, run the command with -vvv to output verbose logs.
$ sftp -vvv -i ~/.ssh/id_rsa_pfops_user pfops_user@SFTP_HOST
For permission issues
⚠️ Verify that chroot location is owned by root:root and permissions in user’s .ssh directory is correctly set.
For network issues
⚠️ If it’s a remote server, check whether its public IP is correctly set. If it’s in your corporate network, check the static IP assigned to it. If your server and client machines are located in different subnets, double-check whether there are strict rules avoiding connections between those subnets. Set firewall rules in your cloud servers (in general, cloud firewall rules must be changed using web control panel, not via terminal) and corporate networks throughout the entire network route from client to server.
⚠️ If you have OS firewalls enabled in your server, you may need to open ports to allow incoming traffic.
// for RHEL/CentOS $ sudo systemctl start firewalld $ sudo systemctl enable firewalld $ sudo systemctl status firewalld $ sudo firewall-cmd --zone=public --add-service=ssh --add-port=22/tcp --permanent $ sudo firewall-cmd --reload $ sudo firewall-cmd --list-all-zones | grep ssh // for Ubuntu/Debian $ sudo ufw allow 22/tcp $ sudo ufw disable $ sudo ufw enable
⚠️ On client machine, run the below commands to run a port scan on your server.
⚠️ If you want to try pinging to your server from client, verify that an ICMP service is running on your server. Also you can even try curl more conveniently.
ping SFTP_HOST -vvv curl SFTP_HOST:22 -vvv
👉 Any questions? Please comment below.
Updated: November 02, 2019
Настройка домашнего каталога SFTP или SSH Chroot
Обновлено: 08.10.2018 Опубликовано: 30.10.2017
По умолчанию, при подключении по SFTP пользователь имеет возможность спускаться по дереву каталогов и видеть структуру папок. А при наличии прав, редактировать и удалять файлы. Доступ можно ограничить, создав специальное окружение для определенной папки и всех ее подпапок.
1. Настройка SSH
Открываем конфигурационный файл openssh:
Комментируем следующую строку:
#Subsystem sftp /usr/lib/openssh/sftp-server
Добавляем следующее (обязательно в самый конец файла).
Для определенного пользователя:
Subsystem sftp internal-sftp -f AUTH -l VERBOSE
Match user sftpuser
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
* где sftpuser — имя пользователя, для которого срабатывает набор правил; %h (home directory) — домашняя директория пользователя (здесь также можно указать конкретный каталог); ForceCommand internal-sftp — использовать только sftp, встроенный в ssh.
** если данные строки добавить не в конец файла, сервис ssh может не запуститься.
Для группы пользователей:
Subsystem sftp internal-sftp -f AUTH -l VERBOSE
Match group sftpgroup
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no
* как видим, в данном примере все то же самое — только меняем user на group. /home/%u — другой способ прописать путь к домашней директории (/home + имя пользователя).
После перезапускаем службу:
systemctl restart ssh || systemctl restart sshd || service ssh restart || service sshd restart
* команда рассчитана на запуск в разных версиях Linux (CentOS / Ubuntu / Red Hat / Debian и так далее, а также на базе systemd или ранних версий), так как служба может называться ssh или sshd.
2. Создание пользователя и группы
Если в системе еще нет группы или пользователя, для которого мы настроили SSH chroot, выполняем следующие команды.
Создание пользователя
useradd sftpuser -d /home/sftpuser -m
* где sftpuser — имя пользователя; /home/sftpuser — домашний каталог пользователя.
Задаем пароль для пользователя:
Создание группы
Для добавления пользователя в группу можно воспользоваться командой:
usermod sftpuser -G sftpgroup
* 1004 — идентификатор группы (может быть любым числом).
3. Выставление прав на каталог
При попытке подключиться по SFTP мы получим ошибку fatal: bad ownership or modes for chroot directory, так как необходимо выставить правильные права. Система требует, чтобы все каталоги пути имели права 755 и их владельцем был root.
В нашем примере мы выполняем следующие команды:
drwxr-xr-x 2 root root 4096 окт. 30 09:00 /home/sftpuser/
Проверка и решение проблем
Проверить настройку можно с помощью любого sftp-клиента, например Filezilla или WinSCP.
При возникновении проблем, стоит просмотреть лог
* первая команда подходит для систем на базе RPM, вторая — Debian.
Lshell как альтернатива chroot ssh
По сути, это более простой способ настроить окружение chroot для пользователя UNIX систем.
Его развертывание сводится к установке:
* первая команда для Red Hat / CentOS / Fedora . вторая — Debian / Ubuntu.
И смене шела для пользователя:
Остальная настройка выполняется в файле /etc/lshell.conf.