画出解密后的路径:VPN 设备在哪一段落实策略
停在加密监听口上的图,并不能说明真正重要的策略。先画出解密后的路径,再按请求跨越了什么来比较部署位置。
厂商的图通常画到加密监听口为止,因为那是唯一有公网地址的一段。决定安全态势的问题,是解密之后发生了什么,数据包变成普通 IP,可以到达路由表允许的任何地方。没人画过那一段,也就没人对它负责。下面的 runbook 先把这段画出来,再按解密后的请求实际跨越了什么来比较各种部署位置。
画解密之后的报文,而不是解密之前
外层路径是厂商会写进文档的部分:一个公网端点、一条放行该连接的传输策略,以及一个终结该连接的服务。内层路径从数据包丢掉隧道头的那一刻开始,此后由与隧道毫无关系的路由和过滤规则支配。把两者画在同一页上,因为只画前者的图会暗示接入和授权是同一个决定。它们不是,而两者之间的缺口正是大多数部署出错的地方。
内层这一段要写成带编号、点名设备类型的序列,而不是一根箭头。箭头掩盖了请求到底有没有经过过滤器,而经不经过正是全部问题所在。下面每一步都点名该跳的设备以及在那里生效的规则集,于是一条缺失的过滤会表现为一个空洞,而不是被一根线暗示过去。
- 远程客户端:发起隧道的用户设备。
- 边缘策略:把外层传输放行到公网监听口的规则集。
- 终结设备:完成解封装、把报文交给普通 IP 的 VPN 端点。
- 内层过滤器:限制客户端到服务流量的转发规则或安全组规则集。
- 应用主机:接收解密后请求的服务。
两套策略,两个负责人
外层策略回答谁能建立隧道,它体现在放行传输到终结服务的规则里。内层策略回答一个已通过身份验证的用户能到达哪些服务,它存在于转发规则、安全组或应用自身之中。一台设备可以同时承载两者,多台设备的设计也仍然两者俱备。把它们分开命名,才能在一个用户访问不到应用时,说清是哪一层失效了。
证书、多因素认证这类接入控制只回答身份问题,别的一概不回答。它们不决定部署位置,也不会在用户进入内网之后按资源授权。
部署位置决定请求跨越哪一条边界
常见的部署位置有三种,每一种都会改变解密后的请求跨越哪条边界。比较的维度是:那里终结了什么、谁能看到明文、还有哪一层控制能否决请求、以及设备故障时会同时带走什么。下表用这四列而不是一个笼统的问题,因为每个答案都是一个独立的设计决定。
| Placement | What terminates there | What sees plaintext | Which control can still deny | Failure domain |
|---|---|---|---|---|
| Termination in a dedicated segment | A dedicated VPN endpoint | The endpoint and anything on its segment | The filter between that segment and the application | The segment path can bypass the filter if no rule sits on it |
| Termination on the edge firewall | The firewall's public listener | The firewall, after decapsulation | The firewall's inner rule set | Admission and inspection fail together |
| Termination on the protected LAN | The appliance's LAN leg | Every host on the protected LAN | Only a host control or a downstream gateway | The appliance and the protected hosts fail together |
第三种位置会悄悄地把管控拿掉,因为设备在受保护网段上有一条图里未必画出来的直连路径。要查的是接口和路由,而不是那张图:ip route get 10.20.5.10 会告诉你报文从哪个接口发出,而答案往往不是设计所假设的那个。防火墙在态势之间控制流量的经典角色,正如NIST SP 800-41,在这里是个有用的检验,因为一台对受保护网络有不受限直连的设备,其实管控不了什么。路由查询比汇报用的那张图更诚实。
管理面应当走它自己那条被明确放行的路径。允许用户访问应用,从来不需要同时允许他们访问设备的控制接口,这两项权限应该由不同的规则授予。两条路径要分别审计,因为共用一条规则会掩盖到底是哪一条被打开了。
地址转换会改变下游规则能看见什么
源地址转换很方便,但它同时销毁了信息。做 masquerade 之后,每个客户端看起来都是这台设备,于是原本用来区分用户的下游规则再也区分不了。这不仅是日志问题,更是策略问题:一条以客户端地址为键的规则,悄悄变成了以网关为键的规则。如果按用户区分策略很重要,那就保留源地址,或者在转换之前先把策略执行掉。
回程路径同样值得追查。记录目的端为回包选择了哪条路由,因为非对称回程会绕过状态化检查,产生一条能建立却随后卡住的连接。两个方向都必须跨过你画的那条边界,否则这条边界只是装饰。
sudo tcpdump -ni inside0 host 10.20.5.10
ip route get 10.20.5.10
sudo iptables -t nat -S POSTROUTING既要验证一个被允许的操作,也要验证一个被拒绝的操作
从真实的远程客户端测试,而不是从管理主机测试,因为管理主机所在的位置,用户永远到不了。一个被允许的操作证明路径通,一个被拒绝的操作证明策略真的在起作用。每次改动部署位置之后,两个都要跑,并记录你用的源身份和目的地址。只证明成功的测试,分不清规则写对了还是根本缺失。
接着测那些会改变状态的情形:重新连接、跨越密钥轮换仍存活的会话,以及设备自身的故障。把更新、容量和恢复放在同一张布局里比较,因为一台设备承载多个逻辑控制,就是一个贴着多个标签的故障域。当共享的管理凭据或一条不受限的路由击穿了本该存在的边界时,第二台机器同样不算独立。
把端点、解密后的路径,以及限制它的那层控制写下来。无论实现叫什么名字,这三行都仍然成立。