LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Security
User Name
Password
Linux - Security This forum is for all security related questions.
Questions, tips, system compromises, firewalls, etc. are all included here.

Notices


Reply
  Search this Thread
Old 09-02-2007, 04:16 PM   #1
mjl3434
Member
 
Registered: Sep 2003
Location: USA
Distribution: Ubuntu 20.04
Posts: 111

Rep: Reputation: 15
trouble understanding iptables default policy


Hi, I have been looking at some firewall examples and have been having some trouble understanding the default policies.

This is my understanding--correct me if I am wrong; As a packet arrives it is compared against each rule one by one until a match is made, then it is send to the target of that rule. If no matches are made then the default policy is applied to that packet.

I'm confused because I've seen things like this when people initialize their firewalls:


Code:
# Set the default policy to drop
iptables --policy INPUT   DROP
iptables --policy OUTPUT  DROP
iptables --policy FORWARD DROP

iptables -A INPUT -m unclean -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
iptables -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP
Am I correct in thinking that all these rules are dumb? Since the default policy is drop, they would have been dropped anyway if the rules weren't even there. Is this right?

It would make more sense to me to create a chain to accept a packet first, and then to apply these rules after a packet has been accepted. (For example, accept incoming HTTP traffic, and then do strict filtering on it to rule out any abnormal behaviors).





P.S. To give some context... what I am trying to do is configure my host which is one of 2 PCs behind a DSL connection shared via a Netgear NAT box/router. The only services I want to use are web browsing and downloading, Pidgin, remote SSH access from a select set of IPs, and yum. Right now I'm just starting and I want to understand how to set up the firewall. Once I get this done my approach will be to create separate chains for each type of traffic I want to allow, and then filter each of those chains for abnormal behavior.
 
Old 09-02-2007, 07:22 PM   #2
win32sux
LQ Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Rep: Reputation: 380Reputation: 380Reputation: 380Reputation: 380
The way I see it, bad packet chains/rules typically serve two purposes:

1-> Let the admin know of weird packets.

2-> Filter weird packets (which would have otherwise been sent to ACCEPT).

IMHO, yes, a DROP rule could be considered "dumb" if it sends to DROP a packet which would have been sent to DROP anyways by the chain's policy. The problem here is that in your example we have no way to know whether the packet would have been sent to DROP, as the example only includes DROP rules.

There's also the fact that, in your example, packets won't get sent to LOG before they are sent to DROP by the policy. So even without those bad packet rules, the admin won't know about the weird packets getting sent to DROP - a situation which could be considered to be "just as dumb".

In any case, regarding filtering by means of set bits, perhaps it would be better for you to make ACCEPT rules for packets with bit combinations you approve of, and then send packets which don't match those to LOG and then DROP. In other words, a whitelist (default-deny) approach versus a blacklist (default-accept) approach. It's just a thought, and I do admit I haven't really thought about it before. It might be completely insane.

Basically what I'm saying is that bad packet rules can be very useful, when done properly.

Let's say you have this rule for your SSH daemon:
Code:
iptables -A INPUT -p TCP --dport 22 -m state --state NEW -j ACCEPT
You know that a packet initiating a connection to the daemon *should* have the SYN bit set (and the RST, ACK, and FIN bits unset), however, even if it isn't (such as could be the case with a port scan) then the packet will still get sent to ACCEPT by that rule (assuming the IP wasn't in the state table). So by having had a bad packet rule for packets of state NEW that aren't properly SYN we could have filtered the unorthodox packet and have been notified of it:
Code:
iptables -A INPUT -p TCP ! --syn -m state --state NEW -j LOG \
--log-prefix "NEW NOT SYN: "
iptables -A INPUT -p TCP ! --syn -m state --state NEW -j DROP
iptables -A INPUT -p TCP --dport 22 -m state --state NEW -j ACCEPT
EDIT: Keep in mind that "--syn" is synonymous to "--tcp-flags SYN,RST,ACK,FIN SYN".

Last edited by win32sux; 09-02-2007 at 09:43 PM.
 
Old 09-03-2007, 03:38 AM   #3
mjl3434
Member
 
Registered: Sep 2003
Location: USA
Distribution: Ubuntu 20.04
Posts: 111

Original Poster
Rep: Reputation: 15
Thank you, you helped clarify things. In the example I had seen those rules were being used to "set up" the firewall. However since the default policies were drop they alone served no purpose.

You are right it would make a lot more sense to include those rules, but send them to LOG first and then to DROP.

I guess one thing I still do not understand however is the ordering of the rules. Is it possible to ACCEPT a packet, then check it against more rules, and (if it fails those checks) then send it to DROP. I.E. Is the following code going to do what I just said?

Code:
# Create a new table for filtering SSH
iptables -N ssh_conns

# Accept new ssh connections
iptables -A INPUT -p TCP --dport 22 -m state --state NEW -j ACCEPT

# Deny connections from some blacklisted host
iptables -t ssh_conns -A -s 123.456.789.000 -j DROP
 
Old 09-03-2007, 01:21 PM   #4
win32sux
LQ Guru
 
Registered: Jul 2003
Location: Los Angeles
Distribution: Ubuntu
Posts: 9,870

Rep: Reputation: 380Reputation: 380Reputation: 380Reputation: 380
No, once a packet gets sent to ACCEPT, that's the end of the line for it (pun intended). Same goes for DROP and REJECT. If the purpose of this example is to allow any IP except 123.456.789.000 to connect to port 22, you could do it like:
Code:
iptables -A INPUT -p TCP --dport 22 -s 123.456.789.000 -j DROP
iptables -A INPUT -p TCP --dport 22 -m state --state NEW -j ACCEPT
Packets traverse chains from top to bottom, so the order is important. Notice how, since we specificed TCP port 22 in both rules, a person using IP 123.456.789.000 won't be able to connect to TCP port 22, but will be able to connect to any other port (including UDP port 22). To *completely* filter packets from that IP, regardless of the port (or protocol), we'd need to make the rule more general:
Code:
iptables -A INPUT -s 123.456.789.000 -j DROP
iptables -A INPUT -p TCP --dport 22 -m state --state NEW -j ACCEPT
Now we can say the IP has been completely blacklisted.

If you would like to have a chain specifically designed to make sure no blacklisted IPs connect to our box it's sort of the same as with a bad packet chain. For example, let's say we have a box with HTTP (TCP port 80), HTTPS (TCP port 443), SSH (TCP port 22), and BitTorrent (TCP ports 6881-6999) services:

Code:
iptables -P INPUT DROP

iptables -N CHECKLIST
iptables -A CHECKLIST -s 123.123.123.123 -j DROP
iptables -A CHECKLIST -s 456.456.456.456 -j DROP
iptables -A CHECKLIST -s 789.789.789.789 -j DROP
iptables -A CHECKLIST -j RETURN

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state NEW -j CHECKLIST
iptables -A INPUT -p TCP -m multiport --dports 80,443,22,6881:6999 \
-m state --state NEW -j ACCEPT
iptables -A INPUT -j LOG --log-prefix "INPUT DROP: "
A couple things to point-out here. Notice how I've placed the "-j CHECKLIST" rule _below_ the RELATED,ESTABLISHED rule. This is so that packets which are already part of RELATED or ESTABLISHED connections don't have to each get checked. On systems with a crapload of blacklisted IPs and a crapload of connections this *could* be a performance saver. Only attempts to start new connections get checked to see if the connection is trying to be started by a bad IP.

The second thing I'd like to point-out is that we are only sending to CHECKLIST packets of state NEW, so if, for example, one of the bad IPs would send us packets in state INVALID, they wouldn't get sent to CHECKLIST, but would run into the chain's policy of DROP right after they got sent to LOG. This could be useful if we wanted to know about INVALID packets even if they came from a bad IP. If we didn't really care about anything from a bad IP then removing the NEW state match from the rule would suffice to send anything from a bad IP to DROP silently:
Code:
iptables -P INPUT DROP

iptables -N CHECKLIST
iptables -A CHECKLIST -s 123.123.123.123 -j DROP
iptables -A CHECKLIST -s 456.456.456.456 -j DROP
iptables -A CHECKLIST -s 789.789.789.789 -j DROP
iptables -A CHECKLIST -j RETURN

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -j CHECKLIST
iptables -A INPUT -p TCP -m multiport --dports 80,443,22,6881:6999 \
-m state --state NEW -j ACCEPT
iptables -A INPUT -j LOG --log-prefix "INPUT DROP: "
Also, if we wanted to have a log of all packets from blacklisted IPs wihtout having to make a LOG rule for each IP we could do it by creating a chain specially for blacklisting IPs:
Code:
iptables -P INPUT DROP

iptables -N CHECKLIST
iptables -N BLACKLIST

iptables -A CHECKLIST -s 123.123.123.123 -j BLACKLIST
iptables -A CHECKLIST -s 456.456.456.456 -j BLACKLIST
iptables -A CHECKLIST -s 789.789.789.789 -j BLACKLIST
iptables -A CHECKLIST -j RETURN

iptables -A BLACKLIST -j LOG --log-prefix "BLACKLISTED PACKET: "
iptables -A BLACKLIST -j DROP

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -j CHECKLIST
iptables -A INPUT -p TCP -m multiport --dports 80,443,22,6881:6999 \
-m state --state NEW -j ACCEPT
iptables -A INPUT -j LOG --log-prefix "INPUT DROP: "
Of course, bad packet chains would be applied to *all* packets, so you'd usually see the bad packet rule appear even before the RELATED,ESTABLISHED one, like:
Code:
iptables -P INPUT DROP

iptables -N CHECKLIST
iptables -N BLACKLIST
iptables -N BADPACKETS

iptables -A CHECKLIST -s 123.123.123.123 -j BLACKLIST
iptables -A CHECKLIST -s 456.456.456.456 -j BLACKLIST
iptables -A CHECKLIST -s 789.789.789.789 -j BLACKLIST
iptables -A CHECKLIST -j RETURN

iptables -A BLACKLIST -j LOG --log-prefix "BLACKLISTED PACKET: "
iptables -A BLACKLIST -j DROP

iptables -A BADPACKETS -p TCP ! --syn -m state --state NEW -j LOG \
--log-prefix "BAD PACKET NEW NOT SYN: "
iptables -A BADPACKETS -p TCP ! --syn -m state --state NEW -j DROP

iptables -A BADPACKETS -p TCP --tcp-flags ALL NONE -j LOG \
--log-prefix "BAD PACKET NO FLAGS: "
iptables -A BADPACKETS -p TCP --tcp-flags ALL NONE -j DROP

iptables -A INPUT -j BADPACKETS
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -j CHECKLIST
iptables -A INPUT -p TCP -m multiport --dports 80,443,22,6881:6999 \
-m state --state NEW -j ACCEPT
iptables -A INPUT -j LOG --log-prefix "INPUT DROP: "
Remember that packets will only traverse user-created chains when they are sent there from a built-in chain. This is why we can have our user-created chains at the top of the script without any problems, since the packet will hit the INPUT chain first (in these examples). But note that if you execute an INPUT rule (or any other rule in a built-in chain) where you send the packet to a user-created chain, that user-created chain must have already been created when the command is executed, otherwise an error will occur.

That is why we can do a:
Code:
iptables -N CHECKLIST
iptables -N BLACKLIST

iptables -A CHECKLIST -s 123.123.123.123 -j BLACKLIST
iptables -A CHECKLIST -s 456.456.456.456 -j BLACKLIST
iptables -A CHECKLIST -s 789.789.789.789 -j BLACKLIST
iptables -A CHECKLIST -j RETURN

iptables -A BLACKLIST -j LOG --log-prefix "BLACKLISTED PACKET: "
iptables -A BLACKLIST -j DROP
But we can NOT do a:
Code:
iptables -N CHECKLIST
iptables -A CHECKLIST -s 123.123.123.123 -j BLACKLIST
iptables -A CHECKLIST -s 456.456.456.456 -j BLACKLIST
iptables -A CHECKLIST -s 789.789.789.789 -j BLACKLIST
iptables -A CHECKLIST -j RETURN

iptables -N BLACKLIST
iptables -A BLACKLIST -j LOG --log-prefix "BLACKLISTED PACKET: "
iptables -A BLACKLIST -j DROP

Last edited by win32sux; 09-03-2007 at 04:18 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
iptables DEFAULT POLICY lappen Linux - Newbie 8 02-23-2011 03:55 AM
Samba System Policy, Default User Policy scooter549 Linux - General 2 02-24-2009 02:23 AM
iptables says 'bad policy name' Tom Douglas Linux - Kernel 2 07-22-2007 03:42 PM
iptables - default output policy ridertech Linux - Networking 1 05-08-2004 06:37 PM
iptables: Bad policy name rioguia Linux - Security 10 01-09-2003 11:21 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Security

All times are GMT -5. The time now is 03:15 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration