iptables 介绍
iptables basics
Introduction
iptables 是一个配置 Linux 防火墙的工具,是 netfilter 项目的一部分。
在 Linux Kernel 3.13 及以上版本中, nftables 将作为后继者取代 iptables 以成为更强大易用的防火墙工具
Basic Concepts
工作方式
-
iptables 作为防火墙, 一般是有 疏 和 堵 两种策略, 可以通过配置规则来决定是拒绝请求、转发请求或者改写请求数据。
-
iptables 包含 table, chain, rule, target 等概念
iptables 的有机组预定义好的 table, 每个 table 包含若干个预定义好的 chain, 每条 chain 都由 0 ~ N 个 rule 组成,
每个 rule 包含多个匹配条件,条件匹配后有个 target 作为最终的目标(action)-
几组预定义的 table,
- filter: 用于存放与防火墙相关配置的表,也是默认表
- nat: 用于 NAT 操作
- mangle: 用于对特定 packet 的数据修改
- raw: 用来配置规则,消除对特定 packet 的信息记录
- security: 用于 强制访问配置 的,如 SELinux 使用的规则
最常用的是 nat 和 filter 这两个 table
-
预定义的 chain:
- INPUT: 处理输入数据包
- FORWARD: 处理转发数据包
- OUTPUT: 处理输出数据包
- PREROUTING: 用于目标地址转换 (DNAT)
- POSTROUTING: 用于源地址转换 (SNAT)
-
预定义的 target:
- ACCEPT: 接收数据包
- DROP: 丢弃数据包
- REDIRECT: 重定向、映射、透明代理
- SNAT: 源地址转换
- DNAT: 目标地址转换
- MASQUERADE: IP 伪装(NAT)
- LOG: 日志记录
-
每个 rule 包含 predicate 条件和匹配该条件的 target (可以认为是 action),
匹配对应的 predicate 则执行对应的 target 动作,否则,忽略该条 rule,开始对下一条 rule 匹配。
如果匹配到 chain 的结尾,则返回到 跳转到跳转前的 chain -
filter 表包含的 chain 为: INPUT, FORWARD, OUTPUT
-
nat 包含的 chain 为: PREROUTING, FORWARD, POSTROUTING
-
mangle 包含的 chain 为: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
-
Examples
各种常用场景的使用: 封 ip、协议、端口,限制连接数、请求数、并发数等,转发端口、ip、协议控制,改写数据包内容
-
日常操作命令
# iptables -L -n -v # 展示 filter 表中的所有 chain 的规则, -n 以精确的 ip、数字替代名字, -v 展示详细信息 # iptables -t nat -L # 展示 nat 表中的所有 chain 的规则 # iptables -F # 清空 filter 中所有 chain 的 rules # iptables -t nat -F # 清空 nat 表中所有 chain 的 rules # iptables -t nat -F FORWARD # 清空 nat 表中的 FORWARD chain 中所有 rules # iptables -S [chain] # 列出 filter 表中的指明的 chain 中的所有 rules,如果 [chain] 不填,则列出对应 table 下所有 chain 的 rules # iptables -z [chain [rulenum]] # 清空 filter 表中 [chain] 中的某个 rule [rulenum], 如果 [chain] 或者 [rulenum] 不指定 # iptables -A chain rule-specification # 将 rule-specification 插入到 filter 表中的 chain 中
-
禁止访问本地 loop 地址, 如禁止访问本地 127.0.0.1 地址:
# iptables -A INPUT -i lo -d 127.0.0.1 -j DROP
-
禁止访问某个 ip 、某个网段、某个网址:
# iptables -A OUTPUT -d 192.168.1.1 -j DROP # 禁止访问 192.168.1.1 这个 ip # iptables -A OUTPUT -d 192.168.1.0/24 -j DROP # 禁止访问 192.168.1.0/24 这个网段
-
禁止访问某个 ip 的某种协议:
# iptables -A OUTPUT -i eth0 -d 54.222.178.154 -p tcp -j DROP # 禁止我们的 internal 服务器
-
开放本机端口:
# iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 开启本机 tcp 80 端口 # iptables -A INPUT -p icmp --icmp-type 8 -J ACCEPT # 允许被 ping 通 # iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 已经建立的连接能让数据进来
-
配置 ip 白名单:
# iptables -A INPUT -p all -s 192.168.1.0/24 -j ACCEPT # 允许 192.168.1.0/24 网段的机器访问当前机器 # iptables -A INPUT -p tcp -s 192.168.2.1 --dport 3306 # 允许 ip 为 192.168.2.1 的机器访问本机 3306 端口 (mysql 标准端口)
-
启动 nat 转发:
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 54.222.178.154 # 让 192.168.1.0/24 网段机器可以通过 54.222.178.154 访问网络
-
端口映射:
# iptables -t nat -A PREROUTING -d 127.0.0.1 -p tcp --dport 2222 -j DNAT --to-dest 54.222.178.154:22 # 访问本地 2222 端口会被转发到 internal 机器的 22 端口 (ssh 转发)
-
防止 tcp syn flooding attack:
# iptables -A INPUT -p tcp --syn -m limit --limit 5/second -j ACCEPT
-
字符串匹配
# iptables -A INPUT -p tcp -m string --algo kmp --string "test" -j REJECT --reject-with tcp-reset # tcp 包中一旦出现 "test" 数据,则 重置该 tcp 连接