异地P2P组网-使用tailscale并自建DERP服务

2022-11-29

前言

此文的P2P可能即指真正的P2P(通过NAT打洞/穿越),也可能指基于relay的P2P,具体含义参照语境来理解。

需求背景

很多时候我们需要访问异地的局域网设备服务,比如NAS,往往人在外地的时候就无法访问了,为此出现许多种解决方案,什么DDNS、frp、蒲公英以及zerotier,都可以实现不错的网络访问。 但是DDNS、FRP要有公网访问权限,蒲公英注册账号很麻烦,zerotier不能指定自己的plant或者moon(在iOS上)。 但是tailscale,配置简单方便,功能也非常强大。

实验设备

手机:iPhone 13 mini(iOS 15)、iQOO neo 5(Anroid 12) PC:HONOR laptop(Windows 10、AMD Ryzen 5 4500U) 路由器:Xiaomi 4A gabit(Openwrt、misple) 云服务器:Aliyun 1c 1g(Rocky Linux 8、x86_64)

基本功能

登录tailscale的网站,https://tailscale.com/,注册一下,下载对应平台的客户端,就可以自行组网。

出现的问题

1、虽然使用很简单方便,但是由于tailscale的中转服务器全部在国外,所以如果不能建立P2P连接的话,就会导致QoS问题。(为什么需要P2P组网还需要中转(relay)服务器?,这是一个非常庞大的话题,具体可以参照这一系列P2P文章)。

问题解决方案

tailscale允许自建relay服务器,官方的叫法是DERP服务器(其实并不只有relay的功能,tailscale默认是先使用此服务组网,然后再进行P2P连接尝试,若P2P可行才会进行P2P组网),我们可以自己在国内建立一个DERP服务器,使用自己的DERP来进行组网服务。

搭建Derp

这个官方教程给的很清楚了,重点在于如何使用自定义的端口和域名,为了简单易懂,我在这里把步骤从零再来一遍。

安装golang和derper

大部分的服务器只需要xxx install golang即可,但注意版本问题,若golang的版本低,则你可能需要手动安装,安装完成后记得配置GOPROXY和GO111MODULE,以及配置PATH环境变量,之后大概率无脑

go install tailscale.com/cmd/derper@main

就可以安装了。

配置证书和域名并开启DERP服务

自定义端口和域名的DERP服务必须要证书,而且证书名称必须是域名.pem 域名.crt 域名.key这种,将他们放在一个文件夹内。 然后执行

derper --certmode=manual --certdir=/cadir/tailscale  --hostname=域名 -a :7006  -stun-port 7007 -http-port 7008

其中7006是DERP端口,7007是STUN端口,7008是HTTP端口。

配置ACLs

打开tailscale的Admin的Access Controls面板,然后配置ACLs规则的derpMap如下:

{
       //....其他配置
        "derpMap": {
                "OmitDefaultRegions": false,      //禁止使用官方的DERP服务器
            "Regions": {
                        "901": {                         //自定义的DERP服务器
                           "RegionID":   901,            //900以上
                             "RegionCode": "anything",
                             "Nodes": [
                                  {
                "Name":     "1",
                                           "RegionID": 901,      //就是上面的RegionID
             "HostName": "yourdomain.com",        //域名
                                                "DERPPort": 7006,        //服务器配置的DERP端口
                                         "STUNPort": 7007,                             //服务器配置的STUN端口
                                    },
                            ],
                    },
            },
},
    //....其他配置
}

点击Save后,就可以通过自定义的DERP服务器来进行组网了。

derper的鉴权

到现在,服务器的derper还是所有人都可以使用的,添加鉴权很简单,在服务器上安装tailscale客户端并在启动derper的时候加入--verify-clients参数就可以了。

derper --certmode=manual --certdir=/cadir/tailscale  --hostname=域名 -a :7006  -stun-port 7007 -http-port 7008 --verify-clients

再次使用

至此,所有连接到此账户的设备(包括iOS)都可以进行P2P组网,大致步骤为: 1、首先通过自定义DERP服务器进行relay的P2P组网。 2、尝试NAT穿越的P2P组网,若可以,则提升至此方式来组网。

子网桥接

是不是还有这样一种情况,有一个设备,它没有办法安装tailscale的客户端,但是它也想加入局域网,对于这种情况,可以使用tailscale的子网路由功能来进行路由转发(以下步骤均在openwrt路由器上进行):

opkg update
opkg install wget #安装wget
cd /tmp                 #所有操作在tmp里面进行就好了,
wget https://github.com/adyanth/openwrt-tailscale-enabler/releases/download/v1.32.2-8466375-autoupdate/openwrt-tailscale-enabler-tag   #下载openwrt-tailscale-enabler
tar x -zvC / -f openwrt-tailscale-enabler-<tag>.tgz#换成自己下载的tgz就可以了
opkg install libustream-openssl ca-bundle kmod-tun   #openwrt可能已经有别的SSL了 总之有一个就行
/etc/init.d/tailscale start     #启动tailscaled
tailscale up --accept-dns=false --advertise-routes=192.168.1.0/24      #注意把192.168.1.0/24换成自己需要转发的子网的网段,并且确定自己其他各设备的各网段都不与此网段重复
/etc/init.d/tailscale enable#可选 开机自启tailscale 并不推荐
ls /etc/rc.d/S*tailscale*             #可选 验证tailscale

然后登录tailscale的面板,选中此设备,点击右侧的三个点配置设备,点击Edit route settings of openwrt,在Subnet routes中开启子网路由。 此时就可以通过tailscale访问路由设备的子网网段以及其中的设备。

引用

P2P技术详解

Custom DERP Servers

内网穿透软件tailscale自定义中转节点DERP安装方法

Tailscale的子网路由和出口节点

Tailscale 基础教程:部署私有 DERP 中继服务器

如何利用 Caddy 搭建 Tailscale 的 Custom DERP Servers

tailscale部署私有中继服务器