On an Ubuntu VPS, the usual FTP implementation is vsftpd. Install it from Ubuntu’s package repositories, create a restricted account, confine that account to an upload directory, configure a narrow passive-port range, and open the matching ports in both firewalls. Do not expose passwords or files with unencrypted FTP: use SFTP when your client supports it, or add TLS and run FTPS when you must retain FTP compatibility.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
Decide whether you need FTP, FTPS or SFTP
FTP is a TCP protocol for transferring files. Its control connection normally uses TCP port 21, while a separate data connection carries directory listings and file contents. In plain FTP, usernames, passwords and transferred data are sent without encryption. Anyone able to observe the network can potentially read them.
As an Amazon Associate I earn from qualifying purchases.
FTPS keeps the FTP command and account model but protects the connections with SSL/TLS. SFTP is not “FTP with SSH”; it is a different file-transfer subsystem carried inside an encrypted SSH session. The choice affects firewall rules, client compatibility and how users authenticate.
| Characteristic | Plain FTP | FTPS | SFTP |
|---|---|---|---|
| Encryption | None by default; credentials and data are clear text | FTP protected with SSL/TLS | SSH-encrypted file-transfer subsystem |
| Server software | vsftpd |
vsftpd with TLS enabled |
OpenSSH server |
| Firewall shape | Control connection plus negotiated data ports | Control connection plus negotiated encrypted data ports | Usually the SSH port only |
| Account model | FTP/PAM users or anonymous mode | The same FTP account model, with TLS | SSH accounts, optionally restricted to SFTP |
| Client compatibility | Legacy FTP clients | Clients supporting explicit or implicit TLS | Clients that support SFTP |
For an Internet-facing VPS, SFTP is the simplest secure default when available. If a vendor, appliance or application specifically requires FTP commands, configure FTPS rather than plain FTP. Anonymous uploads should not be enabled on a public server; Ubuntu describes that as an extreme security risk.
#1 Best Overall
Prepare the Ubuntu VPS
Complete these checks before changing the server:
- Run a supported Ubuntu Server release and apply current security updates.
- Have administrative SSH access that is separate from the account you intend to use for file transfer.
- Know the VPS public IPv4 address or a DNS name that resolves to it. A stable DNS name is particularly useful for TLS certificates.
- Record whether your hosting provider has a second network firewall or security-group layer. UFW rules alone do not open ports that the provider blocks upstream.
- Take a VPS snapshot or another restorable backup so a configuration mistake can be rolled back.
Keep a second SSH session open while editing the FTP configuration. That gives you a recovery path if a firewall change or service restart behaves unexpectedly.
Install and verify vsftpd
Ubuntu supplies vsftpd as a package. Update the package index, install the daemon and inspect its initial state:
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchsudo apt update
sudo apt install vsftpd
sudo systemctl status vsftpd
Enable the service at boot and start it immediately if the package did not already do so:
sudo systemctl enable --now vsftpd
Before editing, preserve the distribution configuration:
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak.$(date +%F-%H%M)
The primary configuration file is /etc/vsftpd.conf. Lines beginning with # are comments. If the file contains the same setting more than once, remove or comment out the older copy so that the active value is obvious.
Create a dedicated, least-privilege FTP account
Never use root or a service account that owns operating-system files for FTP. Create a normal user whose home is the directory you will later chroot:
sudo adduser --home /srv/ftp/ftpuser ftpuser
Choose a long, unique password when prompted. The account needs only the files it must transfer. Do not add it to sudo or other administrative groups. Ubuntu uses /etc/ftpusers as a deny list; verify that the new account is not listed, while leaving root and other protected system users on that list:
grep -Fx ftpuser /etc/ftpusers || true
An FTP login should not become an SSH administration path. Keep administrative SSH users separate and, if appropriate for your environment, deny this transfer-only account in /etc/ssh/sshd_config with a DenyUsers ftpuser entry, then validate and reload SSH:
Rank #2
sudo sshd -t
sudo systemctl reload ssh
Test that restriction in a separate SSH session before closing your existing administrative session.
Apply a secure baseline in /etc/vsftpd.conf
Open the file:
sudo nano /etc/vsftpd.conf
For authenticated users, a practical baseline is:
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
chroot_local_user=YES
pasv_enable=YES
pasv_min_port=40000
pasv_max_port=40100
xferlog_enable=YES
use_localtime=YES
What each important setting does
anonymous_enable=NOdisables unauthenticated sessions. Do not turn it on for a public upload service.local_enable=YESpermits Unix users to authenticate through the FTP service.write_enable=YESis the master switch for authenticated-user write operations. Without it, logins may work but uploads, renames and deletes will fail.local_umask=022applies a conservative creation mask. Use a different mask only when your collaboration requirements justify the resulting permissions.chroot_local_user=YESplaces each local user inside its FTP home instead of allowing ordinary directory traversal through the rest of the filesystem.pasv_enable=YESenables passive transfers. The two port settings limit the data ports to a range you can document and firewall.xferlog_enable=YESenables transfer logging, which is useful when investigating failed uploads or unexpected activity.
Do not combine conflicting listener modes. If you use IPv4 only, set listen=YES and listen_ipv6=NO. If you need IPv6, use the IPv6 listener mode instead and make sure your DNS and firewall rules support it. A service that fails immediately after an edit often has both listener modes enabled or another daemon already bound to the selected port.
Build a chroot that users can write to safely
A chroot root should not be writable by the account it contains. Make the FTP home owned by root, then create a child directory owned by the transfer user:
sudo chown root:root /srv/ftp/ftpuser
sudo chmod 755 /srv/ftp/ftpuser
sudo mkdir /srv/ftp/ftpuser/upload
sudo chown ftpuser:ftpuser /srv/ftp/ftpuser/upload
sudo chmod 750 /srv/ftp/ftpuser/upload
The user will see / as the chroot and an upload directory beneath it. Files placed in /srv/ftp/ftpuser/upload are therefore outside the account’s ability to modify the chroot boundary itself. If you want downloads from a read-only directory, create a separate directory and grant only the read and execute permissions required.
An alternative is a carefully maintained chroot_list_file, but that model is easy to misunderstand because the meaning of the list changes with chroot_local_user. Use one consistent policy, document which accounts are exceptions and review it whenever an account is added.
Configure passive FTP and both firewall layers
Passive FTP is essential for many clients behind NAT or restrictive firewalls. The client connects to port 21 for commands, then the server tells it which high-numbered port to use for each data transfer. Opening only port 21 therefore allows login but often makes directory listings and transfers hang.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteThe example range above uses TCP ports 40000 through 40100. A smaller range reduces firewall exposure, but it must be large enough for the number of simultaneous transfers you expect. Keep the range stable and record it in your operations documentation.
Advertise the address clients can actually reach
If the VPS has a directly reachable public address, no extra address setting may be necessary. When the server has private addressing, provider NAT or multiple interfaces, set the advertised address explicitly:
Rank #3
pasv_addr_resolve=YES
pasv_address=ftp.example.com
Use a DNS name only with pasv_addr_resolve=YES; otherwise use the public IP address assigned to the VPS. The value must be reachable from the client, not the server’s private interface address. If the public address changes, update DNS and this setting before testing again.
Open UFW
sudo ufw allow 21/tcp
sudo ufw allow 40000:40100/tcp
sudo ufw status verbose
Do not open a wider high-port range “just in case.” The passive range in the daemon configuration and the UFW range must match exactly.
Free tools Windows power users keep installed
One-click scans. No signup required.
Open the provider firewall
In your VPS provider’s network firewall or security group, allow TCP 21 and TCP 40000–40100 from the client networks that need access. If the provider firewall blocks either the control port or the passive range, changing UFW cannot fix the connection. Restrict source addresses where practical instead of allowing the entire Internet.
Add TLS when FTP semantics are required
Plain FTP is not suitable for credentials or data on an untrusted network. If SFTP cannot be used because the application requires FTP, configure explicit TLS (often labelled FTPES) and test with a client that validates certificates.
Obtain a certificate whose name matches the host clients will use, and store the certificate and private key in root-owned files. Replace the package’s example certificate and key with your host-specific paths. Then add settings similar to:
Recommended Free Tools
ssl_enable=YES
rsa_cert_file=/etc/ssl/certs/ftp.example.com.crt
rsa_private_key_file=/etc/ssl/private/ftp.example.com.key
force_local_logins_ssl=YES
force_local_data_ssl=YES
Set restrictive ownership and permissions on the private key:
sudo chown root:root /etc/ssl/private/ftp.example.com.key
sudo chmod 600 /etc/ssl/private/ftp.example.com.key
force_local_logins_ssl=YES prevents local users from sending passwords without TLS. force_local_data_ssl=YES protects directory listings and file contents as well. Anonymous TLS settings are unnecessary when anonymous access is disabled.
Do not confuse FTPS with SFTP. FTPS still uses FTP’s control and passive data connections, so the port range and firewall rules remain necessary. SFTP uses the SSH service and normally needs only the SSH port. Configure the client for explicit TLS on the FTP service, not for SFTP, and verify that it checks the certificate name rather than silently accepting any certificate.
Rank #4
Restart, inspect and test from outside the VPS
After saving the configuration, restart the service and inspect both its state and recent log messages:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
sudo systemctl restart vsftpd
sudo systemctl status vsftpd --no-pager
sudo journalctl -u vsftpd -n 50 --no-pager
sudo ss -ltnp | grep -E ':(21|40000|40001|40100)b'
A listening control socket confirms only that the daemon started; it does not prove that passive transfers, permissions or TLS are correct. From a separate network, test each required behavior:
- Resolve the DNS name and confirm it reaches the VPS public address.
- Connect with the intended client and the dedicated account. Never put the password in a shell command that will remain in history.
- Confirm the initial directory is the chroot and that the user cannot browse the VPS filesystem above it.
- Upload a small test file into
upload, download it, rename it if required, and verify that operations outside the permitted directory fail. - Repeat the test with passive mode enabled. A successful login followed by a stalled listing indicates a data-channel or firewall problem, not an authentication problem.
- For FTPS, verify the certificate chain, hostname and expiration date, and confirm that an unencrypted login is rejected.
- Reboot or stop/start the service during a maintenance window and confirm that
systemctl enablebrought it back with the same settings.
The configuration steps establish a defensible setup, but the sources for this procedure do not represent a test of your particular VPS, provider firewall or client. An external test is therefore part of the deployment, not an optional formality.
Troubleshoot the failures that occur most often
“530 Login incorrect” or an immediate disconnect
- Reset the account password with
sudo passwd ftpuserand check that the account is not locked. - Confirm
local_enable=YESand thatftpuseris not present in/etc/ftpusers. - Check the service log for PAM or shell-policy errors. A distribution-specific PAM policy may reject an account whose login shell is disabled; resolve that policy deliberately rather than enabling an administrative shell for every FTP user.
- Ensure the client is using FTP or explicit FTPS as configured, not SFTP against port 21.
Login works but uploads return “permission denied” or “553”
- Verify
write_enable=YESand restart vsftpd after changing it. - Check ownership and mode on the actual destination:
namei -l /srv/ftp/ftpuser/upload. - Make sure the user is writing to
/upload, not to the root of the chroot, which should remain root-owned. - Check filesystem space and quotas with
df -hand any quota tooling used by your VPS.
Directory listings or transfers hang after authentication
- Confirm the client is in passive mode.
- Match
pasv_min_portandpasv_max_portto both UFW and the provider firewall. - Check that
pasv_addressadvertises the public address or resolvable public hostname, not a private address. - Look for a second firewall, NAT rule or security group that still blocks the passive range.
The service will not restart
- Read
journalctl -u vsftpdfor the exact directive or permission error. - Check for a duplicate or contradictory listener configuration, and see whether another process already owns port 21 with
sudo ss -ltnp | grep ':21'. - Verify that the certificate and private-key paths exist and that the daemon can read them without making the key world-readable.
- Restore the timestamped backup if necessary, restart, then reapply one change at a time.
FTPS reports a certificate or handshake error
- Use the DNS name covered by the certificate, not an unrelated IP address.
- Install the complete certificate chain expected by your clients.
- Confirm the private key matches the certificate and that its permissions allow the daemon to read it.
- Check the client’s mode: explicit TLS negotiates on the FTP service’s control connection, whereas implicit TLS uses a different client mode and deployment convention.
When SFTP is the better solution
If every required client supports SFTP, an OpenSSH-based service avoids FTP’s separate passive data channel and normally needs only the SSH port in the firewall. Ubuntu’s own FTP guidance points readers seeking secure uploads and downloads toward OpenSSH.
The basic client connection is:
sftp [email protected]
Install the OpenSSH server package if it is not already present:
sudo apt update
sudo apt install openssh-server
SFTP uses SSH accounts, so apply the same least-privilege principles: create a dedicated account, deny administrative group membership, restrict its filesystem view with an SSH chroot or a purpose-built SFTP-only configuration when required, and allow only the SSH source networks that need access. Do not assume that installing OpenSSH automatically confines an account; ordinary SSH users may receive a shell as well as SFTP until you explicitly restrict them.
Choose FTPS instead when an existing application understands FTP commands, FTP directory semantics or FTP-specific integrations but can be configured to require TLS. Choose neither plain FTP nor anonymous uploads for an Internet-exposed production service.
Operational checklist
- Keep
anonymous_enable=NOand never permit anonymous uploads on a public VPS. - Use named, dedicated accounts; keep root and system accounts out of FTP.
- Review
/etc/ftpusersand SSH access rules whenever accounts change. - Keep the chroot root owned by root and grant write access only to an intended child directory.
- Use a bounded passive range and mirror it exactly in UFW and the provider firewall.
- Prefer SFTP; otherwise require TLS for both local logins and data transfers.
- Renew certificates before expiration and protect private keys with root-only permissions.
- Monitor transfer logs, disk space and failed-login messages.
- Retest from outside the VPS after firewall, DNS, certificate or provider-network changes.
The practical recommendation
For a new deployment, use SFTP through OpenSSH unless an application genuinely requires FTP. If FTP compatibility is unavoidable, run vsftpd with local accounts only, a root-owned chroot and writable subdirectory, a documented passive range, matching firewall rules and mandatory TLS. Plain FTP is appropriate only on a network you fully control and trust; it is not a safe Internet-facing choice because it exposes both credentials and file data.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →




