我确信Linux系统pipe理员对于iptables
是netfilter
包过滤框架的用户界面非常熟悉。
现在,这个“问题”是为了收集各种iptables
智慧中的各种各样的部分。 没有什么太常见或太模糊。 发布任何你知道可以帮助他人充分利用iptables
。
#!/bin/bash WHITELIST=/whitelist.txt BLACKLIST=/blacklist.txt #THIS WILL CLEAR ALL EXISTING RULES! echo 'Clearing all rules' iptables -F # ## Whitelist # for x in `grep -v ^# $WHITELIST | awk '{print $1}'`; do echo "Permitting $x..." $IPTABLES -A INPUT -t filter -s $x -j ACCEPT done # ## Blacklist # for x in `grep -v ^# $BLACKLIST | awk '{print $1}'`; do echo "Denying $x..." $IPTABLES -A INPUT -t filter -s $x -j DROP done
#!/bin/bash ALLOWEDTCP="80 3128 3784" ALLOWEDUDP="3128 3784" # ## Permitted Ports # for port in $ALLOWEDTCP; do echo "Accepting port TCP $port..." $IPTABLES -A INPUT -t filter -p tcp --dport $port -j ACCEPT done for port in $ALLOWEDUDP; do echo "Accepting port UDP $port..." $IPTABLES -A INPUT -t filter -p udp --dport $port -j ACCEPT done
# Attempt to block portscans # Anyone who tried to portscan us is locked out for an entire day. iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP iptables -A FORWARD -m recent --name portscan --rcheck --seconds 86400 -j DROP # Once the day has passed, remove them from the portscan list iptables -A INPUT -m recent --name portscan --remove iptables -A FORWARD -m recent --name portscan --remove # These rules add scanners to the portscan list, and log the attempt. iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:" iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "Portscan:" iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP
# Reject spoofed packets # These adresses are mostly used for LAN's, so if these would come to a WAN-only server, drop them. iptables -A INPUT -s 10.0.0.0/8 -j DROP iptables -A INPUT -s 169.254.0.0/16 -j DROP iptables -A INPUT -s 172.16.0.0/12 -j DROP iptables -A INPUT -s 127.0.0.0/8 -j DROP #Multicast-adresses. iptables -A INPUT -s 224.0.0.0/4 -j DROP iptables -A INPUT -d 224.0.0.0/4 -j DROP iptables -A INPUT -s 240.0.0.0/5 -j DROP iptables -A INPUT -d 240.0.0.0/5 -j DROP iptables -A INPUT -s 0.0.0.0/8 -j DROP iptables -A INPUT -d 0.0.0.0/8 -j DROP iptables -A INPUT -d 239.255.255.0/24 -j DROP iptables -A INPUT -d 255.255.255.255 -j DROP # Drop all invalid packets iptables -A INPUT -m state --state INVALID -j DROP iptables -A FORWARD -m state --state INVALID -j DROP iptables -A OUTPUT -m state --state INVALID -j DROP
# Stop smurf attacks iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP iptables -A INPUT -p icmp -m icmp -j DROP # Drop excessive RST packets to avoid smurf attacks iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT
# Don't allow pings through iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP
ipset
优化netfilter的性能 如果你仅仅基于IP,端口或者两者写出许多类似的规则,可以考虑使用ipset
来优化netfilter的性能。
例如:
iptables -s 192.168.1.11 -j ACCEPT iptables -s 192.168.1.27 -j ACCEPT iptables -s 192.168.1.44 -j ACCEPT ... hundreds of similar rules ... iptables -s 192.168.251.177 -j ACCEPT
这意味着源地址为192.168.251.177的数据包必须首先遍历数百个规则,然后才能获得对ACCEPT的判定。
当然,有经验的系统pipe理员会通过子网划分规则。 但是,这仍然意味着数百个规则。
ipset
来救援!
首先定义一个ipmap
types的IP集合:
ipset -N Allowed_Hosts ipmap --network 192.168.0.0/16
然后,填入地址:
for ip in $LIST_OF_ALLOWED_IP; do ipset -A Allowed_Hosts $ip; done
最后,用一条规则replace上面的数百个iptables规则:
iptables -m set --match-set Allowed_Hosts src -j ACCEPT
当一个数据包到达时,netfilter会根据Allowed_Hosts
IP Set对数据包的源(src)IP执行一个非常快速的位图search。 所有来自192.168.0.0/16的数据包都将经历一条规则。 并且相信我,search一个位图比执行数百个iptables规则检查快至less两个数量级。
ipset
不限于IP地址。 它还可以根据端口,IP端口元组,networking/子网地址,IP-MAC元组等进行匹配。 它可以匹配这些标准作为源或目的地或两者的组合(在元组的情况下)。
最后,用ipset
你可以自动把IP地址放入黑名单/白名单。 这些黑名单/白名单也可以“老化”,从而在经过了可configuration的时间后自动删除IP地址。
有关更多详细信息,请参阅ipset
的手册页 。
一些Linux发行版对ipset 没有 “开箱即用”的支持。 我知道,不支持ipset的两个发行版是Ubuntu和Debian 。 在他们的aptitude
上运行aptitude
显示ipset
包是可用的,但我强烈build议你不要安装这个包,原因有两个:(1)它是一个老版本的ipset,(2)它不会工作。
相反,从它的网站下载ipset
的来源: http : //ipset.netfilter.org/install.html
另外,如果你使用xtables-addons
,ipset包含在它的源代码中: http : //xtables-addons.sourceforge.net/
编辑:以上是真正的Ubuntu 10.04,在写作时最新的LTS。 Ubuntu 12.04内置了对ipset
和/或xtables-addons
,因为安装相关的软件包可以正确启用这些function。 我不知道Debian的情况,但是已经有很长时间没有使用它了。
为您的规则添加评论:
-m comment --comment "Comments help to read output of iptables -nvL"
添加以下规则,最好在-t raw -A PREROUTING
-p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP -p tcp --tcp-flags SYN,RST SYN,RST -j DROP -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j DROP -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN -j DROP -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
被阻止的攻击分别是:
(随意编辑上面的攻击名称)
echo 1 > /proc/sys/net/ipv4/ip_forward
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
步骤1设置内核参数以允许进行IP转发,步骤2设置在接口eth0上启用NAT的iptables规则。
添加以下规则,最好在-t raw -A PREROUTING
-p icmp -m u32 ! --u32 "4&0x3FFF=0" -j DROP -p icmp -m length --length 1492:65535 -j DROP
第一条规则阻止所有“碎片标志”不是0的ICMP数据包。(ICMP 永远不应该被分割;它们应该携带小的有效载荷)
第二个规则阻止超大的片段化的ICMP数据包。
(从我的iptables_tricks.txt文件中,从很多地方重新编译:P)
使iptables在来自同一IP的新连接之间等待15秒钟:
iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP iptables -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT
使用FireHOL – 方便的iptables包装
我发现它比直接iptables命令更直观。 特别是对于其他防火墙有过往经验的人:
FireHOL是一个iptables防火墙生成器,在Linux主机和路由器上生成有状态的iptables包过滤防火墙,具有任意数量的networking接口,任意数量的路由,任意数量的服务,各种服务之间的任何复杂度(包括正面和负面expression式)。
IPTABLESvideo教程
第1集http://www.youtube.com/watch?v=ldB8kDEtTZA&feature=player_embedded
第2集http://www.youtube.com/watch?v=aDaEXxRHeXY&feature=related
最后一集
http://www.youtube.com/watch?v=JojqHKcSxpo&feature=player_embedded
对于任何新手来说都是一个好的开始。
已经有一个提及IP集的答案。 然而,它是一维的,它关注的是性能增益优于传统规则,而IP设置缓解了具有许多独立IP地址的问题,这些IP地址在CIDR表示法中不容易表示为子网。
对于ipset
我将使用由ipset restore
读取并由ipset save
写入的符号。
对应iptables
(和ip6tables
)规则,我将使用iptables-restore
读取的符号和iptables-save
编写的符号。 这可以缩短表示法,并且可以突出显示潜在的仅限IPv4(前缀-4
)或仅限于IPv6(前缀为-6
)的规则。
在一些例子中,我们将分组stream转移到另一个链中。 链被假定为在那一点上存在,所以创build链的行不会被生成(表名也没有提到,或者在末尾COMMIT
命令)。
IP集可以做的比其他答案中提到的要多得多,除了这里的简短条目之外,您还一定要阅读IP集文档( ipset(8)
)以及iptables-extensions(8)
。
例如,我将主要关注三种集合types: hash:ip
, hash:net
和list:set
,但是不止这些,它们都有有效的用例。
例如,您也可以匹配端口号,而不仅仅是IP地址 。
iptables-save
和iptables-restore
您可以批量创buildIP设置声明,并通过将其导入ipset restore
导入它们。 如果您希望使命令对已经存在的条目更具弹性,请使用ipset -exist restore
。
如果你的规则在一个名为default.set
的文件中,你可以使用:
ipset -exist restore < default.set
像这样的文件可以包含条目来create
集和向其中add
条目。 但是通常来自命令行的大部分命令在文件中似乎都有相应的版本。 示例(创build一组DNS服务器):
create dns4 hash:ip family inet create dns6 hash:ip family inet6 # Google DNS servers add dns4 8.8.8.8 add dns4 8.8.4.4 add dns6 2001:4860:4860::8888 add dns6 2001:4860:4860::8844
这里为IPv4( dns4
)和IPv6( dns6
)创build一个集合。
IP套件中的超时可以设置为默认设置,也可以设置为每个条目。 这对于暂时阻止某人的场景非常有用(例如,用于端口扫描或试图暴力破解SSH服务器)。
其工作方式如下(创buildIP集时的默认值):
create ssh_loggedon4 hash:ip family inet timeout 5400 create ssh_loggedon6 hash:ip family inet6 timeout 5400 create ssh_dynblock4 hash:ip family inet timeout 1800 create ssh_dynblock6 hash:ip family inet6 timeout 1800
我们将回到下面的这些特定集合,以及为什么要按照它们的方式进行设置。
如果你想设置一个特定的IP地址超时,你可以简单地说:
add ssh_dynblock4 1.2.3.4 timeout 7200
阻止IP 1.2.3.4两小时,而不是(默认)半小时。
如果您在短时间内使用ipset save ssh_dynblock4
来查看,您会看到如下内容:
create ssh_dynblock4 hash:ip family inet hashsize 1024 maxelem 65536 timeout 1800 add ssh_dynblock4 1.2.3.4 timeout 6954
Kernel error received: Unknown error -1
)。 sudo ipset add ssh_dynblock4 1.2.3.4 timeout $((120*60))
在脚本内部,查看一个条目是否已经存在会很有用。 这可以通过ipset test
来实现,如果条目存在则返回零,否则返回非零。 所以通常的检查可以应用在脚本中:
if ipset test dns4 8.8.8.8; then echo "Google DNS is in the set" fi
但是,在许多情况下,您宁愿要使用ipset
的-exist
开关来指示它不要抱怨现有的条目。
iptables
规则iptables
IP集 这在我看来是IP套装的杀手锏之一。 您不仅可以匹配IP组的条目,还可以将新条目添加到现有的IP组。
例如,在这个问题的答案你有:
-A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --update --seconds 15 -j DROP -A INPUT -p tcp -i eth0 -m state --state NEW --dport 22 -m recent --set -j ACCEPT
…打算限制连接尝试到SSH(TCP端口22)的速度。 recent
使用的模块跟踪最近的连接尝试。 但是,我更喜欢conntrack
模块,而不是state
模块。
# Say on your input chain of the filter table you have -A INPUT -i eth+ -p tcp --dport ssh -j SSH # Then inside the SSH chain you can # 1. create an entry in the recent list on new connections -A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit # 2. check whether 3 connection attempts were made within 2 minutes # and if so add or update an entry in the ssh_dynblock4 IP set -4 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock4 src --exist -6 -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock6 src --exist # 3. last but not least reject the packets if the source IP is in our # IP set -4 -A SSH -m set --match-set ssh_dynblock4 src -j REJECT -6 -A SSH -m set --match-set ssh_dynblock6 src -j REJECT
在这种情况下,我将streamredirect到SSH
链,这样我就不必用-p tcp --dport ssh
重复每一条规则。
重申:
-m set
使iptables
知道我们正在使用来自set
模块(处理IP集合)的交换机, --match-set ssh_dynblock4 src
告诉iptables
将源 ( src
)地址与命名集( ssh_dynblock4
)进行匹配
sudo ipset test ssh_dynblock4 $IP
(其中$IP
包含数据包的源IP地址) -j SET --add-set ssh_dynblock4 src --exist
将来自数据包的源 ( src
)地址添加或更新到IP集ssh_dynblock4
。 如果条目存在( – 存在),它将被简单地更新。
sudo ipset -exist add ssh_dynblock4 $IP
(其中$IP
包含数据包的源IP地址) 如果你想匹配目标/目的地址,你可以使用dst
而不是src
。 请参阅手册以获取更多选项。
IP集可以包含其他集合。 现在如果你把这篇文章一直到这里,你都会想知道是否可以合并集合。 当然是的。 对于上面的IP集合,我们可以分别创build两个联合集合ssh_dynblock
和ssh_loggedon
以包含仅限IPv4的和仅限于IPv6的集合:
create ssh_loggedon4 hash:ip family inet timeout 5400 create ssh_loggedon6 hash:ip family inet6 timeout 5400 create ssh_dynblock4 hash:ip family inet timeout 1800 create ssh_dynblock6 hash:ip family inet6 timeout 1800 # Sets of sets create ssh_loggedon list:set create ssh_dynblock list:set # Populate the sets of sets add ssh_loggedon ssh_loggedon4 add ssh_loggedon ssh_loggedon6 add ssh_dynblock ssh_dynblock4 add ssh_dynblock ssh_dynblock6
下一个问题应该在你脑中popup来,是否允许我们以IP版本不可知的方式匹配和操作IP套件。
而答案是一个响亮的: 是的! (唉,上次我没有明确的logging)
因此,上一节的规则可以被重写为:
-A INPUT -i eth+ -p tcp --dport ssh -j SSH -A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist -A SSH -m set --match-set ssh_dynblock src -j REJECT
这更简洁得多。 是的,这是经过尝试和testing,像一个魅力。
在我的服务器上,我有一个脚本作为cron
作业运行,它需要一堆主机名并将其parsing为IP地址,然后将它提供给“可信主机”的IP集。 这个想法是,可信任的主机获得更多的login到服务器的尝试,并不一定像其他任何人一样被阻止。
相反,我有整个国家阻止连接到我的SSH服务器,(可能)例外的信任主机(即规则的顺序)。
但是,这是留给读者的一个练习。 在这里,我想添加一个整洁的解决scheme,它将使用ssh_loggedon
集中包含的集合来允许后续的连接尝试被传递,而不会受到与其他分组相同的审查。
在查看以下iptables
规则时,记住ssh_loggedon
的默认超时值为90分钟, ssh_loggedon
的默认超时ssh_loggedon
30分钟:
-A INPUT -i eth+ -p tcp --dport ssh -j SSH -A SSH -m set --match-set ssh_loggedon src -j ACCEPT -A SSH -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A SSH -m conntrack --ctstate NEW -m recent --set --name tarpit -A SSH -m conntrack --ctstate NEW -m recent --rcheck --seconds 120 --hitcount 3 --name tarpit -j SET --add-set ssh_dynblock src --exist -A SSH -m set --match-set ssh_dynblock src -j REJECT
现在你应该问自己,连接IP地址如何在ssh_loggedon
子集中结束。 所以继续阅读…
如果你已经尝试了sshrc
和朋友,你会知道它的缺点。 但PAM来救援。 一个名为pam_exec.so
的模块允许我们在SSHlogin过程中调用一个脚本,该脚本知道该用户被允许进入。
在pam_env
和pam_selinux
条目下面的/etc/pam.d/sshd
中添加以下行:
session optional pam_exec.so stdout /path/to/your/script
并确保您的脚本版本( /path/to/your/script
)存在且可执行。
PAM使用环境variables来传达正在发生的事情,所以你可以使用这样一个简单的脚本:
#!/bin/bash # When called via pam_exec.so ... SETNAME=ssh_loggedon if [[ "$PAM_TYPE" == "open_session" ]] && [[ -n "$PAM_RHOST" ]]; then [[ "x$PAM_RHOST" != "x${PAM_RHOST//:/}" ]] && SETNAME="${SETNAME}6" || SETNAME="${SETNAME}4" ipset -exist add $SETNAME "$PAM_RHOST" fi
不幸的是, ipset
实用程序似乎没有ipset
的内置智能。 所以当我们添加条目时,我们需要区分IPv4和IPv6 IP集。 否则ipset
将假设我们想要添加另一个集合的集合,而不是IP。 当然,这不太可能会有一个以IP为名称的集合:)
所以我们检查:
在IP地址中,在这种情况下追加6
到设置名称,否则是4
。
结束。
另一个可用于configurationiptables的GUI是Firewall Builder 。 它允许用户创build规则元素作为数据库中的对象,然后将这些对象拖放到规则编辑器中以创build所需的防火墙策略。 然后,应用程序将生成一个脚本文件,其中包含执行规则所需的所有iptables命令。
与其他iptables GUI解决scheme不同,一次只能pipe理一个iptablesconfiguration,在Firewall Builder中,您可以从一个应用程序pipe理大量的iptablesconfiguration。 在Linux,Windows和Mac OS X上运行的防火墙生成器已经存在了十多年,在全世界有数千个活跃用户。
完全披露 – 我是开发防火墙生成器的公司NetCitadel的联合创始人。
例如:你有eth0
和 eth1
并希望允许它们之间的任何stream量?
iptables -A FORWARD -i eth+ -o eth+ -j ACCEPT
过去我使用过这个,以匹配由LXCdynamic创build和命名的veth<something>
接口。 所以我可以一起匹配veth+
。
我也有意地命名一些接口_<something>
为了匹配_+
。
我所做的一些事情,主要是因为我对一个更优雅的解决scheme的无知,是每4个小时手工检查我的Nginx日志,而邮件服务器每2分钟logging一次个别IP的过度访问。 我一起运行几个脚本:
access.log
并列出排名前10位的IP,按他们对服务器的命中次数排列 iptables.save
以下是它的样子:
autoBanIPs_mail.sh
#!/bin/bash # This script checks the last 2 minutes of log entries to see if any # IP has made over 99 connections now=$(date +"%m_%d_%Y") /root/bin/checkBadIPs_mail.sh > /home/ipChecker/ipcheckMAIL_$now.txt cat /home/ipChecker/ipcheckMAIL_$now.txt | \ grep " \\(\\([9][9]\\)\\|\\([0-9][0-9][0-9]\\+\\)\\) " | \ awk '{print $2}' > /home/ipChecker/badMailIPs_$now.sh sed -i "s/^/\/usr\/local\/sbin\/blockIP /g" /home/ipChecker/badMailIPs_$now.sh /bin/bash /home/ipChecker/badMailIPs_$now.sh cat /home/ipChecker/ipcheckMAIL_$now.txt >> /home/ipChecker/ipcheckMAIL_$now.log rm /home/ipChecker/ipcheckMAIL_$now.txt rm /home/ipChecker/badMailIPs_$now.sh
checkBadIPs_mail.sh
有一点非常重要,这里需要注意的一点是,你需要设置一个白名单,或者你将开始阻止来自服务器的许多真正的IP地址,这些服务器只是收到大量的电子邮件,或者在其他日志,IP的情况下只是因为合法的原因才打你的服务器。 我的白名单只是通过在|之后添加greppipe道而构build到此脚本中 grep']' | 那看起来像这样“grep -v 127.0 |” 。
您需要花时间教您的服务器哪些高stream量IP是合法的,哪些不是。 对我来说,这意味着我不得不花费第一个星期左右手动检查我的日志,每隔几个小时,在iplocation.net上查找高stream量的ip,然后添加像amazon,box.com甚至我的家庭/办公室合法的IP范围到这个白名单。 如果你不这样做,你可能会被阻止从你自己的服务器,或者你将开始阻止合法的邮件/ Web服务器,并导致电子邮件或通信中断。
cat /var/log/mail.log | awk \ -v d1="$(date --date="-2 min" "+%b %_d %H:%M")" \ -v d2="$(date "+%b %_d %H:%M")" \ '$0 > d1 && $0 < d2 || $0 ~ d2' | \ grep '\[' | grep '\]' | \ grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -v 127.0 | \ awk '{print $1}' | sort | uniq -c | sort -n | tail -10
Blockip的
#!/bin/bash sudo iptables -I INPUT -s $1 -j DROP sudo bash -c "iptables-save > /etc/network/iptables.save"
我又一次知道这是粗俗的,可能是一个很好的清洁高效的协议,但是我不知道这件事情,现在这个事情已经持续了一两年了,把坏人扼杀了。 我非常认真地推荐的一件事是,你有一个代理服务器或另一台服务器,你可以用它来访问你的主服务器。原因是,如果你有一天在做Web开发,在5个小时内对自己进行2000次testing,以便进行一些testing,除了代理服务器之外,您可以无阻地进行阻止。
你可以在checkBadIPs.sh
看到我已经把grep -v 127.0和在我的实际文件中,我有很多我自己的IP和其他可信IP范围的忽略规则,但有时你的IP更改,你忘记更新,然后你被locking在你自己的服务器之外。
无论如何,希望有所帮助。
我已经改变了一点点,所以现在,而不是检查每几个小时我有一些日志检查每2分钟,主要是我的SSH身份validation日志和邮件日志,因为他们正在捣毁:(。
我为每个日志文件设置了特定的脚本,尽pipe从我想在检查日志时使用自己的手动脚本中可以很容易find。 看起来像这样:
#!/bin/bash log=$1 time=$2 cat /var/log/${log} | awk \ -v d1="$(date --date="-${time} min" "+%b %_d %H:%M")" \ -v d2="$(date "+%b %_d %H:%M")" \ '$0 > d1 && $0 < d2 || $0 ~ d2' | \ grep '\[' | grep '\]' | \ grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | \ sort | uniq -c | sort -n | tail -10
运行时需要2个input,要扫描的日志文件以及要扫描的过去的时间。
所以如果我想检查mail.log的IP计数说过去75分钟,我会运行:
$ sudo script.sh mail.log 75
logging与uid的传出连接
iptables -A OUTPUT -m state --state NEW -m tcp -p tcp -m limit --limit 5/m -j LOG --log-uid --log-prefix="outgoing connection: "
端口/连接转发:
iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.1.7:80 iptables -A INPUT -p tcp -m state --state NEW --dport 80 -i eth1 -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp \ -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
这个目标的目的是检查发送SYN包的主机是否build立了连接,或者在启动SYN连接之后什么也不做。 如果它什么都不做,它会以最小的努力丢弃数据包。
将syn数据包设置为原始表中的连接跟踪表
iptables -t raw -A PREROUTING -p tcp -m tcp --dport 80 --syn -j CT --notrack
为http服务器启用synproxy:
iptables -A INPUT -p tcp -m tcp --dport 80 -m conntrack --ctstate INVALID,UNTRACKED \ -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
资源: 来自RHEL博客的SYNPROXY目标
使用IP集将所有单独的IP地址限制为出站带宽配额
您可能需要configuration您的服务器,以便每个月只允许每个带宽使用的每个IP 15GiByte,希望能够反映或避免带宽使用攻击,也许您的ISP在您的计量带宽配额。 它可以完成如下:
首先为IPv4和IPv6创buildIP套件:
ipset create IP_QUOTA_SET_OUT hash:ip timeout 345600 counters ipset create IP_QUOTA_SET_OUT_INET6 hash:ip timeout 345600 counters family inet6
现在添加你的iptables规则。 第一行会将IP添加到集合中,如果它不在那里的话。 The second line will not match if the bytes transferred for the IP in the set is greater than the amount specified. Then the same is done alike for IPv6.
iptables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT dst -j SET --add-set IP_QUOTA_SET_OUT dst --timeout 345600 iptables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT dst --bytes-gt 16106127360 -j DROP ip6tables -I OUTPUT -m set ! --match-set IP_QUOTA_SET_OUT_INET6 src -j SET --add-set IP_QUOTA_SET_OUT_INET6 src --timeout 345600 ip6tables -I OUTPUT -m set --match-set IP_QUOTA_SET_OUT_INET6 src --bytes-gt 16106127360 -j DROP
This will prevent attacks such as a user requesting a large file from your webserver for a long period of time, or from any service for that matter. The same can be done for the INPUT chain.
#!/bin/bash # The following iptables/ip6tables configurations have # been kindly shared with us from ArckWiki. There are # a few additions apart from what has been defined. # #=================Flush current definitions============== iptables -F ip6tables -F iptables -X ip6tables -X # #=================Chains================================= # #----Define chains for opened ports iptables -N TCP ip6tables -N TCP iptables -N UDP ip6tables -N UDP # #----Setting up the filter table for NAT # iptables -N fw-interfaces # ip6tables -N fw-interfaces # iptables -N fw-open # ip6tables -N fw-open # #================Default Chain reactions================= # #----Default FORWARD reaction iptables -P FORWARD DROP ip6tables -P FORWARD DROP # #----Default OUTPUT reaction iptables -P OUTPUT ACCEPT ip6tables -P OUTPUT ACCEPT # #----Shellshock iptables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP ip6tables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP # #----Default INPUT reaction iptables -P INPUT DROP ip6tables -P INPUT DROP # #----Drop spoofing packets iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP iptables -A INPUT -i wlan0 -s 127.0.0.0/8 -j DROP iptables -A INPUT -i wlan1 -s 127.0.0.0/8 -j DROP iptables -A INPUT -s 10.0.0.0/8 -j DROP iptables -A INPUT -s 169.254.0.0/16 -j DROP iptables -A INPUT -s 172.16.0.0/12 -j DROP iptables -A INPUT -s 224.0.0.0/4 -j DROP iptables -A INPUT -d 224.0.0.0/4 -j DROP iptables -A INPUT -s 240.0.0.0/5 -j DROP iptables -A INPUT -d 240.0.0.0/5 -j DROP iptables -A INPUT -s 0.0.0.0/8 -j DROP iptables -A INPUT -d 0.0.0.0/8 -j DROP iptables -A INPUT -d 239.255.255.0/24 -j DROP iptables -A INPUT -d 255.255.255.255 -j DROP # #================Ping rate limiting globally============= iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 30/min --limit-burst 8 -j ACCEPT ip6tables -A INPUT -p icmpv6 --icmpv6-type 8 --match limit --limit-burst 8 -j ACCEPT iptables -A INPUT -p icmp --icmp-type 8 -j DROP ip6tables -A INPUT -p icmpv6 --icmpv6-type 8 -j DROP # #----flooding RST packets, smurf attack Rejection iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT ip6tables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT # #----Bogus packet DROP iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP ip6tables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP ip6tables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP # #================RELATED,ESTABLISHED reaction============ iptables -A INPUT --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT ip6tables -A INPUT --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # #================unfetered loopback====================== iptables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -i lo -j ACCEPT # #================INVALID catagory of packets============= iptables -A INPUT -p 41 -j ACCEPT iptables -A INPUT --match conntrack --ctstate INVALID -j DROP ip6tables -A INPUT --match conntrack --ctstate INVALID -j DROP # #================IPv6 reactions and definitions========== ip6tables -A INPUT -s fe80::/10 -p icmpv6 -j ACCEPT ip6tables -t raw -A PREROUTING -p icmpv6 -s fe80::/10 -j ACCEPT ip6tables -t raw -A PREROUTING --match rpfilter -j ACCEPT ip6tables -t raw -A PREROUTING -j DROP # #=======Acceptable INVALIDs and a curteous response====== iptables -A INPUT -p udp --match conntrack --ctstate NEW -j UDP ip6tables -A INPUT -p udp --match conntrack --ctstate NEW -j UDP iptables -A INPUT -p tcp --syn --match conntrack --ctstate NEW -j TCP ip6tables -A INPUT -p tcp --syn --match conntrack --ctstate NEW -j TCP # #================Defining the TCP and UDP chains # ######################################################### # Notes for port open definitions # # It is important to note that this should be config- # # ured differently if you're providing any routing # # activity for any purpose. it is up to you to actively # # define what suites your needs to get the job done. # # In this example, I'm exempting IPv6 from being able # # to interact with SSH protocols for two reasons. The # # first is because it is generally easier and more com- # # for internal networks to be deployed with IPv4. The # # second reason is, IPv6 can be deployed globally. # ######################################################### # #----SSH configured for eth0 iptables -A TCP -i eth0 -p tcp --dport ssh -j ACCEPT #!---Blocking SSH interactions in IPv6 ip6tables -A TCP -p tcp --dport ssh -j DROP #!---Leave commented for end service device # iptables -A TCP -p tcp --dport 80 -j ACCEPT # ip6tables -A TCP -p tcp --dport 80 -j ACCEPT # iptables -A TCP -p tcp --dport 443 -j ACCEPT # ip6tables -A TCP -p tcp --dport 443 -j ACCEPT # #!---Uncomment for remote service to this device # iptables -A TCP -p tcp --dport 22 -j ACCEPT # ip6tables -A TCP -p tcp --dport 22 -j ACCEPT # #!---Uncomment if you're providing routing services # iptables -A UDP -p udp 53 -j ACCEPT # ip6tables -A UDP -p udp 53 -j ACCEPT # #=================Tricking port scanners================= # #----SYN scans iptables -I TCP -p tcp --match recent --update --seconds 60 --name TCP-PORTSCAN -j DROP ip6tables -I TCP -p tcp --match recent --update --seconds 60 --name TCP-PORTSCAN -j DROP iptables -A INPUT -p tcp --match recent --set --name TCP-PORTSCAN -j DROP ip6tables -A INPUT -p tcp --match recent --set --name TCP-PORTSCAN -j DROP # #----UDP scans iptables -I UDP -p udp --match recent --update --seconds 60 --name UDP-PORTSCAN -j DROP ip6tables -I UDP -p udp --match recent --update --seconds 60 --name UDP-PORTSCAN -j DROP iptables -A INPUT -p udp --match recent --set --name UDP-PORTSCAN -j DROP ip6tables -A INPUT -p udp --match recent --set --name UDP-PORTSCAN -j DROP # #----For SMURF attack protection iptables -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP iptables -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP iptables -A INPUT -p icmp -m limit --limit 2/second --limit-burst 2 -j ACCEPT ip6tables -A INPUT -p icmpv6 -m limit --limit 2/second --limit-burst 2 -j ACCEPT # #----Ending all other undefined connections iptables -A INPUT -j DROP ip6tables -A INPUT -j DROP # #=======Defining the IN_SSH chain for bruteforce of SSH== # #!---I've elected to keep IPv6 out of this realm for #!---ease of use iptables -N IN_SSH iptables -A INPUT -p tcp --dport ssh --match conntrack --ctstate NEW -j IN_SSH iptables -A IN_SSH --match recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP iptables -A IN_SSH --match recent --name sshbf --rttl --rcheck --hitcount 4 --seconds 1800 -j DROP iptables -A IN_SSH --match recent --name sshbf --set -j ACCEPT iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH # #==================Setting up a NAT gateway============== # ######################################################### # # # I commented this half out because it's not something # # that will apply to all setups. Make note of all par- # # tinate interfaces and what exactly is going on. # # # ######################################################### # #----Setting up the FORWARD chain # iptables -A FORWARD --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # ip6tables -A FORWARD --match conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # # #----Defining the fw-interfaces/open chains for FORWARD # iptables -A FORWARD -j fw-interfaces # ip6tables -A FORWARD -j fw-interfaces # iptables -A FORWARD -j fw-open # ip6tables -A FORWARD -j fw-open # iptables -A FORWARD -j DROP # Should be REJECT. But, fuck them # ip6tables -A FORWARD -j DROP # iptables -P FORWARD DROP # ip6tables -P FORWARD DROP # # #----Setting up the nat table # iptables -A fw-interfaces -i ### -j ACCEPT # ip6tables -A fw-interfaces -i ### -j ACCEPT # iptables -t nat -A POSTROUTING -s wxyz/S -o ppp0 -j MASQUERADE # ip6tables -t nat -A POSTROUTING -s fe::/10 -o ppp0 -j MASQUERADE #----The above lines should be repeated specifically for EACH interface # #----Setting up the PREROUTING chain # ####################################################### # # # The PREROUTING chain will redirect either port # # targets to be redirected. This can also redirect # # traffic inbound to your network from the gateway # # to this machine. This can be useful if you're using # # a honeypot or have any service within your network # # that you want to be pointed to a specific device. # # # ####################################################### # #----SSH honeypot server # iptables -A fw-open -d HONEYPOT_IP -p tcp --dport 22 -j ACCEPT # ip6tables -A fw-open -d HONEYPOT_IP -p tcp --dport 22 -j ACCEPT #----With intuition, you can configure the above to also direct specific #----requests to other devices providing those services. The bellow will #----be for a squid server # iptables -A fw-open -d SQUID_IP -p tcp --dport 80 -j ACCEPT # ip6tables -A fw-open -d SQUID_IP -p tcp --dport 80 -j ACCEPT # iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to SQUID_IP # ip6tables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to SQUID_IP # #===============Declare configurations================= iptables -nvL ip6tables -nvL