![无法通过 WireGuard VPN 隧道从互联网访问 URL](https://linux22.com/image/793470/%E6%97%A0%E6%B3%95%E9%80%9A%E8%BF%87%20WireGuard%20VPN%20%E9%9A%A7%E9%81%93%E4%BB%8E%E4%BA%92%E8%81%94%E7%BD%91%E8%AE%BF%E9%97%AE%20URL.png)
我正在尝试从互联网访问路由器设置网页。
我在 AWS EC2 上设置了 WireGuard VPN。路由器和 WireGuard 服务器之间的握手看起来不错,但我无法使用 ec2 实例的公共 IP 访问 URL -http://年:51820。
有没有人有办法解决吗?
服务器
[Interface]
Address = 172.31.16.1/20
SaveConfig = true
ListenPort = 51820
PrivateKey = PrivateKey
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
握手详情如下
服务器
interface: wg0
public key: public key
private key: (hidden)
listening port: 51820
peer: public key
endpoint: x.x.x.x:6140
allowed ips: 172.31.16.2/32
latest handshake: 2 minutes, 1 second ago
transfer: 13.91 KiB received, 3.77 KiB sent
客户
interface: wg0
public key: public key
private key: (hidden)
listening port: 46734
peer: public key
endpoint: y.y.y.y:51820
allowed ips: 0.0.0.0/0
latest handshake: 2 minutes, 7 seconds ago
transfer: 3.77 KiB received, 16.08 KiB sent
persistent keepalive: every 25 seconds
答案1
Wireguard 配置
您的 WG 子网与外部接口子网之间存在冲突。WG 子网需要分开。10.8.x.0/24 是一种常见的选择。放置一个随机 x 可以“确保”它是唯一的。此外,在两侧放置 KeepAlive=20 将确保从路由器到 vps 的隧道数据包的防火墙穿透保持打开状态。否则,如果一段时间内没有通信,vps 可能无法通过隧道传输第一个数据包。
服务器 wg0.conf
[Interface]
Address = 10.8.0.1/24
SaveConfig = true
PreUp = iptables -t nat -I PREROUTING -p tcp --dport 50400 -j DNAT --to-destination 10.8.0.2:443
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -i eth0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = ********************************
客户端会议
[Interface]
Address = 10.8.0.2/24
ListenPort = 51820
PrivateKey = ********************************
路由
在服务器(暴露于互联网)上,检查以下命令输出:
ip rule
ip route
应该显示类似的东西10.8.0.0/24 dev wg0 proto kernel scope link src 10.8.0.1
或者最具限制性的东西 10.8.0.2 dev wg0 proto kernel scope link src 10.8.0.1
。
Ping
服务器通过路由器,并通过 10.8.0.0/24 子网进行反向连接。如果这样可行,则 WG 有效,您的路由也有效。
防火墙工作
首先需要检查路由器上的 Web 接口端口是否打开。因此从服务器, 执行:
curl http://10.8.0.2
curl -k https://10.8.0.2 (the -k is to avoid cert verification if you have a self-signed certificate).
如果可行,则转发到的端口将是 443,避免暴露 80,因为它会在互联网上清晰可见。 (如果只有普通的 http 有效,您需要找到一种方法(例如另一个 VPN)进入您的服务器,以避免互联网上出现任何明文信息。或者使用 stunnel 进行封装,或者使用反向代理等。)
必须在内核中启用转发 echo 1 > /proc/sys/net/ipv4/ip_forward
现在好玩儿的来了! 参考。http://www.do1618.com/wp-content/uploads/2016/06/netfilter_pkt_flow.png 需要以下规则。一旦确认它有效,您就可以将它们全部嵌入配置文件运行的服务器 Wiregard 命令中。让我们跟踪通过服务器的数据包。
iptables -t nat -I PREROUTING -p tcp --dport 50400 -j DNAT --to-destination 10.8.0.2:443
(这将执行目标 nat:从互联网接收的任何请求数据包都将看到其目标地址和端口被重写,甚至在到达路由检查之前。)
iptables -A FORWARD -i eth0 -j ACCEPT
(内核路由系统将在路由检查时识别出它是去往退出接口,而不是输入并传送到本地进程。因此,数据包将通过转发挂钩。此规则将允许转发来自外部接口的任何数据包。
iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
(数据包随后将根据路由表通过 wg0 发送出去。但是,如果保持原样,源 IP 地址仍然是来自互联网上的请求者的 IP 地址。数据包将转到路由器并进行处理。但路由器将回复原始源地址。如果没有更多信息和路由器上的操作,回复返回路径可能会有所不同。甚至在不进入内核反向路径策略设置故事的情况下,防火墙可能不会让数据包到达或进入原始机器。使用传出接口使用自动确定的源地址伪装 NAT。并且 NAT 在回复数据包上以另一种方式返回。不过,请参阅下面的 Gotcha)
iptables -A FORWARD -i wg0 -j ACCEPT
(这是为了让回复数据包从隧道通过服务器到达互联网)。
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
(这是为了让路由器的回复不是来自 10.8.0.2,而是来自服务器公共地址。因此防火墙会让它返回到您的笔记本电脑。
陷阱
伪装wg0 接口有点脏。可能想要调整路由器,用一些元标记标记传入的数据包,并制定一个特定规则将标记回复的数据包路由回 WG 隧道。但这还需要一些工作,而且不确定路由器操作系统是否允许进行调整。这里唯一的缺点是路由器无法记录人们从哪里登录,无论您从哪里连接,它都会始终报告 10.8.0.1。
安全方面,路由器上的 wg0 接口允许您访问路由器上的任何内容。因此,它似乎进入了Openwrt LAN区域。 最初设置时没有什么大问题,但人们希望设置一个特定的防火墙区域,为其分配 wg0 接口,并且只允许端口 443 的传入数据包。只要服务器是安全的,其他任何东西都不应该通过,并且它充当防火墙,但仍然如此。
提示-控制台上的网络分析仪Wireshark
在服务器上安装包“tshark”(Ubuntu)或 wireshark-cli(Redhat)
sudo tshark -i any -Y !ssh
将显示通过所有接口的数据包,但不包括会污染您的输出的笔记本电脑/PC 的 ssh 数据包。
- 在服务器上运行此程序并将其保持写入状态。
- 尝试从浏览器访问 https://public_ip:50400 这样应该很容易看到数据包在接口之间流动,并查看哪里出了问题。您应该看到请求到达,数据包通过 vpn 接口,然后 vpn 接口的回复进入,然后通过 eth0 退出,eth0 源地址端口 50400,目的地是您的浏览器地址,其用于查询的随机端口。
答案2
看起来服务器 ip(端点)是 yyyy,但 51820 是 Wireguard 监听端口。而且您的 iptables 命令似乎没有转发特定端口。
因此,http 请求将最终到达服务器,而不会被传送到 Web 服务器套接字。
因此 yyyy:80 或 yyyy:8080 或 yyyy:443 或 yyyy:zzz(如果您有一个特定的 Web 服务器 zzz 监听端口)可能更符合 http(s) 请求所需要的。
注意:关于 wg-quick 如何设置路由的精彩解释基于策略的路由, 也Wireguard 路由页面
我相信你需要经历以下几个过程:
CLIENT
------
[Interface]
Address = 10.8.0.2/24
#SaveConfig = true
PrivateKey =
[Peer]
PublicKey =
PresharedKey =
Endpoint = y.y.y.y:60000
AllowedIPs = 0.0.0.0/0,::0/0
PersistentKeepalive = 15
SERVER
------
[Interface]
Address = 10.8.0.1/24
#SaveConfig = true
ListenPort = 60000
PrivateKey =
[Peer]
PublicKey =
PresharedKey =
AllowedIPs = 10.8.0.2
PersistentKeepalive = 15
- 设置内部 WG 路由。
- 按照答案中的示例设置固定的内部 IP。以与界面中客户端配置文件上的 IP 相同的方式设置。注意:这里没有真正的客户端和服务器概念,只有用于内部路由到 WG 的 Cryptokey 的端点和 AllowedIP。
- 路由器需要知道可公开访问的端点,另一种方式不需要端点。
- 路由器端口在与服务器建立连接时是随机的,无需设置。确保服务器防火墙上WG监听端口已打开。
在客户端和服务器内部执行 ping 操作,以确保您可以在 10.8.0.1 和 10.8.0.2 之间的隧道中进行路由。这里不需要 iptables 工作,只要两侧的端口都开放供 WG 进行通信即可:这一切都在 Wireguard 内部。
确认后,确保客户端(路由器)上的 Web 端口 XXX 在其 wg0 接口(或 Wireguard 在路由器上创建的任何接口)上打开。登录服务器并尝试 curl 10.8.0.2:XXX。如果成功,则说明您已成功 99%。–
将服务器端口转发到路由器客户端 只需将服务器输入上您选择的任何端口 YYYY 转发到 10.8.0.2 端口 XXX。我对 nftables 比 iptables 更熟悉。如果您使用的是类似 RedHat 的系统,firewalld 也会让您用非常短的命令完成此操作。
你应该达到类似的目标。
- KeepAlive 可确保即使您的两台机器在一段时间内(通常为 30 秒)没有通信,任何 NAT/防火墙仍保持打开状态。否则,如果服务器尝试联系路由器,WG 数据包就会丢失。
- SaveConfig 会定期覆盖配置文件,很麻烦;最好不要这样做。