IPv6 环境下一机多 IP 玩法的讨论

2022-09-05 20:43:12 +08:00
 LnTrx

IPv6 的地址空间很大,在 SLAAC 的配置下很难被外部主动扫到。但是通过自己的主动访问暴露,例如浏览恶意网站、运行 p2p 应用等,还是可能的。这种暴露的风险相比公网 IPv4 要小不少、而且设备自身的安全建设也更加根本,但如何采取其他措施加以预防也值得讨论。IPv4 时代的传统解决方案是防火墙,可是目前 IPv6 路由器的防火墙功能普遍残缺,即使有也需要固定机器的后缀。同时 PCP 等自动化机制也缺少应用,日常配置起来还是颇为麻烦。

楼主认为,IPv6 时代应该适应每台机器都是公网的零信任环境,不应该过度依赖网关和内网来保证安全。对于之前提到的暴露风险,如果转换思路,可以想到利用 IPv6 超大的地址空间,给 bt 、ipfs 这类应用分配独立的地址,从而仅把安全的、与敏感数据隔离的服务主动暴露给外部。搜了一下,IPv6 环境下一机多 IP 成熟的经验还比较少。虽然也存在一些麻烦,但个人感觉自动化的潜力比较很大。在此,楼主想分享在不同场景下非常初步的经验,希望可以起到抛砖引玉的作用:

一、服务器场景

提供 IPv6 的商家,有的是给一个子网随便玩,有的是需要论个申请但可以申请一堆,仅有少数是只能用一个的(如 Lightsail )。
由于服务端 IP 比较固定,通常比较好配置,同时可以沿用一些多公网 IPv4 的经验。
基本的玩法就是监听时不再写[::]:80 ,而是绑定[IPv6]:80 ,这样多个服务就可以分别通过独立的 IPv6 地址访问、解析。特别是当端口打架的时候,就不再需要基于 Host 或者 SNI 的反代来分流了。即使一个源站 IP 暴露了,相对不容易牵连其他服务,也便于换一个新的。

二、家用 PC 场景

在 Windows 下如何让一个应用的所有入站和出站都走指定的 IP 地址,除了虚拟机暂时没有想到很好的方法。
楼主在家宽环境下用 VMware 实测,当网络配置为桥接模式(不复制物理主机状态),虚拟机中的 Windows 和 Ubuntu 都可以获得独立于主机的 SLAAC IPv6 地址,且都可以被公网访问。traceroute 不会经过宿主的 IPv6 地址。其他虚拟化软件还未测试。

三、家用 NAS 场景

在 NAS 配置服务常用的是 Docker 。虽然 Docker 支持 IPv6 ,但相关的功能感觉还比较简单,很多时候需要固定的 CIDR 。楼主见过的 Docker+IPv6 玩法,一种是配 IPv6 私有地址然后做转发,还有一种是主机模式直接用宿主的地址。如果只是为了能用公网,后者相对简单。但想用独立的公网 IPv6 地址,就需要其他的方法。其中,bridge 模式虽然可行(需手动处理 NAP ),但会增加主机网关的一跳,从而暴露宿主的 IP 地址。所以这里以 IPvlan 模式为例,提供一个原理验证流程:

1.建立网桥

假设网卡为 eth0

docker network create -d ipvlan \
--ipv6  --subnet=$ip/80 \
-o parent=eth0 v6ipvlan1

其中$ip可以从公网 IP 裁切( curl -6 ip.sb ),也可以直接指定私网 IP ( fd00::)。无论那种,容器都可以额外从配置 SLAAC 的网关获得的公网 IPv6 地址。

2.运行一个能响应 Web 的 Docker

docker run --name socat --rm --net=v6ipvlan1\
    alpine/socat -v -d -d \
    TCP6-LISTEN:12080,crlf,reuseaddr,fork \
    SYSTEM:"
    echo HTTP/1.1 200 OK; 
    echo Content-Type\: text/plain; 
    echo; 
    echo \"Server: \$SOCAT_SOCKADDR:\$SOCAT_SOCKPORT\";
    echo \"Client: \$SOCAT_PEERADDR:\$SOCAT_PEERPORT\";
    "

3.进到容器里看看

docker exec -it socat sh

查询本容器的公网 IPv6 (设为 2400:11:22:33:aa:bb:cc:dd )

ip addr

有时需要有主动的 IPv6 出站才能打通,例如:

ping6 240c::6666

至此,只要没有其他防火墙拦着,[2400:11:22:33:aa:bb:cc:dd]:12080 应该就可以从外部访问了。
由于地址独立于宿主生成,且 traceroute 不会经过宿主的一跳,或可以避免宿主和其他容器公网 IPv6 的暴露。

需要重申的是,以上仅是粗糙的原理验证,希望可以启发更多关于多 IP 玩法的讨论。

其他问题

4237 次点击
所在节点    宽带症候群
28 条回复
fetich
2022-09-06 00:42:27 +08:00
为 OP 的折腾精神点赞
fetich
2022-09-06 00:43:06 +08:00
@fetich 「折腾」精神
cnbatch
2022-09-06 02:05:09 +08:00
单独给每个应用分配 IPv6 临时地址,这就需要操作系统的支持才行了。

不是做不到,毕竟现在已经可以做到单独让某个 /某类软件走特定通道。就看有没有人愿意贡献代码(仅限于开源系统),或者操作系统的开发商愿不愿意实现。
mxT52CRuqR6o5
2022-09-06 02:28:01 +08:00
我感觉这种多 ip 只有类似于虚拟机、docker 之类的方案能增加安全性,如果被分配了独立地址的应用没有被跑在沙箱里,那我认为并不会有理论上的安全性提升
Jirajine
2022-09-06 08:00:52 +08:00
@cnbatch 操作系统当然支持,ipvlan 配合 netns 就可以做到。不过正常来说也不是完全必须隔离开,如果 host 上的程序都是你可控的话,直接给网卡加个 IP 然后让特定应用绑定,自行注意避免[::]就行了。
lovelylain
2022-09-06 08:18:47 +08:00
玩这么复杂是想实现啥?路由器上用 iptables 阻止所有 ipv6 入站连接,有端口开放请求的话,路由器上部署 frp 监听 ipv6 地址,然后 frp 转发到内网的 ipv4 地址,不就跟 ipv4 一样安全又方便了吗,当然也可以用 socat 等,我喜欢用 frp 一是内网穿透玩了这个很熟悉,而是它支持 proxy_protocol 对于 http 可以保留原始的客户端 ip 。
neroxps
2022-09-06 08:27:49 +08:00
@jobmailcn 终于有一个清醒人 哈哈
titanium98118
2022-09-06 09:02:51 +08:00
现在客户端是不是会主动发送 sni ?
kimigaooo
2022-09-06 11:10:21 +08:00
用无状态分配 ipv6 ,当宽带自动重播的时候系统会获得多个 ipv6 导致无法正常访问这个问题怎么解决呢?
acbot
2022-09-06 11:34:01 +08:00
@kimigaooo SLAAC 模式下 OP 路由器重新拨号以后 路由器会把旧前缀 RA 消息的 valid_lifetime / preferred_lifetime 这两个参数置零,并且发送出去,系统收到之后就会将旧的地址从首选变更为其他状态,新的地址就是首选了。 当然我用的国产路由器这个就处理不太好需要手动去处理或者是等待 旧的 valid_lifetime / preferred_lifetime 失效
LnTrx
2022-09-06 12:28:16 +08:00
一处笔误:NAP → NDP
LnTrx
2022-09-06 12:43:36 +08:00
@mxT52CRuqR6o5 以上设置的初衷是防止应用暴露主机 IP ,导致主机上其他有弱点的入站端口被发现,所以安全性提升是有的。沙箱是防止应用的端口被攻陷、获取高权限后在主机侵染其他应用,这是另一层面的安全性。
LnTrx
2022-09-06 12:52:39 +08:00
@jobmailcn 其实文中已经提过,例如内网设备要开 bt 、ipfs ,这些软件能知道你设了个 frp 么?是不是也要配置一番,除非 All in 网关。但如果很在意安全性,在网关监听外网端口反而不推荐。因为网关是整个内网较容易被发现的设备,如果网关自身的入站端口有安全弱点,同时下属设备都假设内网的安全性,那恐怕更加危险。
cnbatch
2022-09-06 15:14:18 +08:00
@Jirajine 这是需要手动操作,而不是全自动模式。全自动模式还是需要开发商修改一番的。
总不能每次打开浏览器都手动弄一次(哪怕用脚本),玩游戏弄一次,听音乐弄一次,打开 IM 软件再弄一次……
所以全自动还得有人给系统修改代码
cnbatch
2022-09-06 15:26:02 +08:00
对于家用内网,其实还可以配置成内网 IPv6 私网地址 + 网关转换公网 IPv6 ,一对一转换,也就是 NPTv6 (可以看成是 NAT 的进化版)。这样的话,网关防火墙仍旧可以起作用,依然能够像 IPv4 时代那样手动指定 DMZ ,设定哪些主机允许外部主动连进来、哪些继续阻止主动入站。

目前内置 NPTv6 支持的就只有 FreeBSD ,其他系统只能靠第三方软件才能实现,变相等于阻碍了 NPTv6 的推行,导致基于 NPTv6 的方式目前还没人做出专门的 WebUI 配置项。
malash
2022-09-06 17:06:49 +08:00
理论上可行,实际操作起来很麻烦。

家庭 PPPOE 每次拨号后前缀都会变化,SLAAC 本身也有( 24 小时?)的超时时间。你的所有服务都要不停的检测 IPv6 地址变化然后重新监听。这样做成本是很高的,举个例子,你买了一个小米网关开放了一个有漏洞的接口,你要如何刷固件让它监听指定的 IP ?如果买了更多设备呢,每一个设备都要有监听方案

还有一个例子,就是小米网关的监听服务是有漏洞的,并且这个漏洞是一个“有益”的功能,可以用于破解后连接 Home Assistant (见 https://github.com/AlexxIT/XiaomiGateway3 )。我用这个例子是想说明内网许多服务是需要以“不安全”的形式进行运行的,内网安全不太可能和外网安全等同。你的方案对于 VPS 等场景会更加适合,对于内网就不那么合适了。

其实我们不妨做一个思想上的转变,广域网 /局域网地址不等同于公网 /内网。IPv6 下确实每一个设备都有一个唯一的地址,但并不是所有的地址都是“公网”地址。公网和内网的区别其实只是“本地网络”和“本地之外的网络”,假如你在网关 /路由器的防火墙禁用了 IPv6 的开放端口,内网设备即使分配到了 IPv6 地址,依然也只有内网的服务能力,对吧?

如果不太好理解可以想象这样一个例子,在 IPv4 下路由器路由器使用 1.1.1.1 ,我的电脑使用 1.1.1.2 ,笔记本用 1.1.1.3 ,可以吗?技术上当然可以。虽然它们都是公网 IP ,但我只在内网使用并且不会对外(公网)广播,公网也 ping 不到我的这些设备,那么其实它们就是些内网服务而已。就像一些厂商局域网 IP 都用光了,连美国国防部的 IP 都拿来用了 https://www.v2ex.com/t/365031 ,是一样的道理

因此通过使用网关防火墙,人为划分了公网和内网的界限,并没有太大的问题,并且会比为每一个设备配置防火墙要更简单、可行和安全
neroxps
2022-09-06 17:41:12 +08:00
@LnTrx ??? ip6tables 只开放匹配后缀(解决动态 pd 前缀问题)匹配目的端口的端口转发,其他一律禁掉。和 nat 没区别吧。

为何要弄的如此复杂?
LnTrx
2022-09-06 17:44:23 +08:00
@malash 一机多 IP 是针对 PC 、NAS 等现代操作系统场景。我没有建议在家庭场景监听指定的 IP 。简单的物联网设备没有服务间隔离的问题,也不太会随便主动外访,默认的 SLAAC 一般就行了。
内网一般就指局域网,你指的可能是可公网入站和仅内网入站,但重新定义概念恐怕会引发混乱。防火墙的低支持度、需要固定后缀、自动化打洞等问题和可移动设备接入外部网络的风险我就不再赘述了。至少对我来说,如果有防火墙可根据 MAC 地址来配置,才会觉得比较方便。
neroxps
2022-09-06 17:44:42 +08:00
@acbot 我之前就是 ros 的生存周期太长,导致 linux 获得超过 16 个 ipv6 地址 一直获不到新的 ip
LnTrx
2022-09-06 17:54:59 +08:00
@neroxps 现在广泛售卖的路由器能匹配后缀的不多。现代操作系统有的后缀是会跟着前缀变的,需要关掉隐私扩展。NAT 时代的自动化端口映射大多不兼容 IPv6 ,例如 PCP 在网关和应用的支持都比较少,所以开端口基本就要手动。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/877910

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX