两条 OpenVPN 数据包路径的 Shorewall 区域
把加密的 OpenVPN 传输与已解密的客户端流量分开,给隧道单独的区域,并且只放行客户端真正需要的那一个服务。
两条数据包流经过一台终结 OpenVPN 的 Shorewall 网关,其中只有一条是加密的。第一条是客户端到面向互联网的接口上 VPN 监听端的传输。第二条是离开隧道接口的已解密请求,通往办公服务器或网关上的某个服务。修改策略之前先把两条流都画出来,因为满足第一条的规则对第二条毫无作用。
修改策略之前先画出两条流
把两条流写成包含源、目的地、协议和端口的行。在外层路径上,源是客户端的公网地址,目的地是网关的监听端口;Shorewall 把它视为从互联网到防火墙的流量。在内层路径上,源是隧道的地址范围,目的地是已批准的服务。即使同一个管理员同时维护这两行,它们的归属也各不相同。
| Flow | Zone relationship | What to constrain |
|---|---|---|
| Encrypted OpenVPN transport | Internet to the firewall host | The listener's actual protocol and port |
| Decrypted request to a LAN service | VPN clients to the LAN zone | One approved server and service |
| Decrypted request to the gateway | VPN clients to the firewall host | Only the local services required |
| Request to another VPN client | VPN clients to VPN clients | Denied unless deliberately required |
只有当请求终止在网关本身上时才增加一行,例如访问解析器或管理界面。主机上的服务遵循主机输入策略,而不是转发路径。把两者混在一起,正是狭窄的隧道规则最终暴露管理接口的原因。
分配隧道区域与接口范围
漫游用户区域在 /etc/shorewall/zones 中声明,隧道接口在 /etc/shorewall/interfaces 中挂接,外层连接在 /etc/shorewall/tunnels 中描述。请与已安装版本的语法保持一致,因为列顺序和选项名称在主版本之间已经变化。指南里的示例端口并不是放行与守护进程实际监听端口不同的端口的理由。仅仅因为数字相同,TCP 与 UDP 并不能互换。
指南用 tun+ 对接口分组。在有多条隧道的主机上,这个通配符可能把信任级别不同的另一条 VPN 放进同一个区域。请对照实际存在的接口复查范围,并让命名处于连接管理器的生命周期之下,而不是手工修改接口名。
历史指南包含远为陈旧的 OpenVPN 配置示例,其加密建议不应照搬到当前部署。应当借用其中的区域与流模型。加密基线请取自网关受维护的 OpenVPN 策略。
只放行你分类过的那条路径
从 VPN 区域到 LAN 的宽泛放行只是起始草图,不是完成的策略。写下被允许的客户端源、服务的实际地址、协议和端口。然后阅读它上方的规则与区域默认值,因为狭窄的追加并不会取消已经匹配的宽泛许可。通往网关主机的流量与经过它转发的流量是两回事。
客户端之间的流量需要单独决定。OpenVPN 的 client-to-client 与 Shorewall 的 routeback 都会影响客户端能否互相到达,两者都不应仅仅为了让某个 LAN 应用工作而启用。在测试之前先决定在哪里实施隔离。
把回程路径纳入同一份方案。服务或其路由器必须知道如何把流量送回隧道范围,否则设计必须在预期范围内有意转换源地址。
先验证,再证明两条路径
在重启任何东西之前先验证配置,并保持一个独立的管理会话打开,以防新策略有误。
shorewall check
干净检查之后应用配置,并回读 Shorewall 实际加载了什么。这些读取描述的是正在运行的策略,而不是文件看上去在说什么。
shorewall show zones
ip route get 192.168.10.20
从同一客户端测试一个全新的被允许请求和一个故意被拒绝的请求。OpenVPN 握手成功只能证明外层交换;被允许的服务与被拒绝的资源才能证明你想要的内部策略。然后重新连接客户端并重复,因为隧道接口的名称和地址可能在会话之间变化。如果结果不同,请修正区域范围,而不是放宽规则。