我本质上遇到了一个路由问题,但我对路由和 iptables 不够熟悉,无法有效地排除故障并设置我的网络需求。
哪些措施有效
我已经建立并运行了一个 openVPN 网络;客户端可以通过互联网连接到 LAN。
我希望发生什么
...当客户端连接到给定子网上的 VPN 时。
- 客户端应该可以通过 VPN 网络访问
如果规则能够实现以下一项或多项功能,则可以获得加分:
- 客户端不应该能够发起与 VPN 的连接
- 客户端应该出现在我们的 DNS 中
拓扑
我们的网络拓扑结构如下所示:
______ ____________________
/ \ / \
| internet |---| client (10.8.8.0/24) |
\________/ \____________________/
|
______
/ \
| gateway |
\________/
|
-----LAN------ (10.10.10.0/24)
| | | |
L_____VPN Server `VPN1` 10.10.10.2 (fictional name/subnet)
当前的设置
我们的网关定义了以下路线:
10.8.8.0 255.255.255.0 10.10.10.2 LAN & WLAN
在 上VPN1
,iptables 有以下规则
# Flush the filter and nat tables
iptables -t filter -F
iptables -t nat -F
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A INPUT -i eth0 -j ACCEPT -d 10.8.8.0/24
iptables -A FORWARD -i eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.10.0/16 -d 10.8.8.0/24 -o tun+ -j MASQUERADE
当前正在发生什么
运行命令mtr 10.8.8.1
(VPN上连接的客户端的IP)显示当前路由在VPN1和网关之间来回跳动。
答案1
经过又一轮艰苦的 iptables 在线学习疯狂之后,我找到了解决方案。
但是,首先,iptables 有一个无效的假设。我对规则的最初方法是,当收到数据包时,它将通过 INPUT 和 OUTPUT 链运行。事实并非如此;规则与数据包匹配的那一刻,数据包就会离开表。由于除非指定(例如“-t nat”),否则会假定使用过滤表,因此列出的大多数规则都在过滤表上运行。
关于链条
- 输入:在发往服务器的数据包上运行
- 输出:在来自服务器的数据包上运行
- 向前:其他一切 - 如果规则在这里匹配,并且“跳转”(我喜欢认为如果-j因为“工作”;)被接受,数据包将被适当地路由
规则细目
这是以下规则的描述当前的设置多于
iptables -t filter -F
iptables -t nat -F
这些规则只是冲走了筛选和纳特表。请注意,还有更多表和更彻底的清除 iptables 规则的方法。
iptables -A INPUT -i tun+ -j ACCEPT
这条规则不执行任何操作,因为:
- 它在发往 VPN1 而不是其他网络的流量上运行
- 没有为传入流量设置策略,因此默认允许
继续...
iptables -A FORWARD -i tun+ -j ACCEPT
此规则允许路由来自 10.8.8.0/24 的流量。纳特表对与该规则匹配的数据包运行。
iptables -A INPUT -i eth0 -j ACCEPT -d 10.8.8.0/24
该规则对所需路由也没有影响,因为 10.8.8.0/24 流量不是发往 VPN1 服务器。
iptables -A FORWARD -i eth0 -j ACCEPT
此规则允许路由来自 10.10.10.0/16 的流量。
iptables -t nat -A POSTROUTING -s 10.10.10.0/16 -d 10.8.8.0/24 -o tun+ -j MASQUERADE
此规则使从 10.10.10.0/16 发往 VPN 的流量看起来像是来自 VPN1,从而实际上使 VPN1 看起来像一个网关。
怎么了?
规则应该“OK”,以便将流量从一个网络传输到另一个网络。没有任何实际保护措施 - 例如默认的“DROP”策略等,但这不是问题的重点。
如果 iptables 设置为可以通过 VPN 路由流量,那么什么原因会导致流量被发回eth0到网关?如果 VPN1 不知道 10.8.8.0/24。如果 VPN 服务器不知道该网络,它将被视为互联网流量并发送回网关。
修复
解决方案是将网络信息告知 VPN 服务器(这是一个 openvpn 服务器)。有两种方法可以做到这一点;如果服务器只服务于一个网络,这是一个简单的配置设置:
server 10.8.8.0 255.255.255.0
在我的例子中,我已经设置了服务器路由,我需要它知道其他网络。配置看起来更像这样:
server 10.5.5.0 255.255.255.0
route 10.8.8.0 255.255.255.0
就是这样!一旦 VPN1 有了到网络的路由,FORWARD 链就能够路由流量。
更好的 iptables 设置
刷新 iptables 之后,更好的配置看起来应该像这样:
# Forward established traffic so that (in the above case) VPN1 doesn't
# drop responses from the client, A.K.A. "the magic"
iptables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A FORWARD -s 10.10.10.0/16 -d 10.8.8.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.10.10.0/16 -d 10.8.8.0/24 -j MASQUERADE
# Drop everything else that wants to be forwarded
iptables -P FORWARD DROP
请注意,没有针对来自 10.8.8.0/24 的流量的明确规则,这意味着默认情况下流量不会到达 10.10.10.0/16 网络 - 除了响应从 10.10.10.0/16 发送的流量的流量。现在 iptables 已设置,可以在 VPN 配置中为客户端分配一个 IP,并将其添加到 DNS 以获得完整的解决方案。