问题描述
我对 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
文件(如果可能的话)?这可能是一个非常简单的问题,但是 Endpoint
的 AllowedIPs
和 [Peer]
字段之间有什么区别?我从 CryptoKey Routing 推断,一旦 interface
收到一个数据包,它就会使用 interface
私钥对其进行解密,并根据所有 AllowedIPs
的 peers
检查发件人 IP如果凭据实际上与 peer
匹配,则它接受它。另一方面,如果 interface
想要发送一个数据包,它会使用 peer
公钥对其进行加密,但是否将其发送到 Endpoint
或 AllowedIPs
?
编辑 1:我确实使用了 man wg
,而 Endpoint
的定义对我来说仍然很模糊。不过,AllowedIPs
字段似乎更容易掌握。
编辑 2: 经过进一步研究,我认为 AllowedIPs
字段指定了对等方可以用来接收来自或发送流量的 IP 地址。如果有人能确认或更正这一点,我将不胜感激。
解决方法
是的,每个界面都有自己的配置文件。 WireGuard 没有内置的“客户端”或“服务器”角色——每个节点都被视为一个“对等点”。
如果您有两个对等方,对等方 A 和对等方 B,则对等方 A 的配置文件的 [Interface]
部分将包含其本地接口的设置,以及其与对等方 B 中的远程连接的设置[Peer]
部分。类似地,对等方 B 的配置文件将在 [Interface]
部分中包含其自己的本地接口的设置,并在 [Peer]
部分中包含其与对等方 A 的远程连接的设置。因此,Peer A 配置中的 [Interface]
部分对应于 Peer B 配置中的 [Peer]
部分;而 Peer B 配置中的 [Interface]
部分对应于 Peer A 配置中的 [Peer]
部分。
端点([Peer]
配置部分)是远程对等方的“真实”IP 地址和端口,位于 WireGuard VPN 之外。此设置告诉本地主机如何连接到远程对等方以设置 WireGuard 隧道。
在示例配置中,远程对等方的 Endpoint = 54.91.5.139:1952
中,通过该对等方的虚拟 WireGuard 隧道路由的任何数据包实际上都将被加密,包装在一组新的 UDP 数据包中,并通过 Internet 发送(或其他一些“真实”网络,例如您的公司网络)到 54.91.5.139
UDP 端口 1952
。
除非你也在 WireGuard 之外的本地主机上做一些花哨的路由,如果你尝试从本地主机发送 ping 数据包到这个端点(例如 ping 54.91.5.139
),或者如果你尝试访问一些通过此端点地址从本地主机获取远程对等方的其他服务(例如,在 Web 浏览器中导航到 http://54.91.5.139/
),您将不会使用 WireGuard 隧道——您将使用常规 Internet(或其他“真实的”网络)连接。
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
的其他服务(例如导航到 {{1 }} 在网络浏览器中),您将使用 WireGuard 隧道。
相反,就像您提到的那样,对于从这个远程对等点通过隧道的数据包,如果它们在解包和解密后具有 http://10.129.130.1
指定的块之外的源 IP(例如源 IP 是 AllowedIPs
而不是 10.1.1.1
),本地主机将丢弃它们。
Address(10.129.130.1
配置部分)是 WireGuard VPN 中本地主机的虚拟 IP 地址。此设置会影响进出 WireGuard 隧道的数据包的路由,因此不是应该是可在 VPN 外部路由的“真实”IP 地址。
在示例配置中,其中 [Interface]
,WireGuard VPN 中本地主机的虚拟 IP 地址为 Address = 10.193.130.174/16
。因此,本地主机通过 WireGuard 隧道发送的来自本地套接字的任何数据包的源地址为 10.193.130.174
,并且它从隧道接收的目标地址为 10.193.130.174
的任何数据包都将路由回本地套接字(除非您在 WireGuard 之外进行一些奇特的路由)。
假设主机的“真实”网络地址是 10.193.130.174
。如果从主机运行 10.10.10.10
,主机将生成源地址为 ping 10.129.130.1
和目标地址为 10.193.130.174
的 ping 数据包,并通过 WireGuard 隧道发送它们。 WireGuard 将加密这些数据包,并使用源地址为 10.129.130.1
、源端口为 10.10.10.10
的 UDP 数据包将它们包装起来(WireGuard 默认值,因为在配置中未指定 51820
) ,目的地址为ListenPort
,目的端口为54.91.5.139
。然后它将这些 UDP 数据包发送到“真实”网络。
当远程对等点在 IP 地址 1952
和 UDP 端口 54.91.5.139
上侦听“真实”网络接口时,收到这些数据包时,它将解包并解密它们。然后它会将它们以原始形式在其自己的网络堆栈上重新排队,作为源地址为 1952
和目标地址为 10.193.130.174
的 ICMP 数据包。
如果原始主机收到来自该远程对等方的回复,则该回复最初将从“真实”网络接口作为 UDP 数据包接收,源地址为 10.129.130.1
,源端口54.91.5.139
,目的地址1952
,目的端口10.10.10.10
。 WireGuard 会将这些数据包解包并解密回其原始形式,作为源地址为 51820
和目标地址为 10.129.130.1
的 ICMP 数据包,并将它们重新排队。由于虚拟 WireGuard 接口的 IP 地址是 10.193.130.174
(通过 10.193.130.174
设置配置),本地主机将知道将这些数据包路由回本地套接字。
请注意,为 Address
设置(在我们的示例中为 Address
)指定网络掩码会影响本地主机做出的关于应将哪些流量发送到隧道(以及如何处理)的路由决策隧道接收到的流量),这种方式对于 /16
设置来说可能是多余的,或者与 AllowedIPs
设置交叉。在我们的示例中,Address = 10.193.130.174/16
,这通常会导致所有发往 10.193.x.x
范围内任何地址的流量都被路由到本地主机上的这个 WireGuard 接口(不包括接口自己的地址,{{ 1}},这将被路由到环回接口)。
但是,我们示例中唯一对等方的 10.193.130.174
设置不包含 AllowedIPs
范围内的任何内容。因此,如果我们在主机上运行 10.193.x.x
,主机将生成源地址为 ping 10.193.0.1
和目标地址为 10.193.130.174
的 ping 数据包,并通过 WireGuard 隧道发送它们。但由于该目标地址不适合任何配置的对等方的 10.193.0.1
,WireGuard 会丢弃这些数据包。
因此通常最简单的方法是省略 AllowedIPs
设置中的网络掩码(对于 IPv4 地址,或使用 Address
,具有相同的效果),并仅使用 /32
设置每个对等点来控制路由到它的内容。通常,仅当您有多个不同的对等点使用相同的虚拟子网时(或者如果您在 WireGuard 之外进行一些奇特的路由),您才需要指定网络掩码。
关于 AllowedIPs
的另一件事是,您只需将其设置在 WireGuard 隧道的一侧(但如果两侧都有静态 IP,则可以在两侧设置)。如果您在 Peer A 的配置中为 Peer B 设置了 Endpoint
,但在 Peer B 的配置中为 Peer A 省略了它,则 Peer A 将能够与 Peer B 启动和设置隧道,而 Peer B 不必提前知道 Peer A 的端点。
如果 Peer A 具有动态分配的公共 IP 地址,这是理想的;但缺点是 Peer B 将无法启动隧道——它必须等待 Peer A 连接到它。如果您有时需要 Peer B 启动与 Peer A 的连接,您可以通过在 Peer A 的配置中为 Peer B 包含 Endpoint
设置来缓解这种情况——这将引导 Peer A 主动联系并连接到 Peer B 每 N 秒(其中 N 是您在 PersistentKeepalive
设置中输入的值)。
端点是Wireguard 可以通过云连接的URL。所以它应该包含公共IP地址和端口号。
Allowed-ips 是将路由到对等方的地址列表。确保至少指定一个包含 WireGuard 连接的内部 IP 地址的地址范围。
因此端点具有公共 IP 地址,但 Allowed-ips 是地址列表(Wireguard 连接的内部 IP 地址)
,对于路德维希先生的回答,我真的没有什么可以补充的。 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
Ubuntu(服务器)端的 nftables 规则,存储在 /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
}
}