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.
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)
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)
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!!
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
New connections start with a syn. Everything else is stealth scan acitvity, broken clients or due to packet loss:
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
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.
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)
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.
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
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?
Thanks again for the good info!!
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?
why are u suspicious about enable related, established? btw is there a short description some one to give about differences between those two states?>
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.
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.
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.
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?
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
Knowing people, I know that people are creative and figure ways
Perhaps my concern is overkill, perhaps not. (= I'd rather be on the
but the opposite. This would work better for me, in my favor, if I knew more
about security. (=
in this book. Granted, this book was released in 2000...
on my plate to add that. (=
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.
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 10:20 AM.|