我在一台同时托管 NGINX 服务器的服务器上运行着 openVPN。
当通过 openVPN 连接并运行时,它会在各处显示服务器的 ip,但是当连接到在同一服务器上的 NGINX 上运行的域时,它会显示通过 openVPN 连接的客户端的真实外部 ip。
我希望它也能将传入 nginx 的流量路由到服务器,然后在 NGINX 访问日志中显示 127.0.0.1 或 10.xxx
我正在使用以下设置。
local 136.x.x.x
port 1194
proto tcp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
auth SHA512
tls-crypt tc.key
topology subnet
server 10.8.0.0 255.255.255.0
server-ipv6 fddd:1194:1194:1194::/64
push "redirect-gateway local def1 ipv6 bypass-dhcp"
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
cipher AES-256-CBC
user nobody
group nogroup
persist-key
persist-tun
verb 3
crl-verify crl.pem
答案1
你不能——至少使用你正在使用的方法不行。
问题在于您正在使用操作系统的传统路由表 - 而它们不是为这种特定场景设计的。
当 OpenVPN 连接并被告知通过 VPN 重定向 0.0.0.0/0 时,它必须添加一条路由以到达 VPN 服务器。此路由为 /32,下一跳为本地网关,这是最具体的路由。
特定的路由总是优于不太特定的路由,因此所有目的地的流量都会使用此路由。
大致来说,有两种方法可以解决此问题:
- 提供分割水平 DNS,以便您的 VPN 用户获得 Web 服务器的 RFC1918-IP,从而通过隧道。
- 在客户端上使用某种基于策略的路由。在 Linux 上,可以命名空间例如。
答案2
我在与 nginx 服务器相同的 ubuntu 20.04 机器上对 openvpn 进行了非常类似的设置。(如果我在路由器上为所有设备启用 NAT 环回,通常只会将其用于转发端口...)奇怪的是,我的 nginx 日志显示路由器 ip 使用 openvpn for android 进行连接,但单个 WebSocket 连接显示真实的外部 ip。使用 Windows 10 进行连接,配置相同,连接到我的网站时始终显示真实的外部 ip。
我通过更改 vpn - wiregaurd 解决了这个问题,看起来(我不是专家)几乎相同的 IP 表规则工作正常。始终显示本地 IP,无论是 Windows 还是 Android。它也更快,至少在我的测试中是这样。遗憾的是它搞乱了 WSL2 路由(与 openvpn 客户端不同)......不是大问题,但很烦人,这是另一个故事......
编辑 在 Windows 客户端中,split DNS 适用于 openVPN,但 WebSocket 连接除外,后者仍显示为真实 IP。在我使用 dnsmasq 的情况下,只需在 dnsmasq 配置中添加一行即可:
address=/www.example.com/local.ip.of.nginx-server
最后,为了让 websocket 连接显示本地 ip,我必须将 nginx 配置中的 ssl_stapling 解析器更改为本地 dnsmasq 服务器(我之前已经设置了 Cloudflare 的 dns)。