LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (http://www.linuxquestions.org/questions/linux-security-4/)
-   -   TCP packet flags (SYN, FIN, ACK, etc) and firewall rules (http://www.linuxquestions.org/questions/linux-security-4/tcp-packet-flags-syn-fin-ack-etc-and-firewall-rules-317389/)

TheLinuxDuck 04-26-2005 02:53 PM

TCP packet flags (SYN, FIN, ACK, etc) and firewall rules
 
Ok, I'm trying to learn more about TCP packets and how to create a good solid firewall ruleset to prevent scans and illegal/invalid access. I want to make sure that I understand this stuff before I start plugging in rules into my firewall to block various packet sets and stuff.

Basically, if you have a good understanding of TCP packets, could you confirm for me which items are correct and which ones are wrong? I'd appreciate it!

Here are the truths as I understand them.

New connections:
Only SYN may exist in a new connection.
ACK,FIN,RST,URG,and PSH are not allowed.
(possibly URG/PSH but why? Especially since URG marks importance which shouldn't be known yet, and PSH tells the receiver to terminate buffering, which shouldn't occur for an intiation packet)

Existing/related connections:
ACK must exist in existing/related connections.
SYN may exist, but only with ACK; no other flag may be set.
(Here I apply the same logic as above, that SYN is used to establish a connection (in initial packet, and then the server response packet), not to perpetuate an existing connection that has already been acknowledged.)
FIN and RST may not exist in the same packet.
FIN and PSH may not exist in the same packet (not sure)
RST and PSH may not exist in the same packet (not sure)
(and what about URG? I think it's status is mostly irrelevant to a packet filter)

Other truths:
All flags cannot be set (SYN,ACK,FUN,RST,URG,PSH) at the same time.
At least one flag must be set (cannot have none set).
Invalid packets should be dropped.


Some confusion and/or questions I have:
Obviously, a new connection should have only the SYN flag. But, is the SYN/ACK response to this new connection also considered a new connection? Or is it considered RELATED? Or ESTABLISHED?

Additional questions not related to flags:
1) Is there any situation where a 1 NIC public server will send packets to itself?
2) For ports 1-1024, should a packet filter specifically allow traffic only to certain ports (as needed), and deny all others?
3) What about for ports above 1024? Isn't it bad to deny packets above 1024?
4) What are good rules-of-thumb to use when dealing with ports above 1024?

I'll stop here because I've already covered a boatload of ground with these questions, and I'd really like people to reply, instead of being overwhelmed by everything I'm asking.

So, if you know something about all of this, any of this, etc, please reply and offer suggestions for improvement, corrections to my misunderstanding, etc.

Thanks a bunch!!

demian 04-26-2005 07:30 PM

As for the flags you're right with everything you said. (To be honest I'm not sure about the URG flag either. I tend to ignore it in the context of packet filtering.)

If you want a stateful firewall the first rule in every chain should be
Code:

iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT
TCP flags can be used to log certain port scan attempts:
Code:

iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix "Port scan (xmas): "
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "Port scan (SYN/RST): "
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "Port scan (SYN/FIN): "
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "Port scan (NULL): "

(There's a variation of the xmas scan with all flags being set but the FIN,URG,PSH variant is much more common (it's what nmap uses))

New connections start with a syn. Everything else is stealth scan acitvity, broken clients or due to packet loss:
Code:

iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
Put the port scan logging rules before the last rule since otherwise the packets are dropped before being logged. Mind you that propper portscan protection can't be achived with a packet filter. Use snort or some other IDS to detect port scans and then have it autoadjust the firewall to flat out deny everything from the IP that port scanned you. (You will have to do some fine tuning to avoid false positives. But snort is really pretty good with this.)

As for "invalid packets should be dropped" that's mostly right. And it's something that's done even without a firewall. Say a server receives a packet with FIN,URG,PSH flags set on an open port. It will silently drop the packet. If the port is closed it will send a RST. (This is true for RFC-793 compliant TCP/IP stacks.) I have seen people deliberately send RST packets for open ports and drop the packets for closed ports or do something else that's unexpected. I'd call this security through obscurity since it does nothing more than confuse the script kiddies...

The SYN/ACK packet is the response the server sends to the client after the client's SYN request. Anyway, it's covered with the ESTABLSIHED rule. (Even though the connection isn't yet established since it's the second packet in the three way handshake.)

Your additional questions:

1) if it does it will send it through the loopback interface. A rule like
Code:

iptables -I INPUT 1 -i lo -j ACCEPT
iptables -I OUTPUT 1 -o lo -j ACCEPT

takes care of that.

2) by all means, YES!!

3,4) no, it's not bad to deny ports>1024. Not at all. Most connections to the high range ports are handled by the connection tracking with the ESTABLISHED,RELATED rules (think passive ftp transfers) just make sure your kernel supports the various protocols with conntrack modules (most vendor kernels do that out of the box).

Things you didn't ask for:
Set up some basic spoof protection. Check for private LAN ips (192.168.0.0/24, 10.0.0.0/8, 172.16.0.0/12) and loopback ips (127.0.0.0/8) entering from the outside interface. Or anything else that mustn't happen (like your internal IP being the source IP of a packet entering from the outside interface). A good place to do that is in PREROUTING so that the packets are dropped before they even hit the routing table.

The connection tracking code of netfilter is really quite intelligent. It even covers stateless (connectionless) protocols. So there's no need to explicitly allow echo reply packets (--imcp-type 0/0) or udp responses on port 53 (DNS) provided you have an ESTABLISHED,RELATED rule. So if you allow pings (--icmp-type 8/0) in the OUTPUT chain the echo reply will come trough. Same with dns or ntp queries. Just allow them to go out and connection tacking will handle the rest.

SciYro 04-27-2005 04:11 PM

i recommend limiting icmp packets, i usually block types 15-19 (i forget the numbers, but they are the types that request info that i feel is not needed), only also limit allowed types from NEW connections.

also, there is a firewall script (or of the sort) that sets up anti port scan rules based on snort rules (i think) that can be used as firewall rules ..... i forget its name tho, but i think it would be better for most people (as port scan rules are a pain to setup, there are so many)

also, its usually dangerous to block upper ports, as if you accidentally block a client port, your web browser might not work, usually a good stateful firewall with extra filters is good enough, and going thru all ports and allowing only certain ones is usually unnecessary (unless there is a running server on that port)

TheLinuxDuck 04-27-2005 06:07 PM

demian:

Thank you so much for the solid and informational response!
This was more than I was expecting! I've already implemented
some of the items I'd asked about, and have been keeping a
close eye on the log files to see what's being dropped and
from whom. So far, it's working well. Today, I've added in a
few additional rules to cover some of the port scans and such
that I didn't have before, and so far they're working well. Of
course, keeping a watchful eye on the logs will tell me how
things are going. (=

Anyway, I have a few questions and comments based on your
replies, if you have the time.

Quote:

Originally posted by demian
If you want a stateful firewall the first rule in every chain
should be

Code:

iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT

I feel hesitant to simply let any established/related packet in.
Maybe because I feel like this opens a door for overlapping
fragments to compromise the system. I feel it would be bad
to simply refuse fragmented packets (since legitimate packets
can come in fragmented), however I don't really have any ideas
how to better handle this.

My understanding is that packets that are not the first packet
should not contain another TCP header. I don't know if there
are instances where this is possible, or if the IP in IP/IPSEC/GRE
type use this as their means for packet handling, but I don't know
of any way to specify, with iptables, which packets should have
them or which ones should not. Do you know anything about this?

Anyway, for the "accept all est/rel packets", should that at least
take it to one further step, and check the flags of the packets
to make sure that:
1. If they contain SYN and ACK, they don't contain anything else
2. If they contain ACK and any other flag, they should not contain
SYN.
?

Quote:


TCP flags can be used to log certain port scan attempts:
... snip port scan rules ...

Shouldn't these only apply to NEW connections? Or am I missing
the point?

Quote:


Mind you that propper portscan protection can't be achieved with
a packet filter. Use snort or some other IDS to detect port scans
and then have it autoadjust the firewall to flat out deny
everything from the IP that port scanned you. (You will have to
do some fine tuning to avoid false positives. But snort is really
pretty good with this.)

But, this only applies to open ports. My understanding is that
you have to be running snort and snort only on that open port,
in order for it to work. Or does snort act sort of like a tcpwrapper
to pass the connection onto the daemon?

Quote:


The SYN/ACK packet is the response the server sends to the
client after the client's SYN request. Anyway, it's covered with
the ESTABLSIHED rule. (Even though the connection isn't yet
established since it's the second packet in the three way
handshake.)

Ok. I thought that was the case, but wanted to make sure.


Thanks again for the good info!!

johnnydangerous 04-28-2005 12:23 AM

I use kind of very big iptables for my home machine with just the necessary rules (~400 lines) + snort + portsentry + hostsentry + logsentry + tripwire + aide and maybe last two are not needed while having the other running but.... anyone to tell which is a more proper config?

johnnydangerous 04-28-2005 12:56 AM

why are u suspicious about enable related, established? btw is there a short description some one to give about differences between those two states?>

SciYro 04-28-2005 01:06 AM

ESTABLISHED are connections were you have sent and received at least 1 packet.

RELATED are packets sent as a result of connections.

related traffic includes icmp errors, as well as others.

i restrict the RELATED part, by allowing icmp in that state, and thats usually it.

its also a good idea to allow ESTABLISHED connections, as they are already set up, tho i us ally have checks to make sure its valid traffic still.

demian 04-28-2005 08:35 AM

Quote:

Originally posted by TheLinuxDuck
I feel hesitant to simply let any established/related packet in.
Wow. You are one paranoid person. And I mean that as a compliment. I guess it comes down to how much you trust Rusty Russell who wrote the bulk of the netfilter code in linux 2.6. I at one point in time decided to trust that he knows what he's doing and adopted the est/rel rule practice. I guess it depends on the network you are protecting. If it's an easily accounted for bunch of workstations and you know exactly what kind of applications are being used you can probably get away without any connection tracking or implement your own (because that's basically what you are doing when sorting out all the valid tcp flags).
I guess if you don't want est/rel for every packet you can construct some rules that drop certain packets based on their TCP flags and insert them before the est/rel rule. Then using the packet counter you quickly get a picture of whether these rules are actually needed.

Quote:

Maybe because I feel like this opens a door for overlapping
fragments to compromise the system. I feel it would be bad
to simply refuse fragmented packets (since legitimate packets
can come in fragmented), however I don't really have any ideas
how to better handle this.
Frankly, I don't know much about the issue of fragmentation. I hardly ever see fragmented packets on my LAN but I wouldn't feel comfortable to just flat out reject fragmented traffic. There are certain dos attacks that try to crash a packet filtering hosts by sending really small fragments hoping the reassembly will eat up all the resources. So I guess there's a lower limit to the packet size you can enforce.

Quote:

My understanding is that packets that are not the first packet
should not contain another TCP header.
No, every single packet contains a full tcp header. Otherwise there would be no way of sorting out what connection the packet belongs to.

Quote:

Anyway, for the "accept all est/rel packets", should that at least
take it to one further step, and check the flags of the packets
to make sure that:
1. If they contain SYN and ACK, they don't contain anything else
2. If they contain ACK and any other flag, they should not contain
SYN.
Yes, that sounds pretty good. I'm gonna try that myself.


Quote:

Shouldn't these only apply to NEW connections? Or am I missing
the point?
Hmm, now that I think about it the port scan rules should probably go before the est/rel rule since these combinations of flags are never ok: A NULL packet is something you should never see. Similarly SYN/FIN doesn't make sense (either you want to start a new connection with a SYN or want to end a connection (FIN, FIN/ACK or FIN/PSH/ACK)) same goes for SYN/RST and xmas. I'm gonna move these rules up and monitor the logs for a while. If this gives a problems I'll report back.

Quote:

But, this only applies to open ports. My understanding is that
you have to be running snort and snort only on that open port,
in order for it to work. Or does snort act sort of like a tcpwrapper
to pass the connection onto the daemon?
There's a lot of ground to cover when it comes to snort. Much more than can possibly fit in a single thread. Snort runs independedly of your firewall. It can be configured to grab any packet passing your NIC and analyse the packet _content_ (it also analyses the tcp, udp or whatever protocol header but that's something netfilter does already. So the header scan is just a backup.) Per se snort does nothing more than inform you of evil traffic entering you LAN. In most default configurations it will log the attack signature it detected and save a tcpdump of the traffic for you to review. It can be configured to act on certain attack patterns. For instance by sending a RST upon detection of a code red worm package. Also using snort inline you can do funky things like in situ virus scanning and whatnot provided you have the CPU power.

To readjust the firewall rules there are several plugins available. I use SnortSam for that. But only in the most extreme cases when I can be 100% sure that what snort recorded was indeed an attack carried out by a human being and not just some virus infected windows box trying to spread some sort of malware or access other infected machines through a backdoor. Mostly it's an informational system for me that I use to analyse what sort of threads are hot at the moment.
I've got a dedicated logging server that collects snort messeges from various snort enabled hosts and dumps them into a mysql database. (Along with normal system logs). A great tool for snort log analysis is ACID.

johnnydangerous 04-28-2005 10:58 AM

btw how to packet count?
especially to count your rules output?
and how can you send for example this or the snort output to mysql?

TheLinuxDuck 04-28-2005 05:54 PM

Quote:

by johnnydangerous
why are u suspicious about enable related, established?
I'm suspicious of everything. (= One thing I know for certain, is that
there is no such thing as an impenetrable system. I am by far not an
expert in systems cracking... I am always amazed to hear about how
a system was compromised, how they subverted the security. I am
willing to bet that there are ways to create new connections from a
compromised system, and once the connection is considered
"established/related", then modify packet content to somehow bypass
the security.

Knowing people, I know that people are creative and figure ways
around things.

Perhaps my concern is overkill, perhaps not. (= I'd rather be on the
safe side.

TheLinuxDuck 04-28-2005 06:06 PM

Quote:

Originally posted by demian
Wow. You are one paranoid person. And I mean that as a compliment.
(= When it comes to security, I don't live by 'innocent until proven guilty',
but the opposite. This would work better for me, in my favor, if I knew more
about security. (=

Quote:

No, every single packet contains a full tcp header. Otherwise there
would be no way of sorting out what connection the packet belongs to.

Not according to the book Building Internet Firewalls in chapter 4, in the 'IP Fragmentation Section':
Quote:

* ..snip .. An attacker can construct a packet with acceptable headers in the first
fragment but then overlap the next fragment so that it also has headers in it.
Since packet filters don't expect TCP headers in non-first fragments, they won't
filter on them, and the headers don't need to be acceptable.
Now, I'm basing my understanding solely and completely on this mention
in this book. Granted, this book was released in 2000...


Quote:


There's a lot of ground to cover when it comes to snort. ...snip... A great tool
for snort log analysis is ACID.

Thanks for the info on snort. While I will look into it, right now I have too many things
on my plate to add that. (=

SciYro 04-28-2005 06:18 PM

TheLinuxDuck: firewalls should just help keep things out, if you think your computer can get busted without one, then your computer has bad security from the start.

you really don't need to worry about the firewall all that much, if they can get past it, then they have only a few options: attack the service ruining on the port they got into, or attack the kernels network layer. The first would be easy to keep people from, run all program that are servers as non root, or limit there ability, and/or run them in a jail. You can use PAX to help make it difficult to use a buffer overflow to attack the server, and use it. The kernel problem is the bad one, all you can really do is keep your kernel patched.

firewalls just keep script kiddies out, so don't rely on them to hold off a attacker.

johnnydangerous 04-29-2005 12:30 AM

SciYro you are in the right direction but consider services vulnerabilities pop-up more then mushrooms do..., SELinux might be handy here... and what of the common sevies can run as non-root and how?

any references to good jail and/or pax pls?


All times are GMT -5. The time now is 05:52 AM.