How to Configure IPTables rules for restricted Incoming
Hi All,
I want to configure iptables to allow connection from only three ips(146..xxx.xxx.a1,146..xxx.xxx.a2,146..xxx.xxx.a3) for a particular port.
All other connections comming in to that port should be rejected.
How to configure. Please help.
Responses
Her eis a quick answer (because it depends largely on how your firewall is configured):
(order is important)
iptables -I INPUT -i eth0 -s bad.host.ip -p tcp --dport 80 -j REJECT
iptables -I INPUT -i eth0 -s 146..xxx.xxx.a1 -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -i eth0 -s 146..xxx.xxx.a2 -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -i eth0 -s 146..xxx.xxx.a3 -p tcp --dport 80 -j ACCEPT
This puts the rules at the top of the table to ensure no other rules are hit before them. Alternatively you can use 'append' instead of 'insert' so the order matches how the rules will look in the table with the reject rule at the end.
iptables -A INPUT -i eth0 -s 146..xxx.xxx.a1 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -s 146..xxx.xxx.a2 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -s 146..xxx.xxx.a3 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -s bad.host.ip -p tcp --dport 80 -j REJECT
Once you have confirmed that the rules are working correctly:
service iptables save
The "INSERT" method generally requires a rule index-number argument (e.g., iptables -I INPUT 7 -i eth0 -s bad.host.ip -p tcp --dport 22 -j REJECT
). You'd want to use iptables --line-numbers -L INPUT
to ascertain an appropriate index-number
If you use the "APPEND" method, instead, you can skip the index-number: the rule will be added to the end of the named chain.
The APPEND method runs the risk of being ignored if a rule matches further up the chain (ie. there may be a drop all at the end of the cahin and you using -A will only add the rules after that), that is why I provided -I which inserts at the top of the chain if no index is provided.
I have provided a more complete solution / explanation lower down this thread.
The insert location is optional. If you don't provide a location the rule is inserted as the first rule in the chain.
From the documentation (square brackets denotes optional)
iptables [-t table] -I chain [rulenum] rule-specification
The insert failed because he used the literal 'bad.host.ip' rather than replacing it with a valid IP address.
Manikandan,
Apologies, I only provided a single block address and you wanted to block all other addresses.
The IP Jan provided is close, but you actually need to specify 0.0.0.0/0 (can be short handed to 0/0) for anywhere so the source in 'iptables -L' listing shows 'anywhere' not 'default'
So this should give you what you need (replace the other REJECT rule)
iptables -A INPUT -i eth0 -s 0/0 -p tcp --dport 22 -j REJECT
Be careful when doing this over SSH as you will likely block yourself if you insert the REJECT rule first! To get around this you can provide '-I' a 'rulenum' so it inserts at a specific location in the chain, like this:
iptables -I INPUT 1 -i eth0 -s 146..xxx.xxx.a1 -p tcp --dport 22 -j ACCEPT
iptables -I INPUT 2 -i eth0 -s 146..xxx.xxx.a2 -p tcp --dport 22 -j ACCEPT
iptables -I INPUT 3 -i eth0 -s 146..xxx.xxx.a3 -p tcp --dport 22 -j ACCEPT
iptables -I INPUT 4 -i eth0 -s 146..xxx.xxx.a4 -p tcp --dport 22 -j ACCEPT
iptables -I INPUT 5 -i eth0 -s 0/0 -p tcp --dport 22 -j REJECT
Apologies again.
If the desired source hosts are in a contiguous IP range, you can use CIDR notation to allow that range via an "-s" rule. You can also pass a comma-delimited IP-list through the "-s" flag. However, iptables will tend to parse such a list into adjacent, identical rules for each IP address (but, at least it will save you some typing).
Correct.
Rules are processed in order from top to bottom in the chain and it follows the first match. If there are no matches, the default policy is used. There are some specific cases (jump and return is one example) which don't nullify lower rules, but as a general rule yes.
The complexity with answering firewall questions is not knowing the current state of the firewall. It is extremely common for the last rule on the INPUT chain to be DROP all (as well as having a default policy of DROP). This causes problems when suggesting the use of '-A' because the rule will be added to the end of the chain after the DROP all.
Using '-I' which default inserts above everything else is a way to guarantee that the rule you want to enact gets processed first and as a result should behave as you expect, but in the wider context this may not be the best place to put the rule in the chain (this is really a decision the firewall owner needs to make).
When inserting new rules without a a rule number, you need to execute your REJECT rule command first because subsequent inserts without a rule number will be put before it. Hope that makes sense :)
To confirm your rules are working use
iptables -Lv
There is a counter to the left of the rule with 'packets' and 'bytes'. If the rule is being hit/matched by incoming traffic, these counters will increase.
Basically, iptables
has a set of default chains (ones that are always present): these would be your INPUT, OUTPUT and FORWARD chains. In your rulesets, the INPUT and OUTPUT filters both reference a user-defined chain "RH-FIREWALL-1-INPUT".
You've essentially got no outbound filtering as your OUTPUT chain is devoid of any entries and its default action is "ACCEPT"
Your INPUT and FORWARD rules are essentially identical as both reference the same user-defined chain as their only action.
The contents of your "RH-Firewall-1-INPUT" chain would be processed top-to-bottoms for matches. Whether your rules are ordered efficiently, only an audit of the traffic coming into your host could say. In general, you'd want to order your rules such that the most-frequently hit ports/protocols are higher up and the least-frequently hit ones are at the bottom.
It can also help to break related rules into their own named-chains: makes things a bit more self-documenting (speaking of "self-documenting", it can be a good idea to use the comments module for iptables rules) and ensures that future INSERT operations within the larger chain don't create performance-lumps within a given rule-group. Most people aren't running systems with loads where they'll notice the impact (and, if they are, they'd likely achieve better performance using an external device to handle the rule processing), but it's something to consider.