概念
iptables 和 netfilter
- iptables 是命令行工具, 位于用户空间
- netfilter 是安全框架, 位于内核空间
- netfilter 是内核提供的数据包处理功能模块, 不是严格意义上的服务, 它能进行 NAT, 数据包内容修改, 数据包过滤
链
- 分为 prerouting, input, output, forward, postrouting
- 请求报文(到本机): client --> prerouting --> input
- 请求报文(转发): client --> prerouting --> forward --> postrouting --> 其他主机
- 响应报文: output --> postrouting --> client
表
- filter, 负责过滤, 对应内核模块: iptables_filter
- nat, 负责地址转换, 对应内核模块: iptables_nat
- mangle, 负责拆解报文, 修改及重新封装, 对应内核模块: iptables_mangle
- raw, 关闭 nat 表上启用的连接追踪机制, 对应内核模块: iptable_raw
- 优先级: raw --> mangle --> nat --> filter
rule(规则)
- 通过定义链和表而形成
- 规则存在内核空间的信息报过滤表中
- 规则指定了原地址, 目的地址, 传输协议(TCP, UDP, ICMP), 服务类型(HTTP, FTP, SMTP) 等要求
- 当规则匹配时, 就根据规则定义的方法处理(accept-放行, reject-拒绝, drop-丢弃)数据包, 如果数据包头符合这样的条件, 就"如此"处理这个数据
处理动作
- accept, 允许数据包通过
- drop, 丢弃数据包, 不会受到拒绝消息, 会受到超时消息
- reject, 拒绝数据包通过, 会受到拒绝消息
- snat, 原地址转换
- masquerade, 是 snat 的一种特殊形式, 用于动态, 临时会变的 ip 上
- dnat, 目的地址转换
- redirect, 本机做端口映射
链、表关系图示
定义规则
查看
# 默认查看 filter 表, 所有链信息
iptables -L
# 指定 nat 表
iptables -t nat -L
# 指定表, 指定链
iptables -t nat -L INPUT
# 常用
iptables -t filter --line-number -nL INPUT
# 参数解析
# -v 详细信息,包括命中的流量信息,生效的网卡信息
# -n 显示 ip 地址。默认将 0.0.0.0/0 显示为 any
# -x 显示到字节大小
# --line-number 显示条目行号
导入导出
# 导出
iptables-save > iptables.conf
# 导入
iptables-restore < iptables.conf
添加
- 默认规则
# 默认规则, 默认情况下 filter 表, INPUT 链, 丢弃所有
# 白名单使用 DROP 兜底,黑名单使用 ACCEPT 兜底
iptables -t filter -P INPUT ACCEPT
- 普通规则
# 指定表, 指定链, 指定源地址, 指定动作
# -A 插入到顺序最后
# -I 默认插入到首位
# -I 3 插入到序号 3 位置
iptables -t filter -A INPUT -s 192.168.248.79 -j DROP
删除
# 清空所有
iptables -F
# 指定表清空
iptables -t filter -F
# 指定表指定链清空
iptables -t filter -F INPUT
# 根据规则删除
iptables -t filter -D INPUT -s 192.168.248.79 -j DROP
# 根据序号删除, 删除条目后序号会前移
# iptables -t filter --line-numbers -vnL
iptables -t filter -D INPUT 3
设置流量匹配条件
地址(-s&-d)
# -s 或者 -d 不指定默认都是 0.0.0.0/0
# 单一 IP
iptables -t filter -A INPUT -s 192.168.248.79 -j ACCEPT
# 多个 IP
iptables -t filter -A INPUT -s 192.168.248.79,192.168.248.80 -j ACCEPT
# IP 段
iptables -t filter -A INPUT -s 192.168.248.79/24 -j ACCEPT
# 反选
iptables -t filter -A INPUT ! -s 192.168.248.79 -j ACCEPT
# 注: 这个条目的意思是,原地址不为 192.168.248.79 的流量被放行
# 并没有对原地址为 192.168.248.79 的流量做限制,示例这里还是会放行(使用默认策略)
# ---- "源地址不是 192.168.248.79 会通过" 和 "源地址是 192.168.248.79 不通过" 是不同的 ----
# 目的地址为 192.168.248.80 的数据包都会被丢弃
iptables -t filter -A INPUT -d 192.168.248.80 -j DROP
地址段(iprang --src-range&–dst-range)
# -m 指定 iprange 模块, 横线连接 ip 收尾, 支持 ! 反选
iptables -t filter -A INPUT -m iprange --src-range 192.168.248.75-192.168.248.78 -j REJECT
端口(tcp&udp --dport&–sport)
# 端口匹配属于扩展匹配条件
# 使用它必须指定 -p, 本例中是 tcp 协议
# -m 建议写全, 不写的话默认使用 -p 的协议同名模块
# 拒绝源地址为 192.168.248.79 且目的端口为 22 的流量
iptables -t filter -A INPUT -s 192.168.248.79 -p tcp -m tcp --dport 22 -j REJECT
# 支持反选,拒绝原地址为 192.168.248.79 且目的端口不为 22 的流量
iptables -t filter -A INPUT -s 192.168.248.79 -p tcp -m tcp ! --dport 22 -j REJECT
# 范围端口
# [start]:[end]
# :22 0-22, 25: 25-65535
iptables -t filter -A INPUT -s 192.168.248.79 -p tcp -m tcp --dport 22:25 -j REJECT
# 离散端口, 支持范围选择用法
iptables -t filter -A INPUT -s 192.168.248.79 -p tcp -m multiport --dport 22,25:90,993,3306 -j REJECT
协议(-p)
# 丢弃来自 192.168.248.80 的 tcp 请求
iptables -t filter -I INPUT -s 192.168.248.80 -p tcp -j DROP
# 支持如下: tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh
# 不指定协议类型时,默认表示所有类型的协议都会被匹配到,与使用-p all的效果相同。
网卡(-i&-o)
# 丢弃来自 em1 的 icmp 请求
iptables -t filter -I INPUT -i em1 -p icmp -j DROP
# prerouting, input, forward 因为有数据包流入, 有 -i 选项
# forward, output, postrouting 因为有数据包流出, 有 -o 选项
自定义链
# 在 filter 表创建自定义链 yang
iptables -t filter -N yang
# 为自定义链 yang 定义规则, 仅允许 192.168.248.80 流量通过
iptables -t filter -A yang -s 192.168.248.80 -j ACCEPT
iptables -t filter -A yang -j DROP
# 引用链
iptables -t filter -A FORWARD -j yang
# 删引用
iptables -t filter -D FORWARD -j yang
# 删除链
iptables -t filter -X yang
NAT
- DNAT
- 修改目的地址及端口
- 通常使用 NAT 表,PREROUTING 或 INPUT 链
- SNAT
- 修改源地址及端口
- 通常使用 NAT 表, OUTPUT 或 POSTROUTING 链
# 数据包发送时, 修改源地址, 从75改为80
iptables -t nat -A POSTROUTING -s 192.168.248.75 -j SNAT --to-source 192.168.248.80
# 数据包接收时, 修改目的地址, 从80改为75
iptables -t nat -A PREROUTING -d 192.168.248.80 -j DNAT --to-destination 192.168.248.75
# 修改目的地址和端口, 从80:80改为75:8080
iptables -t nat -A PREROUTING -d 192.168.248.80 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.248.75:8080