How to Configure IPTables rules for restricted Incoming

Latest response

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

Hi Pixel,

Thanks for the response. But I am not able to insert the rules.
Getting the below error.

[root@usculrhelt03v ~]# iptables -I INPUT -i eth0 -s bad.host.ip -p tcp --dport 22 -j REJECT
iptables v1.4.7: host/network bad.host.ip' not found
Try
iptables -h' or 'iptables --help' for more information.

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.

Right, but an INSERT operation doesn't work if you don't give it an insert location (Manikandan was seeking input on why his attempted rule-change failed).

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.

146..xxx.xxx.a3 is your example
bad.host.ip is also an example

You need to fill in the ip-address you want to block.
0.0.0.0 would block all other ip-address except the ones you allow, so use with care.

I have used 0.0.0.0, But still I am able to connect to the server from other IPs.

iptables -L

Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 146.xxx.xxx.4 anywhere tcp dpt:ssh
REJECT tcp -- default anywhere tcp dpt:ssh reject-with icmp-port-unreachable
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

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).

Apologies for getting Back on this...

Pixe Thank you very much for the commands, Thanks all for the healthy discussion.

Just to clarify... So the rule on the top takes the priority in IPtables. if a rule to allow the traffic sits at the top of the IPtables will nullify the rule below to reject the connection for the same.

Am I correct? Thanks

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.

Thanks a Lot for the explanation.

Can you please check and say from the below iptables what is this part

Chain INPUT (policy ACCEPT)
target prot opt source destination
RH-Firewall-1-INPUT all -- anywhere anywhere

Chain FORWARD (policy ACCEPT)
target prot opt source destination
RH-Firewall-1-INPUT all -- anywhere anywhere

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain RH-Firewall-1-INPUT (2 references)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:asterix
ACCEPT udp -- anywhere anywhere udp dpt:abarsd
ACCEPT udp -- anywhere anywhere udp dpt:cvd
ACCEPT tcp -- anywhere anywhere tcp dpt:asterix
ACCEPT tcp -- anywhere anywhere tcp dpt:abarsd
ACCEPT tcp -- anywhere anywhere tcp dpt:cvd
ACCEPT tcp -- anywhere anywhere tcp dpt:8610
ACCEPT tcp -- anywhere anywhere tcp dpt:canon-bjnp1
ACCEPT tcp -- anywhere anywhere tcp dpt:canon-bjnp2
ACCEPT tcp -- anywhere anywhere tcp dpt:canon-bjnp3
ACCEPT tcp -- anywhere anywhere tcp dpt:canon-bjnp4
ACCEPT tcp -- anywhere anywhere tcp dpt:8615
ACCEPT tcp -- anywhere anywhere tcp dpt:8616
ACCEPT tcp -- anywhere anywhere tcp dpt:8617
ACCEPT tcp -- anywhere anywhere tcp dpt:8618
ACCEPT tcp -- anywhere anywhere tcp dpt:8619
ACCEPT tcp -- anywhere anywhere tcp dpt:8620
ACCEPT all -- anywhere anywhere
ACCEPT icmp -- anywhere anywhere icmp any
ACCEPT esp -- anywhere anywhere
ACCEPT ah -- anywhere anywhere
ACCEPT udp -- anywhere 224.0.0.251 udp dpt:mdns
ACCEPT udp -- anywhere anywhere udp dpt:ipp
ACCEPT tcp -- anywhere anywhere tcp dpt:ipp
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:42098
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:8089
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:irdmi
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited

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.

[Chain RH-Firewall-1-INPUT (2 references)] what is this part in above iptables

Thanks Jones, Last query.

When I add or insert the rules its going to the default phrases.
How to direct the rules to RH-Firewall-1-INPUT parse.

iptables -I <number> <chainname> <rule statements>

for example, to allow port 80 traffic and inserting it as the 18th rule:

iptables -I 18 RH-Firewall-1-INPUT -m tcp -p tcp --dport 80 -m comment --comment "HTTP Traffic" -j ACCEPT