Blog Home
Updated: 2023 Oct 09

IPtables HowTo

iptables 是用于 linux 内核防火墙的命令行配置工具。它工作在用户态,而非内核态。它是通过接口控制内核模组 netfilter 来完成操作的。新版本内核使用了 nftables(nft) 作为用户态接口,不过仍提供 iptables 命令作为兼容。下面我们仅讨论 iptables 接口命令。

iptables 使用 Xtables 框架。该框架存在表(tables)、链(chain)和规则(rules)三个层面。在每个表中,各种链由各种不同的规则组成。不同链作用在不同的位置,不同表又作用在不同的链位置上。这就是它们三者的大致关系。

iptables.png

表(tables)

  • filter 表 针对数据包的过滤操作,默认表。
  • nat 表 针对连接进行地址转换操作。
  • mangle 表 针对数据包的更改操作。
  • raw 表 针对配置数据包确保不会被系统跟踪。
  • security 表 针对强制访问控制网络规则操作。

日常使用最多的是 filter 表和 nat 表。

链(chain)

  • INPUT 输入(接收)的链 //应用于传入的数据包
  • OUTPUT 输出(传输)的链 //应用于发送的数据包
  • FORWARD 转发(传输)的链条 //对转发数据包的应用
  • PREROUTING 接收时转换目的地址(DNAT)的链。 时机比 filter 适用的规则更靠前。//路由前应用
  • POSTROUTING 发送时转换源地址(SNAT)的链。 时机在 filter 之后在数据包发送之前。//路由后应用

规则(rules)

每个规则包含一组条件(conditions)和一个操作(action)。当数据包通过时,防火墙会按照顺序检查是否满足特定的规则列表,并根据规则作出相应的操作。在设置规则时,为确保安全应使用白名单而非黑名单,即假定所有来源数据包都不可信,应全部丢弃,仅根据需求创建规则,供必要数据进入。但应注意创建规则应从宽到严的顺序,以防被锁到外边。

表和链对应关系

  • filter => INPUT、OUTPUT、FORWARD
  • nat => POSTROUTING、PREROUTING、OUTPUT
  • mangle => POSTROUTING、PREROUTING、INPUT、OUTPUT、FORWARD
  • raw => PREROUTING、OUTPUT

常用命令含义

chain操作基础命令

  • -A(–append) 向指定链添加一个或多个新规则
  • -C (–check) 检查是否存在与规范匹配的规则
  • -D(–delete) 从指定链中删除一个或多个规则
  • -I(–insert) 在指定的链中指定规则编号并插入规则
  • -R (–replace) 替换所选链中的规则
  • -L (–list) 列出所选链中的所有规则
  • -S (–list-rules) 打印所选链中的所有规则。
  • -F (–flush) 重置指定链,未指定则默认全部,操作需谨慎。
  • -P(–policy) 将指定链的策略设置为指定目标
  • -N(–new-chain) 创建一个新的用户定义链
  • -E (–rename-chain) 将用户指定的链重命名为用户提供的名称
  • -X(–delete-chain) 删除指定用户定义链

rule操作常用参数

  • -s (–source) 指定数据包的发送源。
  • -d (–destination) 指定数据包目的地。指定方法与 -s 相同。
  • -p (–protocol) 要检查的数据包协议。可以指定的协议是 tcp、 udp、 icmp 或 all 中的任意一个或数值。
  • -i (–in-interface) 指定接收数据包的接口名称。eth0,eth1,等等。
  • -o (–out-interface) 指定目标接口名称。
  • -j (–jump) 指定目标(accept、 drop、 reject)
  • -g (–goto) 指定链继续处理
  • -m (–match) 指定要使用的扩展模块

action操作常用参数

  • ACCEPT 允许数据包通过
  • DROP 丢弃数据包。不返回响应。
  • REJECT 拒绝数据包并回复 icmp 消息
  • REDIRECT 重定向到特定端口
  • LOG 记录匹配的数据包

一般操作步骤实例演示

1. 列出所有规则

iptables -L -n --line-numbers -v

2. 保存现有规则

导出现有规则,防误删或重启丢失

iptables-save > firewall.ipt

加载规则,误删或重启丢失可重新装载

iptables-restore < firewall.ipt

由于iptables默认重启后会丢失,可使用 iptables-persistent 持久化。

sudo apt install iptables-persistent

3. 重置默认链的默认策略,以防被锁在外边

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT

4. 重置规则(policy的设置不会删除,这也是我们为什么要做上一步的原因)

清除规则,切记:在操作此命令之前一定要确保默认策略为ACCEPT,不然会被锁到外边。

iptables -F

删除用户自定义链

iptables -X

5. 设置任何与已建立的连接相关的传入或传出数据包都应该被允许通过

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

6. 允许SSH 连接

iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT

7. 将默认策略更改为DROP,切记:在操作此命令之前一定要确保不会被关到外面。

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

iproute 基本操作

显示链路列表

ip link list/ls/show

显示IP地址

ip address/addr show

显示ip路由

ip route show

显示arp缓冲表

ip neigh show

删除arp缓冲

ip neigh delete 192.168.0.43 dev eth0 

打印规则列表

ip rule list/ls/show

打印local表[default表为空]

ip route list table local/main/default

添加rule规则

echo 200 John >> /etc/iproute2/rt_tables
ip rule add from 10.0.0.10 table John
ip rule ls

ip route add default via 195.96.98.253 dev ppp2 table John
ip route flush cache

常见案例

允许已建立的会话

sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

允许特定端口上的传入流量

sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT

阻塞传输

sudo iptables -A INPUT -j DROP

插入允许环回网络传输

如果按照上面的顺序,若直接追加允许环回网络,则根本没用了。此时,我们可以插入到最前端或在全部阻塞规则之前。因为执行是按顺序的。

sudo iptables -I INPUT 1 -i lo -j ACCEPT

上面的 1 是index,可以通过下面的命令查看。

iptables -L -n --line-numbers

记录丢弃日志

sudo iptables -I INPUT 5 -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

可以通过tail系统日志查看

sudo tail -f /var/log/syslog | grep "iptables denied"

reference

Comments:

Email questions, comments, and corrections to hi@smartisan.dev.

Submissions may appear publicly on this website, unless requested otherwise in your email.