Chroot FTP User
Why it matters
An FTP account with broad filesystem access creates avoidable risk. Chroot confinement limits the account to a controlled directory, reducing impact from mistakes or stolen credentials.
Why this approach
Combining FTP confinement (chroot) with shell restriction (/usr/sbin/nologin) gives collaborators file access without interactive server access.
When to use it
Use this for designers, content editors, or contractors who need limited file transfer access but should not receive SSH access.
Concept Overview
| Goal | Description |
|---|---|
| Chroot isolation | User is jailed to a specific root path |
| FTP-only access | Login allowed through FTP service, not shell |
| Scoped editing | Restrict writes to approved WordPress directories |
| Security boundary | Minimize host exposure for third-party users |
Environment Preparation
Example site root:
/home/wpstrategist/public_html/
Example target scope for editor access:
/home/wpstrategist/public_html/wp-content/themes/
Install and Enable FTP Service
sudo apt update
sudo apt install vsftpd -y
sudo systemctl enable --now vsftpd
Configure vsftpd
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.backup
sudo nano /etc/vsftpd.conf
Recommended baseline:
listen=YES
listen_ipv6=NO
anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES
allow_writeable_chroot=YES
user_sub_token=$USER
local_root=/home/$USER/public_html
pam_service_name=vsftpd
xferlog_enable=YES
xferlog_std_format=YES
Restart service:
sudo systemctl restart vsftpd
Create FTP-Only User
sudo adduser designer --home /home/designer --shell /usr/sbin/nologin
Verify shell policy:
grep designer /etc/passwd
Expected shell value should end with:
/usr/sbin/nologin
Prepare Directory and Ownership
sudo mkdir -p /home/designer/public_html/wp-content/themes
sudo chown -R designer:designer /home/designer
sudo chmod -R 755 /home/designer
Optional symlink to shared theme path:
sudo ln -s /home/wpstrategist/public_html/wp-content/themes /home/designer/public_html/wp-content/themes
Optional Selective Chroot List
Use this when only specific users should be jailed:
chroot_local_user=NO
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
Add user to list:
echo "designer" | sudo tee -a /etc/vsftpd.chroot_list
sudo systemctl restart vsftpd
Verification Checklist
| Check | Command | Expected Result |
|---|---|---|
| Shell disabled | grep designer /etc/passwd | /usr/sbin/nologin |
| FTP login | FTP client login | Success |
| SSH blocked | ssh designer@server | Login denied |
| Path confinement | Navigate above user root in FTP client | Access denied |
| File upload | Upload test file in allowed path | Success |
Troubleshooting
| Error | Likely Cause | Fix |
|---|---|---|
500 OOPS ... writable root inside chroot() | Chroot writable root restriction | Set allow_writeable_chroot=YES |
530 Login incorrect | Credential or shell mismatch | Verify password and account shell |
| Empty FTP directory | Wrong local_root path | Correct local_root in config |
| User still can SSH | Shell is not nologin | Update user shell and retry |
Summary
Chrooted FTP users are a practical least-privilege pattern for controlled collaboration. This setup keeps access narrow, auditable, and safer than giving full shell accounts.