包过滤型防火墙iptables

1、防火墙

Firewall:防火墙,隔离工具,工作于主机或网络边缘,对于进出本主机或本网络的报文根据事先定义的检查规则作匹配检测,对于能够被规则匹配到的报文作出相应处理的组件。防火墙分为主机防火墙和网络防火墙,从组成结构上分为软件防火墙(软件逻辑)和硬件防火墙(硬件和软件逻辑)。
防火墙框架有:ipfw、ipchains等。

2、iptables(netfilter)

(1)netfilter是防火墙的kernel framework,iptables是编写规则的CLI。
hook function:input、output、forward、prerouting、postrouting。
链(内置):PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。
(2)功能表
filter:过滤作用,防火墙;
nat:network address translation,网络地址转换,用于修改源IP或目标IP,也可以改端口;
mangle:拆解报文,做出修改,并重新封装起来;
raw:关闭nat表上启用的连接追踪机制。
(3)功能所对应的链
raw:PREROUTING, OUTPUT;
mangle:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING;
nat:PREROUTING,[INPUT,]OUTPUT,POSTROUTING;
filter:INPUT,FORWARD,OUTPUT;
(4)报文流向
流入本机:PREROUTING --> INPUT;
由本机流出:OUTPUT --> POSTROUTING;
转发:PREROUTING --> FORWARD --> POSTROUTING;
(5)路由功能发生的时刻:
报文进入本机后,以判断目标主机是哪个;
报文离开本机之前,以判断经由哪个接口送往下一站;

3、iptables规则

组成部分:根据规则匹配条件来尝试匹配报文,一旦匹配成功,就由规则定义的处理动作作出处理;
匹配条件:基本匹配条件和扩展匹配条件;
处理动作:基本处理动作、扩展处理动作和自定义处理机制;
iptables的链:内置链和自定义链
内置链:对应于hook function;
自定义链:用于内置链的扩展和补充,可实现更灵活的规则管理机制;
添加规则时的考量点:
(1) 要实现哪种功能:判断添加到哪个表上;
(2) 报文流经的路径:判断添加到哪个链上;
链:链上的规则次序,即为检查的次序,因此,隐含一定的应用法则:
(1) 同类规则(访问同一应用),匹配范围小的放上面;
(2) 不同类的规则(访问不同应用),匹配到报文频率较大的放在上面;
(3) 将那些可由一条规则描述的多个规则合并起来;
(4) 设置默认策略;

4、iptables命令

iptables [-t table] {-A|-C|-D} chain rule-specification
iptables [-t table] -I chain [rulenum] rule-specification
iptables [-t table] -R chain rulenum rule-specification
iptables [-t table] -D chain rulenum
iptables [-t table] -S [chain [rulenum]]
iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
iptables [-t table] -N chain
iptables [-t table] -X  [chain]
iptables [-t table] -P chain target
iptables [-t table] -E old-chain-name new-chain-name
rule-specification = [matches...]  [target]
match = -m matchname [per-match-options]
target = -j targetname [per-target-options]

规则格式:iptables [-t table] COMMAND chain [-m matchname [per-match-options]] -j targetname [per-target-options]
-t table:raw, mangle, nat, [filter]
COMMAND:
链管理:
-N:new, 自定义一条新的规则链;
-X: delete,删除自定义的规则链;
-P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:
ACCEPT(接受)、DROP(丢弃)、REJECT(拒绝);
-E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除;
规则管理:
-A:append,追加;
-I:insert, 插入,要指明位置,省略时表示第一条;
-D:delete,删除:(1) 指明规则序号;(2) 指明规则本身;
-R:replace,替换指定链上的指定规则;
-F:flush,清空指定的规则链;
-Z:zero,置零;
iptables的每条规则都有两个计数器:
(1) 匹配到的报文的个数;
(2) 匹配到的所有报文的大小之和;
查看:
-L:list, 列出指定鏈上的所有规则;
-n:numberic,以数字格式显示地址和端口号;
-v:verbose,详细信息;-vv, -vvv;
-x:exactly,显示计数器结果的精确值;
–line-numbers:显示规则的序号;
chain:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING;
匹配条件:
基本匹配条件:无需加载任何模块,由iptables/netfilter自行提供;
[!] -s, --source address[/mask][,...]:检查报文中的源IP地址是否符合此处指定的地址或范围;
[!] -d, --destination address[/mask][,...]:检查报文中的目标IP地址是否符合此处指定的地址或范围;
[!] -p, --protocol protocol:protocol: tcp,udp,udplite,icmp,icmpv6,esp,ah,sctp,mh or “all”:{tcp|udp|icmp};
[!] -i, --in-interface name:数据报文流入的接口;只能应用于数据报文流入的环节,只能应用于PREROUTING,INPUT和FORWARD链;
[!] -o, --out-interface name:数据报文流出的接口,只能应用于数据报文流出的环节,只能应用于FORWARD、OUTPUT和POSTROUTING链;
扩展匹配条件: 需要加载扩展模块,方可生效;
隐式扩展:不需要手动加载扩展模块;因为它们是对协议的扩展,所以,但凡使用-p指明了协议,就表示已经指明了要扩展的模块;
tcp:
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围;
[!] --destination-port,--dport port[:port]:匹配报文的目标端口,可以是端口范围;
[!] --tcp-flags mask comp:mask is the flags which we should examine, written as a comma-separated list,例如 SYN,ACK,FIN,RST,comp is a comma-separated list of flags which must be set,例如SYN
--tcp-flags SYN,ACK,FIN,RST SYN表示,要检查的标志位为SYN,ACK,FIN,RST四个,其中SYN必须为1,余下的必须为0;
[!] --syn:用于匹配第一次握手,相当于--tcp-flags SYN,ACK,FIN,RST SYN
udp:
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围;
[!] --destination-port,--dport port[:port]:匹配报文的目标端口;可以是端口范围;
icmp:
[!] --icmp-type {type[/code]|typename}
echo-request:8,echo-reply:0;
显式扩展:必须要手动加载扩展模块,显式地指明使用的扩展模块进行的扩展,语法格式:[-m matchname [per-match-options]]
处理动作:
-j targetname [per-target-options]
ACCEPT、DROP、REJECT、RETURN(返回调用链)、REDIRECT(端口重定向)、LOG(记录日志)、MARK(做防火墙标记)、DNAT(目标地址转换)、SNAT(源地址转换)、MASQUERADE(地址伪装);
防火墙(服务)的启动停止:
CentOS 6:
service iptables {start|stop|restart|status}
start:读取事先保存的规则,并应用到netfilter上;
stop:清空netfilter上的规则,以及还原默认策略等;
status:显示生效的规则;
restart:清空netfilter上的规则,再读取事先保存的规则,并应用到netfilter上;
默认的规则文件:/etc/sysconfig/iptables;
CentOS 7:
systemctl start|stop|restart|status firewalld.service
禁用防火墙:
systemctl disable firewalld.service
systemctl stop firewalld.service
使用帮助:
CentOS 6:man iptables
CentOS 7:man iptables-extensions

5、显式扩展

(1)multiport扩展
以离散方式定义多端口匹配,最多指定15个端口;
[!] --source-ports,--sports port[,port|,port:port]...:指定多个源端口;
[!] --destination-ports,--dports port[,port|,port:port]...:指定多个目标端口;
[!] --ports port[,port|,port:port]...:指明多个端口;
~]# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.67 -p tcp -m multiport --dports 22,80 -j ACCEPT
(2)iprange扩展
指明连续的(但一般不是整个网络)的IP地址范围;
[!] --src-range from[-to]:源IP地址;
[!] --dst-range from[-to]:目标IP地址;
~]# iptables -A INPUT -d 172.16.100.67 -p tcp --dport 80 -m iprange --src-range 172.16.100.5-172.16.100.10 -j DROP
(3)string扩展
对报文中的应用层数据做字符串模式匹配检测;
--algo {bm|kmp}:字符串匹配检测算法,bm:Boyer-Moore,kmp:Knuth-Pratt-Morris;
[!] --string pattern:要检测的字符串模式;
[!] --hex-string pattern:要检测的字符串模式,16进制格式;
~]# iptables -A OUTPUT -s 172.16.100.67 -d 172.16.0.0/16 -p tcp --sport 80 -m string --algo bm --string "gay" -j REJECT
(4)time扩展
根据将报文到达的时间与指定的时间范围进行匹配;
--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
--timestart hh:mm[:ss]
--timestop hh:mm[:ss]
[!] --monthdays day[,day...]
[!] --weekdays day[,day...]
--kerneltz:使用内核上的时区,而非默认的UTC;
~]# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.67 -p tcp --dport 80 -m time --timestart 14:30 --timestop 18:30 --weekdays Sat,Sun --kerneltz -j DROP
(5)connlimit扩展
根据每客户端IP做并发连接数数量匹配;
--connlimit-upto n:连接的数量小于等于n时匹配;
--connlimit-above n:连接的数量大于n时匹配;
~]# iptables -A INPUT -d 172.16.100.67 -p tcp --dport 21 -m connlimit --connlimit-above 2 -j REJECT
(6)limit扩展
基于收发报文的速率做匹配,令牌桶过滤器。
--limit rate[/second|/minute|/hour|/day]
--limit-burst number
~]# iptables -I INPUT -d 172.16.100.67 -p icmp --icmp-type 8 -m limit --limit 3/minute --limit-burst 5 -j ACCEPT
~]# iptables -I INPUT 2 -p icmp -j REJECT
(7)state扩展
根据“连接追踪机制”去检查连接的状态;
conntrack机制:追踪本机上的请求和响应之间的关系。状态有如下几种:
NEW:新发出请求,连接追踪模板中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求;
ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前期间内所进行的通信状态;
RELATED:相关联的连接;如ftp协议中的数据连接与命令连接之间的关系;
INVALID:无效的连接;
UNTRACKED:未进行追踪的连接;
[!] --state state
~]# iptables -A INPUT -d 172.16.100.67 -p tcp -m multiport --dports 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT
~]# iptables -A OUTPUT -s 172.16.100.67 -p tcp -m multiport --sports 22,80 -m state --state ESTABLISHED -j ACCEPT
调整连接追踪功能所能够容纳的最大连接数量:/proc/sys/net/nf_contrack_max;
已经追踪到到的并记录下来的连接:/proc/net/nf_conntrack;
不同的协议的连接追踪时长:/proc/sys/net/netfilter/;
iptables的链接跟踪表最大容量为/proc/sys/net/ipv4/ip_conntrack_max,链接碰到各种状态的超时后就会从表中删除,当模板满载时,后续的连接可能会超时。
解決方法一般有两个:
1)加大nf_conntrack_max 值
vi /etc/sysctl.conf

net.ipv4.nf_conntrack_max = 393216
net.ipv4.netfilter.nf_conntrack_max = 393216

2)降低 nf_conntrack timeout时间
vi /etc/sysctl.conf

net.ipv4.netfilter.nf_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120

iptables -t nat -L -n
如何开放被动模式的ftp服务?
1)装载ftp连接追踪的专用模块:
~]# modproble nf_conntrack_ftp
2)放行命令连接(假设Server地址为172.16.100.67):
~]# iptables -A INPUT -d 172.16.100.67 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
~]# iptables -A OUTPUT -s 172.16.100.67 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
3)放行数据连接(假设Server地址为172.16.100.67):
~]# iptables -A INPUT -d 172.16.100.67 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
~]# iptables -I OUTPUT -s 172.16.100.67 -m state --state ESTABLISHED -j ACCEPT

6、规则优化

服务器端规则设定:任何不允许的访问,应该在请求到达时给予拒绝;
1)可安全放行所有入站的状态为ESTABLISHED状态的连接;
2)可安全放行所有出站的状态为ESTABLISHED状态的连接;
3)谨慎放行入站的新请求;
4)有特殊目的限制访问功能,要于放行规则之前加以拒绝;
如何使用自定义链:
自定义链:需要被调用才能生效,自定义链最后需要定义返回规则,返回规则使用的target叫做RETURN;
规则的有效期限:使用iptables命令定义的规则,手动删除之前,其生效期限为kernel存活期限;
保存规则至指定的文件:
CentOS 6:
~]# service iptables save
将规则保存至/etc/sysconfig/iptables文件中;
~]# iptables-save > /PATH/TO/SOME_RULES_FILE
CentOS 7:
~]# iptables-save > /PATH/TO/SOME_RULES_FILE
重新载入预存规则文件中规则:
~]# iptables-restore < /PATH/FROM/SOME_RULES_FILE
CentOS 6:
~]# service iptables restart
自动生效规则文件中的规则:
1)用脚本保存各iptables命令,让此脚本开机后自动运行。
在/etc/rc.d/rc.local文件中添加脚本路径:/PATH/TO/SOME_SCRIPT_FILE
2)用规则文件保存各规则,开机时自动载入此规则文件中的规则。
在/etc/rc.d/rc.local文件添加:
iptables-restore < /PATH/FROM/IPTABLES_RULES_FILE
CentOS 7:
引入了新的iptables前端管理工具firewalld,其管理工具有:firewalld-cmd,firewalld-config。

7、Target

iptables中的Target可以有以下动作:ACCEPT, DROP, REJECT, RETURN、LOG, SNAT, DNAT, REDIRECT, MASQUERADE;
LOG:--log-level level,--log-prefix prefix
NAT表的target:
SNAT:Source NAT,POSTROUTING,OUTPUT;
让本地网络中的主机通过某一特定地址访问外部网络时;
--to-source [ipaddr[-ipaddr]][:port[-port]]
--random
DNAT:Destination NAT,PREROUTING;
把本地网络中的某一主机上的某服务开放给外部网络中的用户访问时;
--to-destination [ipaddr[-ipaddr]][:port[-port]]
PNAT:Port NAT;
MASQUERADE:
--to-ports port[-port]
--random
SNAT示例:
~]# iptables -t nat -A POSTROUTING -s 192.168.12.0/24 -j SNAT --to-source 172.16.100.67
MASQUERADE示例:
源地址转换:当源地址为动态获取的地址时,MASQUERADE可自行判断要转换为的地址;
~]# iptables -t nat -A POSTROUTING -s 192.168.12.0/24 -j MASQUERADE
DNAT示例:
~]# iptables -t nat -A PREROUTING -d 172.16.100.67 -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77
~]# iptables -t nat -A PREROUTING -d 172.16.100.67 -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77:8080
~]# iptables -t nat -A PREROUTING -d 172.16.100.67 -p tcp --dport 22012 -j DNAT --to-destination 192.168.12.78:22
REDIRECT:端口重定向;

8、recent

利用iptables的recent模块来抵御DOS攻击(SSH 22号端口),建立一个列表,保存有所有访问过指定的服务的客户端IP。

iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "
iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

注意:
1)利用connlimit模块将单IP的并发设置为3,会误杀使用NAT上网的用户,可以根据实际情况增大该值;
2)利用recent和state模块限制单IP在300s内只能与本机建立2个新连接,被限制五分钟后即可恢复访问。
3)第二句是记录访问tcp 22端口的新连接,记录名称为SSH;
–set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目。
4)第三句是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。
–update 是指每次建立连接都更新列表;
–seconds必须与–rcheck或者–update同时使用;
–hitcount必须与–rcheck或者–update同时使用;
5)iptables的记录:/proc/net/xt_recent/SSH;
也可以使用下面的这句记录日志:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"

9、layer7

(1)layer7概述
layer7是一种第三方扩展模块,是iptables实现七层访问过滤所用模块,用来识别应用层协议。

iptables/netfilter
iptables -m state, 
netfilter state

对内核中的netfilter,打补丁layer7,重新编译内核,对iptables打补丁,补上layer7模块,重新iptables。
(2)diff:文本操作工具
diff是Unix系统的一个很重要的工具程序。它用来比较两个文本文件的差异,是代码版本管理的核心工具之一。其用法非常简单:
# diff <变动前的文件> <变动后的文件>
由于历史原因,diff有三种格式:正常格式(normal diff)、上下文格式(context diff)和合并格式(unified diff)。
1)正常格式的diff
例如,对file1(变动前的文件)和file2(变动后的文件)进行比较可使用如下命令:# diff file1 file2
显示结果中,第一行是一个提示,用来说明变动位置。它分成三个部分:前面的数字,表示file1的第n行有变化;中间的"c"表示变动的模式是内容改变(change),其他模式还有"增加"(a,代表addition)和"删除"(d,代表deletion);
2)上下文格式的diff
上个世纪80年代初,加州大学伯克利分校推出BSD版本的Unix时,觉得diff的显示结果太简单,最好加入上下文,便于了解发生的变动。因此,推出了上下文格式的diff。它的使用方法是加入-c选项(即context)。
# diff -c f1 f2
结果分成四个部分。第一部分的两行,显示两个文件的基本情况:文件名和时间信息,"***“表示变动前的文件,”—“表示变动后的文件。第二部分是15个星号,将文件的基本情况与变动内容分割开。第三部分显示变动前的文件,即file1。
另外,文件内容的每一行最前面,还有一个标记位。如果为空,表示该行无变化;如果是感叹号(!),表示该行有改动;如果是减号(-),表示该行被删除;如果是加号(+),表示该行为新增。
第四部分显示变动后的文件,即file2。
3)合并格式的diff
如果两个文件相似度很高,那么上下文格式的diff,将显示大量重复的内容,很浪费空间。1990年,GNU diff率先推出了"合并格式"的diff,将f1和f2的上下文合并在一起显示。它的使用方法是加入u参数(代表unified):# diff -u f1 f2
其结果的第一部分,也是文件的基本信息。”—“表示变动前的文件,”+++“表示变动后的文件。第二部分,变动的位置用两个@作为起首和结束。第三部分是变动的具体内容。除了有变动的那些行以外,也是上下文各显示3行。它将两个文件的上下文,合并显示在一起,所以叫做"合并格式”。每一行最前面的标志位,空表示无变动,减号表示第一个文件删除的行,加号表示第二个文件新增的行。
(3)patch:打补丁工具
尽管并没有指定patch和diff的关系,但通常patch都使用diff的结果来完成打补丁的工作,这和patch本身支持多种diff输出文件格式有很大关系。patch通过读入patch命令文件(可以从标准输入),对目标文件进行修改。通常先用diff命令比较新老版本,patch命令文件则采用diff的输出文件,从而保持原版本与新版本一致。
patch的标准格式为:patch [options] [originalfile] [patchfile]
如果patchfile为空则从标准输入读取patchfile内容;如果originalfile也为空,则从patchfile(肯定来自标准输入)中读取需要打补丁的文件名。因此,如果需要修改的是目录,一般都必须在patchfile中记录目录下的各个文件名。绝大多数情况下,patch都用以下这种简单的方式使用:
patch命令可以忽略文件中的冗余信息,从中取出diff的格式以及所需要patch的文件名,文件名按照diff参数中的"源文件"、"目标文件"以及冗余信息中的"Index:“行中所指定的文件的顺序来决定。
-p参数决定了是否使用读出的源文件名的前缀目录信息,不提供-p参数,则忽略所有目录信息,-p0(或者-p 0)表示使用全部的路径信息,-p1将忽略第一个”/"以前的目录,依此类推。如/usr/src/linux-2.4.15/Makefile这样的文件名,在提供-p3参数时将使用linux-2.4.15/Makefile作为所要patch的文件。
patch,-p,-R
(4)mockbuild
(5)使用layer7模块操作步骤
1)获取并编译内核

# useradd mockbuild
# rpm -ivh kernel-2.6.32-431.5.1.x86_64.el6.src.rpm
# cd rpmbuild/SOURCES
# tar linux-2.6.32-*.tar.gz -C /usr/src
# cd /usr/src
# ln -sv 

2)给内核打补丁

# tar xf netfilter-layer7-v2.23.tar.bz2
# cd /usr/src/linux
# patch -p1 < /root/netfilter-layer7-v2.23/kernel-2.6.32-layer7-2.23.patch
# cp /boot/config-*  .config
# make menuconfig

3)按如下步骤启用layer7模块
Networking support → Networking Options →Network packet filtering framework → Core Netfilter Configuration
“layer7” match support
4)编译并安装内核

# make
# make modules_install
# make install

5)重启系统,启用新内核
6)编译iptables

# tar xf iptables-1.4.20.tar.gz
# cp /root/netfilter-layer7-v2.23/iptables-1.4.3forward-for-kernel-2.6.20forward/* /root/iptables-1.4.20/extensions/
# cp /etc/rc.d/init.d/iptales /root
# cp /etc/sysconfig/iptables-config /root
# rpm -e iptables iptables-ipv6 --nodeps
# ./configure  --prefix=/usr  --with-ksource=/usr/src/linux
# make && make install
# cp /root/iptables /etc/rc.d/init.d
# cp /root/iptables-config /etc/sysconfig

7)为layer7模块提供其所识别的协议的特征码

# tar zxvf l7-protocols-2009-05-28.tar.gz
# cd l7-protocols-2009-05-28
# make install	

8)使用layer7模块
ACCT的功能已经可以在内核参数中按需启用或禁用。此参数需要装载nf_conntrack模块后方能生效。
net.netfilter.nf_conntrack_acct = 1
l7-filter uses the standard iptables extension syntax

# iptables [specify table & chain] -m layer7 --l7proto [protocol name] -j [action] 
# iptables -A FORWARD -m layer7 --l7proto qq -j REJECT

9)编译内核

make menuconfig
make -j #
make modules_install
make install

清理内核源码树。
xt_layer7.ko依赖于nf_conntrack.ko模块。

你可能感兴趣的:(Linux,Linux,Architecture)