对于公有云上的虚拟机,仅开放需要的端口。采用的方式常常是用 ACL(Access Control List)来控制 IP 和端口。
设置好规则,只有指定的 IP 段能访问指定的开放接口,这些规则的集合称为安全组。
安全组如何实现?
网络包进入一台机器的过程:
Netfilter 框架可在上图 5 个节点中插入 hook 函数,截获数据包,对数据包干预。
一个著名的实现,是内核模块 ip_tables。它在 5 个节点中埋下函数,从而可根据规则进行包的处理。按功能分为四大类:
- 连接跟踪(conntrack)
- 数据包过滤(filter)
- 网络地址转换(nat)
- 数据包的修改(mangle)
在用户态,可通过客户端程序 iptables,用命令行干预内核规则。内核的功能对于 iptables 命令,是表和链的概念。
iptables 的表有四种:raw–>mangle–>nat–>filter,优先级依次降低,raw 不常用,每个表可设置多个链。
1、filter 表处理过滤功能,主要包含3条链:
- INPUT 链:过滤所有目标地址是本机的数据包;
- FORWARD 链:过滤所有路过本机的数据包;
- OUTPUT 链:过滤所有由本机产生的数据包。
2、nat 表主要处理网络地址转换,可进行 Snat(改变数据包的源地址)、Dnat(改变数据包的目标地址),包含3条链:
- PREROUNTING 链:可在数据包到达防火墙时改变目标地址;
- OUTPUT 链:可改变本地产生的数据包的目标地址;
- POSTROUTING 链:在数据包离开防火墙时改变数据包的源地址。
3、mangle 表主要是修改数据包,包含5条链。
将 iptables 的表和链加入上图,形成下图:
有了 iptables 命令,可在云中实现一定的安全策略。例如将所有的门都关闭。
iptables -t filter -A INPUT -s 0.0.0.0/0.0.0.0 -d X.X.X.X -J DROP
-s 源 IP 地址段
-d 目标地址段
DROP 丢弃
打开 ssh
iptables -I INPUT -s 0.0.0.0/0.0.0.0 -d X.X.X.X -p tcp --dport 22 -j ACCEPT
手动配置比较麻烦,云平台上,一般允许一个或多个虚拟机属于某个安全组,而属于不同安全组的虚拟机之间的访问及外网访问虚拟机,都需要通过安全组过滤。
例如上图,所有网站的前端都在 Tomcat 里,对外开放 8080 端口,数据库使用 MySQL,开放 3306 端口。
为方便运维,创建两个安全组:
1、安全组 A,有 Tomcat 所在的虚拟机,允许任意 IP 地址 0.0.0.0/0 访问 8080 端口,仅允许管理员网段 203.0.112.0/24 访问 ssh 的 22 端口。
2、安全组 B,有 MySQL 所在的虚拟机,仅允许来自 A 的机器访问 3306 端口,仅允许管理员网段 203.0.112.0/24 访问 ssh 的 22 端口。
如何将安全组规则自动下发到每个安全组里的虚拟机?
两个 VM 都通过 tap 网卡连接到一个网桥上,但网桥是二层的,两个 VM 可随意互通,因而需要有一个地方统一配置这些 iptables 规则。
可多加一个网桥,然后每台机器跑一个 Agent,将用户配置的安全组变成 iptables 规则,放到这个网桥上。
iptables 中的 nat
设计云平台时,虚拟机网络和物理网络隔离,但虚拟机还是需通过物理网和外界通信,因而出物理网时,需进行网络地址转换 nat,可用 iptables 做。
转换源 IP 地址的,为 Snat;转换目标 IP 地址的,为 Dnat。
云平台的虚拟机只有私网 IP 地址,到达外网网口要做一次 Snat,转换为机房网 IP,出数据中心时,再转换为公网 IP。
公网 IP 比较贵,所以 Snat 时,所有虚拟机共享一个机房网和公网的 IP 地址,所有从外网网口出去的,都转换成这个 IP 地址。这种 Snat 是地址伪装 MASQUERADE。
结果返回时,nat 成哪个私网的 IP ?
用到 Netfilter 的连接跟踪(conntrack)功能。TCP 建立的“源/目标 IP + 源/目标 端口”标识的连接会放在 conntrack 表中,虚拟机请求163 网站时,虽然源地址已经 Snat 成公网 IP,但 conntrack 表中会记录这个连接,163 网站返回数据时,会根据该记录找到正确的私网 IP。
如何用虚拟机做服务器?即虚拟机中部署的是 163 网站。
给该网站配置固定的物理网 IP 和公网 IP。外部访问进来时,外网网口通过 Dnat 将公网 IP 转换为私网 IP,然后到达虚拟机中的 163 网站。返回结果时,外网网口会通过 Snat 将私网 IP 转换为那个分配好的固定公网 IP。