Tips for a secure iptables config to defend from attacks. (client side!)
I realize there are different opinions, but one major attitude of people who really know about networking and security is that most of these iptables/sysctl rules are redundant, if not damaging to you and the network. Some will aggressively criticize you for breaking with standard behavior without reason. Some examples:
The standard TCP/IP behavior is to REJECT so that the peer gets some hint on what is going on. Maybe someone just typed a URL wrong or your admin is counting the hosts or somebody wants to connect to your gaming server but typed the wrong port. With DROP they only get obscure and annoying timeouts.
There is no need to drop invalid or malformed packets, all of these attacks are a decade old. The Linux kernel devs are much more up to date than you concerning which kind of packets are valid and which not. "What about future flaws", some might argue. Well, how do you know the future flaw will be in the TCP handler and not in the iptables TCP parser?
Most of the sysctl settings are default. If they are not, there is usually a reason. Eg, why disable sending redirects? I find it very useful to be informed by a peer that my routing is bad, even if I would never react("accept_redirects", default=0) automatically.
With your log_martians and other logging rules I hope you also have a quota on /var/log, or it will be big fun to remotely fill your disk, usually killing your services/apps. In addition, you should use a rate limit for the logging or someone might fill the quota to prevent you from seeing the SSH password bruteforce attempts in auth.log, or other stuff. Are you actually reading those logs on a desktop? I recommend logcheck.
You appear to block ICMP. Apart from the mentioned DHCP issue, this also prevents PMTU discovery. Without PMTUD, you will get strange behavior when you use the system in places with DSL connection or other network settings. Some packets will just be dropped and nobody tells you why.
Filtering outbound packets is kind of obscure. Do you not trust yourself? You should generally not run any programs you cannot trust. Commodity operating systems are mostly incapable of isolating these programs from eavesdropping or even manipulating other program's data (e.g., cache timing attacks)
You require NEW packets to have SYN. This will break if a TCP connection is continued after the respective state in iptables already timed out. Not sure what the default timeouts are, but some netfilter guy warned about it.
So, when should a desktop have a firewall?
If there is a specific attack in the news that your current OS or servers are vulnerable to, and one of the recommended quick fixes is a firewall rule.
You have to run certain services that do not allow secure configuration. Most do, and the rest is best replaced by secure alternatives.
You have more complex networks with several VMs and/or interfaces on your desktop.
The first and foremost tool for your network security is the system update. Secondly, there is netstat and nmap, which you should use to find and confirm what services you are running. Then just disable those you don't need or confine them to 127.0.0.1.
Bonus if you read this far: Packets are either ESTABLISHED,RELATED or NEW, everything else you drop. You also drop NEW unless only SYN is set. Since ESTABLISHED,RELATED seems to check flags, this makes all of the --tcp-flags rules and also the -f rule redundant. Same for OUTPUT, but since no packets are ACCEPTed for OUTPUT anyhow, that probably doesn't matter.
I would be careful in making these part of the same ruleset for devices inside a trusted network and those in a DMZ. By using the rules you've got defined there, you're not going to respond to a DHCP server asking (ICMP echo) if your IP is in use. This could lead to a duplicate address situation.
I would create two different sets of rules to apply to each scenario, something like what's listed above is a good baseline for a DMZ machine, but creates some challenges on a typical LAN.
Also I would definitely recommend adding logging to martians, outbound drops, inbound dropped connections etc. This can be crucial for troubleshooting and can be more useful data for your SIEM to eat.
For a client PC, connected directly to the internet via ppp, the following ruleset is a good start:
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
iptables -A INPUT -p udp -j REJECT
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
ip6tables -A INPUT -j REJECT
- It allows everything on the internal local interface.
- It allows any packet that is an answer for a packet you send out. This includes packets within an TCP connection, answers to UDP packets such as small DNS queries. For the old style unencrypted FTP protocol, this includes the data connection, assuming the ip_conntrack_ftp is loaded
- Reject all tries to open a tcp connection from the outside
- Reject all initial (non answer) udp packets.
Alternatively you can use -j DROP in the last two rules. For a discussion on this topic see Reject IP packets with an ICMP error, or just drop them?