Understanding and Modifying iptables Default Policies: ACCEPT vs DROP in Linux Firewall Configuration


2 views

In iptables, the policy defines the default action taken when no rules match a packet in a chain. There are two fundamental policies:

  • ACCEPT: Allows packets to pass through if no explicit rule matches
  • DROP: Silently discards packets if no rule matches (no response sent to sender)

The CentOS servers you observed demonstrate two common security approaches:

# Server 1 (Permissive):
Chain INPUT (policy ACCEPT)
Chain FORWARD (policy ACCEPT) 
Chain OUTPUT (policy ACCEPT)

# Server 2 (Restrictive):
Chain INPUT (policy DROP)
Chain FORWARD (policy DROP)
Chain OUTPUT (policy ACCEPT)

The restrictive approach (DROP for INPUT/FORWARD) is more secure but requires careful rule configuration to avoid locking yourself out.

Use these commands to change policies (run as root):

# Change INPUT to DROP
iptables --policy INPUT DROP

# Change FORWARD to ACCEPT
iptables --policy FORWARD ACCEPT

# Make changes persistent (CentOS 6)
service iptables save

# Or for CentOS 7+
/usr/libexec/iptables/iptables.init save

Here's a secure baseline configuration for a web server:

# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT

# Allow SSH (change port if needed)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# ICMP (ping)
iptables -A INPUT -p icmp -j ACCEPT

Always verify changes and test connectivity:

# Check current policies
iptables -L -n --line-numbers

# Test before applying (timeout after 5 minutes)
iptables -P INPUT DROP && sleep 300 && iptables -P INPUT ACCEPT

# Monitor blocked packets (useful for debugging)
iptables -L INPUT -v -n | grep DROP

In iptables, the policy defines the default action taken when no rules in a chain match the network traffic. There are two fundamental policies:

  • ACCEPT: Allows packets to pass through if no rules match
  • DROP: Silently discards packets if no rules match (no response to sender)

The configuration you observed shows two common security approaches:

# Server 1 (Permissive)
Chain INPUT (policy ACCEPT)
Chain FORWARD (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)

# Server 2 (Restrictive)
Chain INPUT (policy DROP)
Chain FORWARD (policy DROP) 
Chain OUTPUT (policy ACCEPT)

The second configuration is more secure - it implements a "deny by default" policy for incoming traffic while allowing outgoing connections.

To change policies, use these commands:

# Set INPUT chain to DROP
iptables --policy INPUT DROP

# Set FORWARD chain to ACCEPT
iptables --policy FORWARD ACCEPT

# Make OUTPUT chain DROP (rarely recommended)
iptables --policy OUTPUT DROP

When implementing DROP policies:

  1. First set up ALLOW rules for essential services
  2. Test changes before applying to production
  3. Consider using REJECT instead of DROP for internal networks

Example workflow for securing SSH:

# Allow established connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow SSH from specific IP
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.100 -j ACCEPT

# Finally set default policy to DROP
iptables --policy INPUT DROP

On CentOS/RHEL systems:

service iptables save
# Or
/usr/libexec/iptables/iptables.init save

For newer systems with firewalld:

systemctl stop firewalld
systemctl mask firewalld
yum install iptables-services
systemctl enable iptables