摘要:本文主要介绍iptables的常规配置,传统的4表5链。
来源资料
说明
请求流量图
常用参数说明
命令格式
- 官方的:
iptables [-t table] command [match] [target/jump] - 我们一般拆分的:
iptables [-t table] -rule-action [chain] -matching-criteria
规则表
| 表名称 | 拥有规则链 | 说明 |
|---|---|---|
| nat | PREROUTING, OUTPUT, POSTROUTING | 用于网络地址转换 |
| mangle | PREROUTING, POSTROUTING, OUTPUT, INPUT, FORWARD | 修改数据包内容 |
| filter | FORWARD, INPUT, OUTPUT | 过滤数据包 |
| raw | PREROUTING, OUTPUT | 决定数据包是否被状态跟踪机制处理 |
规则链
| 链名称 | 说明 |
|---|---|
| INPUT | 处理进入本机的数据包;规则应用于目标地址为本机的数据包 |
| OUTPUT | 处理从本机发出的数据包;规则应用于源地址为本机的数据包 |
| FORWARD | 处理经过本机但目的地不是本机的数据包;用于配置路由器或网关上的转发规则 |
| PREROUTING | 在路由决策之前处理进入的数据包;通常用于修改进入数据包的目标地址,如 DNAT(目标网络地址转换) |
| POSTROUTING | 在路由决策之后处理即将离开本机的数据包;通常用于修改数据包的源地址,如 SNAT(源网络地址转换) |
常用命令
| 命令 | 说明 | 案例 |
|---|---|---|
| -A | 向指定链追加规则 | 允许所有 ICMP(ping)流量:iptables -A INPUT -p icmp -j ACCEPT |
| -D | 从指定链删除规则 | 删除允许所有 ICMP(ping)流量规则:iptables -D INPUT -p icmp -j ACCEPT 删除指定行的配置: iptables -D INPUT 1 |
| -I | 在指定链的开头插入规则 | 允许所有 ICMP(ping)流量:iptables -I INPUT -p icmp -j ACCEPT;在第二行插入拒绝8080端口的访问: iptables -I INPUT 2 -p tcp --dport 8080 -j REJECT |
| -L | 列出指定链的规则 | 查看INPUT链:iptables -L INPUT,查看详细: iptables -nvL INPUT,查看附带行号: iptables -nvL INPUT --line-number |
| -F | 清空指定链或表的所有规则 | 清空INPUT链:iptables -F INPUT; 清空filter表: iptables -F filter |
| -P | 设置规则链默认规则 | 设置到本机的数据全部丢弃(所有流量都进不来如果不配置其他放行规则):iptables -P INPUT DROP |
常用匹配规则
| 匹配规则 | 说明 | 案例 |
|---|---|---|
| -p | 指定数据包的协议类型,如 tcp、udp、icmp 等 --sport [port] 指定源端口号,也可以是端口号范围,如 --sport 22 或 --sport 1024:2048 --dport [port] 指定目标端口号,同样可以是单个端口号或端口号范围,如 --dport 80 或 --dport 8000:8100 | 允许22端口访问:-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT |
| -s | 指定数据包的源地址 | 允许192.168.0.0/16网段访问本机:iptables -I INPUT -s 192.168.0.0/16 -j ACCEPT |
| -d | 指定数据包的目标地址 | 允许本机访问本机环路:iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT最优环路配置: iptables -A INPUT -i lo -j ACCEPT |
| -i | 指定数据包进入的网络接口 | 允许eth0网卡的所有流量进入:iptables -A INPUT -i eth0 -p tcp -j ACCEPT |
| -o | 指定数据包离开的网络接口 | 允许eth0网卡发出所有tcp流量:iptables -A OUTPUT -o eth0 -p tcp -j ACCEPT |
| -f | 这个选项用于匹配伪造的(伪造的源地址)数据包 | 不常用 |
规则执行动作-j
| 动作值 | 说明 | 案例 |
|---|---|---|
| ACCEPT | 接受数据包,允许它通过或进入系统 | 允许所有数据包进入:iptables -A INPUT -j ACCEPT |
| DROP | 丢弃数据包,不给予任何回应。 | 丢弃所有数据包:iptables -A INPUT -j DROP |
| REJECT | 拒绝数据包,并向发送方发送一个错误响应,通常是 “port unreachable” 或 “admin prohibited” 消息 | 拒绝所有数据包:iptables -A INPUT -j REJECT |
| RETURN | 立即接受数据包 在自定义链中使用 优化规则链 | 所有来自 192.168.1.100 的数据包都将被立即接受:iptables -A INPUT -s 192.168.1.100 -j RETURN |
| LOG | 记录数据包的信息,通常用于调试或监控 | 记录所有数据包:iptables -A INPUT -j LOG |
| MASQUERADE | 用于 IP 伪装,通常在 POSTROUTING 链中使用 | |
| NAT | 用于网络地址转换,通常在 PREROUTING 和 POSTROUTING 链中使用 | |
| DNAT | 目标地址转换,用于修改数据包的目标 IP 地址 | |
| SNAT | 源地址转换,用于修改数据包的源 IP 地址 | |
| REDIRECT | 重定向连接到本机的某个端口,通常用于端口转发 | 将所有进入的 SSH 数据包重定向到端口 2222:iptables -A INPUT -p tcp --dport 22 -j REDIRECT --to-port 2222 |
| MARK | 设置数据包的 netfilter 标记,用于更复杂的规则处理 |
常见配置方案
开放端口给外部访问
| 案例名 | 配置 | 说明 |
|---|---|---|
| 开放80端口给所有外部访问 | iptables -A INPUT -p tcp --dport 80 -j ACCEPT | |
| 开放80端口给指定的ip访问 | iptables -A INPUT -p tcp --dport 80 -s 192.168.1.100 -j ACCEPT | |
| 开放80端口给指定的网段访问 | iptables -A INPUT -p tcp --dport 80 -s 192.168.1.0/24 -j ACCEPT | |
| 允许本地回环接口 | iptables -A INPUT -i lo -j ACCEPT |
拒绝外部访问本机
| 案例名 | 配置 | 说明 |
|---|---|---|
| 设置默认策略 | 设置默认策略为 DROP:iptables -P INPUT DROP置默认策略为 REJECT: iptables -P INPUT REJECT | |
| 拒绝特定 IP 地址 | iptables -A INPUT -s 192.168.1.100 -j REJECT | |
| 拒绝特定 网段 地址 | iptables -A INPUT -s 192.168.1.0/24 -j REJECT | |
| 拒绝特定端口 | iptables -A INPUT -p tcp --dport 22 -j REJECT | |
| 拒绝所有 ICMP 请求 | iptables -A INPUT -p icmp -j REJECT |
本机端口转发到本机
实际上用得比较少,
2222端口和22端口都用于ssh连接。目的端口22必须开放访问外部才能通过2222端口访问。
用于本机的流量转发
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j REDIRECT --to-port 22
如果允许外部访问2222端口
还需要配置如下规则,因为上面的规则实际上是重定向到了
filter表的INPUT链22端口的校验
iptables -I INPUT -p tcp -m tcp --dport 22 -j ACCEPT
本机端口转发到其他服务器端口
比如我们需要转发指定端口到其他机器的端口,则可以用端口转发。
打开路由转发功能
如果已经存在了则手动修改为1
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p
允许访问中间机器的8080端口到172.20.0.2机器的80端口
PREROUTING上的网段的--dport 8080不受filter表的INPUT链管控。
# 将访问172.20.0.2 80端口的地址改写为本机的网卡地址
iptables -t nat -A POSTROUTING -d 172.20.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
# 将本机的8080端口转发到172.20.0.2的80端口
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.20.0.2:80
注意事项
filter表的FORWARD链规则需要开启路由转发访问
- 注释如下这行,表示允许了所有的
# 设置允许处理经过本机但目的地不是本机的数据包
:FORWARD ACCEPT [0:0]
# 注释这行表示不拦截FORWARD的流量
#-A FORWARD -j REJECT --reject-with icmp-host-prohibited
- 推荐配置一
允许指定来源和目的地的流量转发
:FORWARD ACCEPT [0:0]
# 所有与已建立的连接相关的数据包都能够通过你的服务器
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# 指定来源地址是192.168.137.0/24 的流量通过
-A FORWARD -s 192.168.137.0/24 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
- 我当前的完整配置
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.20.0.2:80
-A POSTROUTING -d 172.20.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp --dport 8080 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
# 允许已经连接的通道进行数据发送
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# 指定来源地址是192.168.137.0/24 的流量通过
-A FORWARD -s 192.168.137.0/24 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
推荐配置二
允许被访问的网段通过
FORWARD链
-A FORWARD -d 172.20.0.0/24 -j ACCEPT
-A FORWARD -s 172.20.0.0/24 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
如果配置网卡可以如下配置
# 它允许所有从 `enp0s3` 接口进入并从 `enp0s8` 接口出去的转发流量
-A FORWARD -i enp0s3 -o enp0s8 -j ACCEPT
# 它允许所有从 `enp0s8` 接口进入并从 `enp0s3` 接口出去的转发流量
-A FORWARD -i enp0s8 -o enp0s3 -j ACCEPT
# 其他未被前面的规则匹配的转发流量拒绝
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
- 也可以简写为如下,只配置最终转发的网卡
-A FORWARD -o enp0s8 -j ACCEPT
-A FORWARD -i enp0s8 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
完整配置,注意自己机器的多网卡
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.138.101:80
-A POSTROUTING -d 192.168.138.0/24 -p tcp -m tcp --dport 80 -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -i enp0s3 -o enp0s8 -j ACCEPT
-A FORWARD -i enp0s8 -o enp0s3 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
路由转发(通过中间机器访问外网)
打开路由转发功能
如果已经存在了则手动修改为1
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p
配置nat链源地址改写为本机的网卡地址
iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
配置filter链转发
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 192.168.137.0/24 -j ACCEPT
iptables -A FORWARD -j REJECT --reject-with icmp-host-prohibited
其他机器配置访问路由
我需要在另一台机器通过
192.168.137.100机器访问172.20.0.0/24网段。
root@u-191:/etc/rsyslog.d# ip route show
default via 192.168.137.1 dev ens33 proto static
192.168.137.0/24 dev ens33 proto kernel scope link src 192.168.137.191
root@u-191:/etc/rsyslog.d# ip route add 172.20.0.0/24 via 192.168.137.100
root@u-191:/etc/rsyslog.d# ip route show
default via 192.168.137.1 dev ens33 proto static
172.20.0.0/24 via 192.168.137.100 dev ens33
192.168.137.0/24 dev ens33 proto kernel scope link src 192.168.137.191
我最终的配置一
配置的
ip段
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o ens33 -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp --dport 8080 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.137.0/24 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
我最终的配置二
配置的网卡,事实上多网卡机器配置网卡就行
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o enp0s8 -p tcp -m tcp -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -i enp0s3 -o enp0s8 -j ACCEPT
-A FORWARD -i enp0s8 -o enp0s3 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
注意事项
默认表
iptables不用-t指定表,默认是filter表- 如果
iptables配置没有按照预想的生效调试方法
先去掉一些拒绝的策略,然后再慢慢加回来,很多时候是我们没有加
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT这种的配置,允许已经连接的通道继续发送数据。
ip route路由使用说明
| 指令 | 说明 | 案例 |
|---|---|---|
ip route show | 显示已经配置的路由 | |
ip route add | 添加路由 | 添加默认路由:ip route add default via <网关IP> dev <设备名称>ip route add default via 192.168.137.1 dev ens33添加特定网络路由: ip route add <目标网络> via <下一跳IP> dev <设备名称>ip route add 172.20.0.0/24 via 192.168.137.100 dev ens33 |
ip route del | 删除路由 | 指令格式:ip route del <目标网络> via <下一跳IP>删除指定路由: ip route del 172.20.1.0/24 via 192.168.137.100 |
iptables默认策略
以前的文章默认策略都是
ACCEPT,我个人觉得设置DROP策略更方便后续扩展,一般设置INPUT + FORWARD链为REJECT策略;因为其他程序直接使用iptables -A INPUT这种追加在最后就能生效,上文的策略最后基本上都加上了-A INPUT -j REJECT --reject-with icmp-host-prohibited,这个拒绝策略,如果加在这个后面就无法生效了。
- 变为
DROP后流量转发配置案例
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o enp0s8 -p tcp -m tcp -j MASQUERADE
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT
-A FORWARD -o enp0s8 -j ACCEPT
-A FORWARD -i enp0s8 -j ACCEPT
COMMIT