Difference between revisions of "Iptables (1.4)"

From Hexwiki
Jump to navigation Jump to search
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
I use shell scripts to load my firewall, your mileage may vary on specifics.
+
__TOC__
 +
This IPTables script is written from the perspective of someone who manages a pair of massive web forums and a dozen smaller ones, with highly committed users. If something goes wrong, I find out about it relatively soon - either directly or from the user's friends. Alternately, if I see something is going wrong - something that appears to be abusive - I can go over the problem with the member in question.
  
I see a lot of people making 'strict' firewalls. Running two major forums with extremely committed userbases (i.e. people who let me know if things go wrong for themselves or their friends), I know for a fact that if your firewall is draconian, you will be blocking valid, perfectly harmless traffic from legitimate visitors to your website. This configuration still occasionally trips on valid users, but it is rare, they are still able to use the site, and the situation it prevents (opening a crazy number of connections) is a genuine problem that is worth addressing.
+
Obviously, if you are not running a website or similar Internet service, this will be of limited use for you. There is probably still some information you can take from this, however.
 +
 
 +
I see a lot of people making 'strict' firewalls. I know for a fact that if your firewall is draconian, you will be blocking valid, perfectly harmless traffic from legitimate visitors to your website, possibly frustrating them and turning away genuine human beings. This configuration still occasionally trips on valid users, but it is rare, they are still able to use my sites, and the situation it prevents (opening a crazy number of connections) is a genuine problem that is worth addressing.
  
 
== Important Notes ==
 
== Important Notes ==
  
 
I explain some of these issues in the scripts proper, but I think they deserve more attention.
 
I explain some of these issues in the scripts proper, but I think they deserve more attention.
 +
 +
=== VPS and Control Panel Users ===
 +
 +
Proceed with a bit of caution. This is still a useful script, but back when I was still using cPanel and VPSes - not always at the same time - I had to make additional modifications for each. I do not know what has changed in the intervening years, so I cannot make good recommendations about what needs gutting. For certain, cPanel does not like it when you gut their license verification.
  
 
=== limit vs. hashlimit vs. connlimit ===
 
=== limit vs. hashlimit vs. connlimit ===
  
The short of it is, if you are using ''limit'' in your IPTables ruleset, you are probably doing it wrong, and it is not doing what you think it is doing. I have seen some people bragging about their rules, and limiting SYN packets to 20 per second - or less.
+
The short of it is, if you are using ''limit'' in your IPTables ruleset, you are probably doing it wrong. I have seen some people bragging about their rules, and doing things like limiting SYN packets to 20 per second - or less - using limit.
  
This means that, if any combination of hosts, anywhere on the Internet, sends the victim 20 SYN packets per second, no one else can open a TCP connection until the table holding that rule gets cleared. Limit is just that, a limit in total across the entirety of the system.
+
This means that, if any combination of hosts, anywhere on the Internet, sends the victim 20 SYN packets per second, no one else can open a TCP connection until the table holding that rule gets cleared. Limit is just that, a limit in total across the entirety of your system.
  
What most people think limit works like is a proper hashlimit declaration. I go into more detail in the script itself, but if you are only skimming to see what to grab for your own firewall rules, do not skip the hashlimit section. It will do you good.
+
What most people think limit works like is a proper hashlimit declaration. I go into more detail in the script itself, but if you are only skimming to see what to grab for your own firewall rules, do not skip the hashlimit section.
  
For connlimit, while the documentation states that it is 'parallel connections', I have a suspicion that when IPTables breaks, what it considers to be a connection is not necessarily what the other side thinks is a connection. Be careful about setting it too low, even for a small site. The 256 to report/512 to block is based on what my members have managed to generate individually, and it was nothing special with how much they actually used my site, nor was it a lot of people behind a NAT or even one person using multiple browsers. One person, one browser, 300 conntrack entries. For awhile, AoL proxies were a problem, though this has not been an issue in years.
+
For connlimit, while the documentation states that it is 'parallel connections', I have a suspicion that when IPTables breaks, what it considers to be a connection is not necessarily what the other side thinks is a connection. Be careful about setting it too low, even for a small site. The 256 to report/512 to block is based on what my members have managed to generate individually, and it was nothing special with how much they actually used my site, nor was it a lot of people behind a NAT or even one person using multiple browsers. One person, one browser, 300 conntrack entries. For awhile, AoL proxies were also a problem, though this has not been an issue in years.  
  
I tend to think of connlimit as a means to mitigate a single-user DOS. Better than nothing.
+
I tend to think of connlimit as a means to mitigate a single-user DOS. Better than nothing. In any case, stuff like SYN floods are best handled via your sysctl.conf settings, and many of the defaults work okay there.
  
 
=== INVALID ===
 
=== INVALID ===
  
Dropping all INVALID packets also drops a lot of packets from valid users of your services, and if someone has a poor connection to your website, this will make that problem even worse. The rules I've set cover the overwhelming majority of legitimate goofs that may crop up - please consider accepting these special NEW cases rather than dropping INVALID cases.
+
Dropping all INVALID packets also drops a lot of packets from valid users of your services, and if someone has a poor connection to your website, this may make that problem even worse. Just because IPTables is confused - something that happens often - does not mean that the traffic is actually bad. The rules I have set cover the overwhelming majority of legitimate goofs that may crop up.
 +
 
 +
To be fair, surveying user experience in this regard is difficult. "Do things seem to be working smoother now?" "Yes, I think so..."
 +
 
 +
Regardless, I have had no negative result from accepting INVALID packets, at least in limited quantities. The script does start preferentially dropping invalid traffic once it gets to a lot of connections.
  
 
=== ICMP ===
 
=== ICMP ===
  
For some reason, pings now have an established connection. I've accounted for this below, but outright accept RELATED ICMP incoming requests, which covers every non-ping ICMP request that you will see incoming.
+
For some reason, pings now have an established connection. I have accounted for this below, but outright accept RELATED ICMP incoming requests, which covers every non-ping ICMP request that you should see incoming.
  
 
=== UDP ===
 
=== UDP ===
Line 33: Line 44:
 
== Preparation ==
 
== Preparation ==
  
The first thing you should do, is make a reset script that runs at a regular interval through cron or somesuch. This way, if (or rather when), you make a mistake, you only have to wait a short while rather than digging out KVM details. Or worse, paying your host for it if you do not have a virtual solution.
+
The first thing you should do, is make a reset script that runs at a regular interval through cron or somesuch. This way, if (or rather when), you make a mistake, you only have to wait a short while rather than digging out KVM details. Or worse, paying your host for it if you do not have a virtual solution. Adjust the path as needed, of course.
  
Adjust the path as needed, of course.
+
Additionally, some IPTables settings can only be configured through modprobe - may as well set them now.
  
 
=== iptreset.sh ===
 
=== iptreset.sh ===
Line 54: Line 65:
 
  /sbin/ip6tables -P FORWARD ACCEPT
 
  /sbin/ip6tables -P FORWARD ACCEPT
 
  /sbin/ip6tables -P OUTPUT ACCEPT
 
  /sbin/ip6tables -P OUTPUT ACCEPT
 +
 +
=== /etc/modprobe.d/iptables.conf ===
 +
 +
# General modprobe config items for iptables.
 +
# The default is to only store 100 entries per recent table in /proc/net/ipt_recent/
 +
# Since we expect to be able to handle a larger DDOS than that, let's up it.
 +
options xt_recent ip_list_tot=4095
 +
# This should be tuned up or down based on the number of recent matches needed.
 +
# Default is 20
 +
options xt_recent ip_pkt_list_tot=64
 +
# Can't set the bucket size/max in sysctl.conf, has to be done here.
 +
options nf_conntrack hashsize=65536
  
 
== Using these scripts ==
 
== Using these scripts ==
 +
 +
The scripts can be found at Github: https://github.com/Vekseid/Tablewall
  
 
If you're not using the tools in e.g. CentOS to save/restore rules and the associated tracking entries, you will probably want to load them at bootup. Add
 
If you're not using the tools in e.g. CentOS to save/restore rules and the associated tracking entries, you will probably want to load them at bootup. Add
Line 66: Line 91:
  
 
to your main ipv6 interface declaration, likewise.
 
to your main ipv6 interface declaration, likewise.
 +
 +
{{Bottom Wheezy}}

Latest revision as of 23:36, 25 June 2020

This IPTables script is written from the perspective of someone who manages a pair of massive web forums and a dozen smaller ones, with highly committed users. If something goes wrong, I find out about it relatively soon - either directly or from the user's friends. Alternately, if I see something is going wrong - something that appears to be abusive - I can go over the problem with the member in question.

Obviously, if you are not running a website or similar Internet service, this will be of limited use for you. There is probably still some information you can take from this, however.

I see a lot of people making 'strict' firewalls. I know for a fact that if your firewall is draconian, you will be blocking valid, perfectly harmless traffic from legitimate visitors to your website, possibly frustrating them and turning away genuine human beings. This configuration still occasionally trips on valid users, but it is rare, they are still able to use my sites, and the situation it prevents (opening a crazy number of connections) is a genuine problem that is worth addressing.

Important Notes

I explain some of these issues in the scripts proper, but I think they deserve more attention.

VPS and Control Panel Users

Proceed with a bit of caution. This is still a useful script, but back when I was still using cPanel and VPSes - not always at the same time - I had to make additional modifications for each. I do not know what has changed in the intervening years, so I cannot make good recommendations about what needs gutting. For certain, cPanel does not like it when you gut their license verification.

limit vs. hashlimit vs. connlimit

The short of it is, if you are using limit in your IPTables ruleset, you are probably doing it wrong. I have seen some people bragging about their rules, and doing things like limiting SYN packets to 20 per second - or less - using limit.

This means that, if any combination of hosts, anywhere on the Internet, sends the victim 20 SYN packets per second, no one else can open a TCP connection until the table holding that rule gets cleared. Limit is just that, a limit in total across the entirety of your system.

What most people think limit works like is a proper hashlimit declaration. I go into more detail in the script itself, but if you are only skimming to see what to grab for your own firewall rules, do not skip the hashlimit section.

For connlimit, while the documentation states that it is 'parallel connections', I have a suspicion that when IPTables breaks, what it considers to be a connection is not necessarily what the other side thinks is a connection. Be careful about setting it too low, even for a small site. The 256 to report/512 to block is based on what my members have managed to generate individually, and it was nothing special with how much they actually used my site, nor was it a lot of people behind a NAT or even one person using multiple browsers. One person, one browser, 300 conntrack entries. For awhile, AoL proxies were also a problem, though this has not been an issue in years.

I tend to think of connlimit as a means to mitigate a single-user DOS. Better than nothing. In any case, stuff like SYN floods are best handled via your sysctl.conf settings, and many of the defaults work okay there.

INVALID

Dropping all INVALID packets also drops a lot of packets from valid users of your services, and if someone has a poor connection to your website, this may make that problem even worse. Just because IPTables is confused - something that happens often - does not mean that the traffic is actually bad. The rules I have set cover the overwhelming majority of legitimate goofs that may crop up.

To be fair, surveying user experience in this regard is difficult. "Do things seem to be working smoother now?" "Yes, I think so..."

Regardless, I have had no negative result from accepting INVALID packets, at least in limited quantities. The script does start preferentially dropping invalid traffic once it gets to a lot of connections.

ICMP

For some reason, pings now have an established connection. I have accounted for this below, but outright accept RELATED ICMP incoming requests, which covers every non-ping ICMP request that you should see incoming.

UDP

Most UDP traffic gets dropped by default here. This includes traceroutes. Windows will fall back to ICMP, but you may need to let *nix users know they should use the -I switch. The ICMP rules have been loosened to make this go smoothly.

Preparation

The first thing you should do, is make a reset script that runs at a regular interval through cron or somesuch. This way, if (or rather when), you make a mistake, you only have to wait a short while rather than digging out KVM details. Or worse, paying your host for it if you do not have a virtual solution. Adjust the path as needed, of course.

Additionally, some IPTables settings can only be configured through modprobe - may as well set them now.

iptreset.sh

#!/bin/sh
/sbin/iptables -F
/sbin/iptables -X
/sbin/iptables -t raw -F
/sbin/iptables -t raw -X
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -P OUTPUT ACCEPT
/sbin/ip6tables -F
/sbin/ip6tables -X
/sbin/ip6tables -t raw -F
/sbin/ip6tables -t raw -X
/sbin/ip6tables -P INPUT ACCEPT
/sbin/ip6tables -P FORWARD ACCEPT
/sbin/ip6tables -P OUTPUT ACCEPT

/etc/modprobe.d/iptables.conf

# General modprobe config items for iptables.
# The default is to only store 100 entries per recent table in /proc/net/ipt_recent/
# Since we expect to be able to handle a larger DDOS than that, let's up it.
options xt_recent ip_list_tot=4095
# This should be tuned up or down based on the number of recent matches needed.
# Default is 20
options xt_recent ip_pkt_list_tot=64
# Can't set the bucket size/max in sysctl.conf, has to be done here.
options nf_conntrack hashsize=65536

Using these scripts

The scripts can be found at Github: https://github.com/Vekseid/Tablewall

If you're not using the tools in e.g. CentOS to save/restore rules and the associated tracking entries, you will probably want to load them at bootup. Add

pre-up /root/firewall.sh

(or whatever you named/placed it) to your main ipv4 interface declaration in /etc/network/interfaces, and

pre-up /root/firewall6.sh

to your main ipv6 interface declaration, likewise.