iptables基本认识
- Netfilter组件
- 内核空间,集成在linux内核中
- 官网文档:https://netfilter.org/documentation/
- 扩展各种网络服务的结构化底层框架
- 内核中选取五个位置放了五个hook(勾子) function(INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING),而这五个hook function向用户开放,用户可以通过一个命令工具 (iptables)向其写入规则
- 由信息过滤表(table)组成,包含控制IP包处理的规则集(rules),规则被分组放在链(chain)上
- 三种报文流向:
- 流入本机:PREROUTING --> INPUT–>用户空间进程
- 流出本机:用户空间进程 -->OUTPUT–> POSTROUTING
- 转发:PREROUTING --> FORWARD --> POSTROUTING
iptables的组成
- iptables由五个表和五个链以及一些规则组成
- 五个表table:filter、nat、mangle、raw、security
- filter表:过滤规则表,根据预定义的规则过滤符合条件的数据包
- nat表:network address translation 地址转换规则表
- mangle:修改数据标记位规则表
- raw:关闭NAT表上启用的连接跟踪机制,加快封包穿越防火墙速度
- security:用于强制访问控制(MAC)网络规则,由Linux安全模块(如SELinux)实现
- 优先级由高到低的顺序为:security -->raw–>mangle–>nat–>filter
- 五个内置链chain
- INPUT
- OUTPUT
- FORWARD
- PREROUTING
- POSTROUTING
- 五个表table:filter、nat、mangle、raw、security
- 内核中数据包的传输过程
- 当一个数据包进入网卡时,数据包首先进入PREROUTING链,内核根据数据包目的IP判断是否需要转送出去
- 如果数据包就是进入本机的,数据包就会沿着图向下移动,到达INPUT链。数据包到达INPUT链后,任何进程都会收到它。本机上运行的程序可以发送数据包,这些数据包经过OUTPUT链,然后到达POSTROUTING链输出
- 如果数据包是要转发出去的,且内核允许转发,数据包就会向右移动,经过FORWARD链,然后到达POSTROUTING链输出
iptables规则
- 规则rule:根据规则的匹配条件尝试匹配报文,对匹配成功的报文根据规则定义的处理动作作出处理
- 匹配条件:默认为与条件,同时满足
- 基本匹配:IP,端口,TCP的Flags(SYN,ACK等)
- 扩展匹配:通过复杂高级功能匹配
- 处理动作:称为target,跳转目标
- 内建处理动作:ACCEPT,DROP,REJECT,SNAT,DNATMASQUERADE,MARK,LOG…
- 自定义处理动作:自定义chain,利用分类管理复杂情形
- 匹配条件:默认为与条件,同时满足
- 规则要添加在链上,才生效;添加在自定义上不会自动生效
- 链chain:
- 内置链:每个内置链对应于一个钩子函数
- 自定义链:用于对内置链进行扩展或补充,可实现更灵活的规则组织管理机制;只有Hook钩子调用自定义链时,才生效
- 链chain:
- iptables规则添加时考量点
- 要实现哪种功能:判断添加在哪张表上
- 报文流经的路径:判断添加在哪个链上
- 报文的流向:判断源和目的
- 匹配规则:业务需要
man帮助
man 8 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命令
- 规则格式:iptables [-t table] SUBCOMMAND chain [-m matchname [per-match-options]] -j targetname [per-target-options]
- -t table:
- raw, mangle, nat, [filter]默认
- SUBCOMMAND:
- 1、链管理:
- -N:new, 自定义一条新的规则链
- -X:delete,删除自定义的空的规则链
- -P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:
- ACCEPT:接受
- DROP:丢弃
- -E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除
- 2、查看:
- -L:list, 列出指定鏈上的所有规则,本选项须置后
- -n:numberic,以数字格式显示地址和端口号
- -v:verbose,详细信息
- -vv 更详细
- -x:exactly,显示计数器结果的精确值,而非单位转换后的易读值
- –line-numbers:显示规则的序号
- 常用组合:
- -vnL
- -vvnxL --line-numbers
- 常用组合:
- -S selected,以iptables-save 命令格式显示链上规则
- 3、规则管理:
- -A:append,追加
- -I:insert, 插入,要指明插入至的规则编号,默认为第一条
- -D:delete,删除
- (1) 指明规则序号
- (2) 指明规则本身
- -R:replace,替换指定链上的指定规则编号
- -F:flush,清空指定的规则链
- -Z:zero,置零
- iptables的每条规则都有两个计数器
- (1) 匹配到的报文的个数
- (2) 匹配到的所有报文的大小之和
- iptables的每条规则都有两个计数器
- chain:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
- 1、链管理:
- 处理动作:
- -j targetname [per-target-options]
- 简单:ACCEPT,DROP
- 扩展:REJECT:–reject-with:icmp-port-unreachable默认
- RETURN:返回调用链
- REDIRECT:端口重定向
- LOG:记录日志,dmesg
- MARK:做防火墙标记
- DNAT:目标地址转换
- SNAT:源地址转换
- MASQUERADE:地址伪装
- -j targetname [per-target-options]
基本应用
,若iptables停止后,查看仍有信心,需卸除虚拟网卡
[root@iptables ~]# yum remove libvirt-daemon -y
[root@iptables ~]# reboot
[root@iptables ~]# iptables -vnL #清空配置
Chain INPUT (policy ACCEPT 0 packets, 0 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 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
[root@iptables ~]# iptables -t filter -A INPUT -s 192.168.8.17 -j DROP 扔掉
-t filter(默认,可以不写,其他表示需要指定,如-t nat)
-A INPUT (在INPUT链上-A增加规则;-R替换,-I插入、-D删除 )
-s 192.168.8.17(-s 源地址 -d目标地址)
-j DROP (ACCETP接受 DROP扔掉 REJECT拒绝)
[root@hostB ~]# ping 192.168.8.7 ping没反应,可以抓包看到没到对方主机
PING 192.168.8.7 (192.168.8.7) 56(84) bytes of data.
[root@hostB ~]# tcpdump -i ens33 -nn host 192.168.8.7
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
04:05:46.404941 IP 192.168.8.27 > 192.168.8.7: ICMP echo request, id 2203, seq 99, length 64
04:05:47.406525 IP 192.168.8.27 > 192.168.8.7: ICMP echo request, id 2203, seq 100, length 64
04:05:48.406995 IP 192.168.8.27 > 192.168.8.7: ICMP echo request, id 2203, seq 101, length 64
04:05:49.408410 IP 192.168.8.27 > 192.168.8.7: ICMP echo request, id 2203, seq 102, length 64
04:05:50.408741 IP 192.168.8.27 > 192.168.8.7: ICMP echo request, id 2203, seq 103, length 64
没有回来的报文
[root@hostB ~]# tcpdump -i ens33 -nn src 192.168.8.7 查看7发过来的没有
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
[root@iptables ~]# iptables -vnL #查看规则(filter表)
Chain INPUT (policy ACCEPT 46 packets, 3393 bytes)
链 默认规则 接收包
pkts bytes target prot opt in out source destination
30 3972 DROP all -- * * 192.168.8.17 0.0.0.0/0
281 23604 DROP all -- * * 192.168.8.27 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 27 packets, 2652 bytes)
pkts bytes target prot opt in out source destination
[root@iptables ~]# iptables -t nat -vnL #查看nat规则
[root@iptables ~]# iptables -vnL --line-number #显示优先级(优先级从上至下)
Chain INPUT (policy ACCEPT 145 packets, 10821 bytes)
num pkts bytes target prot opt in out source destination
1 30 3972 DROP all -- * * 192.168.8.17 0.0.0.0/0
2 449 37716 DROP all -- * * 192.168.8.27 0.0.0.0/0
[root@iptables ~]# iptables -D INPUT 2 删除第二条规则
[root@iptables ~]# iptables -vnL --line-number
Chain INPUT (policy ACCEPT 10 packets, 772 bytes)
num pkts bytes target prot opt in out source destination
1 30 3972 DROP all -- * * 192.168.8.17 0.0.0.0/0
[root@iptables ~]# iptables -F 清空规则
[root@iptables ~]# iptables -vnL --line-number
Chain INPUT (policy ACCEPT 14 packets, 1020 bytes)
num pkts bytes target prot opt in out source destination
[root@iptables ~]# iptables -A INPUT -s 192.168.8.27 -j REJECT 拒绝
[root@iptables ~]# iptables -Aiptables -vnL --line-number
Chain INPUT (policy ACCEPT 10 packets, 724 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 REJECT all -- * * 192.168.8.27 0.0.0.0/0
[root@hostB ~]# ping 192.168.8.7 ping有回应
PING 192.168.8.7 (192.168.8.7) 56(84) bytes of data.
From 192.168.8.7 icmp_seq=1 Destination Port Unreachable
From 192.168.8.7 icmp_seq=2 Destination Port Unreachable
[root@hostB ~]# tcpdump -i ens33 -nn host 192.168.8.7
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
04:28:35.208379 IP 192.168.8.27 > 192.168.8.7: ICMP echo request, id 2840, seq 28, length 64
04:28:35.208781 IP 192.168.8.7 > 192.168.8.27: ICMP 192.168.8.7 protocol 1 port 51751 unreachable, length 92
[root@hostB ~]# tcpdump -i ens33 -nn src 192.168.8.7
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
04:28:46.218676 IP 192.168.8.7 > 192.168.8.27: ICMP 192.168.8.7 protocol 1 port 28151 unreachable, length 92
[root@iptables ~]# systemctl start httpd
[root@iptables ~]# echo welcome to magedu > /var/www/html/index.html
[root@hostB ~]# ping -f 192.168.8.7 暴力ping
PING 192.168.8.7 (192.168.8.7) 56(84) bytes of data.
[root@hostA ~]# curl 192.168.8.7 访问不了
[root@iptables ~]# iptables -A INPUT -s 192.168.8.0/24 -j REJECT 拒绝网段
[root@iptables ~]# iptables -I INPUT -s 192.168.8.0/24 -j REJECT 插入第一行
[root@iptables ~]# iptables -I INPUT 3 -s 192.168.8.0/24 -j REJECT 插入第3行
[root@iptables ~]# iptables -R INPUT 3 -s 192.168.8.0/24 -j REJECT 替换第3行
[root@iptables ~]# iptables -Z INPUT 包计数清零,重新计数
防止策略配错导致不能访问,可以备份后30分钟后还原
[root@iptables ~]# echo wall warning |at now+30 minutes
[root@iptables ~]# echo iptables -F |at now+30 minutes 30分钟配置清空
拒绝所有IP,自己除外
[root@iptables ~]# iptables -A INPUT -j REJECT 拒绝所有IP(一般在最下面)自己也不行
[root@iptables ~]# iptables -I INPUT -d 192.168.8.7,127.0.0.1 -j ACCEPT 排除自己,放前面
[root@iptables ~]# iptables -I INPUT -i ens33 -j ACCEPT 网卡接收
[root@iptables ~]# iptables -P INPUT REJECT 更改默认配置为拒绝
隐式扩展(不指定模块)
当协议和模块一致时,使用协议不需加载模块
- tcp协议的扩展选项
- [!] --source-port, --sport port[:port]:匹配报文源端口,可为端口范围
- [!] --destination-port,–dport port[:port]:匹配报文目标端口,可为范围
- [!] --tcp-flags mask comp
- mask 需检查的标志位列表,用,分隔
- 例如 SYN,ACK,FIN,RST
- comp 在mask列表中必须为1的标志位列表,无指定则必须为0,用,分隔
- mask 需检查的标志位列表,用,分隔
- 示例:
- –tcp-flags SYN,ACK,FIN,RST SYN 表示要检查的标志位为SYN,ACK,FIN,RST四个,其中SYN必须为1,余下的必须为0
- –tcp-flags SYN,ACK,FIN,RST SYN,ACK
- –tcp-flags ALL ALL
- –tcp_flags ALL NONE
- [!] --syn:用于匹配第一次握手
- 相当于:–tcp-flags SYN,ACK,FIN,RST SYN
[root@iptables ~]# rpm -ql iptables
/usr/lib64/xtables/libipt_icmp.so
/usr/lib64/xtables/libxt_tcp.so
/usr/lib64/xtables/libxt_udp.so
[root@iptables ~]# iptables -A INPUT -s 192.168.8.27 -p tcp --dport 80 -j ACCEPT 允许访问tcp80端口(其他不能访问)
[root@iptables ~]# iptables -A INPUT -s 192.168.8.1,127.0.0.1 -j ACCEPT
[root@iptables ~]# iptables -A INPUT -j REJECT
[root@iptables ~]# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 192.168.8.27 0.0.0.0/0 tcp dpt:80
136 10924 ACCEPT all -- * * 192.168.8.1 0.0.0.0/0
0 0 ACCEPT all -- * * 127.0.0.1 0.0.0.0/0
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
[root@iptables ~]# iptables -I INPUT 3 -s 192.168.8.27 -p tcp --syn -j REJECT tcp三次握手第一次就拒绝
- icmp
- [!] --icmp-type {type[/code]|typename}
- type/code
- 0/0 echo-reply icmp应答
- 8/0 echo-request icmp请求
能ping hostB,hostB 不能ping本机
[root@iptables ~]# iptables -I INPUT -s 192.168.8.27 -p icmp --icmp-type 0 -j ACCEPT
[root@iptables ~]# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2 168 ACCEPT icmp -- * * 192.168.8.27 0.0.0.0/0 icmptype 0
543 38229 ACCEPT all -- * * 192.168.8.1 0.0.0.0/0
1 60 REJECT tcp -- * * 192.168.8.27 0.0.0.0/0 tcp flags:0x17/0x02 reject-with icmp-port-unreachable
0 0 ACCEPT all -- * * 127.0.0.1 0.0.0.0/0
2 168 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
显示扩展(指定模块)
multiport
- [!] --source-ports,–sports port[,port|,port:port]…
指定多个源端口 - [!] --destination-ports,–dports port[,port|,port:port]…
指定多个目标端口 - [!] --ports port[,port|,port:port]…多个源或目标端口
同一类型规则针对不同的端口须加多条规则,利用multiport模块可以写成一条,最多指定15个端口
[root@CentOS7 ~]# iptables -I INPUT -s 192.168.8.6 -p tcp --dport 80 -j REJECT
[root@CentOS7 ~]# iptables -I INPUT -s 192.168.8.6 -p tcp --dport 3306 -j REJECT
[root@CentOS7 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 24 packets, 1584 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 192.168.8.6 0.0.0.0/0 tcp dpt:3306 reject-with icmp-port-unreachable
0 0 REJECT tcp -- * * 192.168.8.6 0.0.0.0/0 tcp dpt:80 reject-with icmp-port-unreachable
[root@CentOS7 ~]# iptables -I INPUT -s I INPUT -s 192.168.8.6 -p tcp -m multiport --dport 3306,80 -j REJECT
[root@CentOS7 ~]# iptables -I INPUT -s vnL
Chain INPUT (policy ACCEPT 8 packets, 576 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT tcp -- * * 192.168.8.6 0.0.0.0/0 multiport dports 3306,80 reject-with icmp-port-unreachable
0 0 REJECT tcp -- * * 192.168.8.6 0.0.0.0/0 tcp dpt:3306 reject-with icmp-port-unreachable
0 0 REJECT tcp -- * * 192.168.8.6 0.0.0.0/0 tcp dpt:80 reject-with icmp-port-unreachable
iprange
指明连续的(但一般不是整个网络)ip地址范围
- [!] --src-range from[-to] 源IP地址范围
- [!] --dst-range from[-to] 目标IP地址范围
[root@CentOS7 ~]# iptables -A INPUT -p tcp --dport 80 -m iprange --src-range 192.168.8.8-192.168.8.100 -j REJECT
mac
指明源MAC地址
- 适用于:PREROUTING, FORWARD,INPUT chains
- [!] --mac-source XX:XX:XX:XX:XX:XX
[root@CentOS7 ~]# iptables -A INPUT -s 172.16.0.100 -m mac --mac-source 00:50:56:12:34:56 -j ACCEPT
[root@CentOS7 ~]# iptables -A INPUT -s 172.16.0.100 -j REJECT
string
对报文中的应用层数据做字符串模式匹配检测
- –algo {bm|kmp} 字符串匹配检测算法
- bm:Boyer-Moore
- kmp:Knuth-Pratt-Morris
- –from offset 开始偏移
- –to offset 结束偏移
- [!] --string pattern 要检测的字符串模式
- [!] --hex-string pattern要检测字符串模式,16进制格式
[root@CentOS7 ~]# iptables -A OUTPUT -s 172.16.100.10 -d 0/0 -p tcp --sport 80 -m string --algo bm --string “google" -j REJECT
源IP为172.168.10.10,内容中含有google就拒绝
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…] 星期几,1 – 7 分别表示星期一到星期日
–kerneltz:内核时区,不建议使用,CentOS7系统默认为UTC
注意: centos6 不支持kerneltz ,–localtz指定本地时区(默认)
[root@CentOS7 ~]# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.10 -p tcp --dport 80 -m time --timestart 14:30 --timestop 18:30 --weekdays Sat,Sun --kerneltz -j DROP
connlimit
根据每客户端IP做并发连接数数量匹配
- 可防止Dos(Denial of Service,拒绝服务)攻击 --connlimit-upto #:连接的数量小于等于#时匹配
–connlimit-above #:连接的数量大于#时匹配 - 通常分别与默认的拒绝或允许策略配合使用
[root@CentOS7 ~]# iptables -A INPUT -d 172.16.100.10 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
连接数超过2过以上就拒绝
limit
基于收发报文的速率做匹配
- 令牌桶过滤器
- –limit #[/second|/minute|/hour|/day]
- –limit-burst number
[root@CentOS7 ~]# iptables -I INPUT -d 172.16.100.10 -p icmp --icmp-type 8 -m limit --limit 10/minute --limit-burst 5 -j ACCEPT
ping172.16.100.10每分钟限制8个,广播报文5个
[root@CentOS7 ~]# iptables -I INPUT 2 -p icmp -j REJECT
其余ping拒绝
state
- 根据”连接追踪机制“去检查连接的状态,较耗资源
- conntrack机制:追踪本机上的请求和响应之间的关系
- 状态有如下几种:
- NEW:新发出请求;连接追踪信息库中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求
- ESTABLISHED:NEW状态之后,连接追踪信息库中为其建立的条目失效之前期间内所进行的通信状态
- RELATED:新发起的但与已有连接相关联的连接,如:ftp协议中的数据连接与命令连接之间的关系
- INVALID:无效的连接,如flag标记不正确
- UNTRACKED:未进行追踪的连接,如raw表中关闭追踪
[root@CentOS7 ~]# iptables -A INPUT -d 172.16.1.10 -p tcp -m multiport --dports 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT
新发起和已有的接收
[root@CentOS7 ~]# iptables -A OUTPUT -s 172.16.1.10 -p tcp -m multiport --sports 22,80 -m state --state ESTABLISHED -j ACCEPT
已经连接的接收,其余不接受
- 已经追踪到的并记录下来的连接信息库
/proc/net/nf_conntrack - 调整连接追踪功能所能够容纳的最大连接数量
/proc/sys/net/nf_conntrack_max - 不同的协议的连接追踪时长
/proc/sys/net/netfilter/ - 注意:CentOS7 需要加载模块: modprobe nf_conntrack_ipv4
iptables的链接跟踪表最大容量为/proc/sys/net/nf_conntrack_max,各种状态的超时链接会从表中删除;当模板满载时,后续连接可能会超时 - 解决方法两个:
- (1) 加大nf_conntrack_max 值
vi /etc/sysctl.conf
net.nf_conntrack_max = 393216
net.netfilter.nf_conntrack_max = 393216 - (2) 降低 nf_conntrack timeout时间
vi /etc/sysctl.conf
net.netfilter.nf_conntrack_tcp_timeout_established = 300
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
iptables -t nat -L -n
- (1) 加大nf_conntrack_max 值
实验:开放被动模式的ftp服务
yum install vsftpd
systemctl start vsftpd
vim /etc/sysconfig/iptables-config
IPTABLES_MODULES=“nf_conntrack_ftp"
modprobe nf_conntrack_ftp
iptables -F
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -vnL
-j LOG 记录日志
- LOG:非中断target,本身不拒绝和允许,放在拒绝和允许规则前
并将日志记录在/var/log/messages系统日志中- –log-level level 级别: debug,info,notice, warning, error, crit, alert,emerg
- –log-prefix prefix 日志前缀,用于区别不同的日志,最多29个字符
iptables -I INPUT -s 10.0.1.0/24 -p tcp -m multiport --dports 80,21,22,23 -m state --state NEW -j LOG --log-prefix "new connections: "
规则
- 任何不允许的访问,应该在请求到达时给予拒绝
- 规则在链接上的次序即为其检查时的生效次序
- 基于上述,规则优化
- 1 安全放行所有入站和出站的状态为ESTABLISHED状态连接
- 2 谨慎放行入站的新请求
- 3 有特殊目的限制访问功能,要在放行规则之前加以拒绝
- 4 同类规则(访问同一应用),匹配范围小的放在前面,用于特殊处理
- 5 不同类的规则(访问不同应用),匹配范围大的放在前面
- 6 应该将那些可由一条规则能够描述的多个规则合并为一条
- 7 设置默认策略,建议白名单(只放行特定连接)
- 1) iptables -P,不建议
- 2) 建议在规则的最后定义规则做为默认策略
备份及重新加载
-
CentOS 7 重新载入预存规则文件中规则:
- iptables-restore < /PATH/FROM/SOME_RULES_FILE
- -n, --noflush:不清除原有规则
- -t, --test:仅分析生成规则集,但不提交
-
CentOS 6:
- service iptables restart
- 会自动从/etc/sysconfig/iptables 重新载入规则
-
开机自动重载规则文件中的规则:
- (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
- (1) 用脚本保存各iptables命令;让此脚本开机后自动运行
路由
搭建环境如下
1、开启转发功能,使centos6和centos7互通
[root@firewalld ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@CentOS7 ~]# sysctl -p
2、centos6能ping通centos7,但centos7不能ping通centos6
[root@firewalld ~]# iptables -A FORWARD -j REJECT 拒绝所有
[root@firewalld ~]# iptables -I FORWARD -s 192.168.8.0/24 -p icmp --icmp-type 8 -j ACCEPT
源地址192.168.8.0/24ICMP请求报文通过
[root@firewalld ~]# iptables -I FORWARD -d 192.168.8.0/24 -p icmp --icmp-type 0 -j ACCEPT
目标地址192.168.8.0/24ICMP响应报文通过
------------------------------------------------------------------------------------------
第二种方式实现
[root@firewalld ~]# iptables -vnL
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT icmp -- * * 0.0.0.0/0 192.168.8.0/24 icmptype 0
0 0 ACCEPT icmp -- * * 192.168.8.0/24 0.0.0.0/0 icmptype 8
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
[root@firewalld ~]# iptables -D FORWARD 1
[root@firewalld ~]# iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
添加状态,建立了连接的就接受(ping出去请求报文已经发出)
[root@firewalld ~]# iptables -vnL
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- * * 192.168.8.0/24 0.0.0.0/0 icmptype 8
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
3、centos7httpd服务,centos6能访问
[root@firewalld ~]# iptables -I FORWARD -s 192.168.8.0/24 -p tcp --dport 80 -j ACCEPT
返回的规则已经建立state
添加443端口
[root@firewalld ~]# iptables -R FORWARD 1 -s 192.168.8.0/24 -p tcp -m multiport --dport 80,443 -j ACCEPT
4、centos7可以访问centos6http
[root@firewalld ~]# iptables -I FORWARD 5 -d 192.168.8.6 p tcp -m multiport --dport 80,443 -j ACCEPT
[root@CentOS6 ~]# yum install mod_ssl 安装ssl模块,重启服务
[root@CentOS7 ~]# curl -k https://192.168.8.6
/var/www/html/index.html
自定义链
相当于函数,可以引用,方便管理
- -N:new, 自定义一条新的规则链
- -X:delete,删除自定义的空的规则链
- -P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:
- ACCEPT:接受
- DROP:丢弃
- -E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除
[root@firewalld ~]# iptables -F
[root@firewalld ~]# iptables -A FORWARD -j REJECT
[root@firewalld ~]# iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@firewalld ~]# iptables -N fromlantointernet
[root@firewalld ~]# iptables -E fromlantointernet TOINT
[root@firewalld ~]# iptables -A TOINT -s 192.168.8.0/24 -p tcp -m multiport --dport 80,443 -j ACCEPT
[root@firewalld ~]# iptables -A TOINT 2 -s 192.168.8.0/24 -p icmp --icmp-type 8 -j ACCEPT
[root@firewalld ~]# iptables -I FORWARD -vnL
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 TOINT all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain TOINT (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 192.168.8.0/24 0.0.0.0/0 multiport dports 80,443
0 0 ACCEPT icmp -- * * 192.168.8.0/24 0.0.0.0/0 icmptype 8
修改规则可以修改自定义链,方便管理,如增加22端口
[root@firewalld ~]# iptables -R TOINT 1 -s 192.168.8.0/24 -p tcp -m multiport --dport 80,443,22 -j ACCEPT
[root@firewalld ~]# iptables -vnL
Chain TOINT (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 192.168.8.0/24 0.0.0.0/0 multiport dports 80,443,22
0 0 ACCEPT icmp -- * * 192.168.8.0/24 0.0.0.0/0 icmptype 8
删除自定义链
[root@firewalld ~]# iptables -D FORWARD 1 删除连接
[root@firewalld ~]# iptables -F TOINT 清空规则
[root@firewalld ~]# iptables -X TOINT 删除链
[root@firewalld ~]# iptables -vnL
Chain INPUT (policy ACCEPT 10 packets, 724 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
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT 6 packets, 696 bytes)
pkts bytes target prot opt in out source destination
查出网络出口的公网IP
[root@CentOS7 ~]# curl http://ipinfo.io/ip
125.85.172.57
[root@CentOS7 ~]# curl ifconfig.me
125.85.172.57
SNAT
- NAT: network address translation
PREROUTING,INPUT,OUTPUT,POSTROUTING
请求报文:修改源/目标IP,由定义如何修改
响应报文:修改源/目标IP,根据跟踪机制自动实现 - SNAT:source NAT POSTROUTING, INPUT
让本地网络中的主机通过某一特定地址访问外部网络,实现地址伪装
请求报文:修改源IP - DNAT:destination NAT PREROUTING , OUTPUT
把本地网络中的主机上的某服务开放给外部网络访问(发布服务和端口映射),但隐藏真实IP
请求报文:修改目标IP - PNAT: port nat,端口和IP都进行修改
环境搭建(centos7不配网关)
内网ping外网,源IP需替换,为SNAT,分为固定IP和ADSL拨号上网
- 固定IP
[root@CentOS7 ~]# vieth0
IPADDR=172.16.8.17
NETMASK=255.255.255.0
DNS1=114.114.114.114
DNS2=222.222.222.222
[root@firewalld ~]# iptables -t nat -A POSTROUTING -s 192.168.8.0/24 -j SNAT --to-source 172.16.8.7
[root@firewalld ~]# iptables -vnL -t nat
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 SNAT all -- * * 192.168.8.0/24 0.0.0.0/0 to:172.16.8.7
centos6连接centos7,centos主机认为时防火墙在连他
[root@CentOS6 ~]# ssh 172.16.8.17
[root@CentOS6 ~]# ss -nt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 192.168.8.6:43954 172.16.8.17:22
[root@CentOS7 ~]# ss -nt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 52 172.16.8.17:22 172.16.8.1:65342
ESTAB 0 0 172.16.8.17:22 172.16.8.7:43954
- ADSL
[root@firewalld ~]# iptables -t nat -I POSTROUTING 1 -s 192.168.8.0/24 -j MASQUERADE 插入
[root@firewalld ~]# iptables -t nat -D POSTROUTING 2 删除
[root@firewalld ~]# iptables -vnL -t nat 查看
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * * 192.168.8.0/24 0.0.0.0/0
DNAT
外部网络连接局域网内部IP时,需要将目标IP替换
[root@firewalld ~]# iptables -t nat -A PREROUTING -d 172.16.8.7 -j DNAT --to-destination 192.168.37.6
替换端口一致
[root@firewalld ~]# iptables -t nat -A PREROUTING -d 172.16.8.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.37.6:8080
外网80端口映射成8080,相当于防火墙配置端口映射:192.168.8.6:8080-----172.16.8.7:80
NAT(转发)
跟防火墙没有关系,是自己主机配置,如别人访问本主机时,将80端口转换成8080
[root@CentOS6 ~]# iptables -t nat -A PREROUTING -d 192.168.8.6 -p tcp --dport 80 -j REDIRECT --to-ports 8080
只要别人访问80端口自动转成8080
[root@CentOS6 ~]# vim /etc/httpd/conf/httpd.conf
Listen 8080
[root@CentOS6 ~]# service httpd restart
[root@firewalld ~]# iptables -t nat -R PREROUTING 1 -d 172.16.8.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.8.6:80
[root@CentOS7 ~]# curl 172.16.8.7
/var/www/html/index.html
[root@CentOS7 ~]# curl 192.168.8.6
/var/www/html/index.html
firewalld
- firewalld服务由firewalld包提供
- firewalld支持划分区域zone,每个zone可以设置独立的防火墙规则
- 归入zone顺序:
- 先根据数据包中源地址,将其纳为某个zone
- 纳为网络接口所属zone
- 纳入默认zone,默认为public zone,管理员可以改为其它zone
- 网卡默认属于public zone,lo网络接口属于trusted zone
- firewall-cmd --get-services 查看预定义服务列表
- /usr/lib/firewalld/services/*.xml预定义服务的配置
- 三种配置方法
- firewall-config (firewall-config包)图形工具
- firewall-cmd (firewalld包)命令行工具
- /etc/firewalld 配置文件,一般不建议
firewall-config图形工具配置时,需注意runtime模式下配置为运行模式,保存有几种操作,permanent下再操作一遍保存,或者options下操作
[root@firewalld ~]# firewall-cmd --get-zones 列出所有可用区域
block dmz drop external home internal public trusted work
[root@firewalld ~]# firewall-cmd --get-default-zone 查询默认区域
public
[root@firewalld ~]# firewall-cmd --set-default-zone=trusted 设置默认区域
success
[root@firewalld ~]# firewall-cmd --get-default-zone
trusted
[root@firewalld ~]# firewall-cmd --get-active-zones 列出当前正使用的区域及网卡
trusted
interfaces: ens33 ens37
[root@firewalld ~]# firewall-cmd --add-service=ftp 增加服务
success
[root@firewalld ~]# firewall-cmd --list-services
ftp
[root@firewalld ~]# firewall-cmd --permanent --add-service=ftp 保存
[root@firewalld ~]# firewall-cmd --list-all --zone=trusted 列出该域所有配置
trusted (active)
target: ACCEPT
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ftp
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@firewalld ~]# firewall-cmd --permanent --zone=internal --add-source=192.168.0.0/24 在internal zone中增加源地址192.168.0.0/24的永久规则
[root@firewalld ~]# firewall-cmd --permanent --zone=internal --add-service=mysql 在internal zone中增加协议mysql的永久规则
success
[root@firewalld ~]# firewall-cmd --list-all --zone=internal 没有生效
internal
[root@firewalld ~]# firewall-cmd --reload 加载
success
[root@firewalld ~]# firewall-cmd --list-all --zone=internal 生效
internal (active)
实验:配置firewalld
systemctl mask iptables 禁止手动启动服务,启动需要先停止 systemctl umask iptables
systemctl mask ip6tables
systemctl status firewalld
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --get-default-zone
firewall-cmd --set-default-zone=public
firewall-cmd --permanent --zone=public --list-all
firewall-cmd --permanent --zone=public --add-port 8080/tcp
firewall-cmd —reload
rich规则
拒绝从192.168.0.11的所有流量,当address 选项使用source 或 destination时,必须用family= ipv4 |ipv6
firewall-cmd --permanent --zone=public --add-rich-rule=‘rule family=ipv4 source address=192.168.0.11/32 reject’
限制每分钟只有两个连接到ftp服务
firewall-cmd --add-rich-rule=‘rule service name=ftp limit value=2/m accept’
抛弃esp( IPsec 体系中的一种主要协议)协议的所有数据包
firewall-cmd --permanent --add-rich-rule=‘rule protocol value=esp drop’
接受所有192.168.1.0/24子网端口5900-5905范围的TCP流量
firewall-cmd --permanent --zone=trusted --add-rich-rule=‘rule family=ipv4 source address=192.168.1.0/24 port port=5900-5905 protocol=tcp accept’
接受ssh新连接,记录日志到syslog的notice级别,每分钟最多三条信息
firewall-cmd --permanent --zone=work --add-rich-rule='rule service name=“ssh” log prefix="ssh " level=“notice” limit value=“3/m” accept
从2001:db8::/64子网的DNS连接在5分钟内被拒绝,并记录到日志到audit,每小时最大记录一条信息
firewall-cmd --add-rich-rule=‘rule family=ipv6 source address=“2001:db8::/64” service name=“dns” audit limit value=“1/h” reject’ --timeout=300
接受172.25.X.10/32 httpd新连接,记录日志到syslog的notice级别,每秒钟最多三条信息
firewall-cmd --permanent --add-rich-rule=‘rule family=ipv4 source address=172.25.X.10/32 service name=“http” log level=notice prefix="NEW HTTP " limit value=“3/s” accept’
伪装和端口转发
- 伪装NAT
- firewall-cmd --permanent --zone= --add-masquerade
- firewall-cmd --query-masquerade 检查是否允许伪装
- firewall-cmd --add-masquerade 允许防火墙伪装IP
- firewall-cmd --remove-masquerade 禁止防火墙伪装IP
- 伪装
[root@firewalld ~]# firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.8.0/24 masquerade'
- 转发
转发传入的连接9527/TCP,到防火墙的80/TCP到public zone 的192.168.0.254
firewall-cmd --add-masquerade 启用伪装
firewall-cmd --zone=public --add-forward-port=port=9527:proto=tcp:toport=80:toaddr=192.168.0.254
转发从192.168.0.0/24来的,发往80/TCP的流量到防火墙的端口8080/TCP
firewall-cmd --zone=work --add-rich-rule=‘rule family=ipv4 source address=192.168.0.0/24 forward-port port=80 protocol=tcp to-port=8080’
练习:判断下述规则的意义
- iptables -N clean_in
- iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
- iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP
- iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP
- iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP
- iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP
- iptables -A clean_in -d 172.16.100.7 -j RETURN
- iptables -A INPUT -d 172.16.100.7 -j clean_in
- iptables -A INPUT -i lo -j ACCEPT
- iptables -A OUTPUT -o lo -j ACCEPT
- iptables -A INPUT -i eth0 -m multiport -p tcp --dports 53,113,135,137,139,445 -j DROP
- iptables -A INPUT -i eth0 -m multiport -p udp --dports 53,113,135,137,139,445 -j DROP
- iptables -A INPUT -i eth0 -m multiport -p tcp --dports 1433,4899 -j DROP
- iptables -A INPUT -p icmp -m limit --limit 10/second -j ACCEPT