I have did every thing to stop this kind of ddos.

I have set sysctl like following:

# IP Spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignore ICMP broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0 
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0

# Ignore send redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Block SYN attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5

# Log Martians
net.ipv4.conf.all.log_martians = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1

# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0 
net.ipv6.conf.default.accept_redirects = 0

but still my server got huge amount of syn requests and my server crashed

I checked my grep sync and its look like following

tcp        0      0 myserver     23.254.132.23:41094     SYN_RECV
tcp        0      0 myserver     219.94.128.69:41382     SYN_RECV
tcp        0      0 myserver     54.244.247.155:43522    SYN_RECV
tcp        0      0 myserver     82.77.0.73:48462        SYN_RECV
tcp        0      0 myserver    213.251.182.115:48376   SYN_RECV
tcp        0      0 myserver     77.93.211.208:34071     SYN_RECV
tcp        0      0 myserver     178.250.74.17:57235     SYN_RECV
tcp        0      0 myserver     5.153.9.51:58119        SYN_RECV
tcp        0      0 myserver     156.17.100.82:37296     SYN_RECV
tcp        0      0 myserver     91.109.17.102:50753     SYN_RECV
tcp        0      0 myserver     5.101.156.83:26098      SYN_RECV
tcp        0      0 myserver    77.120.80.6:18506       SYN_RECV

Server log

Jan  7 21:50:17 dede kernel: [ 2459.224731] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=89.143.11.210 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=45 ID=10938 DF PROTO=TCP SPT=49272 DPT=20000 WINDOW=5840 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.224747] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=217.170.198.12 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=45 ID=46501 DF PROTO=TCP SPT=39203 DPT=20000 WINDOW=29200 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.224762] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=63.143.35.163 DST=myserverip LEN=52 TOS=0x06 PREC=0x00 TTL=107 ID=12115 DF PROTO=TCP SPT=52420 DPT=20000 WINDOW=8192 RES=0x00 CWR ECE SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.225473] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=199.115.113.161 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=47 ID=24895 DF PROTO=TCP SPT=49528 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.226873] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=207.150.204.204 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=36 ID=32241 DF PROTO=TCP SPT=38958 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.227007] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=94.23.201.35 DST=myserverip LEN=60 TOS=0x00 PREC=0x00 TTL=57 ID=5044 DF PROTO=TCP SPT=57313 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.228844] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=89.143.11.210 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=45 ID=29438 DF PROTO=TCP SPT=49274 DPT=20000 WINDOW=5840 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.229255] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=89.143.11.210 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=45 ID=45902 DF PROTO=TCP SPT=49273 DPT=20000 WINDOW=5840 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.229443] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=219.94.232.125 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=43 ID=27172 DF PROTO=TCP SPT=58504 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.229546] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=178.162.214.68 DST=myserverip LEN=48 TOS=0x04 PREC=0x00 TTL=47 ID=3245 DF PROTO=TCP SPT=44514 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.229835] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=217.27.220.88 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=48 ID=1603 DF PROTO=TCP SPT=47383 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.229936] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=153.126.166.38 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=41 ID=11932 DF PROTO=TCP SPT=35208 DPT=20000 WINDOW=29200 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.230959] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=136.243.82.67 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=50 ID=62498 DF PROTO=TCP SPT=42850 DPT=20000 WINDOW=29200 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.231661] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=108.171.182.6 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=42 ID=46276 DF PROTO=TCP SPT=35885 DPT=20000 WINDOW=5840 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.231818] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=216.55.73.41 DST=myserverip LEN=48 TOS=0x04 PREC=0x00 TTL=104 ID=31292 DF PROTO=TCP SPT=63952 DPT=20000 WINDOW=64240 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.232131] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=91.121.171.14 DST=myserverip LEN=60 TOS=0x00 PREC=0x00 TTL=57 ID=40245 DF PROTO=TCP SPT=59286 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.233300] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=89.143.11.210 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=45 ID=5891 DF PROTO=TCP SPT=49275 DPT=20000 WINDOW=5840 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.233440] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=89.143.11.210 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=45 ID=62305 DF PROTO=TCP SPT=49276 DPT=20000 WINDOW=5840 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.234031] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=87.197.66.202 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=41 ID=842 DF PROTO=TCP SPT=35866 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.234051] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=95.110.226.239 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=45 ID=48043 DF PROTO=TCP SPT=57222 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.235446] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=199.115.113.161 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=47 ID=26056 DF PROTO=TCP SPT=49644 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 
Jan  7 21:50:17 dede kernel: [ 2459.236044] CONNLIMIT_ADD:IN=ens3 OUT= MAC=fa:16:3e:b4:79:c4:ae:8d:2b:51:5d:cc:08:00 SRC=188.213.163.181 DST=myserverip LEN=60 TOS=0x04 PREC=0x00 TTL=45 ID=30320 DF PROTO=TCP SPT=45924 DPT=20000 WINDOW=14600 RES=0x00 SYN URGP=0 

I really cannot navigate this problem is this a udp attack ? or tcp my server crash very hard

Result of

cat /var/log/kern.log.1 /var/log/kern.log | grep CONNLIMIT_ADD | sed 's/ /\n/g' | grep "SRC=" | sort | uniq -c | sort -g | tail -100




  1 SRC=117.20.96.13
  1 SRC=119.245.150.2
  1 SRC=1.202.251.178
  1 SRC=121.127.236.1
  1 SRC=122.117.47.65
  1 SRC=122.200.208.11
  1 SRC=12.250.148.174
  1 SRC=128.36.245.203
  1 SRC=133.242.128.218
  1 SRC=133.50.175.88
  1 SRC=134.119.247.84
  1 SRC=139.91.151.40
  1 SRC=140.177.205.35
  1 SRC=143.225.212.120
  1 SRC=14.63.166.224
  1 SRC=148.235.89.21
  1 SRC=150.101.205.223
  1 SRC=150.60.4.10
  1 SRC=151.80.185.237
  1 SRC=157.7.188.216
  1 SRC=158.102.4.50
  1 SRC=166.78.22.118
  1 SRC=167.205.25.194
  1 SRC=188.116.19.96
  1 SRC=192.254.215.51
  1 SRC=192.254.216.66
  1 SRC=194.28.87.58
  1 SRC=202.218.49.12
  1 SRC=205.186.141.197
  1 SRC=209.239.37.120
  1 SRC=209.68.59.213
  1 SRC=213.251.182.102
  1 SRC=213.251.182.110
  1 SRC=213.251.182.112
  1 SRC=31.170.160.104
  1 SRC=37.187.88.149
  1 SRC=37.230.106.33
  1 SRC=46.229.170.155
  1 SRC=46.242.145.23
  1 SRC=46.252.18.189
  1 SRC=46.252.18.59
  1 SRC=46.252.18.79
  1 SRC=5.101.156.104
  1 SRC=60.206.66.110
  1 SRC=65.75.154.216
  1 SRC=67.55.117.123
  1 SRC=77.222.61.126
  1 SRC=79.133.53.16
  1 SRC=79.96.130.161
  1 SRC=81.177.135.81
  1 SRC=82.210.30.209
  1 SRC=87.236.20.10
  1 SRC=88.231.31.66
  1 SRC=91.142.255.142
  1 SRC=91.201.153.37
  1 SRC=92.48.101.119

Result of

cat /var/log/kern.log.1 /var/log/kern.log | grep "CONNLIMIT:" | sed 's/ /\n/g' | grep "SRC=" | sort | uniq -c | sort -g | tail -100


   5653 SRC=148.251.1.16
   5686 SRC=5.39.126.34
   5716 SRC=61.221.242.34
   5721 SRC=103.27.120.101
   5746 SRC=119.9.93.157
   5819 SRC=185.84.180.90
   5819 SRC=203.189.105.140
   5928 SRC=31.210.68.2
   5988 SRC=217.119.54.143
   6082 SRC=195.225.106.105
   6118 SRC=89.200.172.224
   6147 SRC=212.71.251.65
   6326 SRC=213.238.178.189
   6326 SRC=64.68.50.128
   6437 SRC=136.243.130.221
   6538 SRC=72.14.185.201
   6676 SRC=74.50.57.192
   6835 SRC=134.119.225.88
   6910 SRC=50.116.48.248
   6912 SRC=176.9.147.121
   7014 SRC=91.221.70.17
   7066 SRC=202.172.28.99
   7138 SRC=175.138.64.74
   7172 SRC=89.111.177.28
   7197 SRC=52.2.232.226
   7223 SRC=94.23.208.114
   7421 SRC=180.150.140.211
   7528 SRC=178.254.50.81
   7610 SRC=203.121.118.2
   7751 SRC=210.57.208.12
   7844 SRC=213.128.72.74
   7917 SRC=94.23.68.50
   8019 SRC=89.107.187.181
   8139 SRC=169.227.254.67
   8256 SRC=202.172.28.129
   8422 SRC=195.140.221.90
   8497 SRC=213.185.87.30
   8553 SRC=94.23.201.35
   8660 SRC=212.87.168.158
   8726 SRC=185.12.95.166
   8916 SRC=82.208.46.109
   8965 SRC=195.222.141.71
   9238 SRC=108.171.182.6
   9289 SRC=176.58.122.93
   9388 SRC=195.128.234.184
   9414 SRC=216.55.73.41
   9704 SRC=50.97.132.8
   9964 SRC=54.154.166.245
  10804 SRC=50.31.101.38
  10824 SRC=207.150.204.204
  11341 SRC=177.73.0.60
  11377 SRC=41.0.5.101
  11651 SRC=87.197.66.202
  11695 SRC=188.40.67.8
  11764 SRC=54.175.72.26
  11860 SRC=200.1.19.9
  12794 SRC=63.134.242.136
  12906 SRC=64.62.202.2
  13374 SRC=209.20.76.89
  13440 SRC=210.171.128.44
  13712 SRC=195.128.49.154
  13792 SRC=91.121.171.14
  13860 SRC=69.41.160.74
  14114 SRC=124.219.27.20
  14262 SRC=101.100.185.182
  14420 SRC=91.226.231.20
  14455 SRC=106.186.118.36
  14534 SRC=185.67.207.42
  14749 SRC=64.119.0.29
  14788 SRC=88.87.217.142
  14810 SRC=54.248.84.249
  14982 SRC=194.204.54.100
  15004 SRC=199.97.121.28
  16042 SRC=206.214.216.234
  16481 SRC=37.59.4.25
  16525 SRC=63.134.215.127
  17802 SRC=219.94.232.125
  19060 SRC=178.162.214.68
  19093 SRC=63.246.2.84
  19439 SRC=188.165.218.200
  19706 SRC=85.18.111.134
  20057 SRC=178.250.74.17
  20399 SRC=174.122.206.146
  21701 SRC=178.162.201.165
  21894 SRC=62.75.181.103
  23622 SRC=41.220.16.236
  24073 SRC=178.162.214.71
  24090 SRC=94.23.47.66
  25418 SRC=66.212.19.28
  27045 SRC=62.75.245.243
  27793 SRC=108.163.195.170
  27953 SRC=193.189.99.15
  28113 SRC=87.236.221.243
  31644 SRC=193.254.184.49
  32474 SRC=46.4.60.68
  32902 SRC=217.27.220.88
  35946 SRC=37.235.1.92
  40613 SRC=54.164.238.200
  42753 SRC=92.222.216.23
  45604 SRC=82.201.140.123

I am using this script to limit connections to my open ports already but still my server gets too much hits.

Correctly limit IP connections


Solution 1:

While originally the iptables script seemed to work adequately for your application, now your server is simply being overwhelmed by a significant increase in volume of the attack. The proposed solution is to avoid CPU hungry stuff such as recent table manipulations and logging by adding the worst offenders to an early direct DROP list and severely rate limiting log entries for the remaining and new attackers.

#!/bin/sh
FWVER=0.05
#
# Vlark.Lopin rule set. Smythies 2017.01.13 Ver:0.05
#     Add a backup method for identiying bad guys
#     that never hit the connection limit.
#     Legitimate users would only connect
#     and disconnect a maximum of 20 times per day.
#     With lots of some margin, we need a bigger than default
#     number of packets to remember.
#     Extend rate limited logging to all logging.
#
# Vlark.Lopin rule set. Smythies 2017.01.10 Ver:0.04
#     Rate limit logging.
#     It seems a table size of 5000 is being used.
#     Change from a default of ICMP allowed to not.
#
# Vlark.Lopin rule set. Smythies 2017.01.09 Ver:0.03
#     In an attempt to reduce server load with time
#     spent manipulating the recent tables and logging,
#     direct DROP the worst offenders.
#     If the direct DROP list gets very long then
#     consider to use ipset instead as it is much faster.
#     If maintenance of the list is too labour intensive
#     then consider automation with fail2ban.
#
# Vlark.Lopin rule set. Smythies 2016.11.05 Ver:0.02
#     Interface name change from eth0 to ens3.
#
# 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 (5000 X 64) than default (100 X 20)
#     Note: 64 was chosen, becuase it goes to 64 with lower numbers anyhow.
#     xt_recent table size.
#
#     See also:
#     https://askubuntu.com/questions/869205/i-dont-know-what-to-do-to-stop-the-synattack
#     https://askubuntu.com/questions/818524/correctly-limit-ip-connections
#     https://askubuntu.com/questions/808297/i-have-massive-attack-on-port-in-my-server
#     https://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="ens3"
# Smythies
# 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

echo "...1..."
# We want to force load the xt_recent module, so that we override the
# default maximum table size. We want 5000 whereas the default is 100.
# Note: It is unlikely that it needs to be 5000 forever. Once the
# bad guys give up, the attempts will become much less frequent, and
# the table size can probably be reduced to default.
# i.e. this force load segment can be commented out, and then it will
# autoload as required.
# V0.04: It seems the bad guys actually increased their efforts.
# V0.05: We also need more remembered packets then the default.
# I do not know the extra CPU burden of such a large table.
# Note: The table length seems to go to 64 anyhow, so just use that.
#
modprobe xt_recent ip_list_tot=5000 ip_pkt_list_tot=64

echo "...2..."
#######################################################################
# 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.
# V0.04: Rate limit the logging.
$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 -m limit --limit 1/s --limit-burst 2 -j LOG --log-prefix "CONNLIMIT_ADD:" --log-level info
$IPTABLES -A add-to-connlimit-list -j DROP
echo "...3..."

#######################################################################
# 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 -m limit --limit 1/s --limit-burst 2 -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

# Just DROP invalid packets.
#
$IPTABLES -A INPUT -i $EXTIF -m limit --limit 1/s --limit-burst 2 -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

# direct drops. I do not like you.
#
$IPTABLES -A INPUT -i $EXTIF -s 5.39.126.34 -j DROP
# ... Vlark manages this list ...
$IPTABLES -A INPUT -i $EXTIF -s 219.94.232.125 -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
# V0.04: Default to commented out.
#
# $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 limit --limit 1/s --limit-burst 2 -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
echo "...5..."

# Port 20000 part 1 of 2: Limit to 3 simultanious 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.
# V0.04: Rate limit the logging.
#
$IPTABLES -A INPUT -i $EXTIF -m limit --limit 1/s --limit-burst 2 -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 limit --limit 1/s --limit-burst 2 -m state --state NEW -p tcp --dport 20000 -j LOG --log-prefix "CONNALLOW:" --log-level info

# Port 20000 part 2 of 2: Limit to 55 attempts to connect per IP address per day.
# Otherwise ban them.
#
$IPTABLES -A INPUT -i $EXTIF -m limit --limit 1/s --limit-burst 2 -m recent --update --hitcount 55 --seconds 86400 --name BADGUY_MANY -j LOG --log-prefix "MANY:" --log-level info
$IPTABLES -A INPUT -i $EXTIF -m recent --update --hitcount 55 --seconds 90000 --name BADGUY_MANY -j DROP
$IPTABLES -A INPUT -p tcp --dport 20000 -m recent --set --name BADGUY_MANY -j ACCEPT
echo "...6..."

# O.K. 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 -m multiport --dport 33434:33448 -j DROP
$IPTABLES -A INPUT -i $EXTIF -p tcp -m multiport --dport 23,2323 -j DROP

# If your log file is too cluttered, consider to comment out this log rule.
# It is useful for debugging, but might overwhelm your log files.
# V0.04: Rate limit the logging.
#
$IPTABLES -A INPUT -s $UNIVERSE -d $UNIVERSE -m limit --limit 1/s --limit-burst 2 -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.

Watch for trends in IP addresses, for example the bad guys from 178.162.???.??? and if you get more of those addresses, just DROP the entire segment, i.e. 178.162.0.0/16, or lookup the segment allocation (in this case Germany) and DROP based on allocation mask.

I am assuming the source IP address is not fake here, because the rule only triggers after one good connection, but I might be wrong (in which case this answer is useless).

If you continue to have troubles, then generic rate limiting could be tried, but then your real legitimate clients would be affected as well.

I am also assuming that you do not know all of your clients, and therefore a a whitelist approach is not a viable option.