搭建tinc实现异地构建局域网
相比于zerotier,tinc可以启用TCPOnly,避免国内网络环境下udp连接不稳定的问题。
服务器和客户端的环境均为Debian,客户端还可以使用Windows。
由于大多数发行版的源中内置的tinc不是最新版,此处主要采用编译安装。
tinc支持3种工作模式,分别为router(路由器)、switch(交换机)和hub(集线器),默认使用router模式。此处采用switch模式,使所有节点相当于有一个虚拟网卡,网卡连接在了同一个交换机下。这种方法可以完全自行控制路由(如可以实现ipv6隧道),同时每个设备也可以继续桥接子设备(如在Proxmox平台上可以将虚拟机的虚拟网卡vmbr桥接到tinc虚拟网卡上,使每个虚拟机无需安装tinc便可与tinc处于同一个网段)。
服务端配置
安装
先下载tinc的源码,当前tinc的最新稳定版本为1.0.36。下载后解压。
wget https://www.tinc-vpn.org/packages/tinc-1.0.36.tar.gz
tar zxvf tinc-1.0.36.tar.gz
安装编译所需的依赖项:
sudo apt-get update && sudo apt-get install gcc cmake make openssl libssl-dev zlib1g zlib1g-dev liblzo2-2 liblzo2-dev
之后cd到解压的目录中,编译并安装tinc:
./configure
make
sudo make install
可执行程序将会被安装到/usr/local/sbin/tincd。
配置Service
首先需要创建运行目录:
sudo mkdir -p /usr/local/var/run/
sudo mkdir -p /usr/local/etc/tinc/
sudo ln -s /usr/local/etc/tinc /etc/tinc
之后添加并修改service。在源码目录下的systemd目录中存放有配置模板,需将 systemd/tinc.service.in 拷贝为 /lib/systemd/system/tinc.service,将 systemd/tinc@.service.in 拷贝为 /lib/systemd/system/tinc@.service。
修改/lib/systemd/system/tinc.service文件,找到WorkingDirectory=@sysconfdir@/tinc行,将其修改为WorkingDirectory=/usr/local/etc/tinc。
# WorkingDirectory=@sysconfdir@/tinc
WorkingDirectory=/usr/local/etc/tinc
修改/lib/systemd/system/tinc@.service文件,找到WorkingDirectory=@sysconfdir@/tinc行,将其修改为WorkingDirectory=/usr/local/etc/tinc。将如下几行注释掉并修改为以下内容:
# WorkingDirectory=@sysconfdir@/tinc/%i
# ExecStart=@sbindir@/tincd -n %i -D
# ExecReload=@sbindir@/tincd -n %i -kHUP
WorkingDirectory=/usr/local/etc/tinc/%i
ExecStart=/usr/local/sbin/tincd -n %i -D
ExecReload=/usr/local/sbin/tincd -n %i -kHUP
更新服务配置:sudo systemctl unmask tinc
配置tinc
以下以接口名为mynet为例。先创建所需目录:
sudo mkdir /etc/tinc/mynet
cd /etc/tinc/mynet
sudo mkdir hosts
执行sudo nano /etc/tinc/mynet/tinc.conf以编辑该网络的tinc.conf文件,编写以下内容。此处指定服务端口为8665。
Name = master
Interface = mynet
Port=8665
Mode=switch
执行sudo nano /etc/tinc/mynet/hosts/master以编辑master文件,编写以下内容。其中服务器的IP和虚拟局域网的IP按需要进行修改。(注:hosts文件夹内的文件中,Subnet可以省略,由tinc自动决定,也可以指定一个比实际使用地址更大的段来使发往该段内的流量优先选择经过该服务器)
Address = 服务器公网IP 8665
Subnet = 10.20.20.1/32
生成tinc密钥对,路径按默认的即可:sudo /usr/local/sbin/tincd -n mynet -K
编写启用脚本:sudo nano /etc/tinc/mynet/tinc-up,注意修改IP,可以使用ifconfig(如注释部分)或ip命令进行ip的设置
#!/bin/bash
# ifconfig $INTERFACE 10.20.20.1 netmask 255.255.255.0
ip link set $INTERFACE up
ip addr add 10.20.20.1/24 dev $INTERFACE
ip route add 10.20.20.0/24 dev $INTERFACE
编写停用脚本:sudo nano /etc/tinc/mynet/tinc-down
#!/bin/bash
# ifconfig $INTERFACE down
ip route del 10.20.20.0/24 dev $INTERFACE
ip addr del 10.20.20.1/24 dev $INTERFACE
ip link set $INTERFACE down
给这两个脚本可执行权限:sudo chmod +x /etc/tinc/mynet/tinc-*
启动服务:sudo systemctl start tinc@mynet
设置开机启动:sudo systemctl enable tinc@mynet
注意如有有服务端安全组、防火墙的需要放行相应端口。此处采用仅TCP连接,放行端口的TCP即可。如需启用P2P功能,则还需放行UDP端口。
客户端配置
Debian系发行版中运行客户端
按服务器同样的方法编译安装tinc,创建配置目录,配置service。
进入/etc/tinc,建立目录/etc/tinc/mynet。
运行 sudo nano /etc/tinc/mynet/tinc.conf 编辑以下信息:
Name = mynet_client1
Interface = mynet
ConnectTo = master
Mode=switch
建立/etc/tinc/mynet/hosts目录。
运行 sudo nano /etc/tinc/mynet/hosts/mynet_client1 编辑以下信息,注意修改客户IP。
Subnet = 10.20.20.2/32
生成客户端密钥:sudo /usr/local/sbin/tincd -n mynet -K
编写启动脚本:sudo nano /etc/tinc/mynet/tinc-up 注意修改IP。(同样可以使用ifconfig或者ip中的一个进行ip设置)
#!/bin/bash
# ifconfig $INTERFACE 10.20.20.2 netmask 255.255.255.0
ip link set $INTERFACE up
ip addr add 10.20.20.2/24 dev $INTERFACE
ip route add 10.20.20.0/24 dev $INTERFACE
编写停用脚本:sudo nano /etc/tinc/mynet/tinc-down
#!/bin/bash
# ifconfig $INTERFACE down
ip route del 10.20.20.0/24 dev $INTERFACE
ip addr del 10.20.20.2/24 dev $INTERFACE
ip link set $INTERFACE down
给脚本可执行权限:sudo chmod +x /etc/tinc/mynet/tinc-*
最后,客户端与服务端互相发送双方hosts目录下的文件。即服务端需要发送含有服务端公钥的master,客户端将该文件保存到hosts目录下。同样,客户端需要发送含有客户端公钥的mynet_client1,服务端将该文件保存到hosts目录下。这种工作模式下,服务端与客户端交换密钥和配置文件即可,客户端之间无需交换配置文件。
然后客户端就可以启动服务:sudo systemctl start tinc@mynet
并设置开机启动:sudo systemctl enable tinc@mynet
在服务端需要重启tinc服务以更新配置:sudo systemctl restart tinc@mynet
Windows中运行客户端
安装预编译包。下载地址:http://www.tinc.link/packages/windows/tinc-1.0.36-install.exe
以下配置是注意使用管理员权限。
假设安装到目录C:\Program Files (x86)\tinc\,到该目录下新建文件夹mynet,以及在mynet中新建hosts文件夹。在mynet下新建tinc.conf文件,写入以下内容:
Name = mynet_client2
Interface = mynet
ConnectTo = master
Mode=switch
在hosts中新建mynet_client2文件,写入以下内容(注意按需求修改IP地址):
Subnet = 10.20.20.3/32
生成客户端密钥:C:\Program Files (x86)\tinc\tincd.exe -n mynet -K
之后以同样的方法与服务端交换密钥文件,并重启服务端以更新服务端配置。
运行C:\Program Files (x86)\tinc\tap-win64\addtap.bat创建虚拟网卡,之后到控制面板中将新建的虚拟网卡名字设置为mynet,IP设置为静态IP,并指定IP地址10.20.20.3,子网掩码为255.255.255.0。
然后C:\Program Files (x86)\tinc\tincd.exe -n mynet即可自动创建并启动服务,完成连接。
目前该方案测试稳定,异地访问家中NAS不会像Zerotier组网时一样即使添加了moon服务器也会频繁传输中断。该配置方式对服务端的网络要求较高,因为所有流量都会经过服务端中转。
如需启用流量压缩,可以在tinc.conf中添加Compression = Value,其中,Value为0表示不压缩,为1-9表示使用zlib算法(其中1为最快,9为最高压缩率),为10-11表示使用lzo算法(其中10为最快,11为最高压缩率)。实测即使在使用Compression = 11时,ping测试的延迟只会增加1~2ms,但是压缩会导致额外的CPU占用,建议对tinc节点中性能最弱设备进行测试后再决定压缩率。对于非按流量计费的场景,不设置Compression,或设置Compression为0即可。
如果服务端无安全组或防火墙功能,则默认会同时启用TCP和UDP,要使用仅TCP模式,可以在tinc.conf中添加TCPOnly = yes。
可以选择对流量进行加密以确保安全,在tinc.conf中指定一个加密算法即可,如使用aes-128-gcm,则可以添加Cipher = aes-128-gcm。
其他问题
(该部分更新于2021年11月3日)
mac地址冲突
该情况主要针对Linux系统,当两台VPS使用同一个IDC的同一个系统版本的系统模板的时候,有可能出现tinc生成的tun网卡生成的mac地址一样的情况,导致虚拟局域网内出现mac地址冲突,使得其中一台VPS无法与tinc虚拟局域网内的其他设备通信。这个时候需要在其中一台VPS的tinc-up文件中手动设置mac地址,即tinc-up增加一行
ip link set address XX:XX:XX:XX:XX:XX dev $INTERFACE
因为tinc的tun网卡和VPS的主网卡不在一个交换机上,所以其中的XX:XX:XX:XX:XX:XX可直接替换为主网卡的mac地址。或者用一个其他的随机的mac地址亦可。