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.
Related
I want to record the packets (using tcpdump) after iptables, but it seems that tcpdump will record all the packets. I don't want the packet dropped by iptables.
Is there any way to
record the packets after iptables? or
output the packets (processing by iptables) into pcap/log file?
Thanks.
Tcpdump acts before iptables for inbound traffic, but you can use iptables "NFLOG" extension to reach your goal: http://ipset.netfilter.org/iptables-extensions.man.html#lbDI
Using "NFLOG" destination you can log desired packets to userspace application, and that's where tcpdump belongs (you can also assign traffic to a specific group and then tell tcpdump to listen from it).
Webserver (very basic) example, let's pretend you are accepting http/https traffic and dropping ssh:
#BASIC RULES
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
#NFLOG REDIRECT ONLY HTTP TRAFFIC
iptables -A INPUT -p tcp --dport 80 -j NFLOG
#TCPDUMP ONLY ON MATCHED TRAFFIC (=HTTP)
tcpdump -i nflog
I'm running Redis on my webserver (Debian/Nginx/Gunicorn) for session storage and have reasons to believe my Redis server is being hacked. It's definitely possible because if I run the command "redis-cli -h (HOST IP)" on a different machine against the web server, I can get into the console and run commands. I have two questions. First, if I add a new section to my iptables files as shown below, will I be correctly blocking access to my Redis server from all machines except the webserver itself? Redis is running on the default port 6379.
*filter
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT
# Allow pings, SSH, and web access
-A INPUT -p icmp -m state --state NEW --icmp-type 8 -j ACCEPT
-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
-A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT
-A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT
# NEW SECTION...
# IS THIS CORRECT?
-A INPUT -p tcp --dport 6379 -j DROP
-A INPUT -p tcp -s 127.0.0.1 --dport 6379 -m state --state NEW -j ACCEPT
# END NEW SECTION
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT
Second, if the above is correct, can I still use 127.0.0.1 in the IPv6 version of my iptables or do I need to use "::1"?
Thanks.
You should be able to do this through the Redis configuration file:
# By default Redis listens for connections from all the network interfaces
# available on the server. It is possible to listen to just one or multiple
# interfaces using the "bind" configuration directive, followed by one or
# more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1
modify redis.conf file :
bind 127.0.0.1 ==>
redis instanse will accept connections only from localhost
bind 127.0.0.1 xxx.xx.xx.xxx ==>
if you want to accept connections from out server add ip of the server
#bind 127.0.0.1 ==> comment this line will make redis listens from any network interface
I need some custom iptables for a login page of my wifi hotspot on my raspberry pi. I want an http login page: this is how it should work, I just don't know how to configure the iptables.:
Any connections on an ip address that is not already logged in, should be redirected to the pi's port 8181 (the server for my login page).
Any connections on an ip address that is logged in should be allowed to access the outside internet.
Any connections initially requesting the pi's port 8181 should be allowed.
How should I set this up with iptables?
Thanks!
I've found the following article very helpful when learning iptables:
http://wiki.centos.org/HowTos/Network/IPTables
Basically you can start with a something similar to:
# iptables -P INPUT ACCEPT
# iptables -F
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# iptables -P INPUT DROP
# iptables -P FORWARD DROP
# iptables -P OUTPUT ACCEPT
This will block pretty much everything other than SSH, outgoing connections, and connections that are previously established (ie from previous outgoing connections)
Once that is in place you need to do the redirection:
http://proghowto.com/iptables-redirect-port-80-to-port-8080
And finally you need to run something like the following for each ip that gets authenticated:
# iptables -A INPUT -s 192.168.0.4 -j ACCEPT
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.
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.