设置:
我有一个 openvpn 客户端/服务器设置(配置文件在底部),我MULTI: bad source address from client [192.168.x.x], packet dropped
在服务器上收到了臭名昭著的消息。服务器有一个公共 IP 地址,而客户端位于 NAT 后面。
先前提出的解决方案的缺点:client-config-dir
服务器配置中的定义目前为空。以前的帖子(此处和 openvpn 支持论坛)建议在 中添加一个以适当规则命名的文件 ,DEFAULT
或client-config-dir
添加一个包含这些规则的每个用户文件来解决问题。
但是,这似乎不是一个长期的解决方案,因为这些规则是特定于客户端位置的。因此,我可以添加一条规则以允许客户端192.168.x.0
连接。但如果他们从另一个使用192.168.y.0
NAT 的网络连接,则需要一条新规则。
问题:
- 所需的规则是否可以以通用/一次性的方式编写?
- 有人能解释一下为什么会出现这个问题吗?
服务器配置:
port 1234
proto tcp
dev tun
ca ca.crt
cert openvpn.crt
key openvpn.key
dh dh2048.pem
server 10.78.96.0 255.255.255.0
keepalive 10 120
comp-lzo
cipher CAMELLIA-128-CBC
user nobody
group nogroup
persist-key
persist-tun
client-cert-not-required
plugin /usr/lib/openvpn/openvpn-auth-pam.so login
status openvpn-status.log
push "redirect-gateway def1"
push "remote-gateway 1.2.3.4"
push "dhcp-option DNS 8.8.8.8"
client-config-dir ccd
verb 4
客户端配置:
ca ca.crt
client
dev tun
proto tcp
remote 1.2.3.4 1234
auth-user-pass
script-security 2
keepalive 5 60
topology subnet
resolv-retry infinite
nobind
persist-key
persist-tun
ns-cert-type server
cipher CAMELLIA-128-CBC
comp-lzo
verb 4
答案1
你问: ”有人能解释一下为什么会出现这个问题吗?“
根据报道官方 OpenVPN 常见问题解答我敢打赌这是由 OpenVPN 引擎内部的路由问题引起的。
为了更好地阐明情况,让我参考下图:
您可以在这里看到:
- 连接到 HEADQUARTER 内部网络 (10.0.1.0/24) 的 OpenVPN “服务器”
- 在远程站点运行的 OpenVPN“客户端”,并连接到远程 192.168.1.0/24 网络
还
- 我们假设 OpenVPN 隧道已建立,并且:
- OpenVPN“服务器”可通过其自己的屯接口,地址为10.10.0.1。tun 接口使用的 P2P 地址也是 10.10.0.2(这对于后面的讨论很重要,所以让我们强调一下)
- OpenVPN“客户端”有一个屯接口 IP 为 10.10.0.2
现在,我们假设:
- OpenVPN“客户端”已重新定义其默认网关,因此可在隧道内重定向所有传出的 IP 流量;
- OpenVPN“客户端”已启用 IP_FORWARDING,因此可以路由来自其内部 LAN(192.168.1.0/24)的数据包(我强调这一点,因为这对我们的讨论至关重要)。
有了这样的场景,让我们详细检查当 R_PC1(192.168.1.2)向 L_PC1(10.0.1.2)发送数据包(如回显请求)时发生的情况:
- 数据包离开 R_PC1 网卡后到达 OpenVPN 客户端;
- OpenVPN 客户端(配置为充当通用路由器)根据其路由表进行路由。由于其默认网关是隧道,因此它将数据包发送到隧道;
- 数据包到达 OpenVPN 服务器的 tun 接口。OpenVPN 会“看到”它,并且由于它(OpenVPN 服务器)知道 10.0.1.2 是属于其 LAN 子网的地址,因此它会将数据包从 TUN“转发”到 LAN;
- 数据包到达 L_PC1。
所以一切都很好...
现在让我们检查一下 L_PC1 回复 R_PC1 的回显答复发生了什么。
- echo-reply 离开 L_PC1 网卡并到达 OpenVPN 服务器 LAN 接口 (10.0.1.1);
现在,如果我们希望 OpenVPN 服务器能够访问远程站点,我们需要使用“静态路由”来定义路由。例如:
route add -net 192.168.1.0 netmask 255.255.255.0 gw 10.10.0.2
请注意用作网关的 P2P 地址。
此类静态路由将在操作系统级别运行。换句话说,操作系统需要它来正确路由数据包。这意味着:“请注意,所有发送到 192.168.1.0/24 子网的流量都需要转发到 OpenVPN 引擎,操作系统可以通过 P2P 地址与其通信”。多亏了这种静态路由,现在...
- 数据包离开 OS 路由上下文并到达 OpenVPN。OpenVPN 实例在 OpenVPN 服务器上运行。因此,此时 OS 无需再执行任何操作,所有路由(VPN 内)都留给 OpenVPN 服务器软件。
所以,现在的问题是:openvpn 服务器软件如何能够决定数据包的路由,其 SRC_IP 为 10.0.1.2,DST_IP 为 192.168.1.2?
请注意,根据 OpenVPN 服务器的配置,它知道没有什么关于 192.168.1.0/24 网络,以及 192.168.1.2 主机。不是连接的客户端。这是不是本地客户端。那么呢?OpenVPN 也知道它是不是“OS-Router”,所以它实际上并不想(也不能……)将数据包发送回本地网关。所以这里唯一的选择就是引发错误。这正是您遇到的错误
用常见问题解答的语言来说:“...它不知道如何将数据包路由到这台机器,所以它丢弃了该数据包...“。
我们怎样才能解决这个问题?
正如你所看到的官方文档, 选项伊洛特完全符合我们的范围:
--iroute network [netmask]
Generate an internal route to a specific client. The netmask
parameter, if omitted, defaults to 255.255.255.255.
This directive can be used to route a fixed subnet from the server
to a particular client, regardless of where the client is
connecting from. Remember that you must also add the route to the
system routing table as well (such as by using the --route
directive). The reason why two routes are needed is that the
--route directive routes the packet from the kernel to OpenVPN.
Once in OpenVPN, the --iroute directive routes to the specific
client.
因此你需要一个:
--iroute 192.168.1.0 255.255.255.0
当您的 OpenVPN 客户端连接时应用(到服务器),例如通过服务器上定义的临时配置文件(client-config-dir 等)。
您是否应该疑惑为什么会出现此问题不是发生在上述步骤 2) 时,我的理解是 OpenVPN 客户端知道如何路由它,因为它知道 VPN 隧道是一个默认网关。
在 OpenVPN 服务器上无法执行相同的操作,因为那里的默认网关通常是不是覆盖。另外,考虑一下,您可能有一个 OpenVPN 服务器和许多 OpenVPN 客户端:每个客户端都知道如何访问服务器,但是...服务器如何确定哪个客户端充当未知子网的网关?
至于你的第一个问题(所需的规则是否可以以通用/一次性的方式编写?),很抱歉,我没明白您的问题。您能重新表述一下并提供更多详细信息吗?
答案2
我也遇到过类似的问题,绞尽脑汁。所有迹象都表明 openvpn 服务器不知道通过客户端连接的下游远程 LAN 的 IP 地址范围。实际客户端可以访问整个服务器 LAN,服务器端 LAN 上的主机可以访问 openvpn 客户端。但是,服务器端 LAN 上的主机和客户端 LAN 上的远程 PC 无法相互访问。
问题在于,在客户端连接时,服务器无法读取 ccd/client 文件。这是由于使用用户/组指令在服务器中降级权限造成的。默认的 Red Hat 安装将 /etc/openvpn 标记为组 openvpn 可读,但不允许任何人(示例配置中显示的用户/组)读取。
日志文件中指出了失败。客户端连接时的服务器日志文件显示无法读取 ccd/client 文件,但连接成功,没有路由。状态日志文件显示已连接的客户端,但路由表仅显示 VPN 隧道,而不是下游 LAN。
将服务器配置权限降级为用户 nobody / 组 openvpn 即可解决问题。
答案3
我遇到了一个看似类似的问题,但我不确定它是否与您的问题相同。我尝试从 openvpn 客户端 ping 到 openvpn 服务器本地网络中的计算机(在服务器配置中路由),没有得到回复,并且我在服务器的 openvpn 日志中看到“源地址错误”消息。
为了解决这个问题,我必须做两件事:
- 在服务器上启用 IP 转发。
- 在服务器网关上为 vpn 子网添加路由,因为在我的例子中,服务器本地网络的网关不是服务器本身,而是路由器。被 ping 的计算机试图通过网关回复,但网关不知道该如何处理 vpn 子网。因此,我在路由器中添加了一条静态路由,使用 vpn 子网作为目的地,并使用 openvpn 服务器的 ip 作为网关。
这帮我解决了这个问题。
答案4
我遇到过完全相同的问题,也尝试过论坛上的许多食谱,push route
但问题仍然存在。此错误的原因很简单:缺少设置iptables
。也就是说,在服务器上,应该调用类似
$ sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
其中是-daemon10.8.0.0
创建的虚拟网络,应该是服务器上网络接口的名称(参见输出)。调用此命令后,一切正常。但有一个问题:当我重新启动服务器时,设置消失了,错误OpenVPN
eth0
ifconfig
iptables
MULTI: bad source address from client [192.168.x.x], packet dropped
又回来了。所以每次重启后都必须调用iptables
上面的命令。这可以按如下方式解决。首先,保存当前iptables
设置
$ sudo iptables-save > /etc/sysconfig/iptables
然后添加行
iptables-restore < /etc/sysconfig/iptables
以便/etc/rc.d/rc.local
在每次重启后加载这些设置。
PS 当然不要忘记取消注释/添加以下行
net.ipv4.ip_forward = 1
并通过调用来/etc/sysctl.conf
应用更改
$ sudo sysctl -p