I'm trying to DROP all incoming connections to my server, except from particular networks. At the same time I want to keep all outgoing connections from my server to external network (any network over any protocol) open. It is working by making below two changes in INPUT chain:

Note: the testing was done with 3 servers (VMs) with IPs on network, and all rules defined on server3 (IP:

a. iptables -P INPUT DROP
b. iptables -A INPUT -s -j ACCEPT
[root@server3 ~]# iptables -nvL

Chain INPUT (policy DROP 124 packets, 22308 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  265 34603 ACCEPT     all  --  *      *           

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 433 packets, 34693 bytes)
 pkts bytes target     prot opt in     out     source               destination         

However, my first question:

  1. When I defined the first rule above (changing the default policy for INPUT chain), it stopped all outgoing connections(ssh , ping) from my server(IP: as well. Why is this happening, if my default OUTPUT chain policy is still accept, and I don't have any rules defined under OUTPUT chain?

I wanted to achieve same thing by not changing the default policy for INPUT chain, like this:

c. iptables -I INPUT -j DROP
d. iptables -A INPUT -s -j ACCEPT

But it still blocks all incoming/outgoing connections to/from my server3. This brings me to my second question:

  1. How are the rules c. and a. working differently ? Kindly help in understanding, as I'm new to linux firewalls.

If you have a default DROP INPUT policy, even the response packets from your outgoint connections will get dropped.

To accept those, add this input rule:

iptables -I INPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

As for your last question, in your c and d example (assuming empty rules before those commands) you are setting a first rule drop everything and a second rule that would accept traffic from a certain network. IPTABLES grabs a match as soon as it can, so the first rule always matches (no condition set) so every rule after that won't execute. Exceptions to a rule must be defined before the rule.

In the first example -P INPUT DROP, you are setting a last rule that will catch whatever was not matched before, so any exception added will be executed before that default rule (-P).

-I inserts into a certain position (for example, in my previous command, I am setting the ESTABLISHED,RELATED rule to be the first so it matches no matter what you set after that.

-A appends to the rule list, so if will be matched just before the default.

If you want to achieve the same as the first example with explicit rules (like c and d), you should exchange possitions of those.

  • thanks so much for the elaborate explanation. Now the importance of the order of the rules in each CHAIN is more clear. One more query relating to the rule that you suggested. Will it behave same as: iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT? – dig_123 Sep 7 '14 at 19:49
  • 1
    It's the same. State is "older" and it seems that conntrack will be the standard on newer kernels. See serverfault.com/questions/358996/… for more detailed explanation. – NuTTyX Sep 7 '14 at 22:02
  • @NuTTyX My default policy of input is drop, but there are rules that allows packets, same as the one you defined. More details of the iptable rules that I have added can be found here 0wned.it/2016/07/30/…. But problem is that I cannot access internet. – Infinity Oct 15 '19 at 9:51
  • Solved my Kubernetes routing problem by applying to the FORWARD chain, that by some process gets set to default DROP. -I FORWARD 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT – Vincent Gerris Feb 14 at 9:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.