Table of Contents
Understanding FTP and SFTP in a Modern Linux Environment
FTP and SFTP both move files over a network, but they are fundamentally different technologies with very different security properties and deployment patterns. For modern Linux servers, SFTP (via SSH) is usually the default choice, while FTP is maintained mainly for legacy compatibility or specific workflows.
This chapter focuses on:
- When and why to use FTP vs SFTP
- Setting up and securing a basic FTP service
- SFTP configuration using OpenSSH
- Common deployment patterns like jailed/SFTP-only users and chrooted FTP
Networking, firewalls, and general SSH concepts are assumed to be known from other chapters; here we focus on the file-transfer aspects.
FTP vs SFTP: Key Differences
Protocol and Transport
- FTP (File Transfer Protocol)
- Old protocol, originally designed without security.
- Uses a control connection (usually TCP port 21) plus separate data connections.
- Supports active and passive modes, each affecting firewall/NAT behavior.
- Credentials and data are clear-text unless wrapped via TLS (FTPS, not covered in depth here).
- SFTP (SSH File Transfer Protocol)
- Completely different protocol from FTP, despite the similar name.
- Runs inside an SSH connection (usually TCP port 22).
- Single TCP connection for both control and data.
- Always encrypted, uses SSH authentication (password, key, etc.).
- Access control is integrated with SSH users, groups, and permissions.
When to Use Which
- Prefer SFTP when:
- Security and encryption are required (almost always).
- You already have SSH access to the server.
- You want to leverage SSH keys for automation.
- Consider FTP when:
- You must support legacy clients or devices that only speak FTP.
- You run an anonymous/public download repository with minimal security requirements.
- High-speed LAN transfers where encryption overhead is an issue (rarely a strong reason today).
FTP on Linux: Basic Concepts
Active vs Passive Mode (High Level)
FTP uses separate connections for control and data:
- Active mode
- Client connects to server’s port 21.
- Server opens a data connection back to the client from port 20 or another port.
- Harder to use behind NAT/firewalls on the client side.
- Passive mode
- Client connects to server’s port 21.
- Server tells client a random high port to connect to for data.
- Easier for clients behind NAT; common on the Internet.
- Requires configuring and opening a range of passive ports on the server firewall.
Understanding this matters mainly when configuring your FTP server’s passive port range and firewall rules.
Common FTP Server Software
On Linux, popular FTP daemons include:
vsftpd(“Very Secure FTP Daemon”) – widely used, focused on security and simplicity.proftpd– Apache-like configuration, highly configurable.pure-ftpd– another secure, feature-rich option.
Below, examples will primarily use vsftpd, as it’s common on major distributions.
Installing and Enabling an FTP Server (vsftpd)
Packages and commands vary slightly per distribution, but the pattern is similar.
Installation
On Debian/Ubuntu:
sudo apt update
sudo apt install vsftpdOn RHEL/Fedora:
sudo dnf install vsftpdOn Arch Linux:
sudo pacman -S vsftpdBasic Service Management
sudo systemctl enable vsftpd --now # enable at boot and start immediately
sudo systemctl status vsftpdIf your firewall is enabled, open the FTP control port (21) and any passive ports you will configure (details below). Firewall setup is covered in firewall-related chapters; here just note which ports you will need.
Basic vsftpd Configuration
The main configuration file is usually /etc/vsftpd.conf.
Always back it up before changing:
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.backupAfter any change:
sudo systemctl restart vsftpdDisabling Anonymous Access
For a non-public server, you usually want authenticated access only:
In /etc/vsftpd.conf, ensure:
anonymous_enable=NO
local_enable=YES
write_enable=YESExplanation:
anonymous_enable=NO– disables anonymous logins.local_enable=YES– allows system users to log in.write_enable=YES– allows write commands (upload, delete, etc.). Without this, server is read-only even for authenticated users.
Restricting Local Users to Their Home Directories (Chroot)
A common requirement: users should only see their own directory.
In /etc/vsftpd.conf:
chroot_local_user=YES
allow_writeable_chroot=YESNotes:
chroot_local_user=YES– confines users to their home directory.- By default,
vsftpddoes not allow a writable chroot for security reasons;allow_writeable_chroot=YESis a trade-off to allow simple deployments. For stricter security, use non-writable top-level directories with writable subdirectories.
Example:
sudo mkdir /home/alice/ftp
sudo chown alice:alice /home/alice/ftp
Then have Alice upload only into /home/alice/ftp, while /home/alice remains non-writable for vsftpd’s chroot rules if you turn off allow_writeable_chroot.
Enabling Passive Mode
To work well with firewalls/NAT, configure a port range for passive connections:
In /etc/vsftpd.conf:
pasv_min_port=40000
pasv_max_port=40100Then open those ports in your firewall and (if needed) in your router / NAT configuration.
If your server sits behind NAT, many setups also require:
pasv_address=your.public.ip.address
Where your.public.ip.address is the external IP clients will connect to.
FTP User Management Patterns
System Users as FTP Users
Simplest approach: existing Linux users log in with their system username/password.
- Pros:
- Simple to set up.
- Integrates with existing user accounts and permissions.
- Cons:
- FTP users might also have shell access unless restricted.
- Harder to separate FTP-only users from real system users.
You can restrict shell access for “FTP-only” users by giving them a nologin shell:
sudo useradd -m -s /usr/sbin/nologin ftpuser1
sudo passwd ftpuser1This user can authenticate for FTP but cannot log into a shell (e.g., via SSH).
FTP-Only User List (User Allow/Deny)
vsftpd supports user whitelists/blacklists for extra control:
In /etc/vsftpd.conf:
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO
With userlist_deny=NO, only users listed in /etc/vsftpd.userlist can log in.
Create/edit the file:
echo "ftpuser1" | sudo tee -a /etc/vsftpd.userlistSFTP: File Transfers via SSH
SFTP vs SCP
Both sftp and scp transfer files over SSH, but:
scpis more like a remotecpcommand; simple but less flexible.sftpis an interactive shell/program:- Supports listing, resuming, changing directories, etc.
- Many GUI clients (FileZilla, WinSCP, etc.) use SFTP.
For modern use, SFTP is generally preferred over SCP.
Basic SFTP Usage (Client Side)
From a Linux client:
sftp user@serverYou’ll be dropped into an interactive SFTP shell, with commands like:
ls– list remote directorypwd– show remote directorylpwd– show local directorycd– change remote directorylcd– change local directoryget file– download remote fileput file– upload local filemget / mput– multiple file transfers!command– run a local shell command
Non-interactive usage:
sftp user@server:/remote/path/file /local/path/
sftp /local/path/file user@server:/remote/path/Key-based authentication, SSH configuration, and tunneling are covered in SSH-related chapters; they apply equally to SFTP.
Configuring an SFTP-Only Subsystem (OpenSSH)
By default, OpenSSH’s SFTP support allows full SSH shell access (unless restricted). Many deployments need SFTP without shell login, often with chrooting.
This is controlled in /etc/ssh/sshd_config.
Always back it up first:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backupAfter changes:
sudo systemctl restart sshd # or ssh, depending on distroConfirming the SFTP Subsystem
Most modern sshd configs already have something like:
Subsystem sftp /usr/lib/openssh/sftp-serveror
Subsystem sftp internal-sftp
Prefer internal-sftp when possible; it runs SFTP code inside the sshd process and is easier to combine with chroot.
If not present, add:
Subsystem sftp internal-sftpCreating SFTP-Only, Chrooted Users
Goal: Users can:
- Only log in via SFTP
- Be chrooted into a directory (cannot see the rest of the system)
- Have no SSH shell access
1. Create a Group for SFTP Users
sudo groupadd sftpusers2. Add a User Restricted to SFTP
sudo useradd -m -g sftpusers -s /usr/sbin/nologin sftpuser1
sudo passwd sftpuser1-s /usr/sbin/nologinprevents normal shell access.-g sftpusersputs the user into the SFTP group.
3. Prepare the Chroot Directory
OpenSSH has strict requirements: the chroot directory must be owned by root and not writable by others.
Common pattern:
- Use
/sftp(or similar) as top-level chroot. - Create a subdirectory for each user’s files.
sudo mkdir -p /sftp/sftpuser1/upload
sudo chown root:root /sftp
sudo chmod 755 /sftp
sudo chown root:root /sftp/sftpuser1
sudo chmod 755 /sftp/sftpuser1
sudo chown sftpuser1:sftpusers /sftp/sftpuser1/upload
sudo chmod 755 /sftp/sftpuser1/upload
The user will be chrooted to /sftp/sftpuser1 but will actually upload into upload/, which is owned by them.
4. Configure sshd_config Match Block
Append something like this to /etc/ssh/sshd_config:
Match Group sftpusers
ChrootDirectory /sftp/%u
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding noExplanation:
Match Group sftpusers– applies these rules only to users in groupsftpusers.ChrootDirectory /sftp/%u–%uis replaced with the username, sosftpuser1is chrooted to/sftp/sftpuser1.ForceCommand internal-sftp– disables shell; only SFTP commands are allowed.X11Forwarding no,AllowTcpForwarding no– limit SSH features for this group.
Restart SSH:
sudo systemctl restart sshd5. Testing
From a client:
sftp sftpuser1@server- You should land in
/(which is actually/sftp/sftpuser1on the server). - You should see
uploadas your working folder. - You should not be able to escape above
/.
Attempting ssh sftpuser1@server should fail with a “This account is currently not available” or similar message, due to the nologin shell and ForceCommand internal-sftp.
Security and Hardening Considerations
For FTP
- Prefer SFTP over FTP on the public Internet whenever possible.
- If you must expose FTP:
- Disable anonymous access unless absolutely needed.
- Use strong passwords or IP restrictions.
- Limit allowed users via
userlistor similar mechanisms. - Restrict users to chrooted home directories.
- Use fail2ban or similar tools to limit brute-force attacks.
- Consider FTPS (FTP over TLS) if encryption is required but clients cannot use SFTP.
For SFTP
- Use SSH keys instead of passwords for automated transfers.
- Restrict SFTP-only users via
Matchblocks,ForceCommand, andChrootDirectory. - Limit features (port forwarding, X11 tunneling) for SFTP groups.
- Combine with firewall rules and intrusion detection as appropriate.
Integrating FTP/SFTP with Other Services
Typical integration patterns include:
- Web hosting
- Users upload web content via SFTP / FTP to a directory served by a web server (e.g., Apache/Nginx).
- Permissions and ownership must be coordinated with the web server’s user.
- Backup and automation
- Scripts use
sftpwith SSH keys for secure offsite backups. - Cron jobs or systemd timers can call SFTP/SCP-based backup scripts.
- Legacy systems
- Old hardware or software may only support FTP; in that case, isolate the FTP server as much as possible and place it behind strict firewall and access controls.
Troubleshooting Common FTP/SFTP Issues
FTP-Specific Issues
- Client can log in but directory listing fails
- Usually passive mode / firewall issue.
- Ensure
pasv_min_port/pasv_max_portare set and ports are opened. - Check server logs (often in
/var/log/vsftpd.logor related files). - “500 OOPS: vsftpd: refusing to run with writable root inside chroot()”
- The user’s root directory (chroot) is writable.
- Either:
- Set
allow_writeable_chroot=YES, or - Make the root non-writable and create a writable subdirectory.
SFTP-Specific Issues
- Chroot SFTP user cannot log in (“Connection closed” immediately)
- Check:
- Chroot directory is owned by root and not writable.
- Correct
ChrootDirectorypath. - Correct permissions on parent directories.
- Look at SSH logs (
journalctl -u sshdor/var/log/auth.log). - SFTP-only user still gets a shell
- Check that:
ForceCommand internal-sftpis in the correctMatchblock.Matchconditions actually match the user (group, user, etc.).- No conflicting rules earlier in
sshd_config.
By understanding the distinct roles and mechanics of FTP and SFTP, and by leveraging vsftpd and OpenSSH’s configuration features, you can provide secure, controlled file-transfer services that integrate cleanly with the rest of your Linux-based network services.