目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

netfilter/iptables

作用

用于保护内网安全的一种设备。

依据规则进行防护。

用户定义规则。(允许或拒绝外部用户访问)

分类

逻辑划分

  • 主机防火墙(个人服务)
  • 网络防火墙(集体服务)

物理划分

  • 硬件防火墙(性能高)
  • 软件防火墙(成本低)

性能指标

  • 吞吐量
  • 并发连接
  • 新建连接
  • 时延
  • 抖动

iptables

  • netfilter 位于内核空间,是 Linux 操作系统核心层内部的一个数据包处理模块。
  • iptables 是位于用户空间对内核空间的 netfilter 进行操作的命令行工具。

netfilter 功能

  • 数据包过滤
  • 数据包转发(重定向)
  • 网络地址转换:NAT

流程图

  • INPUT:处理入站数据包

  • OUT:处理出站数据包

  • FORWARD:处理转发数据包(主要是将数据包转发至本机其他网卡)

    1当数据报文经过本机时,网卡接收数据报文至缓冲区,内核读取报文的ip首部,发现报文不是送到本机时(目的ip不是本机),由内核直接送到forward链做匹配,匹配之后若符合forward的规则,再经由postrouting送往下一跳或目的主机。
    
  • PREROUTING:在进行路由选择前处理数据包,修改到达防火墙数据包的目的 IP 地址,用于判断目标主机。(DNAT)

  • POSTROUTING:在进行路由选择后处理数据包,修改要离开防火墙数据包的源 IP 地址,判断经由哪一接口送往下一跳。(SNAT)

表的概念

每个“规则链”上都设置了一串规则,这样的话,我们就可以把不同的“规则链”组合成能够完成某一特定功能集合的分类,这个集合分类就称之为表,iptables 中有 5 张表,学习 iptables 需要搞明白每种表的作用。

表名 作用 内核模块
filter 过滤功能,确定是否放行该数据包,属于真正防火墙 iptables_filter
nat 网络地址转换,修改数据包中的源、目标 IP 地址或端口 iptable_nat
mangle 对数据包进行重新封装功能,为数据包设置标记 iptable_mangle
raw 确定是否对数据包进行跟踪 iptable_mangle
security 是否定义强制访问控制规则 后加上的

表与链之间的关系

应用防火墙是以表为操作入口,只要在相应的表中的规则链上添加规则即可实现某一功能。

应该知道哪张表包括哪些规则链,在规则链上操作即可。

规则链
filter INPUT、FORWARD、OUTPUT
nat PREROUTING、OUTPUT、POSTROUTING、INPUT
mangle PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
raw PREROUTING、OUTPUT
security INPUT、FORWARD、OUTPUT

数据包流经 iptable 流程

iptables 中表的优先级

security>raw>mangle>nat>filter

规则

基本匹配条件(无需加载扩展模块,匹配规则生效)

1源地址,目标地址,源端口,目标端口等
2
3-p 指定规则协议,tcp udp icmp all
4-s 指定数据包的源地址,ip hostname
5-d 指定目的地址
6-i 输入接口
7-o 输出接口
8!  取反

扩展匹配条件(无需加载扩展模块,匹配规则生效)

  • 显示匹配:必须使用-m 选项指明要调用的扩展模块的扩展机制以及需要手动加载扩展模块。
     1################ multiport 多端口
     2#在INPUT链中开放本机tcp 22,tcp80端口 
     3iptables -I INPUT -d 192.168.2.10 -p tcp -m multiport --dports 22,80 -j ACCEPT 
     4
     5#在OUTPUT链中开发源端口tcp 22,tcp80
     6iptables -I OUTPUT -s 192.168.2.10 -p tcp -m multiport --sports 22,80 -j ACCEPT 
     7
     8################ iprange 多ip地址
     9iptables -A INPUT -d 192.168.2.10 -p tcp --dport 23 -m iprange --src-range 192.168.2.11-192.168.2.21 -j ACCEPT 
    10
    11iptables -A OUTPUT -s 192.168.2.10 -p tcp --sport 23 -m iprange --dst-range 192.168.2.11-192.168.2.21 -j ACCEPT
    12
    13################ time 指定访问时间范围
    14iptables -A INPUT -d 192.168.2.10 -p tcp --dport 901 -m time --weekdays Mon,Tus,Wed,Thu,Fri --timestart 08:00:00 --time-stop 18:00:00 -j ACCEPT 
    15
    16iptables -A OUTPUT -s 192.168.2.10 -p tcp --sport 901 -j ACCEPT
    17
    18################ string 字符串,对报文中的应用层数据做字符串模式匹配检测(通过算法实现)。
    19--algo {bm|kmp}:字符匹配查找时使用算法 
    20--string "STRING": 要查找的字符串 
    21--hex-string “HEX-STRING”: 要查找的字符,先编码成16进制格式 123
    22
    23################ connlimit 连接限制,根据每个客户端IP作并发连接数量限制。
    24--connlimit-upto n 连接数小于等于n时匹配 
    25--connlimit-above n 连接数大于n时匹配
    26
    27################ limit 报文速率限制
    28
    29################ state 追踪本机上的请求和响应之间的数据报文的状态。
    30	状态有五种:INVALID, ESTABLISHED, NEW, RELATED,UNTRACKED
    31--state state 
    32NEW 新连接请求 
    33ESTABLISHED 已建立的连接 
    34INVALID 无法识别的连接 
    35RELATED 相关联的连接,当前连接是一个新请求,但附属于某个已存在的连接 
    36UNTRACKED 未追踪的连接
    37
    381、对于进入的状态为ESTABLISHED都应该放行; 
    392、对于出去的状态为ESTABLISHED都应该放行; 
    403、严格检查进入的状态为NEW的连接; 
    414、所有状态为INVALIED都应该拒绝;
    
  • 隐式匹配:使用-p 选项指明协议时,无需再同时使用-m 选项指明扩展模块以及不需要手动加载扩展模块;
     1-p tcp 
     2	--sport 匹配报文源端口;可以给出多个端口,但只能是连续的端口范围 
     3	--dport 匹配报文目标端口;可以给出多个端口,但只能是连续的端口范围 
     4	--tcp-flags mask comp 匹配报文中的tcp协议的标志位 
     5
     6-p udp 
     7	--sport 匹配报文源端口;可以给出多个端口,但只能是连续的端口范围 
     8	--dport 匹配报文目标端口;可以给出多个端口,但只能是连续的端口范围 
     9
    10--icmp-type 
    11	0/0: echo reply 允许其他主机ping 
    12	8/0:echo request 允许ping其他主机
    

动作

ACCEPT:允许数据包通过

DROP:直接丢弃数据包,不给任何回应信息

REJECT:拒绝数据包通过,发送回应信息给客户端

SNAT:源地址转换

1# 用于静态公网IP
2iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth1 -j SNAT --to-source 202.12.10.100
3
4# 用于动态公网IP
5iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE 

DNAT:目标地址转换

1iptables -t nat PREROUTING -d 202.12.10.100 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.1

REDIRECT:在本机做端口映射

LOG:在日志中记录信息,然后将数据包传递给下一条规则

规则策略

  • 黑名单:没有被拒绝的流量都可以通过。(不推荐)(ACCEPT)
  • 白名单:没有被允许的流量都拒绝。(推荐)(DROP)

指定规则思路

1、选择一张表,词表决定了数据报文处理的方式

2、选择一条链,此链决定了数据报文流经哪些位置

3、选择适合的条件,此条件决定了对数据报文做何种条件匹配

4、选择处理数据报文的动作,指定相应的防火墙规则

1iptables [-t 表名] 管理选项 [链名] [条件匹配] [-j 目标动作或跳转]
2
3iptables不指定表名时,默认表示filter表,不指定链名时,默认表示该表内所有链,除非设置规则链的默认策略,否则
4需要指定匹配条件

iptables 链管理方法

1-N, --new-chain chain:新建一个自定义的规则链; 
2-X, --delete-chain [chain]:删除用户自定义的引用计数为0的空链; 
3-F, --flush [chain]:清空指定的规则链上的规则; 
4-E, --rename-chain old-chain new-chain:重命名链; 
5-Z, --zero [chain [rulenum]]:置零计数器; 
6	注意:每个规则都有两个计数器 
7	packets:被本规则所匹配到的所有报文的个数; 
8	bytes:被本规则所匹配到的所有报文的大小之和; 
9-P, --policy chain target 制定链表的策略(ACCEPT|DROP|REJECT) 12345678

iptables 规则管理

1-A, --append chain rule-specification:追加新规则于指定链的尾部; 
2-I, --insert chain [rulenum] rule-specification:插入新规则于指定链的指定位置,默认为首部; 
3-R, --replace chain rulenum rule-specification:替换指定的规则为新的规则; 
4-D, --delete chain rulenum:根据规则编号删除规则; 
5-D, --delete chain rule-specification:根据规则本身删除规则; 12345

iptables 规则显示

1-L, --list [chain]:列出规则; 
2-v, --verbose:详细信息; 
3-vv 更详细的信息 
4-n, --numeric:数字格式显示主机地址和端口号; 
5-x, --exact:显示计数器的精确值,而非圆整后的数据; 
6--line-numbers:列出规则时,显示其在链上的相应的编号;
7-S, --list-rules [chain]:显示指定链的所有规则;

安装 iptables-services

CentOS7 系统中默认存在 iptables 命令,此命令仅为简单查询及操作命令,不包含配置文件,安装 iptables.services 后,将直接生成配置文件,便于配置保存。包含 ipv4 及 ipv6

 1# 关闭firewalld
 2[root@localhost ~]# systemctl stop firewalld
 3
 4# 安装iptables-services
 5[root@localhost ~]#  yum -y install iptables-services
 6
 7# 启动服务
 8[root@localhost ~]# systemctl start iptables.service
 9[root@localhost ~]# systemctl status iptables.service
10● iptables.service - IPv4 firewall with iptables
11   Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled; vendor preset: disabled)
12   Active: active (exited) since Thu 2021-04-29 15:45
13
14# 设置开机自启动
15[root@localhost ~]# systemctl enable iptables.service
16
17# 查看配置文件
18[root@localhost ~]# rpm -ql iptables-services
19/etc/sysconfig/ip6tables
20/etc/sysconfig/iptables		# 配置文件在这里
21/usr/lib/systemd/system/ip6tables.service
22/usr/lib/systemd/system/iptables.service
23/usr/libexec/initscripts/legacy-actions/ip6tables
24/usr/libexec/initscripts/legacy-actions/ip6tables/panic
25/usr/libexec/initscripts/legacy-actions/ip6tables/save
26/usr/libexec/initscripts/legacy-actions/iptables
27/usr/libexec/initscripts/legacy-actions/iptables/panic
28/usr/libexec/initscripts/legacy-actions/iptables/save
29/usr/libexec/iptables
30/usr/libexec/iptables/ip6tables.init
31/usr/libexec/iptables/iptables.init
32
33# 保存规则
34[root@localhost ~]# iptables-save > /etc/sysconfig/iptables
35
36# 重载
37[root@localhost ~]# iptables-restore < /etc/sysconfig/iptables
38
39# 基本配置
40[root@localhost ~]# iptables -F
41
42# 查询
43[root@localhost ~]# iptables -nL
44
45# 重启iptables 临时设置的规则如果没有保存到配置文件中,iptables下次启动则会丢失当前的规则,会从/etc/sysconfig/iptables配置文件中加载规则
46[root@localhost ~]# systemctl restart iptables

iptables 默认规则

 1[root@localhost ~]# cat /etc/sysconfig/iptables
 2# Generated by iptables-save v1.4.21 on Thu Apr 29 16:14:43 2021
 3*filter
 4:INPUT ACCEPT [0:0]
 5:FORWARD ACCEPT [0:0]
 6:OUTPUT ACCEPT [60:6160]
 7-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 8-A INPUT -p icmp -j ACCEPT
 9-A INPUT -i lo -j ACCEPT
10-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
11-A INPUT -j REJECT --reject-with icmp-host-prohibited
12-A FORWARD -j REJECT --reject-with icmp-host-prohibited
13COMMIT
14# Completed on Thu Apr 29 16:14:43 2021
15

iptables 标准流程

 1# ACCEPT
 2[root@localhost ~]# iptables -F 
 3[root@localhost ~]# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 
 4[root@localhost ~]# iptables -A INPUT -i lo -j ACCEPT 
 5[root@localhost ~]# iptables -A INPUT -s 192.168.2.0/24 -j ACCEPT #允许内网任何访问 
 6[root@localhost ~]# iptables -A INPUT -p tcp --syn --dport 80 -j ACCEPT 
 7[root@localhost ~]# iptables -A INPUT -p tcp --syn --dport 22 -j ACCEPT 
 8[root@localhost ~]# iptables -A INPUT -p tcp --syn --dport 20:21 -j ACCEPT 
 9[root@localhost ~]# iptables -A INPUT -j REJECT 
10[root@localhost ~]# modprobe nf_conntrack_ftp
11[root@localhost ~]# iptables-save > /etc/sysconfig/iptables 
12[root@localhost ~]# vim /etc/sysconfig/iptables-config 
13IPTABLES_MODULES="nf_conntrack_ftp"

iptables 基本操作

 1# 删除现有规则
 2iptables -F
 3
 4# 设置链的默认规则(危险,请勿滥用)
 5iptables -P INPUT DROP 
 6iptables -P FORWARD DROP 
 7iptables -P OUTPUT DROP
 8
 9# 白名单(DROP)
10[root@localhost ~]# iptables -t filter -F 
11[root@localhost ~]# iptables -P INPUT DROP 
12[root@localhost ~]# iptables -t filter -I INPUT -p tcp --dport=22 -j ACCEPT [root@localhost ~]# iptables -t filter -I INPUT -p tcp --dport=80 -j ACCEPT
13
14# 黑名单(ACCEPT)
15[root@localhost ~]# iptables -P INPUT ACCEPT 
16[root@localhost ~]# iptables -F 
17[root@localhost ~]# iptables -t filter -A INPUT -s 192.168.2.20/24 -p tcp --dport 80 -j DROP
18
19# 添加规则
20[root@localhost ~]# iptables -t filter -A INPUT -p tcp --dport=80 -j ACCEPT
21[root@localhost ~]# iptables -t filter -I INPUT -p tcp --dport=80 -j ACCEPT
22[root@localhost ~]# iptables -t filter -I INPUT -s 192.168.31.244 -p tcp --dport=80 -j DROP
23
24# 删除规则
25[root@localhost ~]# iptables -t filter -D INPUT -p tcp --dport=80 -j ACCEPT
26
27# 通过lo访问本机数据
28[root@localhost ~]# iptables -I INPUT -d 127.0.0.1 -p tcp --dport=9000 -i lo -j ACCEPT

案例

案例一

 1[root@localhost ~]# yum -y install httpd vsftpd sshd 
 2[root@localhost ~]# systemctl start httpd vsftpd sshd 
 3
 4[root@localhost ~]# iptables -t filter -F 
 5[root@localhost ~]# iptables -I INPUT -p tcp --dport 80 -j ACCEPT 
 6[root@localhost ~]# iptables -I INPUT -p tcp --dport 20:21 -j ACCEPT 
 7[root@localhost ~]# iptables -I INPUT -p tcp --dport 22 -j ACCEPT 
 8[root@localhost ~]# iptables -A INPUT -j REJECT 
 9
10#在存问题 
11
12本机无法访问本机 例如:ping 127.0.0.1 
13解决方法 
14[root@localhost ~]# iptables -I INPUT -i lo -j ACCEPT 
15
16本机无法访问其它主机 
17例如:ssh remote_host 
18解决方法 
19[root@localhost ~]# iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 
20
21FTP无法访问 
22解决方法1: (被动模式)
23[root@localhost ~]# iptables -I INPUT -p tcp --dport 20:21 -j ACCEPT 
24[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf 
25pasv_min_port=50000 
26pasv_max_port=60000 
27[root@localhost ~]# iptables -I INPUT -p tcp --dport 50000:60000 -j ACCEPT
28
29解决方法2:使用连接追踪模块 
30[root@localhost ~]# iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 
31[root@localhost ~]# iptables -I INPUT -p tcp --dport 20:21 -j ACCEPT 
32[root@localhost ~]# modprobe nf_conntrack_ftp #临时方法,添加连接追踪模块 
33
34[root@localhost ~]# vim /etc/sysconfig/iptables-config  #iptables的配置文件
35IPTABLES_MODULES="nf_conntrack_ftp" 
36#启动服务时加载 
37#针对数据端口连接时,将三次握手第一次状态由NEW识别为RELATED

案例二:扩展匹配

 1#-m icmp 
 2[root@localhost ~]# iptables -F 
 3[root@localhost ~]# iptables -t filter -I INPUT -p icmp -m icmp --icmp-type echo-reply -j ACCEPT #允许ping回应 
 4[root@localhost ~]# iptables -A INPUT -j REJECT 
 5
 6#-m iprange 
 7[root@localhost ~]# iptables -t filter -I INPUT -m iprange --src-range 192.168.2.10- 192.168.2.100 -j REJECT 
 8
 9#-m multiport 
10[root@localhost ~]# iptables -t filter -I INPUT -p tcp -m multiport --dports 20,21,22,25,80,110 -j ACCEPT 
11
12#-m tos 根据ip协议头部 type of service进行过滤 
13[root@localhost ~]# iptables -F 
14[root@localhost ~]# tcpdump -i eth0 -nn port 22 -vvv 
15
16#抓取远程主机访问本机的ssh数据包,观察TOS值 
17[root@localhost ~]# tcpdump -i eth0 -nn port 22 -vvv #抓取远程从本机rsync或scp复制文件,观察TOS值 
18#ssh: tos 0x0 0x10 
19#scp: tos 0x0 0x8 
20#rsync: tos 0x0 0x8 
21[root@localhost ~]# iptables -t filter -A INPUT -p tcp --dport 22 -m tos --tos 0x10 -j ACCEPT 
22[root@localhost ~]# iptables -t filter -A INPUT -j REJECT 
23
24#-m tcp 按TCP控制位进行匹配 
25Flags:SYN ACK FIN RST URG PSH ALL NONE
26[root@localhost ~]# iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags SYN,ACK,FIN,RST SYN --dport 80 -j ACCEPT 
27[root@localhost ~]# iptables -t filter -A INPUT -p tcp --syn --dport 80 -j ACCEPT #--tcp-flags SYN,ACK,FIN,RST SYN 检查四个标记位,只有SYN标记位才匹配,即只允许三次握手中的第一次 握手,等价于--syn 
28
29#-m comment 对规则进行备注说明 
30[root@localhost ~]# iptables -A INPUT -s 192.168.2.250 -m comment --comment "cloud host" -j REJECT 
31
32#-m mark 使用mangle表的标记方法,配合mangle表使用 
33[root@localhost ~]# iptables -t filter -A INPUT -m mark 2 -j REJECT

案例三:扩展动作

 1#-j LOG 记录至日志中 
 2[root@localhost ~]# grep 'kern.*' /etc/rsyslog.conf 
 3kern.* /var/log/kernel.log 
 4[root@localhost ~]# systemctl restart rsyslog 
 5[root@localhost ~]# iptables -j LOG -h 
 6[root@localhost ~]# iptables -t filter -A INPUT -p tcp --syn --dport 22 -j LOG --log- prefix " localhost_ssh " 
 7[root@localhost ~]# iptables -t filter -A INPUT -p tcp --syn --dport 22 -j ACCEPT 
 8[root@localhost ~]# iptables -t filter -A INPUT -j REJECT 
 9
10#-j REJECT 
11当访问一个未开启的TCP端口时,应该返回一个带有RST标记的数据包 
12当访问一个未开启的UDP端口,结果返回port xxx unreachable 当访问一个开启的TCP端口,但被防火墙REJECT,结果返回port xxx unreachable 
13[root@localhost ~]# iptables -j REJECT -h 
14[root@localhost ~]# iptables -t filter -A INPUT -p tcp --dport 22 -j REJECT --reject- with tcp-reset //返回一个自定义消息类型 
15
16#-j MARK 进行标记,可在LVS调度器中应用 
17[root@localhost ~]# iptables -t mangle -L 
18[root@localhost ~]# iptables -j MARK -h 
19[root@localhost ~]# iptables -t mangle -A PREROUTING -s 192.168.2.110 -j MARK --set- mark 1 
20[root@localhost ~]# iptables -t mangle -A PREROUTING -s 192.168.2.25 -j MARK --set- mark 2 
21[root@localhost ~]# iptables -t filter -A INPUT -m mark --mark 1 -j ACCEPT //按照标记匹 配
22[root@localhost ~]# iptables -t filter -A INPUT -m mark --mark 2 -j REJECT

SNAT

 1#开启路由转发功能
 2[root@localhost ~]# cat /etc/sysctl.conf
 3net.ipv4.ip_forward = 1
 4[root@localhost ~]# sysctl -p 
 5net.ipv4.ip_forward = 1
 6
 7# SNAT规则
 8[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ens37 -j SNAT --to-source 192.168.3.1 
 910[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ens37 -j MASQUERADE

DNAT

1#开启路由转发功能
2[root@localhost ~]# cat /etc/sysctl.conf
3net.ipv4.ip_forward = 1
4[root@localhost ~]# sysctl -p 
5net.ipv4.ip_forward = 1
6
7# 开启DNAT功能
8[root@localhost ~]# iptables -t nat -A PREROUTING -d 192.168.3.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2

作者:Soulboy