[TOC]
# 1. 基础概念
1. iptables是Linux防火墙工具,用来定义数据包操作规则(用户空间),用来操作netfilter规则
2. netfilter组件:称为内核空间,是内核的一部分,由一些信息包过滤表组成,这些表是内核用来控制信息包过滤处理的规则集,
3. iptables和firewall是给用户操作netfilter的工具,真正起到防火墙作用的是netfilter组件
# 2. table、chain和rule
## 2.1 三张表
1. 最常用的有三个表,分别是`filter`,`nat `和`mangle`.其中每个表又有各自包含不同的操作链(chains):
**filter**用于过滤数据包,进入本机(input)、从本机出去(output),转发的数据
**nat**用于转发数据包,转入(prerouting)和转出(postrouting)
![](https://img.kancloud.cn/72/82/72824116f26302c1f4425ccbbb65375f_612x142.png)
2. iptables的表与链的工作流程,如图想要修改input链,只能在filter(过滤)表和Mangle表上进行,同理其他链操作参考下图
![](https://img.kancloud.cn/4d/34/4d348100c672225714e867ce7084afe2_673x291.png)
## 2.2 五种链
1. **input**:
匹配目标ip 是本机的数据包时,进入此链
2. **output**:
出口数据包,从本机发出的数据包,进入此链
3. **forward**:
匹配流经本机的数据包,nat转发
4. **prerouting**:
可以**用来修改目的地址**用来做DNAT,如把内网的80端口映射到路由器外网端口上,然后内核的”路由模块”-`route`根据”数据包目的IP”以及”内核中的路由表”判断是否需要转送出去(注意,这个时候数据包的DestIP有可能已经被修改过了)
5. **postrouting**:
用来修改源地址用来做SNAT,如内网通过路由器NAT转换功能实现内网PC机通过一个公网ip地址上网
> 入站数据:prerouting -> input
> 转发数据:prerouting -> forward -> postrouting
> 出站数据:putput -> postrouting
**包处理流程**
1. 首先进入preruteing,决定是进入本机还是转发
2. 若果目的地址是本机的(数据包的目的ip是本机的网口ip),进入input链,到达input链后,任何的进程都有可能得到这个数据包
3. 如果数据包是要转发出去的(即目的IP地址不再当前子网中),**且内核允许转发**,数据包就会向右移动,经过FORWARD链,然后到达POSTROUTING链输出(选择对应子网的网口发送出去) -》源ip不变,目的ip变内网,记录nat表,数据包返回是参照nat表,数据返回给外网,达到暴露服务的目的
4. 本机上运行的程序也可以发送数据包,这些数据包经过OUTPUT链,然后到达POSTROTING链输出(注意,这个时候数据包的SrcIP有可能已经被我们修改过了) -》改变源ip,目的IP不变,记录nat表,数据包回来参照nat表,又回到了内网,达到上网的目的
## 2.3 包处理规则target
**防火墙处理数据包的方式(规则):**
1. `ACCEPT`:允许数据包通过
2. `DROP`:直接丢弃数据包,不给任何回应信息
3. `REJECT`:拒绝数据包通过,必要时会给数据发送端一个响应的信息。
4. `SNAT`:源地址转换。在进入路由层面的route之前,重新改写源地址,目标地址不变,并在本机建立NAT表项,当数据返回时,根据NAT表将目的地址数据改写为数据发送出去时候的源地址,并发送给主机。**解决内网用户用同一个公网地址上网的问题**。
5. `MASQUERADE`,是SNAT的一种特殊形式,适用于像adsl这种临时会变的ip上
6. `DNAT`:目标地址转换。和SNAT相反,IP包经过route之后、出本地的网络栈之前,重新修改目标地址,源地址不变,在本机建立NAT表项,当数据返回时,根据NAT表将源地址修改为数据发送过来时的目标地址,并发给远程主机。可以隐藏后端服务器的真实地址。 (暴露内网地址和端口)
7. `REDIRECT`:是DNAT的一种特殊形式,将网络包转发到本地host上(不管IP头部指定的目标地址是啥),方便在本机做端口转发。
8. `LOG`:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则
除去最后一个`LOG`,前3条规则匹配数据包后,该数据包不会再往下继续匹配了,所以编写的规则顺序极其关键。
# 3. iptables命令使用
## 3.1 命令格式
> iptable是给用户调用netfilter的工具,用来修改防火墙规则
```
iptables [-t 表名] 管理选项 [链名] [条件匹配] [-j 目标动作或跳转]
```
1 ) 不指定表名时,默认表示filter表
2 ) 不指定链名时,默认表示该表内所有链
3 ) 除非设置规则链的缺省策略,否则需要制定匹配条件
**1. command 选项,操作链上的规则**
~~~
-A :增加
-D: 删除
-I : 插入
-R
-L:列出表的规则,默认是filter表
-F: 清空规则
-Z
-N:用于新建一个自定义链
-X:清空引用为0的自定义链规则
-P : 设置某个链的默认规则,链的默认规则最后触发
~~~
**2. parameter选项,数据包过滤,协议端口ip**
~~~
-P:协议类型
-s:来源地址
-d:目的地址
-i:流入
-o:流出
-sport:来源端口
-dport:目标端口
~~~
**3. target**
包处理方式
~~~
-j ACCEPT
-j DROP
-j REJECT
...
~~~
## 3.2 例子
> 查看默认策略
```
iptables -L
```
![](https://img.kancloud.cn/f4/70/f470138064a878864d88553565428f9c_1033x454.png)
> 拒绝所有连接,没有指定规则则,则匹配所有
```
iptables -t filter -A INPUT -j DROP
```
> 删除规则 -D
按照序号展示 `iptables -L --line-numbers`
```
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 KUBE-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes service portals */
2 KUBE-EXTERNAL-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes externally-visible service portals */
3 KUBE-FIREWALL all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 KUBE-FORWARD all -- anywhere anywhere /* kubernetes forwarding rules */
2 KUBE-SERVICES all -- anywhere anywhere ctstate NEW /* kubernetes service portals */
3 DOCKER-USER all -- anywhere anywhere
4 DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
5 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
6 DOCKER all -- anywhere anywhere
```
删除filter表的input 链的第一条规则
```
iptables -t filter -D INPUT 1
```
方式2,按内容
> 删除filter表的input链中内容为 "-s 192.168.0.1 -j DROP" 的规则
```
iptables -t filter -D INPUT -s 192.168.0.1 -j DROP
```
> 设置某个链的默认规则
`iptables -P INPUT DROP`
> 清空规则 -F
清空filter表INPUT链的所有规则
```
iptables -t filter -F INPUT
```
> 清空filter表的所有链的规则
```
iptables -t filter -F
```
注意事项
-F 不清除默认规则
-P 设置了DROP后,使用-F 一定要小心
如不写链名,默认清空某表里所有链里的所有规则
### 3.2.2 nat 表
> PREROUTING 链的所有规则
```
iptables -t nat -vnL PREROUTING
```
**1. 按流入网络接口匹配(-i)**
> -i 匹配数据进入网络接口 #主要用于nat表
例子
-i eth0 匹配是否从网络接口eth0进来
-i ppp0 匹配是否从网络接口ppp0进来
2. 按流出网络接口匹配(-o)
`iptables -t nat -o eth0 条件 动作`
3. 按来源地址匹配(-s)
-s 匹配来源地址,可以是ip,net,domain ,也可空(任何地址)
例如:
```
-s 192.168.0.1 匹配来自192.168.0.1的数据包
-s 192.168.1.0/24 匹配来自192.168.1.0/24 的数据包
-s 192.168.0.0/16 匹配来自192.168.0.0/16 的数据包
```
4. 按目的地址匹配(-d)
-d 匹配来源地址,可以是ip,net,domain ,也可空(任何地址)
例如:
```
-d 192.168.0.1 匹配去往192.168.0.1的数据包
-d 192.168.1.0/24 匹配去往192.168.1.0/24 的数据包
-d 192.168.0.0/16 匹配去往192.168.0.0/16 的数据包
```
5. 按协议匹配(-p)
-p 匹配来源地址,可以是TCP、UDP,ICMP,也可为空
例如:
```
-p tcp 匹配协议为 tcp的数据包
-p udp 匹配协议为 udp的数据包
-p icmp 匹配协议为 icmp的数据包
```
6. 按来源端口匹配(sport)
例如:
```
--sport 1000 匹配源端口是1000的数据包
--sport 1000:3000 匹配源端口是1000-3000的数据包
--sport :3000 匹配源端口是3000以下的数据包
--sport 1000: 匹配源端口是1000以上的数据包
```
7. 按目的端口匹配(dport)
```
--dport 1000 匹配目的端口是1000的数据包
--dport 1000:3000 匹配目的端口是1000-3000的数据包
--dport :3000 匹配目的端口是3000以下的数据包
--dport 1000: 匹配目的端口是1000以上的数据包
```
注意:
1. --sport 和 --dport 必须和 -p 配合使用
2. 条件越多,匹配越精确,范围越小
数据包结构
目标端口 目标ip地址 内容址 源端口 源ip地址
80 192.168.1.64 xxx 3211 192.168.1.65
### 动作(处理方式)
#### ACCEPT(接受)
通过,允许数据包通过本链而不拦截
格式: -j ACCEPT
> 允许所有访问本机ip的数据包通过
```
iptables -A INPUT -j ACCEPT
```
#### DROP (丢弃,不给对方任何回应)
丢弃,不允许数据包通过本链而丢弃它
格式: -j DROP
阻止来源地址为192.168.80.39的数据包通过本机
```
iptables -A FORWARD -s 192.168.80.39 -j DROP
```
#### REJECT (拒绝,给对方一个回应)
#### SNAT(上网)
原地址转化,snat 支持转化为单ip,也支持转化到ip地址池
> 格式: -j SNAT --to IP[-IP][:端口-端口]
适用范围: nat表的 postrouting
单个地址情况
1. 将内网 192.168.0.0/24的源地址修改为公网IP地址 1.1.1.1
```
iptables -t nat -A POSTROUNTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1
```
2. 将内网 192.168.0.0/24的源地址修改为公网IP地址 1.1.1.1- 1.1.1.10
iptables -t nat -A POSTROUNTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1-1.1.1.10
#### DNAT(端口映射)
目标地址转化,DNAT 支持转化为单ip,也支持转化到ip地址池
> 格式: -j DNAT --to IP[-IP][:端口-端口]
> 适用范围: nat表的 prerouting
**1. 暴露端口**
> 把eth0进来的要访问TCP/80的数据包目的地址改为192.168.0.1
```
iptables -t nat -A PREROUNTING -i eth0 -p tcp -dport 80 -j SNAT --to 192.168.0.1
```
多个地址情况
**2. 把eth0进来的要访问TCP/80的数据包目的地址改为192.168.0.1-192.168.0.10**
```
iptables -t nat -A PREROUNTING -i eth0 -p tcp -dport 80 -j DNAT --to 192.168.0.1-192.168.0.10
```
#### MASQUERADE(伪装ip地址)
> 动态源地址转换(动态ip的情况下使用)
将源地址是192.168.0.0/24的数据包进行地址伪装,转换成eth0上的ip地址,eth0为路由器外网IP地址
```
iptables -t nat -A POSTROUNTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE
```
## 附加模块
### 按包状态匹配
-m state --state 状态
状态:NEW、RELATED、ESTABLIShED、INVALID
```
NEW: 有别于tcp的syn
RELATED: 衍生态
ESTABLISHED: 连接状态
INVALID: 不能被识别属于哪个连接或没有任何状态
```
> 将连接状态为RELATED 和ESTABLISHED 的访问数据包通过
```
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
```
### 按来源MAC匹配
格式
-m mac --mac-source mac地址
> 阻断来自某mac 地址数据包通过本机
```
iptables -A FORWARD -m mac --mac-source xxxx -j DROP
```
### 按包速率匹配
> 格式
-m limit --limit 匹配速率 [--burst 缓冲数量]
> 只允许192.168.0.1 一秒发送50个数据包
```
iptables -A FORWARD -d 192.168.0.1 -m limit --limit 50/s -j ACCEPT
iptables -A FORWARD -d 192.168.0.1 -j DROP
```
### 多端口匹配
格式
```
-m multport <--sports|--dports|--ports>
```
一次行匹配多个端口,可以区分源端口,目的端口或不制定端口
> 允许所有客户端访问本服务器的21、22、 25和 80端口的服务
```
iptables -A INPUT -p tcp -m multiport --dports 21,22,25,80 -j ACCEPT
```
注意: 必须与 -p 参数一起使用
三、网络基本拓扑图
graph LR
终端用户--> 互联网
互联网--> 防火墙
防火墙--> 路由器
路由器--> 交换机
交换机--> 服务器
# 4. 案例
## 4.1 对web服务器保护
> 匹配规则,自上而下,只要匹配到一条就停止,无论是通过还是不通过
```
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m mutiport --dports 22,80 -j ACCEPT
iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT DROP
```
## 4.2 让内网pc机上网
可连接外网主机|,有两块网卡
```
内网ip:192.168.56.10
外网ip: 10.0.2.15
```
内网主机
```
内网ip: 192.168.56.13
```
**1. 在可上外网主机配置路由规则,转发数据包到外网网卡接口**
```
iptables -t filter -P FORWARD DROP
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -s 192.168.56.10/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.56.1/24 -j SNAT --to 10.0.2.15
```
**2. 外网机器打开数据包转发**
```
vim /etc/sysctl.conf
# 配置=1,开启转发
net.ipv4.ip_forward=1
```
**3.在内网机器上,设置其网关为外网主机ip,将外网请求发送到网关**
![](https://img.kancloud.cn/15/74/157466669f5e1a6f3450ece836fc2fb6_817x454.png)
重启网络
`service network restart`
**4. 配置域名解析**
```
vi /etc/resolv.conf
nameserver 114.114.114.114
nameserver 8.8.8.8
```
![](https://img.kancloud.cn/14/8b/148b6203168dd4d61b7d6ab64de3aeaa_814x263.png)
## 4.3 暴露端口
- Linux
- 高级
- 杀毒
- 记一次中毒事件
- clamav查毒软件
- 处理挖矿病毒
- 定时任务
- kill
- chattr文件保护
- 运行级别
- Linux启动
- 文件加密
- ssh免密登录
- .ssh
- 问题
- 脚本
- 阿里云域名解析
- yum源
- 时间同步
- keepalived实现高可用
- dos字符与unix字符
- 大文件上传
- 基础
- proc目录
- 设置宋体
- 基础命令_01
- 基础命令_02
- SELinux
- 文件描述符
- 基础命令_03
- awk
- 系统日志
- date命令
- bc命令
- lsof
- vim快捷键
- shell
- 循环控制
- expr
- 执行脚本的方式
- declare
- shell脚本
- 控制启停脚本
- 数值计算
- centos
- 配置网络
- 环境
- 灰度环境
- ansible
- 模块
- 语法
- file模块
- setup模块
- ping模块
- copy模块
- command模块
- shell模块
- service模块
- cron模块
- yum模块
- user 模块
- group模块
- 指定用户
- playbook
- 实例
- ansible安装
- Jenkins
- shell部署
- 导入已有项目的配置
- 执行shell
- tungsten数据同步
- 防火墙
- netfilter