26

I want to make some simple iptables rules to deny all incoming connections and allow outgoing. How can I do that?

Renan
  • 8,062
polyglot
  • 461

5 Answers5

42

Try this with root access:

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.

# 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

Yohann
  • 775
  • 9
  • 11
17

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.

BenjiWiebe
  • 9,173
Miphix
  • 277
8

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.

bhelm
  • 1,411
2

Both answers above somehow correct, but they don't accurate enough to origin answer. (Sorry i havn't enough reputation to add comment, so writing complete answer).

I my case i met overloaded apache server, over-floated with cron jobs, over-utilizing cpu. Threads limits were stored in SQL database, but i met limit of its connections. I wanted to limit incoming apache connections from local host (this part is optional), but keep all other connection possible. Including those which were actually established.

I did it with command

sudo iptables -I INPUT -p tcp --dport 80 -m state --state NEW -j REJECT

It means: for each incoming tcp package on the port 80, load state module, and if this is the first package (incoming connection) reject it. For localhost you might just use -s 127.0.0.0/8

And for real world use, in some cases you might add 'INVALID' to the states, NEW,INVALID, because one can send "malicious" packages, trying bypass your rule. And also replace with -j DROP to save your outbound traffic (it wont send rejection beacon)

Offenso
  • 43
0

Deny specific website:

# iptables -A OUTPUT -p tcp -d www.twitter.com --dport 443 -j DROP
# iptables -A OUTPUT -p tcp -d twitter.com --dport 443 -j DROP
# service iptables save
# service iptables restart
# iptables -L

Reference

Vishrant
  • 297