iptables(防火墙)与netfilter
=================================================
推荐博客:
http://www.360doc.com/content/11/0506/09/706976_114731108.shtml#
http://drops.wooyun.org/tips/1424
netfilter/iptables 简介:
(1)IP数据包过滤系统由 netfilter 和 iptables 两个组件构成。
(2)netfilter是集成在内核中的一部分,其作用是定义、保存相应的规则,
(3)iptables是一种工具,用来修改信息的过滤规则及其他配置,而这些规则会保存在内核空间之中。
(4)netfilter是Linux核心中的一个通用架构,其提供了一系列的表(tables)每个表由若干个链(chains)组成,而每条链可以由一条或若干条规则(rules)组成。
防火墙工作流程:
报文流向:
(1)流入本机:PREROUTING --> INPUT ==> 用户空间进程。
(2)流出本机:用户空间进程==> OUTPUT --> POSTROUTING
(3)转发:PREROUTING --> FORWARD --> POSTROUTING
注释:==> 进入用户空间, --> 进入系统空间。
四表(同一链上的不同的表的规则优先级 高-->低):
(1):raw:关闭在nat表启用的连接追踪机制。
表与链关系:PREROUTING -> OUTPUT
(2):mangle:拆解报文,按需修改。
表与链关系:PREROUTING -> INPUT -> FORWARD -> OUTPUT -> POSTROUTING
(3):nat:network address translation (ip层地址,传输层地址)。
表与链关系:PREROUTING -> INPUT -> OUTPUT -> POSTROUTING
(4):filter:过滤,防火墙。
表与链关系:INPUT -> FORWARD -> OUTPUT
五链(netfilter):五个参考点实现报文管理功能。
(1):PREROUTING: 数据包进入路由表之前
(2):INPUT: 通过路由表后目的地为本机
(3):FORWARD: 通过路由表后,目的地不为本机
(4):OUTPUT: 由本机产生,向外转发
(5):POSTROUTIONG:发送到网卡接口之前
=================================================
iptables 使用:
服务应用:
CentOS 7
~]# systemctl stop firewalld.service
~]# systemctl disable firewalld.service
CentOS 6
~]# service iptables stop
~]# chkconfig iptables off
...........................................................................................................................................................................
(1)命令
格式:iptables [-t table] SUBCOMMAND chain [matches...] [target]
iptables [-t 表名] 命令选项 [链名] [条件匹配] [-j 目标动作或跳转]
...........................................................................................................................................................................
-t table: raw, mangle, nat, [filter]
~]# iptables -t raw -nvL
~]# iptables -t mangle -nvL
~]# iptables -t nat -nvL
~]# iptables -nvL
...........................................................................................................................................................................
(2)SUBCOMMAND:
(2.1) 链管理:
-N: new:新增一条自定义链。
~]# iptables -N test
-X:delete:删除自定义的空链。
~]# iptables -X mytest
-P:policy:设置链的默认策略。
ACCEPT:接受
DROP:丢弃
REJECT:拒绝:互联网访问时最好不要使用REJECT。
~]# iptables -t filter -P FORWARD DROP
~]# iptables -t filter -P INPUT DROP
~]# iptables -t filter -P OUTPUT DROP
备注:设置 filter 规则控制时要先将 FORWARD,INPUT,OUTPUT 设为 DROP 或者 REJECT
-E:rename:重命名自定义的未被引用(引用计数为0)的链。
~]# iptables -E test mytest
(2.2) 规则管理:
-A:append:插入到末尾(最后一个)。
-I:insert:插入到开始(第一个)。
-D:delete:删除。
1:rule specification
2:rule number
~]# iptables -D OUTPUT 1
-R:replace:替换。
-F:flush:清洗,清空。
-Z:zero:清 0。
iptables的每条规则都有两个计数器。
1:由本规则匹配到的所有的packets。
2:由本规则匹配到的所有的bytes。
S:selected,以 iptables-save 命令的格式显示链上的规则。
(2.3)查看:
-L: list,列出规则
-n:numeric,以数字格式显示地址和端口;
-v:verbose,详细信息;-vv, -vvv
-x:exactly,显示计数器的精确值而非单位换算后的结果
--line-numbers:显示链上的规则的编号
~]# iptables -nvL --line-numbers
组合:-nvL
~]# iptables -nvL
...........................................................................................................................................................................
(3)matches 匹配条件:
1:基本匹配:netfilter自带的匹配机制
[!] -s, --source address[/mask][,...]:原地址匹配
~]# iptables -A INPUT -s 172.18.0.0/16 -j ACCEPT
~]# iptables -A OUTPUT -s 172.18.0.0/16 -j ACCEPT
~]# iptables -A FORWARD -s 172.18.0.0/16 -j ACCEPT
[!] -d, --destination address[/mask][,...]:目标地址匹配
~]# iptables -A INPUT -s 172.18.21.72 -d 172.18.21.62 -j ACCEPT
~]# iptables -A OUTPUT -s 172.18.21.62 -d 172.18.21.72 -j ACCEPT
[!] -i, --in-interface name:限制报文流入的接口,只能用于PREROUTING,INPUT及FORWARD。
[!] -o, --out-interface name:限制报文流出的接口,只能用于OUTPUT,FORWARD及POSTROUTING。
[!] -p {tcp|udp|icmp}:限制协议
~]# iptables -I INPUT -s 172.18.21.72 -d 172.18.21.62 -p tcp -j ACCEPT
~]# iptables -I OUTPUT -s 172.18.21.62 -d 172.18.21.72 -p tcp -j ACCEPT
2:扩展匹配:经由扩展模块引入的匹配机制,-m matchname
注释:
隐式扩展:可以不用使用-m选项专门加载相应模块;前提是要使用-p选项可匹配何种协议。
显式扩展:必须由-m选项专门加载相应模块。
(1):隐式扩展:
[!] -p, --protocol PROTOCOL PROTOCOL:
协议:tcp, udp, icmp, icmpv6, esp, ah, sctp, mh or "all"
tcp: 隐含指明了“-m tcp”,有专用选项:
[!] --source-port,--sport port[:port]:匹配报文中的tcp首部的源端口;可以是端口范围。
[!] --destination-port,--dport port[:port]:匹配报文中的tcp首部的目标端口;可以是端口范围。
~]# iptables -A INPUT -s 0/0 -d 172.18.21.62 -p tcp --dport 22 -j ACCEPT
~]# iptables -A OUTPUT -s 172.18.21.62 -d 0/0 -p tcp --sport 22 -j ACCEPT
注释:放行ssh连接。
~]# iptables -A INPUT -s 0/0 -d 172.18.21.62 -p tcp --dport 80 -j ACCEPT
~]# iptables -A OUTPUT -s 172.18.21.62 -d 0/0 -p tcp --sport 80 -j ACCEPT
注释:开放 80 端口
[!] --tcp-flags mask comp:检查报文中mask指明的tcp标志位,而要这些标志位comp中必须为1;
--tcp-flags syn,fin,ack,rst syn
--tcp-flags syn,fin,ack,rst ack,fin
[!] --syn:
--syn相当于“--tcp-flags syn,fin,ack,rst syn”;tcp三次握手的第一次;
udp:隐含指明了“-m udp”,有专用选项:
[!] --source-port,--sport port[:port]:匹配报文中的udp首部的源端口;可以是端口范围;
[!] --destination-port,--dport port[:port]:匹配报文中的udp首部的目标端口;可以是端口范围;
icmp:隐含指明了“-m icmp”,有专用选项:
[!] --icmp-type {type[/code]|typename}
type/code:
0/0:echo reply:请求
8/0:echo request :响应
~]# iptables -A OUTPUT -s 172.18.21.62 -d 0/0 -p icmp --icmp-type 8 -j ACCEPT
~]# iptables -A INPUT -s 0/0 -d 172.18.21.62 -p icmp --icmp-type 0 -j ACCEPT
~]# iptables -A INPUT -d 172.18.21.62 -p icmp --icmp-type 8 -j ACCEPT
~]# iptables -A OUTPUT -s 172.18.21.62 -p icmp --icmp-type 0 -j ACCEPT
注释:icmp type:http://baike.baidu.com/link?url=rph8HhXWXtekVwXLMz2FcUHaPru6DgG7-fDXFJOUt4qGann-4pwVaCTnF0JiGNiCzeiOg51fQzhWY8XEP_tyE_#7
(2):显式扩展:
(1):multiport:多端口匹配:以离散方式定义多端口匹配,最多可以指定15个端口;
[!] --source-ports,--sports port[,port|,port:port]...
[!] --destination-ports,--dports port[,port|,port:port]...
[!] --ports port[,port|,port:port]...
~]# iptables -I INPUT -s 0/0 -d 172.18.21.62 -p tcp -m multiport --dports 22,80 -j ACCEPT
~]# iptables -I OUTPUT -d 0/0 -s 172.18.21.62 -p tcp -m multiport --sports 22,80 -j ACCEPT
(2):iprange:指明一段连续的ip地址范围做为源地址或目标地址匹配;
[!] --src-range from[-to]:源地址范围
[!] --dst-range from[-to]:目标地址范围
~]# iptables -A INPUT -d 172.18.21.62 -p tcp --dport 23 -m iprange --src-range 172.18.21.1-172.18.21.100 -j ACCEPT
~]# iptables -A OUTPUT -s 172.18.21.62 -p tcp --sport 23 -m iprange --dst-range 172.18.21.1-172.18.21.100
(3):string:对报文中的应用层数据做字符串匹配检测;
--algo {bm|kmp}:(bm = Boyer-Moore, kmp = Knuth-Pratt-Morris) 算法
[!] --string pattern:给定要检查的字符串模式;
[!] --hex-string pattern:给定要检查的字符串模式;
~]# iptables -I OUTPUT -s 172.18.100.6 -d 0/0 -p tcp --sport 80 -m string --algo bm --string "old" -j REJECT
~]# iptables -I OUTPUT -s 172.18.21.62 -d 0/0 -p tcp --sport 80 -m string --algo bm --string "old" -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...]:匹配一个周中的哪些天。
~]# iptables -R INPUT 4 -d 172.18.100.6 -p tcp --dport 23 -m iprange --src-range 172.18.100.1-172.18.100.100 -m time --timestart 09:00:00 --timestop 16:00:00 --weekdays 1,2,3,4,5 -j ACCEPT
~]# iptables -I INPUT -d 172.18.21.62 -p tcp --dport 23 -m iprange --src-range 172.18.21.1-172.18.21.100 -m time --timestart 09:00:00 --timestop 18:00:00 -j ACCEPT
(5):connlimit:根据每客户端主机做并发连接数限制,即每客户端最多可同时发起的连接数量;
--connlimit-upto n:连接数量小于等于n则匹配;
--connlimit-above n:连接数量大于n则匹配;
~]# iptables -A INPUT -s 0/0 -d 172.18.100.6 -p tcp --dport 23 -m connlimit --connlimit-upto 2 -j ACCEPT
~]# iptables -A INPUT -s 0/0 -d 172.18.21.62 -p tcp --dport 23 -m connlimit --connlimit-upto 2 -j ACCEPT
~]# iptables -A INPUT -d 172.18.21.62 -p tcp --dport 23 -m connlimit ! --connlimit-above 2 -j ACCEPT
(6):limit:基于令牌桶算法对报文的速率做匹配;
--limit rate[/second|/minute|/hour|/day]
--limit-burst number
~]# iptables -A INPUT -d 172.18.21.62 -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 3 -j ACCEPT
~]# iptables -A OUTPUT -s 172.18.21.62 -p icmp --icmp-type 0 -j ACCEPT
(7):state:是conntrack的子集,用于对报文的状态做连接追踪
[!] --state state
INVALID:无法识别的连接。
ESTABLISHED:连接追踪模板当中存在记录的连接。
NEW:连接追踪模板当中不存的连接请求。
RELATED:相关联的连接。
UNTRACKED:未追踪的连接。
1:已经追踪到的并记录下来的连接:cat /proc/net/nf_conntrack
2:连接追踪功能所能够记录的最大连接数量(可调整): /proc/sys/net/nf_conntrack_max
~]# sysctl -w net.nf_conntrack_max=300000 #第一种方式
net.nf_conntrack_max = 300000
~]# echo 200000 > /proc/sys/net/nf_conntrack_max #第二种方式
~]# cat /proc/sys/net/nf_conntrack_max
200000
conntrack所能够追踪的连接数量的最大值取决于/proc/sys/net/nf_conntrack_max的设定;已经追踪到的并记录下来的连接位于/proc/net/nf_conntrack文件中,超时的连接将会被删除;当模板满载时,后续的新连接有可能会超时;解决办法:
(1) 加大nf_conntrack_max的值;
(2) 降低nf_conntrack条目的超时时长;
不同协议的连接追踪时长:/proc/sys/net/netfilter/
示例1:
~]# iptables -A INPUT -s 172.18.0.0/16 -d 172.18.21.62 -p tcp -m multiport --dports 22,23,80 -m state --state NEW,ESTABLISHED -j ACCEPT
~]# iptables -A OUTPUT -d 172.18.0.0/16 -s 172.18.21.62 -p tcp -m multiport --sports 22,23,80 -m state --state ESTABLISHED -j ACCEPT
~]# iptables -A INPUT -d 172.18.21.62 -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED -j ACCEPT
~]# iptables -A OUTPUT -s 172.18.21.62 -p icmp --icmp-type 0 -m state --state ESTABLISHED -j ACCEPT
示例2:
~]# iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
~]# iptables -A INPUT -d 172.18.21.62 -p tcp -m multiport --dports 22,23,80 -m state --state NEW -j ACCEPT
~]# iptables -A INPUT -d 172.18.21.62 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
~]# iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
示例3:
~]# modinfo nf_conntrack_ftp
~]# modprobe nf_conntrack_ftp
~]# lsmod | grep ftp
nf_conntrack_ftp 11953 0
nf_conntrack 79206 7 nf_conntrack_ftp,xt_connlimit,iptable_nat,nf_nat,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state
~]# service vsftpd restart
~]# iptables -A INPUT -d 172.18.21.62 -p tcp --dport 21 -m state --state NEW -j ACCEPT
~]# iptables -I INPUT -d 172.18.21.62 -m state --state ESTABLISHED -j ACCEPT
...........................................................................................................................................................................
(4):保存与启动规则
1:保存:
CentOS 6:
~]# service iptables save
~]# iptables-save > /etc/sysconfig/iptables
~]# iptables-save > /PATH/TO/SOME_RULE_FILE
CentOS 7:
~]# iptables -S > /PATH/TO/SOME_RULE_FILE
~]# iptables-save > /PATH/TO/SOME_RULE_FILE
2:启动:
手动:
~]# iptables-restore < /PATH/FROM/SOME_RULE_FILE
CentOS 6:service iptables restart
备注:自动从 /etc/sysconfig/iptables 文件中重载规则。
自动:
(1):/etc/rc.d/rc.local
~]# vi /etc/rc.d/rc.local
iptables-restore < /PATH/FROM/SOME_RULE_FILE
(2):/usr/bin/iptables.sh
~]# vi /usr/bin/iptables.sh
iptables-restore < /PATH/FROM/SOME_RULE_FILE
...........................................................................................................................................................................
(4)处理动作:
-j targetname [per-target-options]
1:ACCEPT, DROP, REJECT
2:RETURN:返回调用的链
示例:
~]# iptables -N web
~]# iptables -A web -s 10.0.1.0/24 -p tcp --dport 80 -j ACCEPT
~]# iptables -I web 1 -m string --alog kmp --string "old" -j REJECT
~]# iptables -I web 2 -p tcp -m state --state ESTABLISHED -j ACCEPT
~]# iptables -A FORWARD -p tcp -j web
~]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 22 -m state --state NEW -J ACCEPT
~]# iptables -A web -j RETURN
注释:返回调用者(默认隐含)。
3:REDIRECT:端口重定向,端口映射:仅使用在 PREROUTING 和 OUTPUT 链。
--to-ports port[-port]
示例:
~]# 修改监听端口为 8080 。
~]# iptables -t nat -A PREROUTING -d 172.18.21.72 -p tcp --dport 80 -j REDIRECT --to-ports 8080
访问:
http://172.18.21.72:8080
http://172.18.21.72
4:LOG:日志
--log-level level:等级(默认为4):emerg, alert, crit, error, warning, notice, info or debug.
--log-prefix prefix:指定前缀
示例:
~]# iptables -I FORWARD 2 -s 10.0.1.0/24 -p tcp -m multiport --dports 80,21,22,23 -m state --state NEW -j LOG --log-prefix "(new connctions)"
日志记录位置:
~]# cat /var/log/messages
5:MARK:防火墙标记
6:SNAT:源地址转换:修改IP报文中的源IP地址:POSTROUTING 和 INPUT (CentOS 7 支持) 链
--to-source [ipaddr[-ipaddr]]
示例:
~]# iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j SNAT --to-source 172.18.21.71
~]# iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j SNAT --to-source 172.18.21.70-172.18.21.100
备注:让本地网络中的主机可使用统一地址与外部主机通信,从而实现地址伪装
请求:由内网主机发起,修改源IP,如果修改则由管理员定义
响应:修改目标IP,由nat自动根据会话表中追踪机制实现相应修改
7:DNAT:目标地址转换:修改IP报文中的目标IP地址:RPEROUTING 和 OUTPUT (CentOS 7)链
--to-destination [ipaddr[-ipaddr]][:port[-port]]
示例1:
~]# iptables -t nat -A PREROUTING -d 172.18.21.71 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.2
~]# curl http://172.18.21.71/
示例2:
~]# 修改 10.0.1.2 监听地址为 Listen 8090
~]# iptables -t nat -A PREROUTING -d 172.18.21.71 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.2:8090
~]# curl http://172.18.21.71/
备注:让本地网络中服务器使用统一的地址向外提供服务(发布服务),但隐藏了自己的真实地址。
请求:由外网主机发起,修改其目标地址,由管理员定义。
响应:修改源地址,但由nat自动根据会话表中的追踪机制实现对应修改。
8:MASQERADE:地址伪装,地址动态伪装
示例:
~]# iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j MASQUERADE
9:recent:
...........................................................................................................................................................................
完整的示例:
设置网卡地址:nmtui
基本设置:
关闭 CentOS6 的iptables 和 CentOS7的 firewalld。
清空三台主机的防火墙规则:
~]# iptables -F
主机:172.18.21.71
查看是否打开网卡转发:
~]# cat /proc/sys/net/ipv4/ip_forward
开启网卡转发:
~]# echo 1 > /proc/sys/net/ipv4/ip_forward
备注:地址属于内核不属于网卡。
注释:
1:10.0.1.1未设置网关的时候不能 ping 通172.18.21.71,但是可以ping通10.0.1.1
2:172.18.21.71设置转发后可以 ping 通172.18.21.72,但是得不到 ping 回应。
主机:10.0.1.1
~]# ping 172.18.21.72
主机:172.18.21.72:抓包查看。
~]# tcpdump -i eno16777736 icmp
注释:172.18.21.72主机回应了但是回应到了网关。
添加路由:
主机:172.18.21.72
~]# route add -net 10.0.1.0/24 gw 172.18.21.71
~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.18.0.1 0.0.0.0 UG 100 0 0 eno16777736
10.0.1.0 172.18.21.71 255.255.255.0 UG 0 0 0 eno16777736
172.18.0.0 0.0.0.0 255.255.0.0 U 100 0 0 eno16777736
注释:此时 10.0.1.2主机ping请求172.18.21.72得到回应。
主机:172.18.21.71
~]# iptables -P FORWARD DROP
~]# tcpdump -i eno16777736 -nn icmp -vv
基础写法:
内网 ping 外网
~]# iptables -A FORWARD -s 10.0.1.0/24 -d 0/0 -p icmp --icmp-type 8 -j ACCEPT
~]# iptables -A FORWARD -s 0/0 -d 10.0.1.0/24 -p icmp --icmp-type 0 -j ACCEPT
外网 ping 内网
~]# iptables -A FORWARD -s 10.0.1.0/24 -d 0/0 -p icmp --icmp-type 0 -j ACCEPT
~]# iptables -A FORWARD -s 0/0 -d 10.0.1.0/24 -p icmp --icmp-type 8 -j ACCEPT
合并写法:
~]# iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
内部 ping 外部
~]# iptables -A FORWARD -s 10.0.1.0/24 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
外网 ping 内网
~]# iptables -A FORWARD -s 0/0 -d 10.0.1.0/24 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
同时允许内网和外网互 ping
~]# iptables -A FORWARD -p icmp -m state --state NEW -j ACCEPT
~]# lsmod | grep ftp
内网访问外网服务 80和21
~]# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
~]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT
~]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 21 -m state --state NEW -j ACCEPT
~]# modprobe nf_conntrack_ftp
合并写法:
~]# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
~]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp -m multiport --dports 80,21 -m state --state NEW -j ACCEPT