Blocking web bots with iptables - iptables

I am trying to block web bots that open up numerous connections within a short period of time. I am using this syntax:
-A INPUT -p tcp --dport 80 -m state --state NEW -m recent --set
-A INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 1 --hitcount 20 -j logdropconnection
My problem is that I can't relax these parameters without iptables throwing an error. When I try to increase the hitcount beyond 20, I get an error. Shouldn't I be able to set that to anything I want? For example, limit my connections to 100/second?

Since you failed to mention the error in your question, I'll take a wild guess that dmesg shows this error:
xt_recent: hitcount (100) is larger than packets to be remembered (20)
This is a setting of the xt_recent (sometimes referred to as ipt_recent) kernel module.
You can increase the limit by updating (or creating) /etc/modprobe.d/options.conf with:
options xt_recent ip_pkt_list_tot=100
Note: this could be a problem to implement on VPS hosts with kernel-sharing features.

Related

HTTP Flood on Tomcat server causing issues

I am getting hit with small HTTP floods on my apache server running port 80 which is proxying tomcat on port 8080.
Now what is happening is this is causing tomcat to create 100s - 1000s of sessions depending on how many clients get passed the cloudflare firewall(s) and my server ones (I have libapache2-mod-qos installed for my Apache server).
IPTABLES:
/sbin/iptables -A INPUT -p tcp -m connlimit --connlimit-above 111 -j REJECT --reject-with tcp-reset
/sbin/iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP
/sbin/iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP
iptables -A INPUT -p tcp --dport 80 -m hashlimit --hashlimit-upto 50/min \
--hashlimit-burst 500 --hashlimit-mode srcip --hashlimit-name http -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j DROP
example:
Now this is causing major issues for me and if someone could help shed some light on how to get around this I would be greatful.
mod-qos conf:
<IfModule qos_module>
# handle connections from up to 100000 different IPs
QS_ClientEntries 100000
# allow only 50 connections per IP
QS_SrvMaxConnPerIP 10
# limit maximum number of active TCP connections limited to 256
MaxClients 256
# disables keep-alive when 180 (70%) TCP connections are occupied
QS_SrvMaxConnClose 180
# minimum request/response speed
# (deny slow clients blocking the server, keeping connections open without requesting anything
QS_SrvMinDataRate 150 1200
</IfModule>
As far as you know is this legitimate traffic and not part of a DOS / DDOS?
I assume with cloudflare involved it is not however if so then it is best to have an IPS inspect the traffic at an application level and to deny it based on a matching attack signature.
If ligitmate then you will need to assess how the tomcat application is operating based on its code and logs being produced.
Maybe the Tomcat application is requiring the clients to send this data inbound.

Iptables, enforce multiple rules at the same time

I am learning how to use iptables in Ubuntu
there is a server and two clients
my professor asks me to finish the three task below at once:
1.block all accesses from a client except ssh and web access
2.allow at most 2 ssh connections from each client.
3.allow at most 3 total tcp connections from each client.
I can set those rules using 3 command and i think he wants us to use a single command to finish three tasks at once.
I tried:sudo iptables -A INPUT -p tcp -m multiport ! --dports 22,80 --syn --dport 22 -m connlimit --connlimit-above 2 -m connlimit --connlimit-abve 3 -j DROP
But it didn't work
Why don't you just ask him what he wants? I don't think it is possible to do so at least based on the fact that you want to introduce both rejecting and accepting rules.
If it is really necessary to do just in one line, you can use && operator between your iptables commands as follows:
iptables your_rule1 && iptables your_rule2 && iptables your_rule3

How to block FIN-WAIT-2 by iptables?

My site now is under ddos-attack,
"ss -ant" shows a lot of FIN-WAIT-2 (and some FIN-WAIT-1) connections from one ip (and random ports), about 500-700 connections:
FIN-WAIT-2 0 0 ::ffff:MY_IP:443 ::ffff:ATTACKERS_IP:RANDOM_PORT
.... 500-700 times
Im trying to use
iptables -A INPUT -s ATTACKERS_IP -j DROP
and
iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,RST RST -m limit --limit 1/s -j ACCEPT
and
echo "2" > /proc/sys/net/ipv4/tcp_fin_timeout
but it doesnt help - new connections are coming in with another random ports.
So, how to TOTALLY block specific IP by iptables (or maybe something else) to prevent FIN-WAIT-2 flood by ip which freezes the server?
It depends, there's a ton of ways to approach the problem. You could block the whole country if it's a foreign-language country (provided your website is not of international market or interest).
or
You could block an entire ip block
or
You could use cloudflare to pre-mitigate the problem
or
You could ....

Understanding iptables rate limit

I am new to iptables and I was trying to make sure I understand this statement.
iptables -t nat -A PREROUTING -p tcp -d 5.5.5.5 --dport 25 -m limit --limit 20/min --limit-burst 25 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp -d 5.5.5.5 --dport 25 -j DROP
If an address connects to 5.5.5.5 more than 25 times in 20 minutes block that ip?
You're close. This isn't on a TCP-connection level, it's on a packet level. To deal with connections instead of packets - you'd want to use the state module.
See: https://www.debian-administration.org/article/187/Using_iptables_to_rate-limit_incoming_connections
The negotiation of TCP connections alone is already many packets. See: http://www.inetdaemon.com/tutorials/internet/tcp/3-way_handshake.shtml
These 2 rules state - for all ethernet devices -> if protocol is tcp, destination ip address is 5.5.5.5, and destination port is 25 limit incoming packets to 20 per minute with a burstable amount of an additional 25 per minute. Drop any over this limit.
You might want to look at fail2ban: it will block multiple failed connections. It works for SSH and can be configured for other protocols.

iptables allow whm mail port 25

Trying to understand iptables (I have cPanel installed on VPS) and having a little play so may sound like a silly question what I am doing.
I have copied the default iptables config to backup (in case goes wrong to restore) and created custom iptables config (/etc/sysconfig/iptables) were I DROP INPUT/OUTPUT/FORWARDING (so everything).
I then managed to get all the ports I want access to required working (incoming/outgoing HTTP/s/SSH/FTP etc) apart from emails (:25). I am using Roundcube and using the below config for emails but emails can not be sent/received on my server (works if I restore default config (ACCEPT everything) so apart from port :25 is there any other ports I need to allow access to for mail to be sent knowing everything has been dropped?). I am using below config for email in my custom (/etc/sysconfig/iptables):-
-A INPUT -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --dport 25 -j ACCEPT
-A INPUT -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
IP is a bidirectional communication, when you receive a mail, packets are sent on your server on port 25, and you will send response packet on a arbitrary allocated port number (determined during connection establishment).
So, common rule on iptables are :
Accepting packet on input from a specified port (25 for mail) whatever the state of connection
-A INPUT -p tcp --dport 25 -j ACCEPT
Accepting to send back packets for all established connection whatever the destination port.-A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
Now, if you want to send mail to a server, you have to allow packet to go out to port 25 and allow incoming all established connection.
-A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --dport 25 -j ACCEPT
Another idea , will be to log packets that should be dropped.
put log line a the end of all chain's rules.
iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT PACKET DROPPED "
iptables -A OUTPUT -p tcp -j LOG --log-prefix "OUTPUT PACKET DROPPED "
With that, you will see in /var/log/message (or with dmesg) a line for each packet reaching the end of chain's rule and beeing dropped.