Skip to main content

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

GoalDescription
Chroot isolationUser is jailed to a specific root path
FTP-only accessLogin allowed through FTP service, not shell
Scoped editingRestrict writes to approved WordPress directories
Security boundaryMinimize 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

CheckCommandExpected Result
Shell disabledgrep designer /etc/passwd/usr/sbin/nologin
FTP loginFTP client loginSuccess
SSH blockedssh designer@serverLogin denied
Path confinementNavigate above user root in FTP clientAccess denied
File uploadUpload test file in allowed pathSuccess

Troubleshooting

ErrorLikely CauseFix
500 OOPS ... writable root inside chroot()Chroot writable root restrictionSet allow_writeable_chroot=YES
530 Login incorrectCredential or shell mismatchVerify password and account shell
Empty FTP directoryWrong local_root pathCorrect local_root in config
User still can SSHShell is not nologinUpdate 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.