How to Configure VSFTPD to Listen Only on Localhost (Secure FTP Setup Guide)


14 views

When dealing with legacy applications requiring FTP (not SFTP), we often need to implement security measures that exceed the protocol's inherent limitations. The classic approach involves:

  • Deploying VSFTPD as the FTP server
  • Restricting port 21 access via firewall rules
  • Establishing SSH tunnels for secure transport

To make VSFTPD listen exclusively on localhost, modify /etc/vsftpd.conf with these critical parameters:

listen=YES
listen_address=127.0.0.1
anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES
allow_writeable_chroot=YES
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

While VSFTPD's native configuration provides the first layer, combining it with firewall rules creates defense in depth. For UFW users:

sudo ufw allow from 127.0.0.1 to any port 21
sudo ufw deny 21

For iptables purists:

iptables -A INPUT -p tcp --dport 21 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j DROP

The complete secure workflow involves establishing the SSH tunnel:

ssh -L 2121:localhost:21 user@your_server

Then configure your legacy client to connect to:

  • Host: localhost
  • Port: 2121

Validate your setup with these commands:

netstat -tulnp | grep 21  # Should show 127.0.0.1:21
nmap -p 21 your_server_ip  # From external host should show filtered

For active connection testing:

ftp localhost  # Should work
ftp your_server_ip  # Should fail

When dealing with legacy applications requiring FTP (not SFTP), security-conscious developers often need to restrict access at multiple layers. While firewall rules can block external connections, configuring VSFTPD itself to listen only on localhost provides an additional security boundary.

The most effective method involves modifying vsftpd.conf with these critical directives:


listen=YES
listen_address=127.0.0.1
listen_ipv6=NO

This configuration ensures:

  • The server binds exclusively to IPv4 localhost
  • IPv6 listening is disabled (prevents potential ::1 binding)
  • All external connection attempts are rejected at the service level

After restarting VSFTPD (systemctl restart vsftpd), verify the binding:


ss -tulnp | grep vsftpd
# Should only show: tcp LISTEN 0 32 127.0.0.1:21

For your tunneled access solution, the client-side SSH command would be:


ssh -L 2121:localhost:21 user@your-server

The legacy application can then connect to localhost:2121 while traffic is securely tunneled.

Consider adding these to vsftpd.conf for defense-in-depth:


allow_writeable_chroot=YES
chroot_local_user=YES
userlist_enable=YES
userlist_deny=NO

This configuration:

  • Restricts users to their home directories
  • Implements explicit user whitelisting
  • Maintains functionality while enhancing security

If connections fail, check:

  1. SELinux contexts (restorecon -Rv /etc/vsftpd)
  2. Firewall rules even for localhost (iptables -L -n -v)
  3. Proper file permissions for chrooted users