前言
- 本文对 iptables 1.6.x 适用
- iptables 下载(版本列表/历史版本):iptables Release of the netfilter/iptables project
表、链、规则
iptables 有四张表
filter 用于过滤 nat 用于网络地址转换 mangle 用于给数据包做标记以修改分组数据的特定规则 raw 表则独立于Netfilter连接跟踪子系统
- iptables 命令在不显式指定表时,默认 filter 表
- iptables 3 种数据包经过的链(chain)
- iptables 数据包详细走向图
iptables 常见 target
ACCEPT # 允许数据包通过
DROP # 丢弃数据包
REJECT # 拒绝数据包通过
SNAT # 源地址转换
MASQUERADE # 地址欺骗,自动化的snat
DNAT # 目标地址转换
REDIRECT # 重定向
LOG # 将数据包信息记录到 syslog 日志
QUEUE # 排队
RETURN # 返回
iptables 防火墙为什么不占用端口?
- 或许更准确的表述是:Linux 下 iptables 在做端口转发时为啥不占用端口?
- 因为不占用端口,所以不能用 netstat 命令查看。
- OSI模型与TCP/IP模型
iptables 工作在 OSI 模型的2/3/4层,做端口转发时,只需要查看和转换运输层的端口号,并不需要占用。以下摘自《计算机网络(第5版)》(谢希仁)175页。
应当指出,从层次的角度看,NAPT 的机制有些特殊。
普通路由器在转发 IP 数据报时,对于源 IP 地址或目的 IP 地址都是不改变的。但 NAT 路由器在转发 IP 数据报时,一定要更换其 IP 地址(转换源 IP 地址或目的 IP 地址)。
其次,普通路由器在转发分组是,是工作在网络层。但NAPT 路由器还要查看和转换运输层的端口号,而这本来应当属于运输层的范畴。也正因为这样,NAPT 曾遭受一些人的批评,认为 NAPT 的操作没有严格按照层次的关系。
实例
只允许
192.168.1.0/24
网段的192.168.1.22
访问本机6389
端口sudo iptables -I INPUT -s 192.168.1.0/24 -j DROP sudo iptables -I INPUT -s 192.168.1.22 -p TCP --dport 6389 -j ACCEPT
iptables 进行 url 过滤
# iptables 其实不是真正对 url 进行过滤,只是对传送的数据包内容进行过滤 # 而 http 头中含有目标 url # 关于 -m 参数,man iptables 只有几句简介, # 详细信息需要在 man iptables-extensions 里面进一步查询 # 开启 # 过滤掉含有 qq.com 的 url # ACCEPT 没用,因为 url 只在 http 头那个包 sudo iptables -A OUTPUT -m string --string "qq.com" --algo bm -j DROP # 如果本机是 squid 服务器,可以通过 INPUT 链过滤 sudo iptables -A INPUT -m string --string "qq.com" --algo bm -j DROP # 对于 nat 转发的内容过滤 sudo iptables -A FORWARD -m string --string "qq.com" --algo bm -j DROP # 查看 sudo iptables -nL --line-numbers # 移除(最后的数字为加 --line-numbers 参数后 num 显示的序号) sudo iptables -D OUTPUT 2
移除过滤规则示例
# 查看 sudo iptables -t filter -nL --line-numbers # 移除。最后的数字为加 --line-numbers 参数后 num 显示的序号 sudo iptables -t filter -D FORWARD 1
iptables限制同一 IP 连接数
sudo iptables -I INPUT -p tcp -j REJECT --reject-with tcp-reset -m connlimit --connlimit-above 20 sudo iptables -I FORWARD -p tcp -j REJECT --reject-with tcp-reset -m connlimit --connlimit-above 10
端口转发
- 监听本机 7777 端口,将数据转发到 192.168.7.8 的 8888 端口,实现 TCP 数据转发。
- 以下步骤在 Ubuntu 18.04 下实测可用
清空规则
sudo iptables -F sudo iptables -X sudo iptables -t nat -F sudo iptables -t nat -X sudo iptables -t mangle -F sudo iptables -t mangle -X sudo iptables -P INPUT ACCEPT sudo iptables -P FORWARD ACCEPT sudo iptables -P OUTPUT ACCEPT
开启端口转发(/etc/sysctl.conf)
# 开启端口转发 sudo sysctl net.ipv4.ip_forward=1 # 查看 sudo sysctl -a | grep ip_forward
配置端口转发
# 转发规则配置(可添加详细的限制规则) sudo iptables -t nat -A PREROUTING -p tcp --dport 7777 -j DNAT --to-destination 192.168.7.8:8888 sudo iptables -t nat -A POSTROUTING -j MASQUERADE # 查看 sudo iptables -t nat -nL
MASQUERADE 在 Ubuntu 18.04 下可能引起 dns 服务异常,参见 How to allow DNS lookup with iptables on Ubuntu 18.04 server,可改成如下配置:
# tap0 为转发出口网卡代号 # 本例 tap0 虚拟网卡 iptables -t nat -A POSTROUTING -o tap0 -j MASQUERADE # OR (192.168.7.1 为虚拟网卡地址) iptables -t nat -A POSTROUTING -o enp4s0 -j SNAT --to-source 192.168.7.1
移除示例
# 查看 sudo iptables -t nat -nL --line-numbers # 移除。最后的数字为加 --line-numbers 参数后 num 显示的序号 sudo iptables -t nat -D POSTROUTING 1
端口查看
sudo netstat -anpt | grep 7777
可以看到 iptables 端口转发的连接并不能用 netstat 查看,因为 NAPT 并不需要占用端口,7777 端口仍然可以被其它程序使用。若需查看,可使用netstat-nat或
conntrack
命令。sudo conntrack -L -p tcp --src-nat # OR sudo conntrack -L -n
备份与还原
- 以下步骤在 Ubuntu 18.04 下实测可用
可以用定时任务执行备份
iptables-save > /home/qbit/iptables_rules_bak/iptables.rules
- 以下重点讲开机自动还原
创建文件
/etc/systemd/system/rc-local.service
在 rc-local.service 里面添加如下内容
[Unit] Description=/etc/rc.local Compatibility ConditionPathExists=/etc/rc.local After=network.target [Service] Type=forking ExecStart=/etc/rc.local start TimeoutSec=0 StandardOutput=tty RemainAfterExit=yes SysVStartPriority=99 [Install] WantedBy=multi-user.target
创建文件:/etc/rc.local 并添加如下内容
#!/bin/bash /sbin/iptables-restore < /home/qbit/iptables_rules_bak/iptables.rules exit 0
给 rc.local 添加可执行权限
sudo chmod 754 /etc/rc.local # centos7 sudo chmod 754 /etc/rc.d/rc.local
启用服务(开机自启动)
sudo systemctl enable rc-local # 等价于 ln -s /etc/systemd/system/rc-local.service /etc/systemd/system/multi-user.target.wants/
启动服务并检查状态
sudo systemctl start rc-local.service sudo systemctl status rc-local.service
- 重启服务器验证是否配置成功
Linux 历代防火墙
ipfwadm > ipchains > netfilter/iptables/ip6tables/arptables > nftables/nft
本文出自 qbit snap
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。