For our Blog Visitor only Get Additional 3 Month Free + 10% OFF on TriAnnual Plan YSBLOG10
Grab the Deal

How to Setup FTP on Linux Server – Complete Guide

To set up FTP on a Linux server, install and configure vsftpd, create a restricted FTP user, open firewall ports (21 and a passive range), enable optional TLS for encryption, and test with an FTP client. This guide shows step-by-step instructions for Ubuntu/Debian and RHEL/CentOS/AlmaLinux with secure, production-ready settings.

If you’re wondering how to set up FTP on a Linux server, you’re in the right place. In this tutorial, I’ll walk you through installing and hardening an FTP server with vsftpd, opening firewall and SELinux rules, enabling FTPS encryption, and testing with FileZilla or lftp. The process is beginner-friendly but follows enterprise-grade best practices I use for production environments.

Before You Begin: FTP vs SFTP and What You Should Choose

FTP is a legacy file transfer protocol that sends data in plain text. SFTP (part of OpenSSH) encrypts traffic end-to-end and is generally preferred for security. If you must use classic FTP for compatibility, always enable TLS (FTPS) to encrypt credentials and data. This guide focuses on vsftpd (very secure FTP daemon) with optional TLS.

What We’ll Use

We’ll deploy vsftpd because it’s fast, stable, and widely available. Steps cover Ubuntu/Debian and RHEL/CentOS/AlmaLinux. We’ll configure passive mode, chroot jails, user allowlists, and (optionally) FTPS so you can pass security scans and work smoothly with GUI clients like FileZilla.

Prerequisites

  • A Linux server (Ubuntu 22.04+/20.04+, Debian 11/12, AlmaLinux/RHEL/CentOS 8+)
  • Root or sudo privileges
  • Firewall access (UFW or firewalld) and, on RHEL-based systems, SELinux tools
  • A domain or IP address for clients to connect

Step 1: Install vsftpd

Ubuntu/Debian

sudo apt update
sudo apt install -y vsftpd
sudo systemctl enable --now vsftpd
sudo systemctl status vsftpd

RHEL/CentOS/AlmaLinux

sudo dnf install -y vsftpd policycoreutils-python-utils
sudo systemctl enable --now vsftpd
sudo systemctl status vsftpd

If the service is active, you can proceed to configuration.

Step 2: Back Up and Harden the vsftpd Configuration

Back up the default config and open it for editing:

sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak
sudo nano /etc/vsftpd.conf

Use these secure, production-ready settings. Add or update the following lines:

anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022

use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES

# Chroot users into their home
chroot_local_user=YES
allow_writeable_chroot=YES

# Passive mode for firewalls/NAT
pasv_enable=YES
pasv_min_port=40000
pasv_max_port=40100

# Allowlist specific users only
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

# Improve security hygiene
pam_service_name=vsftpd
seccomp_sandbox=YES

Save and restart:

sudo systemctl restart vsftpd

Step 3: Create a Restricted FTP User

Create a dedicated user and prevent shell access. We’ll also add nologin to /etc/shells so PAM allows FTP logins with that shell.

# Create user and set password
sudo adduser ftpuser
sudo passwd ftpuser

# Restrict shell access
sudo usermod -s /usr/sbin/nologin ftpuser
echo /usr/sbin/nologin | sudo tee -a /etc/shells

# Optional: create a dedicated FTP directory
sudo mkdir -p /home/ftpuser/ftp
sudo chown -R ftpuser:ftpuser /home/ftpuser/ftp

Now allow the user to log in via the allowlist:

echo "ftpuser" | sudo tee -a /etc/vsftpd.userlist
sudo systemctl restart vsftpd

Step 4: Open Firewall Ports (FTP + Passive Range)

UFW (Ubuntu/Debian)

sudo ufw allow 21/tcp
sudo ufw allow 40000:40100/tcp
sudo ufw reload
sudo ufw status

firewalld (RHEL/CentOS/AlmaLinux)

sudo firewall-cmd --permanent --add-service=ftp
sudo firewall-cmd --permanent --add-port=40000-40100/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

Using passive mode avoids complex NAT traversal and is recommended for cloud servers behind security groups or load balancers.

Step 5: Configure SELinux for FTP (RHEL-Based Only)

Enable home directory access and passive mode; then inform SELinux about your passive port range:

sudo setsebool -P ftp_home_dir 1
sudo setsebool -P ftpd_use_passive_mode 1
sudo semanage port -a -t ftp_port_t -p tcp 40000-40100 || \
sudo semanage port -m -t ftp_port_t -p tcp 40000-40100

If semanage isn’t found, install the policycoreutils-python-utils package (already covered above).

Encrypting FTP (FTPS) protects credentials and data in transit. Generate a self-signed certificate or use a valid one from your CA.

# Generate a self-signed cert (valid 3 years)
sudo openssl req -x509 -nodes -days 1095 -newkey rsa:2048 \
 -keyout /etc/ssl/private/vsftpd.key \
 -out /etc/ssl/certs/vsftpd.crt \
 -subj "/CN=$(hostname -f)"

# Set permissions
sudo chmod 600 /etc/ssl/private/vsftpd.key

Edit vsftpd.conf and add:

ssl_enable=YES
allow_anon_ssl=NO
force_local_logins_ssl=YES
force_local_data_ssl=YES

rsa_cert_file=/etc/ssl/certs/vsftpd.crt
rsa_private_key_file=/etc/ssl/private/vsftpd.key

# Harden TLS
ssl_sslv2=NO
ssl_sslv3=NO
ssl_tlsv1=YES
require_ssl_reuse=NO
ssl_ciphers=HIGH

Restart the service:

sudo systemctl restart vsftpd

In clients like FileZilla, choose “FTP over TLS (explicit)” to avoid plaintext logins.

Step 7: Test Your FTP Server

Command-Line Test

# Install lftp (recommended)
sudo apt install -y lftp  # Ubuntu/Debian
sudo dnf install -y lftp  # RHEL/CentOS/AlmaLinux

# Connect (replace server_ip or domain)
lftp -u ftpuser ftp://server_ip

# With FTPS:
lftp -u ftpuser ftps://server_ip
# If certificate is self-signed:
set ssl:verify-certificate no

GUI Test (FileZilla)

  • Host: your_server_ip or domain
  • Protocol: FTP — if FTPS enabled, select “FTP — TLS (explicit)”
  • Port: 21
  • Encryption: Require explicit FTP over TLS (recommended)
  • Logon Type: Normal, User: ftpuser, Password: your password

Troubleshooting Common FTP Errors

  • 530 Login incorrect: Ensure the user is in /etc/vsftpd.userlist, the password is correct, and /usr/sbin/nologin is listed in /etc/shells.
  • 500 OOPS: refusing to run with writable root: Keep allow_writeable_chroot=YES or make the user’s chroot directory non-writable (and use a writable subfolder).
  • Connection timed out: Open port 21 and passive ports (40000–40100). Check cloud security groups and local firewall.
  • TLS handshake/GnuTLS -15: Add require_ssl_reuse=NO in vsftpd.conf and restart.
  • RHEL-based SELinux denials: Enable ftp_home_dir, ftpd_use_passive_mode, and assign passive ports with semanage.

Best Practices to Keep Your FTP Server Secure

  • Prefer SFTP or FTPS: Avoid plain FTP logins whenever possible.
  • Restrict users: Use userlist_enable=YES and allow only specific accounts.
  • Chroot users: Prevent lateral movement by confining users to their home directories.
  • Harden passwords: Enforce strong password policies and consider MFA at the app layer.
  • Limit exposure: Only open required passive port ranges; avoid wide ranges.
  • Monitor logs: Check /var/log/vsftpd.log and system logs for suspicious activity.
  • Use Fail2ban: Add a vsftpd jail to block brute-force attempts.
  • Automate backups: Regularly back up FTP content to offsite storage.

Quick Alternative: Use SFTP (Built into OpenSSH)

In many cases, SFTP is simpler and more secure. It’s usually enabled by default with SSH. Create a user and connect with an SFTP client on port 22. You can chroot SFTP-only users by editing /etc/ssh/sshd_config with a Match block and restarting sshd. If strict compliance or legacy software mandates FTP, stick with FTPS.

FAQs: How to Set Up FTP on Linux Server

Is FTP or SFTP better for Linux servers?

SFTP is better for security because it encrypts everything via SSH. If you must use FTP for compatibility, use FTPS (FTP over TLS) so credentials and files aren’t exposed in plaintext. Most modern clients support SFTP and FTPS.

Which FTP server should I use on Ubuntu or CentOS?

vsftpd is the most common choice due to its security focus and stability. Alternative servers include ProFTPD and Pure-FTPd, but vsftpd is widely available, easy to harden, and supported by most distributions.

How do I fix “500 OOPS: vsftpd: refusing to run with writable root”?

Either set allow_writeable_chroot=YES in /etc/vsftpd.conf or keep the chroot directory non-writable and create a writable subdirectory (for example, /home/ftpuser/ftp/upload). Then restart vsftpd.

What firewall ports are required for FTP?

Open TCP 21 for control and a passive range (commonly 40000–40100). On RHEL-based systems with SELinux, also map the passive range to the ftp_port_t type with semanage and enable ftpd_use_passive_mode.

How do I enable FTP over TLS (FTPS) on vsftpd?

Generate a certificate, then add ssl_enable=YES, set rsa_cert_file and rsa_private_key_file, disable SSLv2/3, and restart vsftpd. In your client, select “Require explicit FTP over TLS.” This secures credentials and data in transit.

Final Thoughts

You now know how to set up FTP on a Linux server the right way: install vsftpd, lock it down, open the correct firewall/SELinux rules, and enable FTPS for encryption. If you want a faster route with expert hardening and 24/7 help, host on YouStable and let our engineers configure it for you.

Alok Trivedi

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top