Deny all incoming connections with iptables?

17

11

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

polyglot

Posted 2012-05-22T14:27:20.223

Reputation: 361

Answers

26

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.

Yohann

Posted 2012-05-22T14:27:20.223

Reputation: 533

2When I do first line of your rule, i've got disconnected from SSH – holms – 2014-10-06T07:26:27.723

7The question is "deny all incoming connections" and not "deny all incoming connections except SSH" :) – Yohann – 2014-12-04T16:17:57.800

I read warning of @holms about first rule too late... – DenisKolodin – 2016-10-20T07:01:56.790

Note that this has no effect on ipv6 Traffic. Read my answer below if you have ipv6 enabled. – bhelm – 2018-07-19T07:41:08.353

13

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.

Miphix

Posted 2012-05-22T14:27:20.223

Reputation: 237

2

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

Posted 2012-05-22T14:27:20.223

Reputation: 651

1

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

Posted 2012-05-22T14:27:20.223

Reputation: 13