8.13 网络知识必知必会

image0

8.13.1 iptables

推荐文章:朱双印的 iptables 系列文章

从逻辑上讲。防火墙可以大体分为主机防火墙和网络防火墙。

主机防火墙:针对于单个主机进行防护。

网络防火墙:往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网。

网络防火墙和主机防火墙并不冲突,可以理解为,网络防火墙主外(集体), 主机防火墙主内(个人)。

从物理上讲,防火墙可以分为硬件防火墙和软件防火墙。

硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高。

软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低。

iptables其实不是真正的防火墙,我们可以把它理解成一个客户端代理,用户通过iptables这个代理,将用户的安全设定执行到对应的“安全框架”中,这个“安全框架”才是真正的防火墙,这个框架的名字叫netfilter

netfilter才是防火墙真正的安全框架(framework),netfilter位于内核空间。

iptables其实是一个命令行工具,位于用户空间,我们用这个工具操作真正的框架。

netfilter/iptables(下文中简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案,完成封包过滤、封包重定向和网络地址转换(NAT)等功能。

Netfilter是Linux操作系统核心层内部的一个数据包处理模块,它具有如下功能:

网络地址转换(Network Address Translate)

数据包内容修改

以及数据包过滤的防火墙功能

所以说,虽然我们使用service iptables start启动iptables“服务”,但是其实准确的来说,iptables并没有一个守护进程,所以并不能算是真正意义上的服务,而应该算是内核提供的功能。

概念相关

动作

image1

命令相关

# 查看 filter 表的所有链
iptables -t filter -L
iptables -L             # 不指定,默认就为 filter

# 查看其他表的规则
iptables -t nat -L
iptables -t mangle -L
iptables -t raw -L

# 从上面知道了如何查看指定表的规则,这边看看如何查看指定表里的某条链的规则
# 只要在后面直接加上 <链名> 即可
iptables -t nat -L POSTROUTING

如果要查看更详细的信息,就再加个 -v 参数

$ iptables -t nat -vL POSTROUTING
Chain POSTROUTING (policy ACCEPT 21M packets, 1241M bytes)
 pkts bytes target     prot opt in     out     source               destination
 179K   12M SNAT       all  --  any    eth0    172.20.22.0/24       anywhere             to:175.xx.xx.177

多出来的几个字段如何理解呢?我摘取《朱双印的个人日志》的解释到这边。

image2

iptables 默认为我们配置了域名反解(根据ip解析成域名),这个过程效率很低,我们可以指定参数 -n 跳过这个过程,从下面的例子可以看到 in 从上面的 any 变成了 * (0.0.0.0)

$ iptables -t nat -nvL POSTROUTING
Chain POSTROUTING (policy ACCEPT 21M packets, 1241M bytes)
 pkts bytes target     prot opt in     out     source               destination
 179K   12M SNAT       all  --  *      eth0    172.20.22.0/24       0.0.0.0/0            to:175.xx.xx.177

如果你想要展示行号,可以指定 --line-numbers, 在centos上可以缩短为 --line

$ iptables -t nat -nvL POSTROUTING
Chain POSTROUTING (policy ACCEPT 21M packets, 1241M bytes)
 pkts bytes target     prot opt in     out     source               destination
 179K   12M SNAT       all  --  *      eth0    172.20.22.0/24       0.0.0.0/0            to:175.xx.xx.177

从上面几个输出来看,pkts 和 bytes 都会自动转成 humanable 的单位。如果我们想看具体的数值,以方便查看变化,可以加个参数 -x

$ iptables -t nat -nvxL POSTROUTING

如果你想清空某个表中的指定链的规则,比如清空 filter 表中的 input 链。

iptables -F INPUT

添加规则

# ======================基本条件==================
$ iptables -t filter -I INPUT 2 -s 172.20.20.201 -j DROP
# -t : 指定 filter 表(不指定就默认filter)
# -I : 指定 INPUT 链,I 是 insert 即插入的意思
# 2 : 指定插入位置,插入在第二行。
# -s : 匹配规则,来源是 172.20.20.201
# -j : 动作,丢弃

# ======================其他常见条件==================

还可以为你的规则添加其他的匹配条件
-p : 匹配协议
-m : 指定模块,引入其他模块的方法做匹配条件,如:-m tcp --dport 22,就是使用tcp扩展模块下的 --sport 22 做为匹配条件。

-s : 匹配源地址,也可以添加多个 -s 72.20.20.201,172.20.20.202,到iptables那会分成两条规则
-d : 匹配目标地方,可以添加多个 -d 172.20.20.201,172.20.20.202,到iptables那会分成两条规则

--dport : 匹配目标端口,若要使用 --dport,必须指定 -p 协议类型 和 -m 模块类型,
--sport : 匹配源端口

# 指定多个端口
-m multiport --dport 22,80-88,multiport只能用于 tcp 和 udp 协议,必须配置 -p tcp 或者 -p udp 使用

# ======================扩展模块==================

# 匹配ip段
-m iprange --src-range 172.20.20.10-172.20.20.20
-m iprange --dst-range 172.20.20.10-172.20.20.20

# 链接数限制
# 每个客户端ip ssh 的连接数最多为两个
# --connlimit-mask 另外还用这个参数指定为哪个网段的ip进行限制
-m connlimit  --connlimit-above 2 -m tcp --dport 22 j REJECT

# 匹配报文包含的内容
# '-m string'表示使用string模块,'--algo bm'表示使用bm算法去匹配指定的字符串,其他可选项还有kmp,' --string "hello,world" '则表示我们想要匹配的字符串为"hello,world"
-m string --algo bm  --string "hello,world"

# 匹配连接数量,控制报文到达速率:http://www.zsythink.net/archives/1564
-m limit --limit 10/minute

删除规则

# 删除 filter表、INPUT链的第三条规则
$ iptables -t filter -D INPUT 3

# 指定匹配条件删除
$ iptables -D INPUT -s 172.20.20.201 -j DROP

# 删除某表中某条链的所有的规则
$ iptables -t filter -F INPUT

修改规则

# 可用指定第几条规则进行修改,如果使用这种,记得匹配全条件。
iptables -t fileter INPUT 2 -R -s 172.20.20.202 -j REJECT

# 也可以先删除,再添加(更加靠谱)
iptables -t fileter -D INPUT 2
iptables -t filter -I INPUT 2 -s 172.20.20.202 -j REJECT

# 修改链的默认动作
# 当报文没有命中规则,就按默认动作来做
# 那如何更改默认动作呢?
iptables -t filter -P FORWARD DROP

image3

保存规则

# 通过以上命令对规则的所有修改都是临时的,如果将iptables重启。修改就会失败。
# 所以要将规则尽快地保存到配置文件中。

# 在 centos6
service iptables save

# 在centos7
# iptables 是默认安装的,会用 firewall 代替 iptables
# 而iptables-service 需要用户自己安装。有了它,才能像centos6一样使用
service iptables save

# 输出规则到当前屏幕,并不会保存到配置文件
iptables-save

# 或者用重重向的方式输出到文件中
iptables-save > /etc/sysconfig/iptables.bak
iptables-restore < /etc/sysconfig/iptables.bak

8.13.2 arp欺骗

arp的中文释义是地址解析协议,全英文 address resolution protocol,是一个将局域网IP地址映射到网卡物理地址(MAC)的工作协议。

ARP欺骗(英语:ARP spoofing),又称ARP毒化ARP poisoning,网上上多译为ARP病毒)或ARP攻击,是针对以太网地址解析协议ARP)的一种攻击技术,通过欺骗局域网内访问者PC的网关MAC地址,使访问者PC错以为攻击者更改后的MAC地址是网关的MAC,导致网络不通。此种攻击可让攻击者获取局域网上的数据包甚至可篡改数据包,且可让网上上特定计算机或所有计算机无法正常连线。

arp -e 是一个很常用的命令,用于查看与本机有过通信的机器的arp table,主要是 ip与mac地址的映射。如果在 /etc/hosts 里有填写ip与域名的对应关系,Address一列就会显示域名。你也可以使用 arp -a 实现相同功能,只是 -a 是标准输出格式,没有像使用 -e 一样类似表格一样的输出效果。

image4

此时,我们ping一下 172.20.22.3 这个ip,显然是可以的,因为这里的其对应的mac地址是真实准确的。

但是如果我们将172.20.22.3的mac地址,手动改成一个错误了。那么是不是就不能通了呢?

首先,怎么为一个ip地址设置一个mac地址呢?

arp -s 172.20.22.3 00:1b:d1:bb:1d:d8

按如下命令,我们设置了一个在局域网内不存在的mac地址。

既然不存在,那当我们ping这个ip地址时,就会把icmp包发往一个不存在的地址,自然没有回应,你能看到的就是ping不通了。

[root@ws_controller01 ~]# ping 172.20.22.3 -c 1
PING 172.20.22.3 (172.20.22.3) 56(84) bytes of data.

--- 172.20.22.3 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

这就是我们据说的arp欺骗,设置通过错误的ip与mac映射关系,使得机器之间无法正常通信。

那如何恢复呢?

很简单,只要删除arp table里错误的ip与mac映射关系,然后再去ping这个ip,当arp cache里没有这个ip,就会重新发送arp广播,获取到正确的mac地址。

# 从arp cache 里删除
arp -d 172.20.22.3

# 重新 ping ip
ping 172.20.22.3

也可以通过 arping 获取到正确 mac 地址,然后再用 -s 手动配置上去。

[root@ws_controller01 ~]# arping -I eth1 172.20.22.3
ARPING 172.20.22.3 from 172.20.22.201 eth1
Unicast reply from 172.20.22.3 [00:1B:21:BB:29:96]  1.090ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

[root@ws_controller01 ~]# arp -s 172.20.22.3 00:1B:21:BB:29:96

其他几个 arp 的参数

# 指定与 eth1 网卡有关的arp条目
arp -e -i eth1

# 指定文件设置多个arp条目
arp -f /etc/ethers

8.13.3 ovs 流表

使用 ovs-ofctl dump-flows br-int 可以查看从 br-int 到 br0-ovs 的流表。

查看 0x0000/0x1fff 这一行后的 actions=mod_vlan_vid:4 ,其中的 4 是vlan id,意思是从虚拟机的网卡出来的包如果tag=4,在经过 br0-ovs 的时候,就会把 tag 去掉,不会被过滤掉,使其能把包发向公网。

假如不设置tag,br-int 上的包就不会流往 br0-ovs。

假如你的虚拟机是连在 br-int 上,而且没有tag,那么需要你手动加tag

virsh domiflist vm_domain
ovs-vsctl set port vnet0 tag=4

image5