选题: ipatables 及 l7lter 的使用

摘要

ipatables 是一个常用的包过滤防火墙应用。但是,用户的安全设定实际上是由操作系统内部的一个数据包处理模块(netlter)执行的,我们可以把 iptables 看做一个客户端代理。iptables 的核心为四表五链。四表为 raw 表、mangle 表、net 表、lter 表。五链为 PREROUTING、INPUT、FORWARD、OUTPUT、POATROUTING。我们可以向 iptables 中加入不同的过滤规则,实现特定功能。在本次实验中我们测试了 iptables 的基本 accept、drop、reject 动作和 nat 过滤功能。

然而 netlter 不带有应用层过滤的功能。想要实现应用层协议的过滤,我们选用了 l7lter。l7lter 从 2013 年就没有维护,必须选择较老版本的内核才能成功使用 l7lter 提供的过滤协议,在本次实验中我们选用 centos6.9 进行实验。实验需要先对 Linux 内核打补丁,增加 l7lter 的功能模块。完成试验后,能针对性的过滤应用层协议为 http、QQ、迅雷等常见的应用层数据包。

**关键字:**iptables、l7lter、包过滤、防火墙、应用层网关

第一部分 iptables

1 简介

1.1 iptables 与 netlter

iptables 其实不是真正的防火墙,我们可以把它看做一个客户端代理。用户通过 ipta- bles 这个代理,将用户的安全设定执行到 netlter 中。netlter 才是真正的防火墙。netlter 是 Linux 操作系统内部的一个数据包处理模块,它具有如下功能:数据包内容修改、数据包过滤的防火墙功能。

1.2 链

进出报文从网卡到达用户空间需要经过多道关卡,这些关卡在 ipatables 中被称为链(chian),每个链上都放置了一串规则。图 1 简单形象地描述了一个数据包进出主机时会经过的链:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yWUbBUcF-1657181117156)(https://www.writebug.com/myres/static/uploads/2021/11/15/0980243c319185bb462d9a664eeea037.writebug)]

图 1: iptables 链:发送方的数据包到达网卡后,在内核空间内先经过 PREROUTING(转发前)链。当本机的内核支持 IP_FORWARD 时,数据包的目的地址个能不是本机。若目标为本机,数据包进入 INPUT 链,否则进入 FORWARD(转发)链和 POSTROUTING(转发后)链。本机发送报文时,数据包先经过 OUTPUT 链,再经过 POSTROUTING 链,最终经过网卡转发至其他主机。

1.3 表

具有相同功能的规则的集合叫做 ‘表’。不同功能的规则,我们可以放置在不同的表中进行管理。iptables 已为我们定义了 4 种表:

lter 表 负责过滤功能;

nat 表 负责网络地址转换功能;

mangle 表 拆解报文,作出修改,并重新封装;

raw 表 关闭 nat 表上启用的连接追踪机制。

每个链上的规则存在于不同的表如图 2 中:

PREROUTING raw 表、mangle 表、nat 表;

INPUT mangle 表、lter 表;

FORWARD mangle 表、nat 表、lter 表;

OUTPUT raw 表、mangle 表、nat 表、lter 表;

POATROUTING mangle 表、nat 表。

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级

图 2: 不同链上的规则允许存在的表

1.4 处理动作

处理动作在 iptables 被称为 target,常用的有:ACCEPT、DROP、REJECT、SNAT、MASQUERADE、DNAT、REDIREACT、LOG。

2、实验

2.1 基础命令

2.1.1 查看规则命令

查看对应表的所有规则。-v 表示 verbose,详细的。

iptables -t <表名> (-v) -L

查看指定表指定链的所有规则。-n 表示不解析 IP 地址,–line-number 表示显示规则的序号,-x 表示显示计数器的精确值。

iptables -t (--line-number) <表名>(-nvx) -L <链名>

为了方便上述选项常被表示为:

iptables -line -t <表名> -nvxL(<链名>)
2.1.2 添加规则命令

在某条链的尾部(-A)添加一条规则

iptables -t <表名> -A <链名><匹配条件> -j DROP
# 将原地址 192.168.1.146的包丢弃
iptables -t filter -A INPUT -s 192.168.1.146 -j DROP

在指定链的首部添加一条规则

iptables -t <表名> -I <链名><匹配条件> -j <动作>

在指定表的指定链的指定位置添加一条规则

iptables -t <表名> -I <链名><规则序号><匹配条件> -j <动作>
2.1.3 删除规则

按规则序号进行删除

iptables -t <表名> -D <链名><规则序号>

按照具体的匹配条件与动作进行删除

iptables -t <表名> -D <链名><匹配条件> -j <动作>

删除指定表中的指定链中的所有规则

iptables -t <表名> -F <链名>

删除指定表的所有规则

iptables -t <表名> -F

5.1.4 修改规则

修改指定表中指定链的指定规则

iptables -t <表名> -R <链名><规则序号><匹配条件> -j <动作>
iptables -t filter -R 3 -s 192.168.1.146 -j ACCEPT
# -s 192.168.1.146为原本的匹配条件,如果忽略此匹配条件,修改后的规则源地址可能会变成0.0.0.0/0

修改指定表的指定链的默认策略(默认动作),并非修改规则

iptables -t <表名> -P <链名> <动作>

5.1.5 保存规则

# 方法一
service iptables save
# 方法二
iptables -save >/etc/sysconfig/iptables
iptables -restore </etc/sysconfig/iptables

2.2 实验环境

使用 vmware fusion 搭建实验环境,使用虚拟主机 <=> 虚拟路由 <=> 虚拟服务器形式。虚拟主机和虚拟路由均为虚拟机,虚拟服务器在本机搭建。

vmware 默认使用 NAT 模式并使用虚拟网卡 vmnet8 与主机共享网络。具体结构如下图所示:

安卓 iptables 升级 安卓iptables下载_Python_02

图 3: vmware NAT 模式示意图: 我们在/Library/Preferences/VMware Fusion/vm- net8/dhcpd.conf 中配置虚拟 DHCP 服务器分配 ip 地址范围为 172.16.176.128- 172.16.176.254。两台试验用虚拟机使用固定 ip 172.16.176.253 和 172.16.176.137。vmnet8 的 ip 为 172.16.176.2。主机的 ip 为 192.168.1.2。

我们使用虚拟机 1 为客户端,虚拟机 2 为路由,主机网卡为服务器端。

2.2.1 配置路由表

一开始虚拟机 1 与虚拟机 2 的路由表如下图所示:

安卓 iptables 升级 安卓iptables下载_ipatables_03

(a)客户端虚拟机路由表

安卓 iptables 升级 安卓iptables下载_ipatables_04

(b)路由虚拟机路由表

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_05

图 4: 虚拟机路由表

配置客户端虚拟机路由表:删除第一条(默认网关为 vmware 虚拟网关),添加默认网关为路由虚拟机。添加方法与结果如下:

# 删除源默认网关
$sudo route del default
# 添加新默认网关
$sudo route add default gw 172.16.176.137

最终客户端路由表如下图所示:

安卓 iptables 升级 安卓iptables下载_源码_06

图 5: 客户端路由表

配置路由虚拟机转发功能:

temp@ubuntus:-$ sudo systl -w net.ipv4.ip_forward=1
2.2.2 验证配置正确

我们在客户端虚拟机 ping 服务器主机,使用 traceroute 观察转发路径。测试成功!

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_07

图 6: traceroute 测试结果

2.3 实验内容

2.3.1 测试基本功能

这一阶段我们使用虚拟机 1 和虚拟机 2 进行测试。虚拟机 2 在 8888 和 8889 端口分别跑有两个 http 服务。在虚拟机 1 上 curl 都能得到回显结果:

安卓 iptables 升级 安卓iptables下载_ipatables_08

图 7: curl 结果

ACCEPT/DROP icmp 包

设置虚拟机 2 的规则如下

# 先接受ICMP
iptables -A INPUT -p icmp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT

此时可以虚拟机 1 可以 ping 通虚拟机 2, 虚拟机 2 也会给虚拟机 1 应答:

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_09

  • wireshark 测试结果

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_10

ping 结果

图 8: icmp accept

清空 lter 表规则改为 drop icmp

# 再drop icmp
iptables -t filter -F
iptables -A INPUT -p icmp -j DROP
iptables -A OUTPUT -p icmp -j DROP

此时虚拟机 1 不能 ping 通虚拟机 2,并且虚拟机 2 无应答:

安卓 iptables 升级 安卓iptables下载_源码_11

wireshark 测试结果

安卓 iptables 升级 安卓iptables下载_l7lter使用_12

ping 结果

图 9: icmp drop:虚拟机 2 直接丢弃了虚拟机发送的 icmp 包。wireshark 抓包结果分析来看,只有单向发送,没有应答。

5.3.3 其他功能测试

过滤敏感词:虚拟机 2 过滤带有 ‘sex’ 的包

iptables -A INPUT -p tcp --dport 8888 -m string --algo kmp --string"sex" -j DROP

安卓 iptables 升级 安卓iptables下载_源码_13

图 10: 过滤敏感词:未添加条件前可以正常访问,添加条件后收不到应答。

虚拟机 reject 8889 端口收到的包:

iptables -A INPUT -p tcp --dport 8889 -j REJECT

安卓 iptables 升级 安卓iptables下载_ipatables_14

  • wireshark 结果

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_15

  • curl 结果

图 11: reject 8889 测试结果:虚拟机 1 访问虚拟机 2 的 8889 端口。由 wireshark 测试结果可知虚拟机 2 返回了一个 icmp 包,告知虚拟机 1 他被 reject。从而 curl 终止访问(不会和 drop 不停尝试访问)

2.3.4 NAT 功能测试

本阶段虚拟机 1 为客户端,虚拟机 2 为路由,本机为服务器端。虚拟机 2 不再开启服务,关闭 8888 和 8889 端口服务。主机在 8889 端口开启 http 服务。

由于虚拟机 2 扮演角色为防火墙,先置默认规则为 Drop

sudo iptables -P FORWARD DROP

然后设置允许访问外网主机的 8889 端口

sudo iptables -I FORWARD -s 192.168.1.2 -p tcp --dport 8889 -j ACCEPT

curl 测试能否访问主机 8889 端口:

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_16

图 12: curl 测试

wireshark 抓包结果:

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_17

图 13: wireshark 测试

第二部分 l7lter

3、实验

3.1 准备实验环境

使用 Centos6.9 和 ubuntu16.04 作为测试环境。下载 CentOS-6.9-x86_64-minimal.iso,Unbuntu16.04.iso。安装 CentOS 时出现过以下问题,已解决。

vmware-tools install failed 在安装时正会出现 vmware-tools install failed 错误无法进入系统,自定义虚拟机安装。

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_18

图 14: vmware-tools install failed

虚拟机未和 mac 处于同一子网内 原因为 eth0 网卡未设置成 boot 自启,修改/etc/syscong/network- scripts/ifcfg-eth0 中的 onboot 改为 yes。重启网络服务后正常 ‘service network restart’,

如下图所示:

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_19

图 15: 重启网络服务

基本配置 CentOS 作为转发端做以下配置:更新源、安装 Git、make、gcc、automake、autoconf、libtool 等软件包,配置好 SSH 和 vmware-tools 方便管理使用虚拟机:

  • 修改/etc/yum.repos.d/CentOS-Base.repo 配置文件,使用命令 makecache 更新源;
  • 下载软件包安装
root@centos ~]# yum install -y zsh git vim gcc automake autoconf libtool make patch && sh -c $(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
  • 修改配置文件/etc/ssh/sshd_cong 打开 22 端口的服务,使用命令重启 sshd:service sshd restart;
  • 挂载 vmware-tools 光驱在/mnt/cdrom 上,这是一个只读文件系统,把压缩包拷出来再解压,安装好了 vmware-tools,方便管理文件。

3.2 实验内容

3.2.1 编译内核

准备好 linux-2.6.35.8.tar.gz 和 netlter-layer7-v2.23.tar.gz 两个个文件来编译内核:

cd/roottarxflinux2.6.35.8.tar.gzC/usr/src\        &&tarxfnetfilterlayer7v2.23.tar.gz\    &&lns/usr/src/linux2.6.35.8/usr/src/linux
    cd/usr/src/linuxpatchp1</root/netsec/netfilterlayer7v2.23/kernel2.6.35layer72.23.patch
    cp/boot/config2.6.32696.el6.x86_64/usr/src/linux/.configmakemenuconfig

发现报错:unable to nd the ncurses libraries。原因是缺少 ncurses-devel,使用 yum install ncurses-devel 命令重新安装

编译内核时需要将以下几项编译进入内核模块:Netlter connection tracking support、“layer7” match support 、“iprange” address range match support、IPv4 connection tracking support (required for NAT) 和 Iptables Support。步骤如下所示:

  • 先进入 Core Netlter Conguration: Networking support —> Networking options—> Network packet ltering framework (Netlter) —> Core Netlter Conguration

见到如下界面:

安卓 iptables 升级 安卓iptables下载_源码_20

图 16: 内核编译 Core Netlter Conguration 选项

分别把 Netlter connection tracking support 、“layer7” match support 、“iprange” address range match support 添加到内核编译项中。

然后添加 FTP support 和 PPtP support (根据文档描述 If you don’t know what you’re doing, go ahead and enable all of them)

  • 再进入 IP: Netlter Conguration: Networking support —> Networking options —> Network packet ltering framework (Netlter)—>IP: Netlter Conguration 见到如下界面:

安卓 iptables 升级 安卓iptables下载_Python_21

图 17: 内核编译 Netlter Conguration 选项

把 IPv4 connection tracking support (required for NAT) 、Iptables Support 和 Full NAT 添加到内核编译选项中。

  • 开始编译内核,因为只分配了一个核,不用使用多核编译。等待一段时间编译完成, 最后安装内核模块并且写入新的 grub
make
make modules_install
make install
  • 这里出现了几个 module 找不到的错误,因为当前内核有的模块在编译新的 kernal 时没有选择。不影响这次实验,检查 grub.conf 里写入了新的内核的 grub,确实已经包含了 2.6.32 的 grub。

安卓 iptables 升级 安卓iptables下载_l7lter使用_22

图 18: 编译新内核后的/boot/grub/grub.conf 文件

  • 重新启动后查看新的内核版本,发现已经编译成功了:

安卓 iptables 升级 安卓iptables下载_源码_23

图 19: 重新启动后查看内核版本

3.2.2 安装 iptables
  • 下载 iptables-1.4.21.tar.bz2 源码。存入 netsec 目录,开始源码编译安装 iptables:
mkdir iptables
2cp/etc/init.d/iptables iptables/  #备份iptables启动脚本3cp/etc/sysconfig/iptablesconfig./    #备份iptables配置文档
tar xf iptables1.4.21.tar.bz2cp netfilterlayer7v2.23/iptables1.4.3forwardforkernel2.6.20 
    
    forward/libxt_layer7.iptables1.4.21/extensions#把l7filter的拓展模块移到iptables的extention目录

cd iptables1.4.21
./configure prefix=/usr with ksource=/usr/src/linux
make  #编译
make install  #安装
cp iptablesconfig/etc/sysconfig/iptablesconfig   #复制配置文档
cp iptables/iptables/etc/init.d/iptables   #复制启动脚本
  • 最后把/etc/init.d/iptables 启动脚本中的如下部分的/sbin 修改为/usr/sbin,如下所示。
if [! -x /usr/sbin/$IPTABLES]; then
    echo -n $"${IPTABLES}:usr/sbin/$IPTABLES does not exsit."; warning; echo
        exit 5 fi
3.2.3 安装协议特征包
  • lter 过滤各种协议特征需要协议特征包,直接解压安装即可:
tar xf l7 -protocols -2009-05-28
    cd l7 -protocols -2009-05-28
    make install
    ls protocols #查看支持的协议,如下所示

安卓 iptables 升级 安卓iptables下载_ipatables_24

图 20: l7lter 过滤支持协议

3.2.4 开始测试

测试环境:ubuntu16.04,CentOS 6.9. 两台主机在同一子网内,配置 Ubuntu 默认网关为 CentOS,这样 Ubuntu 如果需要连接互联网全部都需要通过 CentOS 转发流量。

1 首先查看 CentOS 的 ip 地址:192.168.125.174

安卓 iptables 升级 安卓iptables下载_ipatables_25

图 21: ifconfg 查看 CentOS 的 ip 地址

2 配置 CentOS 支持转发功能:修改 /etc/sysctl.conf ,把 net.ipv4.ip_forward 的值改为 1,最后使用 sysctl -p 完成修改;

net.ipv4.ip_forward=1
   net.ipv4.conf.default.rp_filter=1
   net.ipv4.conf.default.accept_source_route=0
   kernel.sysrq=0
   kernel.core_uses_pid=1
   net.ipv4.tcp_syncookies=1
   kernel.msgmnb=65536
   kernel.msgmax=65536
   kernel.shmall=4294967296

3 配置 Ubuntu 设置默认网关为 CentOS 的 ip 地址,先查看默认网关可以看到 vmnet8

的中有一个默认网关 192.168.125.2;

安卓 iptables 升级 安卓iptables下载_Python_26

  • 删除这个默认网关后添加 192.168.125.174 为默认网关,再次查看默认网关;
sudo route del default gw 192.168.125.22 
    sudo route add default gw 192.168.125.174
    route n

安卓 iptables 升级 安卓iptables下载_安卓 iptables 升级_27

图 22: 修改 Ubuntu 的默认网关

5 配置 iptables 进制 http 协议前 Ubuntu 的访问情况;

安卓 iptables 升级 安卓iptables下载_ipatables_28

图 23: 配置丢弃 http 包前的 Ubuntu 访问情况

6 然后查看虚拟路由表;

iptables A FORWARD s 192.168.125.0/24 m layer7-l7 proto http j DROP
iptables t filter L

安卓 iptables 升级 安卓iptables下载_源码_29

图 24: 配置丢弃 http 包后的 CentOS 虚拟路由表

7 配置 iptables 使用 l7lter 进制 http 访问后访问情况如下,实验成功。

安卓 iptables 升级 安卓iptables下载_源码_30

图 25: 配置丢弃 http 包后的 Ubuntu 访问情况

8 l7lter 支持的过滤协议中还包括 QQ、迅雷、pop3、telnet、tor、ssl 等。不过因为 l7lter 已经没有人在维护了,测试这些协议的时候出现一些 bug。就没有继续深究下去。