在这样的网络下,双方 OpenWrt 负责 pppoe 拨号上网,下发 ipv6 地址,OP 另一个网口连接着电脑。电脑有 ipv6 地址。OpenWrt 的防火墙 FORWARD 链默认是 DROP 的,没有添加其他防火墙设置。
这样双方有 ipv6 地址就可以直连了吗?算 p2p 吗?经过我的测试,a 电脑起一个 server python3 -m http.server 8080 --bind ::,然后 b 电脑使用 ipv6 地址+端口是无法访问的。
只有在 a 电脑的 OpenWrt 防火墙下转发一下,才可以正常访问。
但是,双方电脑都使用 tailscale 组网的情况下,双方是可以通过 ipv6 直连的。通过 tailscale ping 就可以看到 pong from b (100.64.0.4) via [2408:xxxx:xxx:xxx::9c8]:35973 in 8ms。

我不理解,为什么 tailscale ( WireGuard )是可以做到直连的?双方电脑上建了个虚拟网卡进行连接,但是电脑的上一级是 OpenWrt ,OpenWrt 网口 1 收到数据包后发现不是自己的数据包,要转发给网口 2 ,所以也需要走 FORWARD 链吧?这样的话,默认 DROP 应该阻止连接。那 tailscale 又是怎么突破这一限制的?

可能运营商策略不同?
我这里是从公司电脑 mstsc 到 家里 电脑 mstsc
直接 ipv6 没问题

  1. OpenWrt pppoe 拨号,运营商给得 ipv4 和 ipv6 都是属于这个设备,而不是你内网的电脑,需要转发很正常。
  1. 电脑有 ipv6 地址。没贴地址是什么,无法解答。
  2. tailscale 是隧道组网,双方电脑就处于同一个局域网,双方电脑都没网络防火墙的情况,当然是互通。

"3. tailscale 是隧道组网,双方电脑就处于同一个局域网,双方电脑都没网络防火墙的情况,当然是互通。"
组的局域网,但是数据包肯定是流经了 OpenWrt 来转发到电脑的,数据包既然流经了 OpenWrt ,那就要走 OpenWrt 的防火墙吧?

OpenWrt 的 FORWARD 链默认 DROP ,我的理解是从 WAN 口进来和内部设备建立连接的数据包会被 DROP ; 而 TailScale 是由电脑主动发起对 TailScale 服务器的请求的,由于连接已经建立,TailScale 服务器从 WAN 口进来转发给电脑的数据包不会被阻断。

但是我记得 TailScale 走的是 UDP 吧,打洞成功之后和其他设备怎么握手以及防火墙怎么处理的我就不明白了。

op 的 v6 防火墙规则里必须放行对应设备和端口,

A 电脑使用 ipv6 连接到 B 电脑的过程中,B 电脑的上一级是 Openwrt ,OpenWrt 有两个网口,网口 1 和网口 2 ,网口 2 是和 B 电脑相连。当 A 连接 B 时候,数据包到达 OpenWrt 的网口 1 ,根据路由表发现需要转发到 B 电脑,于是将数据包转发给网口 2 。这时候数据包在 OpenWrt 上两个网口的转发,是不是要经过 FORWARD 链呢?但 tailscale 的虚拟网卡只是设备端的,比如 B 电脑中的,在 OpenWrt 上并不知道是什么样的流量,只知道目标 ip 是 B 电脑,所以要进行转发。我的理解是这样的。
但实际上,使用了 tailscale 可以进行 ipv6 直连,不知道它怎么做到流量可以透过 FORWARD 链的。

哪些是打洞的

你 openwrt 还有运营商的光猫入栈都打开

不管是打不打洞,B 电脑收到的数据包先是经过 OpenWrt 的口,然后再转发到另一个网口,再发到 B 电脑吧。但是 ipv6 直连的话,在经过网口转发的过程中,会触发防火墙的 FORWARD 链吧。默认 drop 会拒绝的。所以 tailscale 是怎么绕过这防火墙的?

#8 这个好像就是打洞的原理

你那种直接起服务,是外部主动发起连接; tailscale 好像是两边都先连接服务器,在防火墙上建立起状态,后面利用这个直接通信

具体可以找资料看看,我大概记得是这样

你说得这个我理解,电脑先连接一下 derp 服务器,比如使用 1234 端口和 derp 服务器进行了连接,这样自己的 1234 端口就打开了,然后其他的设备就可以使用 1234 端口和这台电脑交流。如果 ipv4 中是严格的(Symmetric) NAT ,那么其他的设备无法直连它,因为源地址不同,NAT 会拒绝这些来源请求。如果是 Full Cone NAT 的话可以直接 p2p 连接,NAT 不会限制来源 ip 。

但这是 ipv6 就没有 NAT 的事了。数据包总是先到达 OpenWRT 的网口 1 ,然后转发到网口 2 。这里的转发就应该有防火墙的限制。

我理解,这些都是 wireguard 加密后的数据,openwrt 解不了,就直接路由给虚拟网卡 tun 接口了,解密是客户端完成的,其实压根没走防火墙。

op 后面没接交换机? forward 是 drop v4 还是 v6 ?

你说的 FORWARD 链是 DROP ,那么是双向都 DROP 还是默认从 WAN 过来的新链接 DROP ?咱能不能先去搞清楚最基本的概念?

可以直接连到家里的电脑。在的路由防火墙上放行内部对应的 ipv6 端口。

wan 口转发到其他网口默认 drop 。

op 后面接了个路由器,路由器开的 AP (有线中继),只起到 Wi-Fi 作用。

加密知识数据包内容而已,但对于 tcpip 模型来讲,数据包肯定有目标地址和端口的。要不然互联网上数据包怎么一级级转发。

v4 v6 默认都 drop 。

OpenWrt 对于 wan 口默认入站拒绝、出站接受、转发拒绝,你从外网访问 openwrt 属于入站,访问内网某 ipv6 属于转发,默认情况下这两种都会拒绝,需要在设置页面里添加放行规则。
ipv6 虽然没有 NAT ,但仍然有类似打洞的技术,而且因为没有地址转换,实现起来更容易,两端都通过中间服务器获得对端的 ipv6 地址信息,再给对端 ipv6 地址发包,这样显然属于出站请求,而且直接发给目标地址了,也不用像 ipv4 一样存在多种情形。

元信息是在的,但加密之后对 op 来说内容是个黑盒,就直接转给虚拟网卡处理了,如果一定要拒绝的话,是不是应该在防火墙规则显示指定 tun 接口去 drop 。

#20 可能网络拓扑结构我没讲清楚。发送给 B 电脑的数据包,先是到达 B 的上级 OpenWrt ,OpenWrt 有两个网口,一个公网,一个内网,数据包先到达公网,然后转发给内网。对于 OpenWrt 来讲,什么虚拟网卡都不知道,数据包不是发给 OpenWrt 自己的,就不会再一层层解包处理,会根据路由表转发给内网,数据到达 B 电脑后,才会将数据转发到虚拟网卡来处理。

你把所有的防火墙规则贴出来看下

对的,不管是 v4 还是 v6 ,防火墙默认是有 "iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT"这样一条的。从内部发出去的包,如果收到响应,默认是接收的。

我现在更倾向于我这 OpenWrt 的问题,昨天防火墙的 FORWARD 默认是 DROP ,经过开一个 server 测试,确实是这样的。但是 tailscale 能用 v6 直连。但今天再测,就不能用 v6 直连了,而且我现在把 FORWARD 规则改成默认 ACCEPT 也不行。

由于是办公室的网络环境,不太方便 flush 掉所有规则做测试,具体是这样的:

$ ip6tables -L FORWARD -vn
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
257K 161M forwarding_rule all ::/0 ::/0 / !fw3: Custom forwarding rule chain /
226K 153M ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED / !fw3 /
16675 2716K zone_lan_forward all br-lan ::/0 ::/0 / !fw3 */
14322 5367K zone_wan_forward all pppoe-ppp ::/0 ::/0 / !fw3 */
0 0 zone_docker_forward all docker0 ::/0 ::/0 / !fw3 */
0 0 zone_ipsecserver_forward all ipsec0 ::/0 ::/0 / !fw3 */
0 0 reject all ::/0 ::/0 / !fw3 /

# root @ OpenWrt in ~ [20:32:49]
$ iptables -L forwarding_rule -v -n
Chain forwarding_rule (1 references)
pkts bytes target prot opt in out source destination
1314K 1142M RETURN all -- pppoe+ * 0.0.0.0/0 0.0.0.0/0
886K 333M RETURN all -- * pppoe+ 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- ppp+ * 0.0.0.0/0 0.0.0.0/0 ctstate NEW
0 0 ACCEPT all -- * ppp+ 0.0.0.0/0 0.0.0.0/0 ctstate NEW

#24 数据包是这样走的,数据包来到网口 1 后,经过 forward 链,然后第一条是自建的forwarding_rule(我也不知道谁建的这条 rule ),这个 rule 表示,如果是从 pppoe 开头的网口,那么数据包会 RETURN ,RETURN 代表向下一条规则过滤,也就是走到 ACCEPT 这一条,这一条后面是 ctstate RELATED,ESTABLISHED,代表如果是出站过的流量,那么返回的响应是正常接收的。

然后就是下面这些 OpenWrt 自定义的规则了。能够看到数据包也小,数据量都是在 forwarding_rule 上,估计使用 tailscale 连接是被这条链捕获记录。