I would like to setup basic firewall rules with iptables.
The goal is to reject flood requests per IP. Like "ab -n 100000 -c 1000 "
There are only 2 rules:
iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m limit --limit 100/s --limit-burst 10000 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -i eth0 -j LOG --log-prefix "__test__"
But I when grep iptables log with "sort" and "uniq -c" I see lot's of IPs like:
1 SRC=173.252.77.112
1 SRC=173.252.114.116
1 SRC=173.252.114.114
1 SRC=173.252.114.113
Is "-m state --state NEW" effect only new connections? Then why IPs with low requests count appeared in log?
Please advice.
Finally the solution is:
iptables -A INPUT -i eth0 -p tcp --dport 80 -m hashlimit --hashlimit 1000/sec --hashlimit-burst 5000 --hashlimit-mode dstip --hashlimit-name hosts -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 80 -j REJECT
Do not block SE-crawlers packets and resists against http-flood like: ab -n 1000 -c 100 http://{host}/
Related
If my clients connect to my server on port 5000, how would I set IPTables, to split them evenly between 5001 and 5002?
All of this must be done with caution and make sure you have serial/terminal access because there is a chance of you losing your network connection
First enable ipV4 forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -P INPUT ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 5000 -m statistic --mode nth --every 3 --packet 0 -j REDIRECT --to-port 5000
iptables -t nat -A PREROUTING -p tcp --dport 5000 -m statistic --mode nth --every 2 --packet 0 -j REDIRECT --to-port 5001
iptables -t nat -A PREROUTING -p tcp --dport 5000 -j REDIRECT --to-port 5002
how to block all connections/IP on SSH and allow only 1 or 2 address ?
iptables -A INPUT -p tcp -s [IP] --dport ssh -j ACCEPT
iptables -A INPUT -p tcp --dport ssh -j REJECT
this is my iptables, everything works fine, except that these IP's with more than 20 connection wont get blocked.
iptables -F
iptables -X
iptables -I INPUT 1 -i lo -j ACCEPT
iptables -I INPUT 2 -i eth0 -p tcp --dport 6606 -m state --state NEW,RELATED,ESTABLISHED -m limit --limit 2/s --limit-burst 4 -j ACCEPT
iptables -I INPUT 3 -i eth0 -p tcp --dport 6624 -m state --state NEW,RELATED,ESTABLISHED -m limit --limit 2/s --limit-burst 4 -j ACCEPT
iptables -I INPUT 4 -i eth0 -p tcp --dport 6610 -m state --state NEW,RELATED,ESTABLISHED -m limit --limit 2/s --limit-burst 4 -j ACCEPT
iptables -I INPUT 5 -i eth0 -p tcp --dport 6610 -m state --state NEW,RELATED,ESTABLISHED -m limit --limit 2/s --limit-burst 4 -j ACCEPT
iptables -I INPUT 6 -i eth0 -p icmp --icmp-type echo-request -j ACCEPT
iptables -I INPUT 7 -i eth0 -p icmp --icmp-type echo-reply -j ACCEPT
iptables -I INPUT 8 -i eth0 -m connlimit --connlimit-above 20 -j DROP
iptables -I OUTPUT 1 -o lo -j ACCEPT
iptables -I OUTPUT 2 -o eth0 -p tcp --sport 6606 -m state --state NEW,RELATED,ESTABLISHED -m limit --limit 2/s --limit-burst 4 -j ACCEPT
iptables -I OUTPUT 3 -o eth0 -p tcp --sport 6624 -m state --state NEW,RELATED,ESTABLISHED -m limit --limit 2/s --limit-burst 4 -j ACCEPT
iptables -I OUTPUT 4 -o eth0 -p tcp --sport 6610 -m state --state NEW,RELATED,ESTABLISHED -m limit --limit 2/s --limit-burst 4 -j ACCEPT
iptables -I OUTPUT 5 -o eth0 -p tcp --sport 6610 -m state --state NEW,RELATED,ESTABLISHED -m limit --limit 2/s --limit-burst 4 -j ACCEPT
iptables -I OUTPUT 6 -o eth0 -p icmp --icmp-type echo-reply -j ACCEPT
iptables -I OUTPUT 7 -o eth0 -p icmp --icmp-type echo-request -j ACCEPT
iptables -I OUTPUT 8 -o eth0 -m connlimit --connlimit-above 20 -j DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
What's wrong? Why does connection limit not work?
You're accepting connections without a connlimit specification before the connlimit DROP rule is set.
Try putting the DROP rule above all the others or specify a --connlimit-upto inside each one of your ACCEPT rules. e.g.
iptables -A INPUT -i eth0 -p tcp --dport 6606 \
-m state --state NEW,RELATED,ESTABLISHED \
-m connlimit --connlimit-upto 20 -m limit --limit 2/s --limit-burst 4 -j ACCEPT
Actually which connection you wanted to limit here. SSH or HTTP or HTTPS or TELNET.
In the below rule, just replace the port 80 with 22 for SSH and 23 for TELNET, so it should work.
iptables –I INPUT -p tcp --dport 80 -m state --state NEW -m
connlimit --connlimit-above 20 -j REJECT --reject-with
icmp-admin-prohibited
Also, in some of the recent kernel the connlimit module is removed, so either you have to patch up the module inside the kernel or use the hashlimit module for restricting the connections. Hashlimit module is more stronger and flexible that connlimit module.
The below rule will limit to the 20 connections per min for the corresponding destination ip.
iptables -A INPUT-p tcp --dport 80 -m state --state NEW -m hashlimit
--hashlimit-name \ HTTP_LIMIT –hashlimit 20/day--hashlimit-burst 1 --hashlimit-mode dstip -j ACCEPT
For more explanation, refer http://ipset.netfilter.org/iptables-extensions.man.html#lbAW.
I have the following iptable rules for a new system.
Basically I am trying to allow incoming www, ssl and ssh and allow outgoing ftp,ssh,smtp,dns,www and ssl connections. Plus a special rules for an outgoing mysql connection to a specific mysql server, a DoS attack helper and some dropped packet logging. All other connections I want dropped.
My trouble is, every single time I run the shell script for these rules, I get locked out tighter than a drum. It drops the established ssh session and won't allow me to begin a new one. I have to reboot through a console as even flushing the rules in a console session does not help.
It does not matter if the fallback rules (top three after the flush) are at the beginning or the end. I've tried many ways and I am hoping a new set of eyes may see what I am missing:
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m multiport --sports 80,443 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m multiport --dport 21,22,25,53,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -m multiport --sport 21,22,25,53,80,443 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -p tcp -s 172.xxx.xxx.xxx --sport 1024:65535 -d 172.xxx.xxx.xxx --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -s 172.xxx.xxx.xxx --sport 3306 -d 172.xxx.xxx.xxx --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 80,443 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
iptables -N LOGGING
iptables -A INPUT -j LOGGING
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: " --log-level 7
iptables -A LOGGING -j DROP
Any help would be appreciated. NOTE: I obfuscated the internal IP for posting.
I'm securing my server (with iptables) so that only http and ssh ports are open and that is fine, although I use the mail command (server: CentOS 6.2) in some applications and it does not get through now thanks to iptables blocking everything.
What ports do I allow it access to?
Mail usage: echo "{{message}}" | mail -s "{{subject}}" me#mail.com
I've tried the standard mail port 25, but I have had no success with that.
Here is the current setup:
iptables --flush
iptables -P INPUT DROP
iptables -P OUTPUT DROP
# incoming ssh
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
# outgoing ssh
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
#HTTP
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
# mail (does not work)
iptables -A INPUT -i eth0 -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
(EDIT) ANSWER: The working iptables rule:
iptables -A OUTPUT -o eth0 -p tcp --sport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
The OUTPUT commands should also refer to --dport, not --sport. You'll also want to allow NEW outgoing packets in order to initiate the connection to the SMTP server.
In general, however, since OUTPUT controls only those packets that your own system generates, you can set the OUTPUT policy to ACCEPT unless you need to prevent the generation of outgoing packets.
Two more comments:
1. Jay D's suggestion to "allow everything and then start blocking specific traffic" is insecure. Never configure iptables this way because you'd have to know in advance which ports an attacker might use and block them all individually. Always use a whitelist instead of a blacklist if you can.
2. A hint from the trenches: when you're debugging iptables, it's often helpful to -Insert and -Append log messages at the beginning and end of each chain, then clear the counters, and run an experiment. (In your case, issue the mail command.) Then check the counters and logs to understand how the packet(s) migrated through the chains and where they may have been dropped.