背景:我自己家里的 nas ,有 ipv6 ,没有公网 ipv4 ,在外想通过 ipv6 访问容器内的服务。
问题:netstat 命令看了下,docker 只监听了 v4 端口,没监听 v6 端口。
查到的方案:
1.https://docs.docker.com/config/daemon/ipv6/ 开启 docker 的 ipv6 ,但这踏马竟然是实验性功能??? docker 这么成熟的东西,ipv6 的支持竟然还在实验?而且他这个支持,并不是我需要的,他这个是给每个容器分配不同的 ipv6 ,外网通过容器 ip 访问。那我人在外,我踏马怎么知道容器 ip 是多少啊
2.通过 haproxy 转发一下,把 ipv6 端口流量转到 v4 端口上,增加了架构复杂度,以后维护麻烦。
因此上来问问各种运维大哥,有没有什么优雅一点的姿势啊。
@ssh 大哥(不记得你 id 了)
1
JensenQian 2023-07-25 09:44:41 +08:00
前面放个 openwrt 的路由器
然后直接端口转发 |
2
Cabana 2023-07-25 09:51:21 +08:00 1
我的解决方案
1. nginx 反代 ipv6 的流量到 docker 的 ipv4 端口 2. docker 的网络路由配置为 host |
3
chenjia404 2023-07-25 09:59:09 +08:00
2023 年了,docker 还不默认支持 ipv6
|
4
c1273082756 2023-07-25 10:05:47 +08:00
openwrt+socat 转发即可
|
5
sadfQED2 OP @c1273082756
@JensenQian 大佬,能否细说下,是在 openwrt ,网络->防火墙->端口转发这个地方设置吗。我对 openwrt 不太熟,这里的转发指的是啥?是指所以入站流量都转发吗?假设我需要把请求我 nas 123 端口的 v6 流量转发到 v4 的 123 端口,那我在这里配置”wan and wan6 123 端口 -> lan x.x.x.x 123 端口“ 这样吗? 他这个外部端口指的是对方发起连接的端口还是请求访问的端口呢? 另外,我这样转发,是不是把所有流量都转发了呀?比如请求我家里电脑的 123 端口的流量,也转发到 nas 了? |
6
sadfQED2 OP @Cabana nginx 转发跟我用 ha 转发都一样,挺麻烦的,还得多配一套东西。我不太想把服务部署到物理机上面,尽量都用 docker 维护,方便管理。
我容器网络已经设置成 host 了,依然没监听 v6 端口 |
7
hahasong 2023-07-25 10:52:31 +08:00
docker 不需要单独开启实验性 v6 支持。一是你的服务要支持 v6 ,监听 0.0.0.0 或者[::]:0 这种格式。二是 docker run 的时候指定 --network host 直接使用你 host 的 ip 地址
|
8
villivateur 2023-07-25 10:56:27 +08:00
|
9
Cabana 2023-07-25 11:17:36 +08:00
@sadfQED2 #6 加了--network host 没道理不行的, 要么是你的服务本身就不支持 ipv6.
我的跑 pt 的 Transmission 就是这么跑在 docker 的. |
10
150530 2023-07-25 11:40:03 +08:00
我的 docker 没有开 v6 支持,安装的青龙使用-p 映射的端口,可以使用 ipv6 访问,问题应该在于你容器中的应用有没有监听::就和 v4 监听 0.0.0.0 一样,可以用 netstat -atn 查询一下
|
11
kaedeair 2023-07-25 11:40:03 +08:00
那个 ipv6 是指容器内部的网络,正常使用搞个网关用 host 模式,根据域名分流就搞定了
|
12
ice920 2023-07-25 12:16:13 +08:00
docker 没监听 v6 端口,不知道你的 NAS 是不是群晖,应该群晖 DSM6 和 7.2 才支持监听 v6 端口,也可以 -p 映射出来是使用,否则用 Host 网络模式获得 IPv6
OpenWrt 防火墙 - 通讯规则,开放 NAS 防火墙,限制地址:仅 IPv6 ,协议:TCP+UDP ,目标区域:LAN ,目标地址:::22cd/::ffff ,目标端口:8880 8443 (空格隔开) |
13
zmcity 2023-07-25 13:40:16 +08:00
需要任意端口入站,小规模部署——Host
需要任意端口入站,大规模部署——固定前缀+Docker 开 v6 支持 (家宽肯定搞不定固定前缀) 只需要指定端口入站——Docker 端口转发 只需要指定端口入站,但希望局域网内可以用 v6 地址访问——Docker 端口转发+EUI 前缀+Docker 开 v6 支持。 家用的话,像 PT 这种应用直接 Host 模式搞起,还能直接用 nas 的 ddns 访问。 |
16
s1e42NxZVE484pwH 2023-07-25 13:49:09 +08:00 via iPhone
用的软路由里面的 lucky
ddns 可以直接将 ipv6 和 ipv4 绑定固定域名 然后端口映射后就可以 ipv6 访问容器 |
17
ttimasdf 2023-07-25 15:08:02 +08:00
敢把 NAS 直接放公网上,你也是头铁。
docker network 最大的作用就是做隔离和 NAT ,你不让人家做 NAT 你不是把它活给抢了。所以对于开发者来说做 ipv6 support 没必要。本来 docker 环境做 firewall rule 就麻烦,现在还想在上面整花活……更没必要了 上面提 openwrt + socat 的,都 openwrt 了直接从防火墙配置里端口转发梭一下就完事了,还整啥 socat ,还得手写个 init script 麻烦的要死。 要我说,防火墙和访问控制是个极麻烦的东西,无论是 openwrt 的 fw4 生成还是手写 iptables ,都需要经验,既然你又没经验,我建议就在前面套个 openwrt ,openwrt 上装个 vpn ,openvpn 还是 softether 还是什么 swan 的,随便啥都行,这样攻击面就减小到 vpn 的暴露端口,用 softether 的 vpn over dns/icmp 你甚至一个端口都不用开,里面 NAS 你想 expose 多少个端口都没问题。 如果不懂,就全部无脑 gui ,openwrt 有 luci ,openvpn 和 strongswan 在 openwrt 上也有 gui ,softether 有个独立管理软件。搞什么 haproxy socat 甚至还有说 nginx 的,真的,不懂就别上。那才是真真正正增加管理难度的 |
18
sadfQED2 OP @ttimasdf 兄弟,你先别急,咱就说,有没有可能,我说可能,我 vpn 是通过 docker 安装在 nas 上面的,我现在就是需要把端口暴露到公网上。
|
19
JensenQian 2023-07-25 15:15:14 +08:00
@sadfQED2 #5
我么看懂楼主的需求 楼主是要外面 v6 也能访问你 ddns 家里的 docker 吗 网络防火墙那边可以,我 lede 的固件没法用这个转发,装了个 socat 外部访问啊就直接 ddns 的域名:端口就行 [img][/img] 不过这样子很不安全,我的建议是你搞个 openvpn 或者 wireguard 回家然后访问 |
20
leonshaw 2023-07-25 15:21:05 +08:00
还得做 NAT ,不光是 docker 的问题,IPv6 就没想明白公私域怎么解耦
|
21
sadfQED2 OP @JensenQian 不是,我并不需要 ddns ,我不需要域名。我直接用 ipv6 的地址连回来就行了。
我仔细研究了上面提到的路由器转发,这样结果变成了请求路由器 ip ,然后转发到 nas 。这样搞的话需要我访问 openwrt 地址,然后转发过去。 但是我有注册中心,nas 会实时上报自己的 ip 到注册中心,我 vpn 实时从注册中心拉取地址,拉到的是 nas 地址,搞成路由器地址就废了 |
23
defunct9 2023-07-25 15:51:54 +08:00
听到有人在叫我。
换我来干的话,也是前面架个 nginx+ipv6 ,因为 k8s 就这么干的,学就是了。 那复杂一点的搞法就是用 wg 直连到我自己的 AS ,随便分点 ipv6 得了。 |
24
AkibaSo 2023-07-25 15:54:04 +08:00 1
@sadfQED2 楼上说了 指定 network 为 host ,docker compose 同样可以指定 network_mode: 'host',这样就可以通过你 nas 的 ipv6 访问你的服务,实在不行你还可以用 ipv6 nat
|
25
sadfQED2 OP @Cabana 我需要代理 tcp 流量,看了一眼我群晖上面的 nginx ,没有装 stream 模块,于是我尝试自己编译,又少了一万个依赖,吐了
|
26
des 2023-07-25 15:57:54 +08:00
看看这个 16 楼和 46 楼是不是你想要的 https://v2ex.com/t/955636
|
27
sadfQED2 OP |
29
sadfQED2 OP @des 这真的是,太太太复杂了,所以我才提问,有没有优雅一点的解决方案,这种方案,以后的维护成本简直上天,特别是半年一年以后,都忘了之前是咋配置的了,那时候排查问题,简直要命
|
30
sadfQED2 OP @defunct9 #28 看了一下这 2 个的介绍,这两个似乎不支持 tcp 、udp 的代理吧,这两个好像都是 http 的代理。另外,用啥代理都不是啥大问题。大问题是,机器上没有 systemctl ,没有 supervisor ,服务没法保活。
|
32
ice920 2023-07-25 17:20:33 +08:00
@sadfQED2 #15 不知道你的问题是否是我理解的问题,看你的 docker 版本,20.10.3 是不能监听 v6 端口,貌似在 20.10.6 版本后解决,但群晖套件之前只有 20.10.3 和 18.09 ,以及现在最新的 DSM7.2 是 20.10.23
|
34
zygame 2023-07-25 17:40:14 +08:00
所以这就是路由被误解之后造成的问题,NAT Gateway 本身就不是 Router
v4 时代你们在 Gateway 上弄的那一套花活,根本不是在 Router 上用的,v6 有了公网 IP 你的所有策略都要改变。 就算你 v6 无限制直接公布在网上,传统的扫描器扫一个 60 段的时间你算过么……而且是每次都会换的 60 段,你在担心什么? 安啦 |
35
blackmirror 2023-07-25 17:40:15 +08:00
docker 不是默认 ipv6 优先的?
|
36
AlanBrian 2023-07-25 17:54:08 +08:00
{
"ipv6": true, "fixed-cidr-v6": "fc00:17:1:1::/64", "experimental": true, "ip6tables": true } 我之前这么配置是可以通过宿主机的 ipv6 访问容器的。 |
37
kaedeair 2023-07-25 18:02:54 +08:00
上面已经简短介绍了一下方法,可能不够详细
我来说一下我的方案吧,是已经实践成功,稳定运行半年的;希望对你有所帮助 系统是 pve 网关使用 docker 部署的 traefik ,网络模式使用 host(这里使用 host 的原因是因为我后面几个服务是 PT 和 BT 需要 ipv6 地址,容器网络也选择的是 host ,能不能 bridge 模式需要自行测试,理论上是可行的,因为我看到绑定宿主机 web 端口是监听 ipv6 的),后面几个不需要 ipv6 的服务是 bridge 由于 docker 的 iptables 优先于 pve 的,我关闭了 docker 的 iptables ,同时增加了网络为 bridge 容器所在网段到 docker0 的 MASQUERADE(防止容器不能上网),这样我就只对外暴露了单个 web 端口 对后面容器服务的访问控制是通过 traefik 里面域名规则配置的 对楼上回复的补充:traefik 是支持 tcp 和 udp 的并不是只支持 http |
38
yylang1984 2023-07-25 18:21:18 +08:00
用 host 模式就好了
|
39
lovelylain 2023-07-25 18:30:48 +08:00 via Android
通过 nginx 反代 ipv6 到容器 ipv4 ,nginx 跑在 host 容器或者宿主机上,对于容器内的 web 服务,通过 xff 传递客户端 ip ,非 web 服务暂时没想到什么办法传递 ip 。
|
40
Jirajine 2023-07-25 18:38:12 +08:00
这是 docker 的问题,docker 的网络非常垃圾,或者说是非常特化的,用 docker 就得 docker 按照它自己的方式为你管理地址,或者手动静态管理地址。
任何非 docker 设计的标准网络使用,都不该用 docker ,与其对着 docker 一顿 hack ,不如直接 lxc ,想怎么配就怎么配。 |
41
lentrody 2023-07-25 19:05:15 +08:00
你用的什么 DDNS ? docker 的 IPv6 地址是 EUI64 生成的固定后缀吗?
如果是固定后缀那么就可以通过任意一个地址的前缀拼接得到其他所有设备的完整地址,有些 DDNS 服务商比如 dynv6 可以自动这样拼接地址并关联到子域名。 |
42
whetherTsmile 2023-07-25 22:05:43 +08:00
docker 只监听了 v4 端口,没监听 v6 端口
你可以看下 io 和 docker0 端口有没有 inet6 ,然后看下 net.ipv6.conf.lo.disable_ipv6 开了没 |
43
neroxps 2023-07-25 22:25:28 +08:00 via iPhone
@sadfQED2 dsm 7 已经支持了吧 dsm 6.2 内核是不支持 ipv6 nat 。用工具转发或是路由 66nat 吧
|
44
iceheart 2023-07-26 07:16:31 +08:00 via Android
同意 #40 用 lxc+lxd 就完了,哪有这么多事
|
45
wheat0r 2023-07-26 10:33:00 +08:00
可以通过 docker compose 指定网络和容器的 ipv6 子网信息,但是你似乎没有办法让容器自动获取 RA 出来的地址。所以如果你的 ipv6 地址是运营商给的、每次拨号会变的地址,那就不用折腾了。
|
46
vicv 2023-07-26 11:39:49 +08:00
我和你的使用情景是一样的,移动有公网 IPv6 没有公网 IPv4 。我是群晖 NAS ,我的做法是这样的:光猫开启桥接模式,让主路由器进行拨号,这样的话路由器下的设备都可以拿到 IPv6 地址(这里其实有安全风险,但是一般很少人会扫描 IPv6 网络)。群晖的 docker 配置中启用 IPv6 支持,创建一个新的 docker 网络并使用 docker 的 macvlan 驱动桥接到群晖的物理网卡,然后使用了这个网络创建的容器就相当于在直接连接到路由器上的一个设备,可以获得路由器分配的一个内网 IPv4 地址以及公网的 IPv6 地址(不需要 IPv6 的容器不使用这个 docker 网络就可以了)。然后使用 jeessy/ddns-go 这个 docker 镜像来对容器的 IPv6 地址做 ddns 解析,然后在外网就可以愉快地通过域名访问内网的 IPv6 服务了。
|
47
yzkos 2023-07-26 15:06:22 +08:00
我群晖现在就是通过 ipv6 访问的,但是完全没有配置过 ipv6 这些东西,只要 nas 有 ipv6 公网,开放的端口 ipv6 就能访问到。
群晖 docker 软件界面有两个网络 bridge 和 host , 如果你的容器使用 bridge 用 ipv6 是访问不了的,可以在控制面板-》 synology 应用程序门户-》反向代理服务器,添加一个新的端口号对 docker 的端口反代就可以用 ipv6 访问了。例如 docker 映射端口是 5244 ,在反向代理里面新增一个 5243 反代到 http://localhost:5244 ,使用 ipv6:5243 就能公网访问了。 如果是使用 host 里面就能 ipv6 加端口直接访问。 我的两个里面显示都是 ipv6 已禁用,不耽误外网直接访问。 |
48
tsanie 2023-07-26 16:51:35 +08:00
我的也是,群晖本身有 IPv6 ,没有修改过 docker 配置,网络里面 IPv6 都是 Disabled ,有些服务比如 gitea 用自带的反代到 localhost 映射出来的端口,有些服务比如 aria 设置的--network=host ,这些服务都能走外部由 IPv6 访问,例如手机流量。
办公室没有 IPv6 就走的 zerotier 虚拟组网,另外又弄了个 cloudflare tunnel 作为备用线路。 |
49
ttimasdf 2023-07-26 17:42:24 +08:00
好吧,我们分类讨论
要解决你的需求,你既然容器里有 vpn 了,你也通过 vpn 访问,那直接把需要访问的容器拉个子网,通过 alias 访问即可 要回答你的问题,非得暴露 ipv6 的话,SO 说行,https://serverfault.com/a/1054917 |