正确限制IP连接

我问了很多关于同一主题的问题,例如: 这里和这里。

答案说我应该像这样建立规则:

iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT 

然后开始添加其余内容,如下所示:

 # Dynamic Badguy List. Detect and DROP Bad IPs that try to access port 20000. # Once they are on the BADGUY list then DROP all packets from them. iptables -A INPUT -i eth0 -m recent --update --hitcount 5 --seconds 90000 --name BADGUY -j LOG --log-prefix "Port 20000 BAD:" --log-level info iptables -A INPUT -i eth0 -m recent --update --hitcount 5 --seconds 90000 --name BADGUY -j DROP iptables -A INPUT -i eth0 -p tcp -m tcp --dport 20000 -m recent --set --name BADGUY -j ACCEPT 

我确切地这样做了,但是一些IP仍然可以为每个IP打开100多个连接,那么限制IP连接的正确方法是什么?

我们对此特别感兴趣:

 tcp 0 75981 45.233.22.66:22 77.101.61.108:49746 ESTABLISHED tcp 0 77442 45.233.22.66:22 77.101.61.108:49866 ESTABLISHED tcp 0 106643 45.233.22.66:22 77.101.61.108:49662 ESTABLISHED tcp 0 75826 45.233.22.66:22 77.101.61.108:49727 ESTABLISHED tcp 97 0 45.233.22.66:22 77.101.61.108:50448 CLOSE_WAIT tcp 0 105924 45.233.22.66:22 77.101.61.108:49798 ESTABLISHED tcp 0 77441 45.233.22.66:22 77.101.61.108:49852 ESTABLISHED tcp 0 77442 45.233.22.66:22 77.101.61.108:49813 ESTABLISHED tcp 0 75223 45.233.22.66:22 77.101.61.108:49655 ESTABLISHED 

 tcp 0 73838 45.233.22.66:22 212.252.97.90:24457 ESTABLISHED tcp 0 73502 45.233.22.66:22 212.252.97.90:24101 ESTABLISHED tcp 0 74848 45.233.22.66:22 212.252.97.90:24397 ESTABLISHED tcp 0 70703 45.233.22.66:22 212.252.97.90:24315 ESTABLISHED tcp 0 70620 45.233.22.66:22 212.252.97.90:24292 ESTABLISHED tcp 0 73501 45.233.22.66:22 212.252.97.90:24362 ESTABLISHED tcp 0 73500 45.233.22.66:22 212.252.97.90:24122 ESTABLISHED 

这似乎是比命中计数规则允许的更多连接。

这是iptable vxnl

 Chain INPUT (policy ACCEPT 35537 packets, 4077701 bytes) pkts bytes target prot opt in out source destination 1939108 97521172 REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 flags:0x17/0x02 #conn src/32 > 2 reject-with tcp-reset 1112785 217196313 ACCEPT all -- eth0 * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 69985 3510824 LOG all -- eth0 * 0.0.0.0/0 0.0.0.0/0 recent: UPDATE seconds: 90000 hit_count: 5 name: BADGUY side: source mask: 255.255.255.255 LOG flags 0 level 6 prefix "Port 22 BAD:" 69985 3510824 DROP all -- eth0 * 0.0.0.0/0 0.0.0.0/0 recent: UPDATE seconds: 90000 hit_count: 5 name: BADGUY side: source mask: 255.255.255.255 217171 11052690 ACCEPT tcp -- eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 recent: SET name: BADGUY side: source mask: 255.255.255.255 Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 3258297 packets, 496362303 bytes) pkts bytes target prot opt in out source destination 

针对您的粘性DDOS攻击提出的iptables规则集解决方案是以下脚本:

 #!/bin/sh FWVER=0.01 # # Vlark.Lopin rule set. Smythies 2016.09.18 Ver:0.01 # Attempt to manage severe DDOS attack. # Port 20000 should only ever have 2 open # connections at a time. If more, ban them. # # If too many SSH attempts, ban them. # DROP all other unsolicited input. # If ssh port has been moved, adjust rules # accordingly. # # Requires a larger (1000) than default (100) # xt_recent table size. # # See also: # http://askubuntu.com/questions/818524/correctly-limit-ip-connections # http://askubuntu.com/questions/808297/i-have-massive-attack-on-port-in-my-server # http://askubuntu.com/questions/817478/ip-tables-limit-connetion-per-ip-address-can-be-bypassed # # run as sudo # echo "Loading Vlark.Lopin rule set version $FWVER..\n" # The location of the iptables program # IPTABLES=/sbin/iptables #Setting the EXTERNAL and INTERNAL interfaces and addresses for the network # # Vlark.Lopin EXTIF="eth0" # Doug #EXTIF="enp9s0" UNIVERSE="0.0.0.0/0" #Clearing any previous configuration # echo " Clearing any existing rules and setting default policies.." $IPTABLES -P INPUT DROP $IPTABLES -F INPUT $IPTABLES -P OUTPUT ACCEPT $IPTABLES -F OUTPUT $IPTABLES -P FORWARD ACCEPT $IPTABLES -F FORWARD # Otherwise, I can not seem to delete it later on $IPTABLES -F add-to-connlimit-list # Delete user defined chains $IPTABLES -X # Reset all IPTABLES counters $IPTABLES -Z # We want to force load the xt_recent module, so that we override the # default maximum table size. We want 1000 whereas the default is 100. # Note: It is unlikely that is needs to be 1000 forever. Once the # bad guys give up, the attempts will become much less frequent, and # the table size can probably be reduced to default. # ie this force load segment can be commented out, and then it will # autoload as required. # modprobe xt_recent ip_list_tot=1000 ####################################################################### # USER DEFINED CHAIN SUBROUTINES: # # add-to-connlimit-list # To many connections from an IP address has been detected. # Add the IP address to the bad guy list, and DROP the packet. # If desired, comment out the log rule. $IPTABLES -N add-to-connlimit-list #$IPTABLES -A add-to-connlimit-list -m recent --update --hitcount 1 --seconds 90000 --name BADGUY_CONN $IPTABLES -A add-to-connlimit-list -m recent --set --name BADGUY_CONN $IPTABLES -A add-to-connlimit-list -j LOG --log-prefix "CONNLIMIT_ADD:" --log-level info $IPTABLES -A add-to-connlimit-list -j DROP ####################################################################### # INPUT: Incoming traffic from various interfaces. All rulesets are # already flushed and set to a default policy of DROP. # # loopback interfaces are valid. # $IPTABLES -A INPUT -i lo -s $UNIVERSE -d $UNIVERSE -j ACCEPT # A NEW TCP connection requires SYN bit set and FIN,RST,ACK reset. # More importantly, this check might prevent lingering packets from # a forgotten legitimite connection from getting a valid user on the # bad guy list # $IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "NEW TCP no SYN:" --log-level info $IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j REJECT # Not sure if this one is needed or not # $IPTABLES -A INPUT -i $EXTIF -p tcp -m state --state INVALID -j LOG --log-prefix "IINVALID:" --log-level info $IPTABLES -A INPUT -i $EXTIF -p tcp -m state --state INVALID -j DROP # Allow any related traffic coming back to the server in. # $IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -m state --state ESTABLISHED,RELATED -j ACCEPT # external interface, from any source, for any remaining ICMP traffic is valid # Note: consider to not allow, as this is often how bad guys find you # $IPTABLES -A INPUT -i $EXTIF -p ICMP -s $UNIVERSE -j ACCEPT # Secure Shell on port 22 (Change to whatever port you moved SSH to). # # Sometimes I uncomment the next line to simply disable external SSH access. # Particulalry useful when I am rebooting often, thereby losing my current BADGUY table. #$IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE --dport 22 -j DROP # Dynamic Badguy List. Detect and DROP Bad IPs that do password attacks on SSH. # Once they are on the BADGUY list then DROP all packets from them. # Sometimes make the lock time very long. Typically to try to get rid of coordinated attacks from China. $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 5 --seconds 90000 --name BADGUY_SSH -j LOG --log-prefix "SSH BAD:" --log-level info $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 5 --seconds 90000 --name BADGUY_SSH -j DROP $IPTABLES -A INPUT -i $EXTIF -p tcp -m tcp --dport 22 -m recent --set --name BADGUY_SSH -j ACCEPT # Port 20000. Limit to 2 connections per IP address. # Otherwise ban them. # Note: The logging is useful for debugging, but might overwhelm the log files. Comment out the logging rule as required. # $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 1 --seconds 90000 --name BADGUY_CONN -j LOG --log-prefix "CONNLIMIT:" --log-level info $IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 1 --seconds 90000 --name BADGUY_CONN -j DROP $IPTABLES -A INPUT -p tcp --dport 20000 -m connlimit --connlimit-above 2 -j add-to-connlimit-list $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 20000 -j ACCEPT # port 4 is needed. (Consider doing it the same as the SSH port). # If UDP is needed, then add it. # $IPTABLES -A INPUT -m state --state NEW -p tcp --dport 4 -j ACCEPT # OK at this point, we will DROP the packet, however some will be dropped without logging just to make the log file # less cluttered. # $IPTABLES -A INPUT -i $EXTIF -p udp --dport 33434 -j DROP $IPTABLES -A INPUT -i $EXTIF -p tcp --dport 23 -j DROP # If your log file is too cluttered, consdier to comment out this log rule. # It is useful for debugging, but might overwhlem your log files. # $IPTABLES -A INPUT -s $UNIVERSE -d $UNIVERSE -j LOG --log-prefix "ICATCH:" --log-level info # With a default policy of DROP, the following rule isn't actually neeeded. $IPTABLES -A INPUT -s $UNIVERSE -d $UNIVERSE -j DROP echo Vlark.Lopin rule set version $FWVER done. 

调试此脚本后,如果要在引导时自动加载它,请在/etc/network/intefaces文件中添加一个pre-up指令。 这是我的文件作为示例:

 # interfaces file for smythies.com 2016.01.30 # attempt to set local DNS herein, as the method # used with the old 12.04 server no longer works. # # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback pre-up /home/doug/init/doug_firewall dns-nameservers 127.0.0.1 # The primary interface (d-link PCI card) auto enp4s0 iface enp4s0 inet dhcp # Local network interface (uses built in ethernet port) auto enp2s0 iface enp2s0 inet static address 192.168.111.1 network 192.168.111.0 netmask 255.255.255.0 broadcast 192.168.111.255 

我的脚本文件的权限是:

 $ ls -l /home/doug/init/doug_firewall -rwxr-xr-x 1 doug doug 61703 Aug 27 15:55 /home/doug/init/doug_firewall 

或755。