Deny all incoming connections with iptables?
I want to make some simple iptables rules to deny all incoming connections and allow outgoing. How can I do that?
Try this with root access :
# Set default chain policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Accept on localhost
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow established sessions to receive traffic
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Note that this will brutally cut all running connections - this includes things like the SSH connection you may use to administer the server. Only use this if you have access to a local console.
See Miphix' answer for how to add an exception for SSH.
If you’re working remotely via SSH, you might want to add this (-I
inserts it before all other rules in INPUT
):
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
If your SSH service is listening on another port, you’ll have to use that port instead of 22
.
Otherwise, you might accidentally lose access.
Be aware that the other answers do not cover IPv6! If your system accepts IPv6 traffic, not a single iptables rule will apply to ipv6 traffic.
instead of using iptables / ip6tables directly, i recommend using iptables-restore and save. These tools allow to specify a iptables configuration with multiple rules and easily load it with one command.
create a file (i named it iptables.rules) with the following content:
*filter
# drop forwarded traffic. you only need it of you are running a router
:FORWARD DROP [0:0]
# Accept all outgoing traffic
:OUTPUT ACCEPT [623107326:1392470726908]
# Block all incoming traffic, all protocols (tcp, udp, icmp, ...) everything.
# This is the base rule we can define exceptions from.
:INPUT DROP [11486:513044]
# do not block already running connections (important for outgoing)
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# do not block localhost
-A INPUT -i lo -j ACCEPT
# do not block icmp for ping and network diagnostics. Remove if you do not want this
# note that -p icmp has no effect on ipv6, so we need an extra ipv6 rule
-4 -A INPUT -p icmp -j ACCEPT
-6 -A INPUT -p ipv6-icmp -j ACCEPT
# allow some incoming ports for services that should be public available
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
# commit changes
COMMIT
Note i have added some extra example if you want to allow ICMP and traffic to specific ports.
now you can load it with these commands:
iptables-restore < iptables.rules
ip6tables-restore < iptables.rules
Now your rules cover also ipv6 and are easy to manage.
Additional note to Debian users: if you are satisfied with your rules, you can apt install iptables-persistent
so the rules get restored after reboot. The rules are not auto-saved on shutdown, so run netfilter-persistent save
to update the persistent rules.