Ex5

实验过程

任务一

学习iptables的简单使用

查看iptables的用法 man iptables

在此处可以发现,iptables默认使用filter表,则 iptables -t filter -nvL 可以简写为 iptables -nvL

添加规则,允许所有网络访问本机,-A表示添加规则,INPUT指定添加规则的链,-j表示跳转到ACCEPT 方法。因为未指定任何其他选项,故为放行所有输入的数据包。

为FORWARD链添加默认规则,-P表示设置链的默认策略,这里我们将FORWARD链的默认策略设定为DROP,即丢弃转发包。

再将FORWARD链的规则改回ACCEPT

添加一条自定义链test,查看man手册可知可使用-N选项增加自定义链

删除自定义链test

任务二

熟悉iptables的各种参数

-p可以指定iptables规则匹配的协议,如允许INPUT链的所有tcp协议的数据包通过。

-s可以指定规则匹配的IP源地址,如在INPUT链允许来自192.168.0.1主机的数据包通过。

-d可以指定规则匹配的IP目的地址,如允许目的地址为192.168.0.1的数据包通过。

-i可以指定规则匹配的进入本地的网络接口,即网卡,如允许通过eth0网卡进入的数据包通过。

-o可以指定规则匹配离开本地使用的网络接口,如允许从eth0网卡离开的数据包通过。

这里要注意该匹配操作只能用于OUTPUT,FORWARD和POSTROUTING这三个链,因为INPUT和PREROUTING是没有离开网络的包的。 –sport用于指定规则匹配的通信源端口。如匹配从端口1111发起的tcp连接的数据包。

–dport用于匹配通信目的端口,如匹配目的端口为80的tcp连接的数据包。

可以对数据包的状态进行状态检测,一般有四种状态,分别是

(1)NEW:该包想要建立一个新的连接(重新连接或连接重定向)。(2)RELATED:该包是属于某个已经建立的连接所建立的新连接。(3)ESTABLISHED:该包属于某个已经建立的连接。(4)INVALID:该包不匹配于任何连接,通常这些包被DROP。

如允许目的端口为22的tcp连接且状态为NEW或ESTABLISHED的数据包通过

还可以指定一些特殊参数 –icmp-type指定ICMP连接的类型编号,如匹配icmp协议且icmp类型编号为8的数据包

-m multiport指定多端口号,如匹配类型为tcp连接且目的端口号为22,53,80,110的数据包。

-m iprange指定ip段,可以指定源地址或者目的地址的IP段,如禁止源地址在192.168.1.2-192.168.1.7之间的数据包通过。

-m connlimit –comlimit-above限定每个客户端产生的连接个数,如限制每个客户端最多同时与本地网络有100个tcp连接,超过的连接数据包拒绝。

-m limit限定连接速率,即限定匹配数据包的个数。如限制连接的最大数据包为6(一个客户端)

-m string限定字符串,使用–string来指定具体的字符串,使用–algo来指定算法为bm或者kmp。如丢弃从本地离开的匹配字符串tudou.com且使用bm算法的数据包。

iptables日志记录

rsyslog是CentOS 6以后的系统使用的日志系统,rsyslog是用来管理、记录日志的程序。rsyslog是一个C/S架构的服务,可监听于某套接字,帮其它主机记录日志信息。其配置文件为rsyslog.conf。我们设定将内核中警告级别的日志信息记录到 /var/log/iptables.log 并重启rsyslog服务使之生效。命令为

1
2
echo "kernel.warning /var/log/iptables.log" >> /etc/rsyslog.conf
systemctl restart rsyslog

配置iptables规则为将来自127.0.0.1的icmp数据包打印到日志且日志信息的前缀为 iptables icmp-localhost

验证规则

可见有匹配的数据包,查看日志信息

可以看到两个数据包的相关日志信息再次定义一些日志策略。如获取所有TCP日志且给出相应前缀为

1
iptables -A INPUT -p tcp -j LOG --log-prefix "iptables TCP"

获取所有UDP日志为

1
iptables -A INPUT -p udp -j LOG --log-prefix  "iptables UDP "

获取所有ssh日志为

1
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix  "iptables SSH "

自定义策略

禁止ping本地网络

1
iptables -A INPUT -p icmp -j icmp

在这里使用了REJECT来拒绝数据包,使用DROP丢弃数据包也能达到同样的效果,在实际应用场景中一般推荐使用DROP,因为DROP不会向客户端返回任何信息,可以避免在遭到攻击时让攻击者确定服务的存在。放行状态为已连接的数据包

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

只允许本机访问80端口

1
iptables -A INPUT -p tcp --src 127.0.0.1 --dport 80 -j ACCEPT

利用扩展模块limit限制每个客户端每分中最多发送25个数据包,总共最多发送100个数据包。

1
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT

任务三

安装openvswitch

1
2
3
4
yum -y install openvswitch
systemctl start openvswitch
systemctl enable openvswitch
systemctl status openvswitch

启动后查看状态如下

安装抓包工具tcpdump,网络配置工具bridge-utils

1
yum -y install tcpdump bridge-utils

ip link使用

查看使用帮助

新建网络接口eth0类型为vlan设置vlan id为10,添加一个新的虚拟网卡veth1,设定tunnel对端的网卡为veth2。查看网络设备信息

分别查看虚拟网卡的信息和vlan的信息

ip -d link show可以查看更详细的信息

ethtool命令用于查询和控制网络设备驱动程序和硬件设置,通过这个命令我们可以查看设置的虚拟网卡的信息,-S用于查看某一虚拟网卡的统计信息

启动刚刚设置的各个接口

删除增加的接口

可见接口已经被删除

ip netns使用

查看使用帮助

创建一个名为test的namespace并查看所有namespace,可以直接ip netns效果和ip netns list等同

在名为test的namespace中执行命令ip addr show

在test的namespace中启动bash,并执行命令,查看路由和防火墙,查看完成后退出bash。

给test添加接口tap1并启用

给tap1虚拟接口配置ip

删除test namespace

openvswitch使用

查看openvswitch安装的命令行工具

ovs-ovsctl命令是对交换机上网桥和端口等信息进行配置的命令。我们用它添加一个网桥br0并查看openvswitch中的所有网桥

判断网桥是否存在,新建一个网卡tap1并将网卡添加到网桥br0,查看网桥信息

在网桥br0中新建openvswitch网口并列出网桥br0中所有端口,这里将新建网卡和添加网卡到网桥合并为一条命令。

删除网桥br0上的网口tap2

设置网口tap1的vlan tag为10,查看tap1的属性

从网桥br0删除网口tap1, 并从系统删除虚拟网口tap1,删除网桥br0

任务四

开启主机路由转发

1
2
3
echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf
sysctl -p
sysctl -a | grep ip_forward

创建tag为10的内网1。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 新建网桥
ovs-vsctl add-br br0
# 添加网卡tap1至网桥
ovs-vsctl add-port br0 tap1 tag=10 -- set interface tap1 type=internal
ip link show
# 新建namespace ns-tap1
ip netns add ns-tap1
# 将tap1网卡放入namespace中
ip link set dev tap1 netns ns-tap1
# 查看ns-tap1的网络信息
ip netns exec ns-tap1 ip link show
# 启动ns-tap1网络空间中的网卡lo和tap1
ip netns exec ns-tap1 ip link set dev lo up
ip netns exec ns-tap1 ip link set dev tap1 up
# 将tap1的ip地址设为10.0.0.2/24
ip netns exec ns-tap1 ip addr add dev tap1 10.0.0.2/24
# 设置默认路由经过10.0.0.1
ip netns exec ns-tap1 ip route add default via 10.0.0.1
# 查看ns-tap1中的ip和路由信息
ip netns exec ns-tap1 ip addr show
ip netns exec ns-tap1 ip route show

创建tag为11的内网2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 添加网卡tap2至网桥
ovs-vsctl add-port br0 tap2 tag=11 -- set interface tap2 type=internal
# 新建namespace ns-tap2
ip netns add ns-tap2
# 将tap1网卡放入namespace中
ip link set dev tap2 netns ns-tap2
# 启动ns-tap2网络空间中的网卡lo和tap2
ip netns exec ns-tap2 ip link set dev lo up
ip netns exec ns-tap2 ip link set dev tap2 up
# 将tap2的ip地址设为10.0.1.2/24
ip netns exec ns-tap2 ip addr add dev tap2 10.0.1.2/24
# 设置默认路由经过10.0.1.1
ip netns exec ns-tap2 ip route add default via 10.0.1.1
# 查看ns-tap2中的ip和路由信息
ip netns exec ns-tap2 ip addr show
ip netns exec ns-tap2 ip route show

最终查看ns-tap2中的ip和路由信息如下

查看网桥br0此时的信息

测试两个内网的连通性,在ns-tap1中ping ns-tap2

可见网络不连通使用netns模拟器由器实现内网1与内网2互通

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 给br0网桥增加r1和r2网卡
ovs-vsctl add-port br0 r1 tag=10 -- set interface r1 type=internal
ovs-vsctl add-port br0 r2 tag=11 -- set interface r2 type=internal
# 新建一个网络空间router
ip netns add router
# 将网卡r1 r2放入router
ip link set dev r1 netns router
ip link set dev r2 netns router
# 启动router中的所有网卡
ip netns exec router ip link set dev lo up
ip netns exec router ip link set dev r1 up
ip netns exec router ip link set dev r2 up
# 给router中的网卡配置ip地址使其在同一个网段下
ip netns exec router ip addr add dev r1 10.0.0.1/24
ip netns exec router ip addr add dev r2 10.0.1.1/24
# 测试连通性
ip netns exec router ping -c 1 10.0.0.2
ip netns exec router ping -c 1 10.0.1.2
ip netns exec ns-tap1 ping -c 1 10.0.1.2

测试结果如下

可见内网此时已经互通

任务五

配置router中的数据包从r2网卡中离开网络并进行智能ip伪装

1
ip netns exec router iptables -t nat -A POSTROUTING -o r2 -j MASQUERADE

在ns-tap1网络中ping ns-tap2网络,查看router中的防火墙匹配到的数据包

打开两个终端利用tcpdump进行抓包分析。用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤。实验过程中我们使用-nei参数表示显示数据包的主机ip地址,将链路层信息显示出来,并指定监听的接口。

1
2
3
4
# 第一个终端中
ip netns exec ns-tap1 ping -c 1 10.0.1.2
# 第二个终端中
ip netns exec ns-tap2 tcpdump -nei tap2

监视到的结果为

可见数据包的确从r2经过继续配置SNAT,SNAT为源地址转换,能改变数据包的源地址。

1
2
3
4
# 清除之前的NAT配置
ip netns exec router iptables -t nat -F
# 配置到10.0.1.1网络的数据包从r2网卡离开网络且将源地址伪装成为10.0.0.0/24
ip netns exec router iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o r2 -j SNAT --to 10.0.1.1

同样,在两个网络间进行ping测试,并查看router iptables匹配情况

可见成功匹配到数据包配置DNAT,DNAT为目的地址转换,改变数据包的目的地址。

1
2
3
4
# 清除之前的NAT配置
ip netns exec router iptables -t nat -F
# 添加规则,匹配目标端口为80经过r1网卡的tcp连接,配置放在PREROUTING链上,因为要改变包的目的地址,故应在包开始路由前修改信息。
ip netns exec router iptables -t nat -I PREROUTING -i r1 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.2:80

进行连接测试并查看iptables的匹配情况

可见成功匹配到数据包配置重定向

1
2
3
4
# 清除之前的NAT配置
ip netns exec router iptables -t nat -F
# 添加规则,将目标端口为80的tcp连接的目标端口重定向为81
ip netns exec router iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 81

进行连接测试并查看iptables的匹配情况

可见重定向成功配置网络防火墙,允许内网1访问内网2

1
2
3
4
5
6
# 清除之前的NAT配置
ip netns exec router iptables -t nat -F
# 清除所有iptables配置
ip netns exec router iptables -F
# 允许从内网1来的数据包进入内网2
ip netns exec router iptables -A FORWARD -s 10.0.0/24 -d 10.0.1.0/24 -j ACCEPT

内网1 ping 内网2并查看iptables匹配情况

拒绝内网1访问内网2,只需要将刚才的规则ACCEPT修改为DROP或REJECT即可,配置完成后查看匹配情况

可见此时内网1确实无法访问内网2且匹配到了对应的数据包拒绝内网1访问内网2的80服务

1
2
3
ip netns exec router iptables -F
# 将目标为80端口的tcp数据包丢掉
ip netns exec router iptables -A FORWARD -s 10.0.0/24 -d 10.0.1.0/24 -p tcp --dport 80 -j DROP

内网1访问内网2的80服务并查看匹配情况

可见数据包匹配成功,且内网1无法访问内网2的80服务

实验六

查看上一次实验的实验环境

清空上一次的实验配置

搭建新的实验环境,配置内网1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 添加网桥br0
ovs-vsctl add-br br0
# 添加虚拟网卡qvo-tap1 并设置tunnel另一端网卡为qvb-tap1
ip link add qvo-tap1 type veth peer name qvb-tap1
# 启动qvo-tap1和qvb-tap1网卡
ip link set qvb-tap1 up
ip link set qvo-tap1 up
# 使用brctl来配置网桥,addbr添加网桥qbr-tap1
brctl addbr qbr-tap1
# 启动网桥qbr-tap1
ip link set qbr-tap1 up
# 将qvb-tap1网卡添加至网桥qbr-tap1
brctl addif qbr-tap1 qvb-tap1
# 将qvo-tap1 tag设置为10且添加到br0网桥中
ovs-vsctl add-port br0 qvo-tap1 tag=10
# 新建虚拟网卡tap1,相当于用户主机的网卡
ip link add tap1 type veth peer name tap11
# 将tap11添加到qbr-tap1网桥中
brctl addif qbr-tap1 tap11
# 启动tap11网卡
ip link set tap11 up
# 添加网络空间ns-tap1,作为内网1
ip netns add ns-tap1
# 将tap1网卡添加到ns-tap1空间中
ip link set dev tap1 netns ns-tap1
# 启动ns-tap1中的网卡
ip netns exec ns-tap1 ip link set dev lo up
ip netns exec ns-tap1 ip link set dev tap1 up
# 为tap1配置ip地址为10.0.0.2/24
ip netns exec ns-tap1 ip addr add dev tap1 10.0.0.2/24

配置完成后查看网桥信息和内网1中的ip信息

内网2的配置方法类似,不再赘述,配置完成后查看网桥信息和内网2中的ip信息

在内网1中测试测试二层同网段通信

可见同网段中的网络可以通信配置桥接模式防火墙即br_netfilter。加载br_netfilter内核模块并查看加载情况

修改配置以便桥接模式防火墙可以监控网桥中的arp ipv4 ipv6数据包

1
2
3
echo "net.bridge.bridge-nf-call-arptables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf

使配置生效,查看生效的配置信息

将FORWARD链所有流量导入自定义链

1
2
3
4
# 新建自定义链openvswitch-forward
iptables -N openvswitch-forward
# 添加规则将FORWARD所有流量导入openvswitch-forward链
iptables -A FORWARD -j openvswitch-forward

导入后查看iptables如下

1
2
3
4
5
6
7
# 添加in方向链表
iptables -N openvswitch-i-tap1
# 添加out方向链表
iptables -N openvswitch-o-tap1
# 将从openvswitch-forward中获得的匹配physdev信息的数据包导入这两条链表之中
iptables -A openvswitch-forward -m physdev --physdev-out tap11 --physdev-is-bridged -j openvswitch-i-tap1
iptables -A openvswitch-forward -m physdev --physdev-in tap11 --physdev-is-bridged -j openvswitch-o-tap1

导入后查看iptables如下

给内网1添加规则

1
2
3
4
5
6
7
8
# 新建fallback链
iptables -N openvswitch-fallback
# 新建一个ip集合名为ipv4-tap1使用的存储方法为hash,数据类型为net
ipset create ipv4-tap1 hash:net
# 设定匹配源地址在新建的ipv4-tap1集合中包含set的数据包,将这些数据包返回
iptables -A openvswitch-i-tap1 -m set --match-set ipv4-tap1 src -j RETURN
# 其余数据包导入新链openvswitch-fallback
iptables -A openvswitch-i-tap1 -j openvswitch-fallback

给内网1添加out方向规则,即给openvswitch-o-tap1添加规则

1
2
3
4
5
# 添加新链 openvswitch-s-tap1
iptables -N openvswitch-s-tap1
# 将所有流量导入新链然后将这些流量返回
iptables -A openvswitch-o-tap1 -j openvswitch-s-tap1
iptables -A openvswitch-o-tap1 -j RETURN

给内网1添加安全规则

1
2
3
4
5
6
7
8
# 这里是将tap1的ip地址赋值给tap1_ip变量,第一条指令可以获得tap1网卡的ip信息,再使用awk处理,将'/'之前的文本选择出来,再使用awk选择用空格分割的四个字符串中的第四个,即ip地址。
tap1_ip=`ip netns exec ns-tap1 ip -o -f inet addr show tap1 | awk -F'/' '{print $1}'|awk '{print $4}'`
# 同样先获得tap1的往哪看信息,然后选择出ether网卡信息所在的行并用awk获取mac地址赋值给tap1_mac
tap1_mac=`ip netns exec ns-tap1 ip link show tap1 | grep "link/ether"|awk '{print $2}'`
# 配置防火墙规则,源地址为tap1网卡的地址,mac为tap1的mac含有comment的数据包并给出自定义信息再返回
iptables -A openvswitch-s-tap1 -s $tap1_ip/32 -m mac --mac-source $tap1_mac -m comment --comment "Allow traffic from defined IP/MAC pairs." -j RETURN
# 丢掉匹配后的包
iptables -A openvswitch-s-tap1 -j DROP

匹配的过程

配置好后iptables的情况

拒绝没有匹配的流量

1
iptables -A openvswitch-fallback -m comment --comment "Default drop rule for unmatched traffic." -j DROP

测试内网1和内网2的连通性

ping 不通,可见二层防火墙策略已经生效在刚刚定义的ipset ipv4-tap1中添加内网2的ip地址,再次ping验证连通性,ipset就是用来设置一个ip集合,可以用来帮助配置iptables规则生效的地址集。

可见可以ping通且匹配到了对应的数据包验证内网1能否修改ip mac地址

1
2
3
4
# 删掉之前tap1网卡对应的ip
ip netns exec ns-tap1 ip addr del dev tap1 10.0.0.2/24
# 重新给网卡配置ip
ip netns exec ns-tap1 ip addr add dev tap1 10.0.0.4/24

可见已经不能ping通且iptables匹配到了应该丢弃的数据包

1
2
3
4
# 删掉修改的ip重新设置为之前的ip,修改网卡的MAC地址
ip netns exec ns-tap1 ip addr del dev tap1 10.0.0.4/24
ip netns exec ns-tap1 ip addr add dev tap1 10.0.0.2/24
ip netns exec ns-tap1 ip link set dev tap1 address 16:f7:55:f5:d7:ac

可见不能ping通且iptables匹配到了应该丢弃的数据包。以上两次修改说明只有iptables中指定的ip和MAC传递过来的数据包才能通过防火墙。