Wireguard 서버와 클라이언트는 서로 ping 할 수 있지만 wireguard 클라이언트는 서로 ping 할 수 없습니다.
다음 엔티티가있는 Wireguard 구성을 설정하고 있습니다.
Google Cloud 또는 Amazon AWS와 같은 호스트의 원격 VM 인스턴스. 이것은 내 wireguard 서버에 대한 원격 클라이언트입니다. 이것을 부르 자
gcp_client
내 LAN에서 호스팅되는 컴퓨터의 wireguard 서버. 이것을
srvlan
.
- 이 기기에서 IPv4 전달을 사용하도록 설정했습니다
sysctl
. - WAN과 LAN 사이에 Ubiquiti Edgerouter 4가 있습니다. 이 장치에서 포트 전달 및 헤어핀 NAT를 활성화했습니다. 이 라우터에 동적 DNS도 설정했습니다.
- 내 LAN에있는 하나 이상의 클라이언트. 내 LAN에있는 시스템 인 것처럼 원격 클라이언트에 연결할 수 있어야합니다. 첫 번째 클라이언트 자체의 문제에 직면하고 있으므로
client1
.
내 설정에서 나는 사이에 ping 할 수 있어요 srvlan
와 gcp_client
두 가지, 사이 client1
와 srvlan
도합니다. 하나. 에서 핑 gcp_client
으로는 client1
(그 반대는 반대) 실패합니다.
의 결과를 읽고 tcpdump -i wg0 -n icmp
다음과 같이 관찰했습니다.
- 도달
client1
하기gcp_client
위해 핑을srvlan
했지만 라우터로 전달되지 않습니다. - 에서 핑하여 내 라우터
gcp_client
에client1
도달하면srvlan
. 그러나 패킷에 의해 전달되지 않습니다srvlan
에client1
.
내가 결론을 내릴 수있는 유일한 것은 전달 규칙 srvlan
이 어떻게 든 잘못 되었다는 것 입니다. nftables
이 장치를 관리하는 데 사용 하고 있습니다.
이것은 내 wireguard 구성입니다. IP 주소와 포트 번호가 변경되었습니다.
# wg0.conf for gcp_client
[Interface]
Address = 10.0.1.2/24
ListenPort = 50000
PrivateKey = gcp_client_privkey
[Peer]
PublicKey = srvlan_pubkey
AllowedIPs = 10.0.1.0/24
Endpoint = srvlan_ddns:50000
# wg0.conf for srvlan
[Interface]
Address = 10.0.1.1/24
ListenPort = 50000
PrivateKey = srvlan_privkey
[Peer]
PublicKey = gcp_client_pubkey
AllowedIPs = 10.0.1.2/32
Endpoint = gcp_client_domainname:50000
PersistentKeepalive = 25
[Peer]
PublicKey = client1_pubkey
AllowedIPs = 10.0.1.3/32
Endpoint = client1_lanhostname:50000
PersistentKeepalive = 25 # I realise this one is unnecessary, but I had added it while testing just in case the problem got fixed.
# wg0.conf for client1
[Interface]
Address = 10.0.1.3/24
ListenPort = 50000
PrivateKey = client1_privkey
[Peer]
PublicKey = srvlan_pubkey
AllowedIPs = 10.0.1.0/24
Endpoint = srvlan_lanhostname:50000
이것은 내 방화벽입니다 srvlan
.
# nft list ruleset
table inet firewall {
chain inbound {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" accept
ip protocol icmp accept
ip6 nexthdr ipv6-icmp accept
ip protocol igmp accept
tcp dport 22 accept
iifname "eno1" tcp dport { 80, 443 } ct state new accept
iifname "eno1" udp dport 50000 ct state new accept
iifname "wg0" udp dport 53 ct state new accept
iifname "wg0" tcp dport { 80, 443 } ct state new accept
iifname "wg0" udp dport 50000 ct state new accept
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iifname "wg0" oifname "eno1" ct state new accept
}
chain outbound {
type filter hook output priority filter; policy accept;
ct state invalid drop
}
}
table ip router {
chain prerouting {
type nat hook prerouting priority filter; policy accept;
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifname "eno1" ip saddr 10.0.1.0/24 masquerade
}
}
답변
때 srvlan 전달 트래픽을 WireGuard 터널링, 그것은에서 수신 wg0 및에 ... 루트가 wg0 다시 : 두 번 같은 인터페이스를.
따라서이 항목을 nftables 의 inet 방화벽 포워드 체인에 추가해야합니다 .
iifname "wg0" oifname "wg0" accept
인바운드 체인의 기타 문제 :
ip protocol icmp accept ip6 nexthdr ipv6-icmp accept ip protocol igmp accept
프로토콜 은 IPv4에서 작동 하지만 IPv6 프로토콜의 nexthdr 은 다음 헤더가 ICMPv6임을 보장하지 않습니다 . 고정 헤더와 상위 계층 프로토콜 헤더 사이에 여러 확장 헤더 가있을 수 있습니다 . 이러한 확장 헤더가 일부 패킷에 나타나면 nexthdr ipv6-icmp
더 이상 일치하지 않습니다. IPv4 및 IPv6에 대해 올바른 구문을 사용하십시오.
meta nfproto ipv4 meta l4proto icmp accept
meta nfproto ipv6 meta l4proto ipv6-icmp accept
meta nfproto ipv4 meta l4proto igmp accept
nftables 버전 에 따라 더 간단한 형식으로 다시 표시됩니다.
iifname "wg0" udp dport 50000 ct state new accept
포트 50000은 WireGuard 인터페이스 내부에 나타나지 않고 (WireGuard 내에서 WireGuard를 터널링하려는 경우 제외) 외부 (이미 규칙이 있음)에 나타납니다. 필요하지 않습니다.
더 많은 WireGuard 클라이언트 / 피어를 추가 할 때 (올바르게 한 것처럼) srvlan 의 AllowedIPs 항목이 표준 라우팅 후 적절한 피어를 선택하기 위해 WireGuard에서 발생하는 암호화 라우팅을 결정하므로 겹칠 수 없습니다 . 또한, 만약 gcp_client를 통해 연결 srvlan 서버가 WireGuard 터널을 사용하지 않는, 그들의 LAN 주소도에 모두 추가해야합니다 AllowedIPs 과의 라우팅 테이블 gcp_client . AllowedIPs 는 소스를 기반으로 패킷을 수락하고 (그리고 로밍의 경우 어느 피어를 결정하고 끝점을 업데이트 할 수 있는지) 대상을 기반으로 패킷을 보낼 피어를 결정하는 데 사용됩니다.