iptables 常用配置指南

373 阅读12分钟

摘要:本文主要介绍iptables的常规配置,传统的45链。

来源资料

说明

请求流量图

image.png

常用参数说明

命令格式

  • 官方的:iptables [-t table] command [match] [target/jump]
  • 我们一般拆分的:iptables [-t table] -rule-action [chain] -matching-criteria

规则表

表名称拥有规则链说明
natPREROUTING, OUTPUT, POSTROUTING用于网络地址转换
manglePREROUTING, POSTROUTING, OUTPUT, INPUT, FORWARD修改数据包内容
filterFORWARD, INPUT, OUTPUT过滤数据包
rawPREROUTING, 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指定数据包的协议类型,如 tcpudpicmp 等
--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表的INPUT22端口的校验

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.280端口
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