When configuring VSFTPD on CentOS 5, the common pitfall is overlooking FTP's dual-port nature. The service requires both port 21 (control) and port 20 (data), plus additional ports for passive mode. Many admins struggle with iptables rules that block FTP despite appearing correct.
For FTP to work properly through iptables, we need these critical modules:
ip_conntrack_ftp
ip_nat_ftp
First verify they're loaded:
lsmod | grep ftp
Here's the working configuration that handles both control and data channels:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# Load FTP connection tracking
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Standard FTP ports
-A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT
-A INPUT -p tcp --dport 20 -m state --state NEW -j ACCEPT
# For passive FTP (dynamic ports)
-A INPUT -p tcp --dport 49152:65534 -m state --state NEW -j ACCEPT
COMMIT
For passive FTP (recommended for most setups), you'll need additional configuration in vsftpd.conf:
pasv_enable=YES
pasv_min_port=49152
pasv_max_port=65534
Then add the corresponding iptables rule:
iptables -A INPUT -p tcp --match multiport --dports 21,20,49152:65534 -j ACCEPT
After implementing these rules:
- Restart vsftpd:
service vsftpd restart
- Reload iptables:
service iptables restart
- Test connection:
ftp localhost
- Check firewall logs:
tail -f /var/log/messages
If connections still fail:
# Check module loading
grep nf_conntrack_ftp /etc/sysconfig/iptables-config
# Enable debug logging in vsftpd
debug_ssl=YES
log_ftp_protocol=YES
Remember that CentOS 5 uses an older iptables version. If you're migrating these rules to newer systems, consider updating to firewalld or nftables equivalents.
When configuring IPTables for VSFTPD, it's crucial to understand that FTP uses multiple ports in different modes:
- Command channel (port 21)
- Data channel (port 20 in active mode, random ports in passive mode)
- Connection tracking modules for proper stateful inspection
Here's the proper way to implement FTP rules in your IPTables configuration:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# Allow loopback interface
-A INPUT -i lo -j ACCEPT
# Allow established connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# FTP specific rules
-A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT
-A INPUT -p tcp --dport 20 -m state --state NEW -j ACCEPT
# For passive FTP mode (VSFTPD default)
-A INPUT -p tcp --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
# Load connection tracking modules (add to /etc/sysconfig/iptables-config)
MODULES="ip_conntrack_ftp ip_nat_ftp"
Ensure your VSFTPD configuration (/etc/vsftpd/vsftpd.conf) includes these settings:
pasv_enable=YES
pasv_min_port=30000
pasv_max_port=31000
port_enable=YES
Then adjust your IPTables rules accordingly for the passive port range:
-A INPUT -p tcp --dport 30000:31000 -m state --state NEW,ESTABLISHED -j ACCEPT
After implementing these changes:
- Restart both services:
service iptables restart && service vsftpd restart
- Test connectivity from a remote client:
ftp your.server.ip
- Check IPTables logs:
tail -f /var/log/messages | grep FTP
For debugging, temporarily set IPTables to logging mode:
-A INPUT -p tcp --dport 21 -j LOG --log-prefix "FTP Traffic: "