-
查看防火墙是否启动
systemctl status firewalld.service
-
启动/停止防火墙服务
systemctl start/stop firewalld.service
-
查看iptables里的表项:
iptables -vnL
-
清空iptabls里的规则:
iptables -F
iptables:包过滤型的防火墙
- Firewall:防火墙,隔离工具,工作主机或网络边缘,对于进出本主机或网络的的报文,根据事先定义的检查规则做匹配检测,做出响应的处理
- Firewall分类1:
- 主机防火墙:设置进入本机进程的规则
- 网络防火墙:设置转发的规则
- Firewall分类2:
- 软件防火墙:一般的pc,安装上linux系统,在软件上设置规则
- 硬件防火墙:专门的cpu,在cpu指令级别设置规则,效率比软件防火墙高,但是价格很贵,cisco有专门的硬件防火墙。
linux历代软件防火墙产品:
- ipfw(firewall framework)
- ipchains(firewall framework)
- iptables(netfilter)
- netfilter:kernel
- iptables:rules until
- iptables hook function
- input
- output
- forward
- prerouting
- postrouting
- 链(内置)
- PREROUTING
- INPUT
- FORWARD
- OUTPUT
- POSTROUTING
功能:
- filter:过滤,防火墙
- nat:network address translation:用于修改源IP或目的IP,也可以修改端口
- mangle:拆解报文,做出修改,并重新封装起来
- raw:关闭net表的连接追踪机制
功能<--链:
- raw:PREROUTING,OUTPUT
- mangle:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
- nat:PREROUTING,[INPUT],OUTPUT,POSTROUTING
- filter:INPUT,FORWARD,OUTPUT
报文流向:
- 流入本机:PREROUTING->INPUT
- 由本机流出:OUTPUT->POSTROUTING
- 转发:PREROUTING->FORWARD->POSTROUTING
路由功能发生的时刻:
- 报文进入本机后:判断目标主机是什么
- 报文离开本机之前:判断经由哪个接口,送到下一跳
优先顺序:
iptables/netfilter概要
1,规则
- 组成部分:根据规则匹配来尝试匹配报文,一旦匹配成功,就由规则定义的处理动作作出处理。
- 匹配条件:
- 基本匹配条件:内核自带的
- 扩展匹配条件:由扩展模块提供(使用
rpm -ql iptables
查看)
- 处理动作:
- 基本动作处理:内核自带的
- 扩展动作处理:由扩展模块提供(使用
rpm -ql iptables
查看) - 自定义处理:自定义链
- 匹配条件:
- iptables的链:内置链和自定义链
- 内置链:对应于hook function
- 自定义链:用于内置链的扩展和补充,可实现更灵活的管理机制
2,添加规则是的注意
- 根据要实现的功能,判断把规则添加到相应的表上
- 根据报文流经的方向,判断添加到哪个链上
3,规则书写的次序
- 同类规则,匹配范围越精确的,放到上面书写
- 不同类规则(比如http和ssh),匹配到报文频率大的放在上面
- 尽量将那些可由一条规则描述的多个规则合并起来
- 设置默认策略(是白名单还是黑名单)
4,查看都有哪些扩展模块
使用rpm -ql iptables
查看都有哪些扩展模块。
小写字母是匹配条件(match)要使用的扩展模块;大写字母是处理动作(target)要使用的扩展模块
- libip6t_:对于IPv6
- libipt_:对于IPv4
- libxt_:对于IPv4
/usr/lib64/xtables/libip6t_DNAT.so
/usr/lib64/xtables/libip6t_DNPT.so
/usr/lib64/xtables/libip6t_HL.so
/usr/lib64/xtables/libip6t_ah.so
/usr/lib64/xtables/libip6t_dst.so
/usr/lib64/xtables/libipt_DNAT.so
/usr/lib64/xtables/libipt_ECN.so
/usr/lib64/xtables/libipt_ah.so
/usr/lib64/xtables/libipt_icmp.so
/usr/lib64/xtables/libxt_AUDIT.so
/usr/lib64/xtables/libxt_CHECKSUM.so
/usr/lib64/xtables/libxt_addrtype.so
/usr/lib64/xtables/libxt_bpf.so
iptables命令格式
格式:iptables [-t table] COMMAND chain [-m matchname [per-match-options]] -j targetname [per-target-options]
-
-t table:raw,mangle,nat,[fliter]
-
COMMAND:
-
链管理:
-N:new,自定义一条规则链
-X:delete,删除自定义的规则链;只能删除自定义链,且引用是0,且是空的链(链上没有规则)。
-P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:
- ACCEPT:允许(白名单策略),内嵌的策略
- DROP:丢弃(黑名单策略),内嵌的策略。推荐使用此策略。不给对方响应,所以对方不知道你是怎么处理的。
- REJECT:不允许,扩展的策略。会给对方响应。对方会马上知道,你拒绝了。
-E:重命名自定义链;引用计数不为0的自定义链不能被重命名,也不能被删除
-
规则管理:
-A:append,追加
-I:insert,插入,要指明位置,省略时表示插入到首行之前
-D:delete,删除
- 指明规则序号
- 指明规则本身
-R:replace,替换指定链上的指定规则
-F:flush,清空指定的规则链
-Z:zero,置零。iptables的每条规则都有2个计数器:
- 匹配到的报文的个数
- 匹配到的报文的大小之和
-
查看:
-L:list,列出指定链上的所有规则
-n:numberic,以数字格式显示地址和端口号
-v:verbose,显示详细信息。-vv:更详细;-vvv:更更详细。
-x:exactly,显示计数器接口的精确值
--line-numbers:显示规则的序号
-
-
chain:
PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
-
matchname (匹配条件)
查看表和链
1,查看各个表
# iptables -t raw -L
# iptables -t mangle -L
# iptables -t nat -L
# iptables -L
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 213 16360 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
2 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
- Chain:链名
- policy:策略
- num:行号
- packets:报文个数的计时器
- bytes:报文的大小之和的计时器
- target:处理内容
- prot:协议
- opt:选项
- in:入接口
- out:出接口
- source:源网络地址
- destination:目的网络地址
2, 查看某个表的某个链
# iptables -t mangle -vnxL INPUT --line-numbers
Chain INPUT (policy ACCEPT 366 packets, 30889 bytes)
num pkts bytes target prot opt in out source destination
1 366 30889 INPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0
修改链
1,新建/删除自定义链
# iptables -N in_web
# iptables -vnL
Chain INPUT (policy ACCEPT 33 packets, 2408 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 18 packets, 1920 bytes)
pkts bytes target prot opt in out source destination
Chain in_web (0 references)
pkts bytes target prot opt in out source destination
# iptables -X in_web
# iptables -vnL
Chain INPUT (policy ACCEPT 6 packets, 432 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 4 packets, 480 bytes)
pkts bytes target prot opt in out source destination
2,重命名自定义链
# iptables -N old
# iptables -E old new
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain new (0 references)
target prot opt source destination
3,修改处理动作(策略)。
不要上来就把INPUT链上的所有协议都改成DROP,DROP后,自己的不能远程连接主机了。至少要保留ssh协议。
# iptables -t mangle -L FORWARD
Chain FORWARD (policy ACCEPT)
target prot opt source destination
# iptables -t mangle -P FORWARD DROP
# iptables -t mangle -L FORWARD
Chain FORWARD (policy DROP)
target prot opt source destination
更新规则
1,添加/删除规则
# iptables -t filter -A INPUT -s 192.168.56.0/24 -d 192.168.1.103 -p tcp
# iptables -vnL
Chain INPUT (policy ACCEPT 8 packets, 576 bytes)
pkts bytes target prot opt in out source destination
0 0 tcp -- * * 192.168.56.0/24 192.168.1.103
# iptables -t filter -D INPUT -s 192.168.56.0/24 -d 192.168.1.103 -p tcp
# iptables -vnL
Chain INPUT (policy ACCEPT 8 packets, 576 bytes)
pkts bytes target prot opt in out source destination
# iptables -t filter -A INPUT -s 192.168.56.0/24 -d 192.168.56.103 -p tcp
# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 20 packets, 1440 bytes)
pkts bytes target prot opt in out source destination
20 1440 tcp -- * * 192.168.56.0/24 192.168.56.103
# iptables -t filter -D INPUT 1
# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 6 packets, 432 bytes)
pkts bytes target prot opt in out source destination
添加放行tcp协议的规则后(ssh使用tcp),就可以把规则修改成DROP了。但是就ping不通192.168.56.103
# iptables -t filter -A INPUT -s 192.168.56.0/24 -d 192.168.56.103 -p tcp -j ACCEPT
# iptables -t filter -P INPUT DROP
# iptables -vnL INPUT
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
88 6336 ACCEPT tcp -- * * 192.168.56.0/24 192.168.56.103
由于ping使用的是icmp协议,所有要添加可以进来和可以出去的icmp协议的规则
# iptables -t filter -A INPUT -s 192.168.56.0/24 -d 192.168.56.103 -p icmp -j ACCEPT
# iptables -t filter -A OUTPUT -d 192.168.56.0/24 -s 192.168.56.103 -p icmp -j ACCEPT
# iptables -vnL
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
378 30432 ACCEPT tcp -- * * 192.168.56.0/24 192.168.56.103
4 240 ACCEPT icmp -- * * 192.168.56.0/24 192.168.56.103
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy DROP 18 packets, 2640 bytes)
pkts bytes target prot opt in out source destination
27 3144 ACCEPT tcp -- * * 192.168.56.103 192.168.56.0/24
4 240 ACCEPT icmp -- * * 192.168.56.103 192.168.56.0/24
# ping 192.168.56.103
PING 192.168.56.103 (192.168.56.103) 56(84) bytes of data.
64 bytes from 192.168.56.103: icmp_seq=1 ttl=64 time=0.042 ms
接口
# iptables -t filter -A INPUT -i enp0s3 -j REJECT
# iptables -t filter -A OUTPUT -o enp0s3 -j REJECT
# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
506 39408 ACCEPT tcp -- * * 0.0.0.0/0 192.168.56.103 multiport dports 22,80
0 0 REJECT all -- enp0s3 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
207 25960 ACCEPT tcp -- * * 192.168.56.103 0.0.0.0/0 multiport sports 22,80
0 0 REJECT all -- * enp0s3 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
使用扩展模块
使用man iptables-extensions
查看扩展模块的帮助信息。
隐式使用:
1,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-seperator list,例如SYN,ACK,FIN,RST
comp is a comma-seperator 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
例子:开放ssh
# iptables -I INPUT 1 -d 192.168.56.103 -s 192.168.56.0/24 -p tcp --dport 22 -j ACCEPT
# iptables -I OUTPUT 1 -s 192.168.56.103 -d 192.168.56.0/24 -p tcp --sport 22 -j ACCEPT
# iptables -vnL
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
523 40120 ACCEPT tcp -- * * 192.168.56.0/24 192.168.56.103 tcp dpt:22
28 1968 ACCEPT icmp -- * * 192.168.56.0/24 192.168.56.103
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
95 45704 ACCEPT tcp -- * * 192.168.56.103 192.168.56.0/24 tcp spt:22
4 240 ACCEPT icmp -- * * 192.168.56.103 192.168.56.0/24
2,udp
- [!]--source-port,--sport port[:port]:匹配报文的源端口,可以是端口范围
- [!]--destination-port,--dport port[:port]:匹配报文的目的端口,可以是端口范围
3,icmp
-
[!]--icmp-type {type[/code]|typename}
- echo-request:8
- echo-reply:0
# iptables -t filter -I INPUT -d 192.168.56.103 -p icmp --icmp-type 8 -j ACCEPT # iptables -t filter -I OUTPUT -s 192.168.56.103 -p icmp --icmp-type 0 -j ACCEPT [root@localhost ~]# iptables -vnL INPUT Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 14 1176 ACCEPT icmp -- * * 0.0.0.0/0 192.168.56.103 icmptype 8 [root@localhost ~]# iptables -vnL OUTPUT Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 14 1176 ACCEPT icmp -- * * 192.168.56.103 0.0.0.0/0 icmptype 0
显示使用:
1, multiport:以离散或连续的方式定义多端口匹配条件,最多15个。
- [!] --source-ports,--sports port[,port|,port:port]...
- [!] --destination-ports,--dports port[,port|,port:port]...
- [!] --ports port[,port|,port:port]...
例子:可以进和出:22和80端口
先启动httpd(80端口),nmb(149端口),smb(445端口)服务:systemctl start httpd nmb smb
在/var/www/html/目录下,创建文件index.html,里面随便写点内容。然后用浏览器访问一下,发现无法访问,原因是没有允许80端口进来和出去。添加让80进来和出去的规则就可以用浏览器访问了。
在另一台机器上使用smbclient -L 192.168.56.103
访问本机的smb服务,发现无法访问,原因是没有允许445端口进来和出去。添加让445进来和出去的规则就可以用浏览器访问了。
# iptables -t filter -A INPUT -d 192.168.56.103 -p tcp -m multiport --dports 22,80 -j ACCEPT
# iptables -t filter -A OUTPUT -s 192.168.56.103 -p tcp -m multiport --sports 22,80 -j ACCEPT
# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
140 12192 ACCEPT tcp -- * * 0.0.0.0/0 192.168.56.103 multiport dports 22,80
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
5 968 ACCEPT tcp -- * * 192.168.56.103 0.0.0.0/0 multiport sports 22,80
2,iprange:指定连续地址
- [!] --src-range from[-to]
- [!] --dst-range from[-to]
例子:
# iptables -t filter -R INPUT 1 -d 192.168.56.103 -p tcp -m multiport --dports 22:23,80,445 -m iprange --src-range 192.168.56.1-192.168.56.105 -j ACCEPT
3,time:指定包进来或者出去的时间区间
- --timestart hh:mm[:ss]
- --timestop hh:mm[:ss]
- [!] --monthdays day[,day...]
- [!] --weekdays day[,day...]
- --kerneltz:使用内核配置的时区,而非默认的UTC
例子:不使用--kerneltz就是UTC时间。
# iptables -t filter -R INPUT 1 -d 192.168.56.103 -p tcp -m multiport --dports 22:23,80,445 -m iprange --src-range 192.168.56.1-192.168.56.105 -m time --timestart 4:00:00 --timestop 14:00:00 --weekdays 1,2,3,4,5 -j ACCEPT
# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
6 432 ACCEPT tcp -- * * 0.0.0.0/0 192.168.56.103 multiport dports 22:23,80,445 source IP range 192.168.56.1-192.168.56.105 TIME from 04:00:00 to 14:00:00 on Mon,Tue,Wed,Thu,Fri UTC
# iptables -t filter -R INPUT 1 -d 192.168.56.103 -p tcp -m multiport --dports 22:23,80,445 -m iprange --src-range 192.168.56.1-192.168.56.105 -m time --timestart 4:00:00 --timestop 14:00:00 --weekdays 1,2,3,4,5 --kerneltz -j ACCEPT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
6 432 ACCEPT tcp -- * * 0.0.0.0/0 192.168.56.103 multiport dports 22:23,80,445 source IP range 192.168.56.1-192.168.56.105 TIME from 04:00:00 to 14:00:00 on Mon,Tue,Wed,Thu,Fri
4,string:匹配数据包里数据区域的关键字
明文的数据包才能匹配,比如http;加密的是无法匹配的,比如ssh,https等。
-
--algo {bm|kmp}
-
[!] --string pattern
-
[!] --hex-string pattern
-
--from offset
Set the offset from which it starts looking for any matching. If not passed, default is 0.
-
--to offset
例子:文件/var/www/html/test.html里如果有“abc”字符的话,则在无法访问test.html。
# iptables -t filter -R OUTPUT 1 -s 192.168.56.103 -m string --algo bm --string "abc" -j REJECT
# iptables -vnL OUTPUT
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
6 2202 REJECT all -- * * 192.168.56.103 0.0.0.0/0 STRING match "abc" ALGO name bm TO 65535 reject-with icmp-port-unreachable
3090 416K ACCEPT tcp -- * * 192.168.56.103 0.0.0.0/0 multiport sports 22:23,80,445
851 207K REJECT all -- * enp0s3 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
5,connlimit:允许同一个客户端ip,同时连进来的数量
-
--connlimit-upto n
小于等于n
-
--connlimit-above n
大于n
例子:控制来自同一个客户端ip,连接到mysql的数量为2,超过2个就连不上mysql
创建一个可以远程连接的用户test。
mysql> CREATE USER \'test\'@\'192.168.56.%\' IDENTIFED BY \'1\'
远程登录mysql命令:mysql -utest -h192.168.56.103 -p1
# iptables -t filter -I INPUT 2 -d 192.168.56.103 -p tcp --dport 3306 -j ACCEPT
# iptables -t filter -I OUTPUT 2 -s 192.168.56.103 -p tcp --sport 3306 -j ACCEPT
例子:同一个客户端ip过来的第一次握手超过2次,就拒绝。
# iptables -t filter -I INPUT 2 -d 192.168.56.103 -p tcp --syn --dport 22 -m connlimit --connlimit-above 2 -j REJECT
6,limit:限制流量
-
--limit-burst number
-
--limit rate[/second|/minute|/hour|/day]
Maximum average matching rate: specified as a number
例子:每分钟接收20个ping,从第6个开始计时,也就是说前5个不限速。
从下面ping的结果可以看出来,从第7个开始,由于限速的原因,就有丢失的发生了。
# iptables -t filter -R INPUT 1 -d 192.168.56.103 -p icmp --icmp-type 8 -m limit --limit 20/m --limit-burst 5 -j ACCEPT
$ ping 192.168.56.103
PING 192.168.56.103 (192.168.56.103) 56(84) bytes of data.
64 bytes from 192.168.56.103: icmp_seq=1 ttl=64 time=0.476 ms
64 bytes from 192.168.56.103: icmp_seq=2 ttl=64 time=0.521 ms
64 bytes from 192.168.56.103: icmp_seq=3 ttl=64 time=1.03 ms
64 bytes from 192.168.56.103: icmp_seq=4 ttl=64 time=0.998 ms
64 bytes from 192.168.56.103: icmp_seq=5 ttl=64 time=0.211 ms
64 bytes from 192.168.56.103: icmp_seq=6 ttl=64 time=1.01 ms
64 bytes from 192.168.56.103: icmp_seq=7 ttl=64 time=0.919 ms
64 bytes from 192.168.56.103: icmp_seq=10 ttl=64 time=0.446 ms
64 bytes from 192.168.56.103: icmp_seq=13 ttl=64 time=0.888 ms
64 bytes from 192.168.56.103: icmp_seq=16 ttl=64 time=0.331 ms
64 bytes from 192.168.56.103: icmp_seq=19 ttl=64 time=0.370 ms
64 bytes from 192.168.56.103: icmp_seq=22 ttl=64 time=0.901 ms
7,state:是conntrack模块的子集,根据报文的状态,设置规则
- conntrack模块把追踪到的报文,记录在内核使用的内存空间(把这个空间起名叫追踪表),这个空间的大小可以配置(/proc/sys/net/nf_conntrack_max),记录的内容记录还会保存在文件:/proc/net/nf_conntrack。由于要浪费内存和CPU所有,高并发的主机不建议开启此模块(conntrack),开启此功能后,分分钟被搞死。
# cat /proc/net/nf_conntrack
ipv4 2 unknown 2 487 src=192.168.56.103 dst=224.0.0.22 [UNREPLIED] src=224.0.0.22 dst=192.168.56.103 mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
ipv4 2 unknown 2 494 src=192.168.122.1 dst=224.0.0.22 [UNREPLIED] src=224.0.0.22 dst=192.168.122.1 mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
ipv4 2 unknown 2 486 src=10.0.3.15 dst=224.0.0.22 [UNREPLIED] src=224.0.0.22 dst=10.0.3.15 mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
ipv4 2 tcp 6 299 ESTABLISHED src=192.168.56.1 dst=192.168.56.103 sport=53243 dport=22 src=192.168.56.103 dst=192.168.56.1 sport=22 dport=53243 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
-
配置追踪表里各种协议条目的老化时长的配置文件:/proc/sys/net/netfilter/*timeout*
也就是过多久,把追踪表里的条目删除掉的意思。
nf_conntrack_tcp_timeout_close
nf_conntrack_tcp_timeout_close_wait
nf_conntrack_tcp_timeout_established
nf_conntrack_tcp_timeout_fin_wait
nf_conntrack_tcp_timeout_last_ack
-
查看内核是否装在了模块conntrack:
modinfo conntrack
-
[!] --state state
- INVALID:无法识别的连接
- ESTABLISHED:已经建立的连接
- NEW:新连接请求
- RELATED:虽然是一个新的请求,但是已经关联某个已经存在的连接。
- UNTRACKED:未追踪的连接。
-
有了这些状态,可以根据状态,限制进出就更方便了。
-
情形1:一台web server,它通过80端口,接收客户端的请求,然后再从80端口把响应发回个客户端。所以,web server只可能通过80端口发送ESTABLISHED状态的报文,不可以通过80,发送new状态的报文。
-
情形2:一台ftp server,它通过21端口,接收客户端的请求,然后再从21端口把响应发回个客户端。但还有一种情况,进来的报文状态是RELATED。
-
满足情形1和情形2的规则配置
INPUT第一条:目标是我,报文状态是 ESTABLISHED,RELATED的全部放进来。
注意:要先加载nf_conntrack_ftp模块,加载办法,往下面看。
# iptables -t filter -I INPUT -d 192.168.56.103 -m state --state ESTABLISHED,RELATED -j ACCEPT
INPUT第二条:目标是我,目的端口是21等,协议是tcp,报文状态是NEW的全部放进来
# iptables -t filter -I INPUT -d 192.168.56.103 -p tcp -m multiport --dports 21:23,80,139,445,3306 -m state --state NEW -j ACCEPT
OUT第一条:从我出去的,状态是ESTABLISHED的报文,全部放出去。
# iptables -t filter -A OUTPUT -s 192.168.56.103 -m state --state ESTABLISHED -j ACCEPT
最后,上面意外的,都拒绝。注意,要放到最后。
# iptables -t filter -A INPUT -d 192.168.56.103 -j REJECT # iptables -t filter -A OUTPUT -s 192.168.56.103 -j REJECT
配置结果:
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 315 23904 ACCEPT all -- * * 0.0.0.0/0 192.168.56.103 state ESTABLISHED,RELATED 0 0 ACCEPT tcp -- * * 0.0.0.0/0 192.168.56.103 multiport dports 21:23,80,139,445,3306 state NEW 0 0 REJECT all -- * * 0.0.0.0/0 192.168.56.103 reject-with icmp-port-unreachable Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 93 9832 ACCEPT all -- * * 192.168.56.103 0.0.0.0/0 state ESTABLISHED 0 0 REJECT all -- * * 192.168.56.103 0.0.0.0/0 reject-with icmp-port-unreachable
-
-
使用
lsmod
,查看内核都加载了哪些模块,发现没有ftp的模块,所以就无法判断fpt的RELATED的状态。# lsmod | grep conn nf_conntrack_ipv4 15053 3 nf_defrag_ipv4 12729 1 nf_conntrack_ipv4 xt_conntrack 12760 3 nf_conntrack 133095 2 xt_conntrack,nf_conntrack_ipv4 libcrc32c 12644 2 xfs,nf_conntrack
查看nf_conntrack_ftp模块:
modinfo
# modinfo nf_conntrack_ftp filename: /lib/modules/3.10.0-957.el7.x86_64/kernel/net/netfilter/nf_conntrack_ftp.ko.xz alias: nfct-helper-ftp alias: ip_conntrack_ftp description: ftp connection tracking helper author: Rusty Russell <rusty@rustcorp.com.au> license: GPL retpoline: Y rhelversion: 7.6 srcversion: 83D9304C9B64D8FBC064040 depends: nf_conntrack intree: Y vermagic: 3.10.0-957.el7.x86_64 SMP mod_unload modversions signer: CentOS Linux kernel signing key sig_key: B7:0D:CF:0D:F2:D9:B7:F2:91:59:24:82:49:FD:6F:E8:7B:78:14:27 sig_hashalgo: sha256 parm: ports:array of ushort parm: loose:bool
状态nf_conntrack_ftp模块
modprobe
# modprobe nf_conntrack_ftp # lsmod | grep ftp nf_conntrack_ftp 18638 0
内核加载了nf_conntrack_ftp后,就可以添加RELATED规则了。
处理动作
1,内嵌处理动作:ACCEPT,DROP
2,扩展处理动作:
-
REJECT: This is used to send back an error packet in response to the matched packet: otherwise it is equivalent to DROP so it is a terminating TARGET, ending rule traversal. This target is only valid in the INPUT, FORWARD and OUTPUT chains,and user-defined chains which are only called from those chains
--reject-with type:The type given can be icmp-net-unreachable, icmp-host-unreachable, icmp-port-unreachable, icmp-proto-unreach‐able, icmp-net-prohibited, icmp-host-prohibited, or icmp-admin-prohibited (*), which return the appropriate ICMP error message (icmp-port-unreachable is the default).
-
LOG:匹配到LOG规则后,处理动作是把信息写入到文件。然后,并不退出当前链,继续匹配当前链的下一条规则。
--log-level
--log-prefix
log写入到文件/var/log/messages
例子:把新进来的ssh连接的信息,写入log文件。
# iptables -t filter -I INPUT 2 -d 192.168.56.103 -p tcp --dport 22 -m state --state NEW -j LOG
log的内容:
Jan 26 10:07:47 localhost kernel: IN=enp0s3 OUT= MAC=08:00:27:10:c2:53:0a:00:27:00:00:16:08:00 SRC=192.168.56.1 DST=192.168.56.103 LEN=52 TOS=0x00 PREC=0x00 TTL=128 ID=37589 DF PROTO=TCP SPT=56366 DPT=22 WINDOW=64240 RES=0x00 SYN URGP=0
为了方便用查找log,添加识别前缀:
# iptables -t filter -R INPUT 2 -d 192.168.56.103 -p tcp --dport 22 -m state --state NEW -j LOG --log-prefix "mylog: " # iptables -vnL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 620 51584 ACCEPT all -- * * 0.0.0.0/0 192.168.56.103 state RELATED,ESTABLISHED 0 0 LOG tcp -- * * 0.0.0.0/0 192.168.56.103 tcp dpt:22 state NEW LOG flags 0 level 4 prefix "mylog: "
有前缀的log内容:
Jan 26 10:14:33 localhost kernel: mylog: IN=enp0s3 OUT= MAC=08:00:27:10:c2:53:0a:00:27:00:00:16:08:00 SRC=192.168.56.1 DST=192.168.56.103 LEN=52 TOS=0x00 PREC=0x00 TTL=128 ID=37882 DF PROTO=TCP SPT=56431 DPT=22 WINDOW=64240 RES=0x00 SYN URGP=0
-
RETURN:在自定义链里使用,返回调用此自定义链的链
3,自定义链
-
添加一个自定义链
# iptables -t filter -N in_ping_rules
-
在自定义链上添加规则
# iptables -t filter -A in_ping_rules -d 192.168.56.103 -p icmp --icmp-type 8 -j ACCEPT # iptables -t filter -A in_ping_rules -d 192.168.56.103 -p icmp --icmp-type 8 -s 192.168.56.200 -j REJECT icmptype 8 reject-with icmp-port-unreachable # iptables -vnL in_ping_rules Chain in_ping_rules (0 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT icmp -- * * 0.0.0.0/0 192.168.56.103 icmptype 8 0 0 REJECT icmp -- * * 192.168.56.200 192.168.56.103 icmptype 8 reject-with icmp-port-unreachable
-
把自定义链挂到INPUT链上后,references变成1,说明有一个链,使用了此自定义链。
当匹配到自定义链时,自定义链里的规则没有被匹配上的时候,匹配调用此自定义链的链的,下一条规则。
# iptables -t filter -I INPUT 3 -j in_ping_rules # iptables -vnL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1509 121K ACCEPT all -- * * 0.0.0.0/0 192.168.56.103 state RELATED,ESTABLISHED 1 52 LOG tcp -- * * 0.0.0.0/0 192.168.56.103 tcp dpt:22 state NEW LOG flags 0 level 4 prefix "mylog: " 0 0 in_ping_rules all -- * * 0.0.0.0/0 0.0.0.0/0 3 156 ACCEPT tcp -- * * 0.0.0.0/0 192.168.56.103 multiport dports 21:23,80,139,445,3306 state NEW Chain in_ping_rules (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT icmp -- * * 0.0.0.0/0 192.168.56.103 icmptype 8 0 0 REJECT icmp -- * * 192.168.56.200 192.168.56.103 icmptype 8 reject-with icmp-port-unreachable
-
当references不为0的时候,删除自定义链
# iptables -X in_ping_rules iptables: Too many links.
-
当references为0,但自定义链的的规则不为空的时候,删除自定义链
# iptables -X in_ping_rules iptables: Directory not empty.
-
清空自定义链里的规则后,删除自定义链,就可以删除了
# iptables -F in_ping_rules # iptables -X in_ping_rules # echo $? 0
CentOS6和7通用的保存,加载iptables规则
上面的介绍的命令,都是立即送到kernel,所以是立即生效的,但是当机器重启了,就都失效了。
下面的保存和重载命令,在CentOS6和7里都可以使用。
-
保存当前kernel里的iptable规则到文件:
# iptables-save > /etc/sysconfig/iptables-config-yymmdd-xx
-
把文件里保存的iptables规则,导入到kernel,替换到当前kernel里的规则。
# iptables-restore < /etc/sysconfig/iptables-config-yymmdd-xx
-n,--noflush:在原有规则后面添加文件里保存的规则
-t,--test:仅测试,不实际导入到内核。
-
注意:手动加载的内核模块(nf_conntrack_ftp)的操作,是无法保存到文件的。解决方案是,把加载模块到内核的操作和把文件里保存的规则导入到内核的操作,写到一个脚本里,开机自动执行此脚本即可。
CentOS6专用的保存,加载iptables规则。
-
保存:
service iptables save
把内核里的规则,保存到文件:/etc/sysconfig/iptables
-
加载规则:
service iptables restart
把文件:/etc/sysconfig/iptables里的规则,加载到内存。
-
配置文件:/etc/sysconfig/iptables-config
规则优化的简单思路:
1,使用自定义链管理特定应用的相关规则,模块化管理规则
2,优先放行双方向状态为ESTABLISHED的报文
3,服务于不同协议的规则,流量大的放前面
4,服务于同一个协议的规则,匹配条件严格的放前面
5,建议使用白名单策略
forwar表
查看linux 内核是否打开了核心转发功能,如果值为0,没有打开;值为1,打开了转发功能。
# cat /proc/sys/net/ipv4/ip_forward
1
关闭/打开核心转发功能:
关闭:sysctl -w net.ipv4.ip_forward=0
打开:sysctl -w net.ipv4.ip_forward=1
# sysctl -w net.ipv4.ip_forward=0
net.ipv4.ip_forward = 0
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
0
抓包工具:
抓指定接口,指定协议的包。
-
抓icmp协议数据包:
tcpdump -i enp0s3 -nn icmp
enp0s3:接口
-
抓tcp协议,80端口的数据包
tcpdump -i enp0s3 -nn tcp port 80
例子:从pc1,经由中间的主机,远程连接pc2上的mysql和ssh
步骤1:按图配置ip地址
步骤2:配置pc1的路由表
# route add -net 192.168.56.0/24 gw 172.16.0.1
步骤3:配置pc2的路由表
# route add -net 172.16.0.0/16 gw 192.168.56.103
步骤4:打开中间主机的转发功能
sysctl -w net.ipv4.ip_forward=1
到此为止,pc1和pc2就可以互相ping通了。
步骤5:配置中间主机的FORWARD
# iptables -vnL
Chain INPUT (policy ACCEPT 172 packets, 13369 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
111 19378 ACCEPT tcp -- * * 192.168.56.105 172.16.0.0/16 multiport sports 22,3306
153 13966 ACCEPT tcp -- * * 172.16.0.0/16 192.168.56.0/24 multiport dports 22,3306
24 1512 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT 119 packets, 21448 bytes)
pkts bytes target prot opt in out source destination
到此为止,pc1就可以访问pc2的ssh和mysql服务了,但是又不能ping通了,因为ping的规则在FORWARD里没有写,所以,上面的FORWARD配置不是很好,挺麻烦。优化成下面的样子:用NEW和ESTABLISHED状态就能搞定了。注意NEW只允许pc1主动访问pc2,但是不允许pc2主动访问pc1。如果向让pc2也可以主动访问pc1,就再加一条NEW。
# iptables -vnL
Chain INPUT (policy ACCEPT 6 packets, 432 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
89 12098 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED
8 576 ACCEPT all -- * * 0.0.0.0/0 192.168.56.0/24 state NEW
202 16968 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
# c/c++ 学习互助QQ群:877684253
![](https://img2018.cnblogs.com/blog/1414315/201811/1414315-20181106214320230-961379709.jpg)
# 本人微信:xiaoshitou5854