When configuring a Linux server's firewall using iptables, one common requirement is to allow all outbound traffic originating from the local machine. This includes DNS queries, HTTP/HTTPS requests, SSH connections, and any other services initiated by the server itself.
Many administrators use the simple approach of setting the default OUTPUT policy to ACCEPT:
iptables -P OUTPUT ACCEPT
While this works, it's not considered the most secure approach as it creates a blanket permission for all outbound traffic.
For better control while still allowing all locally originated traffic, you can use these rules:
# Allow established connections
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow all new outbound connections from local processes
iptables -A OUTPUT -m state --state NEW -j ACCEPT
This solution provides more granular control than simply setting OUTPUT to ACCEPT because:
- It explicitly allows only new connections originating from the local machine
- It maintains the ability to track connection states
- It works well with other firewall rules you might have
Here's a more complete example that includes common security practices:
# Flush all existing rules
iptables -F
# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow loopback traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow all new outbound connections
iptables -A OUTPUT -m state --state NEW -j ACCEPT
# Allow specific inbound services (example: SSH)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
After applying these rules, you can verify them with:
iptables -L -v
This will show you the current rules and packet/byte counters for each rule.
Remember that iptables rules are not persistent across reboots. To save them:
iptables-save > /etc/iptables.rules
And to restore them at boot, add this to your startup scripts or use your distribution's method (like iptables-persistent on Debian/Ubuntu).
The simplest way to allow all outbound traffic from a server is to set the default OUTPUT chain policy to ACCEPT:
iptables -P OUTPUT ACCEPT
This configuration permits any traffic initiated by the server itself while maintaining stricter controls on incoming connections through the INPUT chain.
When combined with a restrictive INPUT policy (DROP or REJECT), this approach provides good security because:
- External hosts cannot establish connections to your server unless explicitly allowed
- Your server can freely communicate with external services it needs
- The stateful nature of TCP ensures responses to your outbound connections are allowed
To check your current iptables rules and policies:
iptables -L -n -v iptables -L -n -v -t nat # For NAT rules
For more granular control while still allowing all outbound traffic, you could:
# Allow established/related connections iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow all new outbound connections iptables -A OUTPUT -m state --state NEW -j ACCEPT # Set default OUTPUT policy to DROP (optional) iptables -P OUTPUT DROP
- Blocking DNS (port 53) when you need name resolution
- Forgetting about IPv6 (ip6tables) if your system uses it
- Not considering NTP (port 123) for time synchronization
Here's a sample script that allows all outbound while restricting inbound:
#!/bin/sh # Flush existing rules iptables -F iptables -X # Set default policies iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # Allow localhost iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Allow established/related connections iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Add your specific INPUT rules here (SSH, HTTP, etc.) iptables -A INPUT -p tcp --dport 22 -j ACCEPT # Log dropped packets (optional) iptables -A INPUT -j LOG --log-prefix "IPTABLES DROP: "