通过VPN通过NAT反射访问外部Web服务超时

通过VPN通过NAT反射访问外部Web服务超时

我有一个带有 Raspbian arm64 的 Raspberry Pi 4B,运行 Strongswan VPN 服务器以及多个服务,我可以通过我的外部 IP/域名访问 frow WAN。我在路由器上使用 NAT 反射,以便可以从 LAN 使用相同的服务。 VPN 路由似乎工作正常,因为我可以从任何 VPN 设备访问互联网和 LAN 上的任何设备。同样,我也可以从 LAN 中 ping 任何 VPN 设备。

当我尝试通过我的域名访问我的网络服务时,问题就出现了。我通常可以从 LAN 和 WAN 访问的相同服务对于我的 VPN 设备来说无法访问。如果我在 LAN 上转发不同设备的端口并尝试通过域名在 VPN 设备上访问该端口,那么效果就很好。因此,我的网络设置的路由和 NAT 反射似乎都很好。只有当我尝试通过域名/外部 IP 访问与 VPN 位于同一服务器上的网站(通过本地 IP 访问网站工作正常)时,事情才不会按预期工作。

我的结论是我的 Raspberry Pi 的路由方面出了问题,但是我不知道从哪里开始调试。因此,我不确定哪些配置文件适合在此处发布。我很乐意发送任何必要的进一步信息来帮助我解决此问题。

我的 Strongswan 配置:

conn ikev2-rsa
    auto=add
    compress=no
    type=tunnel
    keyexchange=ikev2
    fragmentation=yes
    forceencaps=yes

    dpdaction=clear
    dpddelay=300s

    left=%any
    [email protected] (this is set to my real domain name)
    leftcert=strongswan-cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0,::/0

    right=%any
    rightid=%any
    rightauth=pubkey
    rightsourceip=10.2.1.0/24
    rightdns=10.0.0.4
    rightsendcert=never

答案1

我想出了一个适合我的解决方案,所以我想将其发布在这里,以防万一有人遇到同样的问题。

这个想法是让服务器接受公共 IP 作为自己的 IP,以停止进一步转发数据包。这意味着即使您连接到 VPN,也可以通过域名访问服务器。

这种方法的缺陷是,所有发往您的公共 IP 地址的流量都将停止在您的服务器上。因此,如果您在同一 WAN 地址上为多个设备设置了端口转发,您将无法再通过 VPN 访问它们,因为流量永远不会到达您的路由器。我愿意接受这种妥协,因为我很少通过外部 IP 地址访问除此服务器之外的其他设备,尤其是在使用 VPN 时。但是,您应该意识到这一点,并看看它是否也适用于您的情况。

为了实现这一点,我编写了一个 bash 脚本,它接受两个位置参数 - 您想要为其分配公共 IP 地址的接口和您的域名。例如,用法可以是:

sudo ~/externalIP.sh eth0 example.com

该脚本应在启动时运行并定期运行,以防您的 IP 地址发生变化。重要的是该脚本由 root 运行,例如使用 root 用户的 crontab:

sudo crontab -e

每小时运行一次并在启动时运行的示例如下所示:

0 * * * * /home/user/externalIP.sh eth0 example.com
@reboot /home/user/externalIP.sh eth0 example.com

最后,脚本的代码如下:

#!/bin/bash
lookup=($(nslookup $2 | grep -oP '(?<=Address:\s)\d+(.\d+){3}')) # look up my address
if [[ "${#lookup[@]}" -ne "2" ]]; then # exit if the address could not be found
        exit
fi
address="${lookup[1]}/32"
addresses=($(ip addr show dev $1 | grep -oP '\d+(.\d+){3}/32')) # get addresses assigned to my interface
exists=0
for i in "${addresses[@]}"
do
        if [[ "$i" = "$address" ]]; then # check if the address already exists
                exists=1
        elif ! [[ "$i" =~ ^((10)|(192\.168)|(127)|(172\.1[6-9])|(172\.2\d)|(172\.3[0-1]))\. ]]; then # remove superfluous public addresses
                $(ip addr del $i dev $1)
        fi
done
if [[ "$exists" -eq 0 ]]; then # add address if it does not exist yet
        $(ip addr add $address dev $1)
fi

具体来说,代码查找您的公共地址并将其附加到指定的接口。它还会删除所有以前添加的公共地址。该代码内置了一些保护措施,以确保无论如何,您的私有 IP 地址都不会受到影响。

不要忘记使其可执行:

sudo chmod u+x ~/externalIP.sh

相关内容