我的设置看起来怎么样

我的设置看起来怎么样

我甚至不确定这是否是正确的措辞,我会尽力解释。

我想设置一个小型 VPN,用于托管一些私人项目以及访问互联网。我还想拥有自己的 DNS 服务器,以便拥有很酷的顶级域名。

我的设置看起来怎么样

我正在使用两个 Docker 镜像:

我的 wireguard 接口有名称main并在端口上运行20000。请注意,因为这些不是“默认”设置。

现在,它几乎可以正常工作,这意味着我可以将多个对等点连接到此“服务器”对等点。我可以从另一个对等点 ping 任何对等点。因此,设置的“wireguard”部分可以正常工作。我相信这是一个超出 wireguard 范围的路由问题。

以下是我的docker-compose.yml文件的相关部分:

services:
  dns:
    image: ubuntu/bind9
    restart: unless-stopped
    networks:
      main:
        ipv4_address: 172.16.0.53 

  wgdashboard:
    image: donaldzou/wgdashboard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    networks:
      main:
        ipv4_address: 172.16.0.2
    ports:
      - 10086:10086
      - 20000:20000/udp

networks:
  main:
    ipam:
      driver: default
      config:
        - subnet: 172.16.0.0/16
          ip_range: 172.16.0.0/24
          gateway: 172.16.0.1

网络已创建,并且两个容器都有正确的 IP

因此,由于我的设置在 UDP 端口 20000 上运行,而不是在网络上运行host,因此我在 iptables 中有一些规则。我对这部分非常不确定。

# iptables  -L | grep 20000
ACCEPT     udp  --  anywhere             172.16.0.2           udp dpt:20000
ACCEPT     udp  --  anywhere             anywhere             udp dpt:20000
# iptables -t nat -L | grep 20000
MASQUERADE udp  --  172.16.0.2           172.16.0.2           udp dpt:20000
DNAT       udp  --  anywhere             anywhere             udp dpt:20000 to:172.16.0.2:20000

我还看到有些人请求此网络信息,因此我将其发布在这里:

$ ip -br link
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP> 
ens3             UP             52:54:00:0c:f3:c5 <BROADCAST,MULTICAST,UP,LOWER_UP> 
docker0          DOWN           02:42:61:07:a5:d4 <NO-CARRIER,BROADCAST,MULTICAST,UP> 
br-e12a65bf943c  UP             02:42:5b:d4:1a:a6 <BROADCAST,MULTICAST,UP,LOWER_UP> 
$ ip -br address
lo               UNKNOWN        127.0.0.1/8 ::1/128 
ens3             UP             XX.YY.ZZ.24/24 
docker0          DOWN           172.17.0.1/16 
br-e12a65bf943c  UP             172.16.0.1/16 
$ ip route
default via XX.YY.ZZ.1 dev ens3 onlink 
XX.YY.ZZ.0/24 dev ens3 proto kernel scope link src XX.YY.ZZ.24 
172.16.0.0/16 dev br-e12a65bf943c proto kernel scope link src 172.16.0.1 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 
$ ip rule
0:  from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 
$ 

怎么了

  • 我可以从运行docker的服务器ping和查询172.16.0.53(“dns”容器)

  • 我可以172.16.0.53从“wgdashboard”容器ping 和查询

  • 1.1.1.1我可以从服务器和两个容器进行ping 和查询

  • 我可以http://172.16.0.2:10086/从所有连接的对等点在浏览器中 ping 并打开(“wgdashboard”)容器

  • 我无法从任何一方 ping 通外部世界

  • 我无法172.16.0.53从任何一方ping 或发出 DNS 查询


我正在尝试解决此问题:

端口映射

首先,我在docker-compose.yml中53:53/udp为服务添加了端口映射( ):dns

$ docker-compose up
[+] Running 3/3
 ⠿ Network apps_main             Created                                                                                                                                                                                                                                                                0.1s
 ⠿ Container apps-dns-1          Created                                                                                                                                                                                                                                                                0.1s
 ⠿ Container apps-wgdashboard-1  Created                                                                                                                                                                                                                                                                0.1s
Attaching to apps-dns-1, apps-wgdashboard-1
Error response from daemon: driver failed programming external connectivity on endpoint apps-dns-1 (4d28f6ed5232a08b266aed9fd232bc9894b7ae0990d25129b27d4f4112ef289f): Error starting userland proxy: listen udp4 0.0.0.0:53: bind: address already in use

呃,什么,它会尝试绑定到主机的端口 53 吗?无论如何,我都不需要这个,因为我只打算从 wireguard(因此也是 docker)网络内部查询此服务器,而不需要从外部查询?

tcpdump

我从四个位置运行了 tcpdump:

  • 主机,接口br-e12a65bf943c(docker-compose 网络),tcpdump -i br-e12a65bf943c icmp
  • 主机、接口ens3(实际互联网)、tcpdump -i ens3 icmp
  • wireguard 容器,接口main(类似 wg0,但我给了它不同的名字),tcpdump -i main icmp
  • bind9 容器,接口eth0(它是唯一的一个)

按时间顺序从连接的对等点pingdns容器(我不知道这些时区是怎么回事,忽略小时):

[wireguard,main]      16:18:22.021439 IP 10.0.0.2     > 172.16.0.53: ICMP echo request 
[host,br-e12a65bf943c]17:18:22.021500 IP 10.0.0.2     > 172.16.0.53: ICMP echo request 
[dns,eth0]            14:18:22.021508 IP 10.0.0.2     > 172.16.0.53: ICMP echo request 
[dns,eth0]            14:18:22.021567 IP 172.16.0.53  > 10.0.0.2:    ICMP echo reply   
[host,br-e12a65bf943c]17:18:22.021575 IP 172.16.0.53  > 10.0.0.2:    ICMP echo reply   
[host,ens3]           17:18:22.021584 IP 172.16.0.53  > 10.0.0.2:    ICMP echo reply   

要点:三次请求,三次回复,但有一个回复决定通过,ens3而不是返回到 wireguard

正在 Ping 1.1.1.1

[wireguard,main]      16:30:16.689460 IP 10.0.0.2 > 1.1.1.1: ICMP echo request
[host,br-e12a65bf943c]17:30:16.689570 IP 10.0.0.2 > 1.1.1.1: ICMP echo request

主机,ens3什么都没有(!!!)

结论:我无法从 10.0.0.0/16 网络 ping 外部网络

所以我有三个问题

  • ICMP 回复发生了什么br-e12a65bf943c?如何让它返回到 wireguard 接口?
  • ICMP 请求在发往 1.1.1.1 的途中发生了什么?
  • 是 iptables 吗

如果你已经读到这里,谢谢你的时间


我猜是解决方案?

谢谢您的回答!您说得对,我忘了提到网络掩码,在本例中我选择了 /16。

dns确实,在容器上添加此路由可以修复 ping 问题

ip route add 10.0.0.0/16 via 172.16.0.2

现在我的任务是使其“永久”,我想我需要将其添加到dockerfile或其他地方。

第二个问题是外部交通。

我将此规则添加到wireguard容器中:

iptables -t nat -A POSTROUTING -s 10.0.0.0/16 -o eth0 -j MASQUERADE

是的,看起来它起作用了

答案1

首先,你应该有一个路线10.0.0.0/24 (嗯,/24因为没有提供所以假设)在 DNS 容器上,作为172.16.0.2下一跳(又名网关)。或者,你需要 (S)NAT(又称 IP 伪装)里面WG 容器(至少用于发往172.16.0.53:53UDP 以及可能的 TCP 的流量)。

至于到互联网的流量(例如1.1.1.1),可能是因为docker守护进程在docker主机上添加的防火墙规则不允许源地址不是172.16.0.0/16subnet:)的流量从转发出去br-e12a65bf943c。同样,其中一个选项是(S)NAT里面源地址为 的流量的 WG 容器10.0.0.0/24

另一种选择是通过某种方式禁用相应的过滤,例如完全阻止 docker 守护进程接触防火墙(--iptables=false),或者在 docker 守护进程启动后添加例外。

10.0.0.0/24如果您决定不在 WG 容器内添加额外的 NAT 层,我不太确定是否需要在 docker 主机上专门添加 (S)NAT 规则。您可以检查 docker 主机上的iptables-save当前SNAT/MASQUERADE规则是否仅限于172.16.0.0/16来自 的流量的源地址br-e12a65bf943c。此外,根据这一决定,您还需要在 docker 主机上添加路由10.0.0.0/24(以172.16.0.2作为下一跳)。

相关内容