Wireguard 配置文件中的 Endpoint 和 AllowedIPs 字段有什么区别?

What is the difference between Endpoint and AllowedIPs fields in Wireguard config file?

我对Wireguard的理解是,服务端和客户端的接口(虽然貌似不可区分?)各自有自己的.conf文件。例如考虑以下 .conf 文件。

[Interface]
PrivateKey = some_key_1
Address = 10.193.130.174/16


[Peer]
PublicKey = some_key_2
PresharedKey = some_key_3
AllowedIPs = 10.129.130.1/32
Endpoint = 54.91.5.130:1952

如何判断这是客户端还是服务器 .conf 文件(如果可能的话)?这可能是一个非常简单的问题,但是 [Peer]EndpointAllowedIPs 字段有什么区别?我从 CryptoKey Routing 推断,一旦 interface 收到一个数据包,它就会使用 interface 私钥对其进行解密,并根据所有 peersAllowedIPs 检查发件人 IP ] 如果凭据实际上与 peer 匹配,它会接受它。另一方面,如果 interface 想要发送一个数据包,它会使用 peer public 密钥对其进行加密,但它会将它发送到 Endpoint 还是 AllowedIPs?

编辑 1: 我确实使用了 man wg 并且 Endpoint 的定义对我来说仍然很模糊。尽管如此,AllowedIPs 字段似乎更容易掌握。

编辑 2: 经过进一步研究,我认为 AllowedIPs 字段指定了对等方可用于接收流量或向其发送流量的 IP 地址。如果有人可以确认或更正此问题,我将不胜感激。

端点是 URL wireguard 可以通过云连接的地方。所以它应该包含 Public IP 地址和端口号。

Allowed-ips 是将路由到对等方的地址列表。确保指定至少一个包含 WireGuard 连接的内部 IP 地址的地址范围。

所以 Endpoint 有 public IP 地址,但 Allowed-ips 是一个地址列表(Wireguard 连接的内部 IP 地址)

是的,每个接口都有自己的配置文件。 WireGuard 没有内置的“客户端”或“服务器”角色——每个节点都被视为“对等节点”。

如果您有两个点,点 A 和点 B,点 A 的配置文件将在 [Interface] 部分中包含其自己的本地接口的设置,以及与点的远程连接的设置B 在 [Peer] 部分。类似地,Peer B 的配置文件将在 [Interface] 部分中设置其自己的本地接口,并在 [Peer] 部分中设置其与 Peer A 的远程连接设置。因此,Peer A 配置中的 [Interface] 部分对应于 Peer B 配置中的 [Peer] 部分;并且节点 B 配置中的 [Interface] 部分对应于节点 A 配置的 [Peer] 部分。


Endpoint[Peer] 配置部分)是 WireGuard VPN 之外的远程对等方的“真实”IP 地址和端口。此设置告诉本地主机如何连接到远程对等点以设置 WireGuard 隧道。

在示例配置中,Endpoint = 54.91.5.139:1952 对于远程对等点,通过该对等点的虚拟 WireGuard 隧道路由的任何数据包实际上都将被加密,包装在一组新的 UDP 数据包中,并通过Internet(或其他一些“真实”网络,如您的公司网络)到 54.91.5.139 UDP 端口 1952

除非你也在 WireGuard 之外的本地主机上做一些花哨的路由,如果你尝试从本地主机发送 ping 数据包到这个端点(例如 ping 54.91.5.139),或者你尝试通过此端点地址从本地主机访问远程对等点的某些其他服务(例如,在网络浏览器中导航到 http://54.91.5.139/),您将不会使用 WireGuard 隧道——您将使用常规互联网(或其他“真实”网络)连接。

AllowedIPs[Peer] 配置部分)是本地主机应通过 WireGuard 隧道路由到远程对等方的 IP 地址集。此设置告诉本地主机隧道中的内容。

在示例配置中,AllowedIPs = 10.129.130.1/32 对于远程对等点,本地主机上发往 10.129.130.1 的任何数据包都不会直接通过您的常规 Internet(或其他“真实”网络)发送) 连接,而是首先发送到虚拟 WireGuard 隧道。 WireGuard 将对它们进行加密,将它们包装在一组新的 UDP 数据包中,然后通过 Internet(或其他“真实”网络)将它们发送到对等端点 54.91.5.139。从那里,对等方将解包和解密数据包,并尝试将它们转发到 10.129.130.1

因此,如果您尝试从本地主机发送 ping 数据包到 10.129.130.1(例如 ping 10.129.130.1),或者尝试访问 10.129.130.1 的某些其他服务(例如导航到 http://10.129.130.1 在网络浏览器中),您 使用 WireGuard 隧道。

相反,如您所提到的,对于来自此远程对等方的隧道的数据包,如果它们在解包和解密后具有 AllowedIPs 指定的块之外的源 IP (例如,源 IP 是 10.1.1.1 而不是 10.129.130.1),本地主机将丢弃它们。

Address[Interface] 配置部分)是 WireGuard VPN 中本地主机的虚拟 IP 地址。此设置会影响进出 WireGuard 隧道的数据包的路由,因此应该 不是 可在 VPN 外部路由的“真实”IP 地址。

在示例配置中,Address = 10.193.130.174/16,WireGuard VPN 中本地主机的虚拟 IP 地址为 10.193.130.174。因此,本地主机通过 WireGuard 隧道发送的来自本地套接字的任何数据包都将具有源地址 10.193.130.174,并且它从隧道接收到的任何目标地址为 10.193.130.174 的数据包都将被路由回一个本地套接字(除非你在 WireGuard 之外做一些花哨的路由)。

假设主机的“真实”网络地址是10.10.10.10。如果,从主机,你 运行 ping 10.129.130.1,主机将生成源地址为 10.193.130.174,目标地址为 10.129.130.1 的 ping 数据包,并通过WireGuard 隧道。 WireGuard 将加密这些数据包,并用源地址为 10.10.10.10、源端口为 51820 的 UDP 数据包包装它们(WireGuard 默认设置,因为在配置中未指定 ListenPort) ,目的地址为54.91.5.139,目的端口为1952。然后它将这些 UDP 数据包发送到“真实”网络。

当远程节点在 IP 地址 54.91.5.139 和 UDP 端口 1952 的“真实”网络接口上侦听时,接收到这些数据包,它将解包并解密它们。然后它将以其原始形式将它们重新排队到自己的网络堆栈中,作为源地址为 10.193.130.174 和目标地址为 10.129.130.1.

的 ICMP 数据包。

并且如果原始主机从该远程对等端接收到对 ping 的回复,它最初将作为 UDP 数据包从“真实”网络接口接收,源地址为 54.91.5.139,a 1952 的源端口、10.10.10.10 的目标地址和 51820 的目标端口。 WireGuard 会将这些数据包解包并解密回其原始形式,即源地址为 10.129.130.1 和目标地址为 10.193.130.174 的 ICMP 数据包,然后将它们重新排队。由于虚拟 WireGuard 接口的 IP 地址是 10.193.130.174(通过 Address 设置配置),本地主机将知道将这些数据包路由回本地套接字。


请注意,为 Address 设置指定网络掩码(在我们的示例中为 /16)会影响本地主机做出的关于应将哪些流量发送到隧道(以及将哪些流量发送到隧道)的路由决策处理隧道接收到的流量),以一种可以冗余或与 AllowedIPs 设置交叉的方式。在我们的示例中,Address = 10.193.130.174/16,这通常会导致所有发往 10.193.x.x 运行ge 中任何地址的流量被路由到本地主机上的这个 WireGuard 接口(不包括接口的自己的地址,10.193.130.174,将被路由到环回接口)。

但是,我们示例中唯一对等点的 AllowedIPs 设置不包含 10.193.x.x 运行ge 中的任何内容。所以如果我们在主机上 运行 ping 10.193.0.1 ,主机会生成源地址为 10.193.130.174 目的地址为 10.193.0.1 的 ping 数据包,并通过 WireGuard 发送它们隧道。但是由于该目标地址不适合任何已配置对等点的 AllowedIPs,WireGuard 将丢弃这些数据包。

所以通常在Address设置中省略网络掩码是最简单的(对于IPv4地址,或使用/32,效果相同),只使用AllowedIPs每个对等点的设置以控制路由到它的内容。通常只有当您有许多不同的对等点使用相同的虚拟子网时(或者如果您在 WireGuard 之外进行一些奇特的路由),您才会指定网络掩码。


关于 Endpoint 的另一件事是您只需将它设置在 WireGuard 隧道的一侧(但如果两侧都有静态 IP,则可以在两侧设置)。如果在对等点 A 的配置中为对等点 B 设置 Endpoint,但在对等点 B 的配置中为对等点 A 省略它,则对等点 A 将能够启动并设置与对等点 B 的隧道,而对等点 B 不必提前知道节点 A 的端点。

如果对等点 A 具有动态分配的 public IP 地址,这是理想的;但缺点是对等点 B 无法启动隧道——它必须等待对等点 A 连接到它。如果您有时需要对等点 B 启动与对等点 A 的连接,您可以通过在对等点 A 的配置中为对等点 B 设置 PersistentKeepalive 来缓解这种情况——这将指示对等点 A 主动伸出并连接到对等点每 N 秒 B(其中 N 是您在 PersistentKeepalive 设置中输入的值)。

对于 Ludwig 先生的回答,我真的没有什么可以补充的。 WireGuard 的设计有点简单。尽管如此,这里是我当前设置的示例,包括“服务器”端的 nftables 规则,允许所有“客户端”对等点 ping 我局域网上的机器。

服务器配置 (Ubuntu),存储在 /etc/wireguard/wg0.conf。本地 LAN 地址 192.168.2.0/24,这个特定的服务器地址在 LAN 接口上是 192.168.2.1,在 VPN (WireGuard) 接口上是 192.168.3.1 (wg0)。分配给 WireGuard VPN 的地址是 192.168.3.0/24:

[Interface]
Address = 192.168.3.1/24
#SaveConfig = true
ListenPort = 51820
PrivateKey = +N3K<redacted>

# Peer configurations
[Peer]
PublicKey = h/tr<redacted>
AllowedIPs = 192.168.3.0/24

客户端(或对等)配置 (Windows),存储在 Windows 的官方 WireGuard 客户端上(不确定文件或注册表在哪里目前位于)。本地 VPN 地址是 192.168.3.2:

[Interface]
PrivateKey = gIIB<redacted>
Address = 192.168.3.2/24

[Peer]
PublicKey = od4j<redacted>
AllowedIPs = 192.168.3.0/24, 192.168.2.0/24
Endpoint = <MyFreeDdnsDomainOn>.duckdns.org:51820
PersistentKeepalive = 25

nftables Ubuntu(服务器)端的规则,存储在 /etc/nftables.conf 中,包括我的防火墙规则:

define wan = "eth0"
define lan = "br0"
define lo = "lo"
define vpn = "wg0"

table ip nat {
        chain PREROUTING {
                # priority dstnat = -100.
                type nat hook prerouting priority dstnat; policy accept;
        }

        chain INPUT {
                # priority srcnat = 100.
                type nat hook input priority 100; policy accept;
        }

        chain OUTPUT {
                # priority dstnat = -100.
                type nat hook output priority -100; policy accept;
        }

        # For all packets to WAN (eth0), after routing, replace the source address
        # with the primary IP of WAN interface (masquerade).
        # Also necessary to enable masquerade on LAN for WireGuard (VPN).
        chain POSTROUTING {
                # priority srcnat = 100.
                type nat hook postrouting priority srcnat; policy accept;
                oifname $wan counter masquerade
                oifname $lan counter masquerade
        }
}

# Allow all outgoing, but drop incoming and forwarding packets by default:
table ip filter {
        chain INPUT {
                type filter hook input priority filter; policy drop;
                # Boilerplate acceptance policy.
                iifname $lo counter accept
                iifname $lan counter accept
                iifname $vpn counter accept
                # Accept already established and related connections.
                iifname $wan ct state established,related counter accept
                # Drop invalid packets.
                iifname $wan ct state invalid counter drop
                # Pass traffic to protocol-specific chains:
                # Only allow new connections (established and related should already be handled)
                # For TCP, additionally only allow new SYN packets since that is the only valid
                # method for establishing a new TCP connection.
                iifname $wan ip protocol udp ct state new counter jump UDP
                iifname $wan tcp flags & (fin | syn | rst | ack) == syn ct state new counter jump TCP
                iifname $wan ip protocol icmp ct state new counter jump ICMP
                # Drop anything that's fallen through to this point.
                counter drop
        }

        chain FORWARD {
                type filter hook forward priority filter; policy drop;
                # Forward filtering boilerplate rules.
                iifname $wan oifname $lan ct state established,related counter accept
                iifname $vpn oifname $lan counter accept
                iifname $lan oifname $vpn counter accept
                iifname $lan oifname $wan counter accept
        }

        chain OUTPUT {
                type filter hook output priority filter; policy accept;
        }

        # Custom per-protocol chains:
        chain ICMP {
        }

        # Acceptable TCP traffic:
        chain TCP {
                # Example:
                #iifname $wan tcp dport 51413 counter accept
        }

        # Acceptable UDP traffic:
        chain UDP {
                # Allow WireGuard
                iifname $wan udp dport 51820 counter accept
        }
}