menu Chancel's blog
rss_feed
Chancel's blog
我就是这样的人

Linux - Syncthing中继服务器搭建

作者:Chancel, 更新:2020 Sep 28, 字数:4495, 已阅:1263

这篇文章更新于 980 天前,文中部分信息可能失效,请自行甄别无效内容。

官方文档也没说在哪里配置客户端,只说了配置协议监听地址,结果两台连接了中继服务器的设备一直无法互连,要给每台设备手动显式的配置中继服务器的地址

1. 前言

What is Syncthing? Syncthing is a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it's transmitted over the internet.

简单讲,Syncthing是一个P2P的同步软件,旨在两台或多台计算机之间实时安全地同步文件

Syncthing不依赖于中心服务器,即你不需要使用任何服务器也可以使用Syncthing完成两台处于完全不同网络的PC之间的文件同步

实现这一点,其实还是依赖于中心服务器的,Syncthing官方称之为“discovery-server”

Syncthing默认提供一个“discovery-server”用于建立同步PC之间的第一次直连,此后直连不再依赖于“discovery-server”

2. 中心服务器 & 中继服务器

中心服务器有很明显的优点,只提供给双方设备的连接地址,普通的内网也可以使用,速度快,不依赖于服务端的性能,直接互连

缺点也同样很明显,面对复杂的NAT多层转换可能会无法顺利同步文件或者速度低的令人发指

这个时候,解决方案便是中继服务器,或是sockets代理,如果不想建立中继服务器或者没有条件建立中继服务器可以参考如下链接

Syncthing - 通过配置全局环境变量来实现代理功能

这个方案通过配置全局环境变量来实现代理功能,但仅实现出站流量功能,无法侦听传入的设备请求

重点讲讲中继服务器“relay-server”,它用于在两台设备无法直接互联的时候通过服务端建立联系,优点是连接稳定,能够适应复杂的Nat网络

缺点也很明显,需要消费服务器带宽以及性能

3. 搭建步骤

3.1. 中心服务器(discovery-server)

根据服务端系统选择软件版本下载 discosrv-server

下载完成之后,解压下载的tar.gz文件夹,并在防火墙开放如下两个端口

sudo firewall-cmd --add-port=8443/tcp --zone=public --permanent
sudo firewall-cmd --add-port=19200/tcp --zone=public --permanent

运行服务端程序,参数请根据需要自行添加,下面是常用的参数例子

./stdiscosrv -debug -listen ":8443" -replication-listen ":19200" -db-dir "./discovery.db" -cert "./certpem"

3.2. 中继服务器(relay-server)

根据服务端系统选择软件版本下载 relay-server

下载完成之后,解压下载的tar.gz文件夹,并在防火墙开放如下两个端口

sudo firewall-cmd --add-port=22067/tcp --zone=public --permanent
sudo firewall-cmd --add-port=22070/tcp --zone=public --permanent

接着运行运行服务端程序

./relaysrv -pools ""

relaysrv的参数可以参考官网文档,这里有一份来自自建Syncthing中继服务器(私密传输或造福大众) - senra的翻译

-debug 启用调试输出
-ext-address=<address> 可选的外部地址(将被上报),能够通过端口转发来监听高权限端口(0-1024)然后外部可以连接这个端口
-global-rate=<bytes/s> 全局限速,单位 bytes/s
-keys=<dir> 用于存储 cert.pem 和 key.pem 的目录,默认是 "."(当前目录)
-listen=<listen addr> 协议监听的地址,默认是 ":22067"
-message-timeout=<duration> 等待消息到达的最大时间(默认 1m0s)
-nat 使用UPnP/NAT-PMP来取得外部端口映射
-nat-lease=<duration> NAT租赁时间,单位分钟(默认 60)
-nat-renewal=<duration> NAT刷新频率,单位分钟(默认 30)
-nat-timeout=<duration> NAT发现超时,单位秒(默认 10)
-network-timeout=<duration> 客户端和中继之间网络操作的超时,如果在这个时间段内客户端和中继之间没有数据被接收到,那么连接将被终止。此外,如果在这段时间内任何被中继的客户端没有数据发送,这个会话也会被终止(默认 2m0s)
-per-session-rate=<bytes/s> 每个会话的限速,单位 bytes/s
-ping-interval=<duration> ping的发送间隔(默认 1m0s)
-pools=<pool addresses> 中继服务器池的地址,使用逗号分隔多个(默认 "http://relays.syncthing.net/endpoint")。留空(-pools "")来禁止公布这个服务器到池中,以便作为私有中继。
-protocol=<string> 监听协议,"tcp"来监听IPv4和IPv6,"tcp4"来监听IPv4,"tcp6"来监听IPv6(默认 "tcp")
-provided-by=<string> 一个可选的描述字段来表示谁提供了这个中继(可以打打广告啥的)
-status-srv=<listen addr> 提供状态服务的监听地址(默认 ":22070"),用于中继服务器池页面来展示服务器状态(传输了多少数据,有多少客户端在线等等),留空(-status-srv="")来禁用这个功能

运行成功之后会有类似如下输出,记住这一串输出,0.0.0.0修改成你的服务器地址,如:relay://chancel.cn:22067 即可

URI: relay://0.0.0.0:22067/?id=4ZVSHHI-ZSJID5Y-CKSUQAV-6KATUHA-HJN6WMQ-TU2KEUJ-H5RYSNN-NREXNA7pingInterval=1m0s&networkTimeout=2m0s&sessionLimitBps=0&globalLimitBps=0&statusAddr=:22070&providedBy=

下面是参考例子

./strelaysrv -debug -pools "" -listen ":22067" -keys "" -message-timeout "1m0s"  -network-timeout "2m0s" -ping-interval "1m0s" -protocol "tcp4" -provided-by "TYFS" -status-srv ":22070"  > /home/temp/log/strelaysrv.log 2>&1 &

4. 客户端配置

A客户端

  1. 运行syncthing程序
  2. 在web GUI界面依次选择右上角的操作-设置-连接,在协议监听地址填入服务端第四步的中继服务器地址(relay://example.com:22067)
  3. 回到web GUI首页,点击右下角的添加远程设备,如果没有显示任何远程设备,则手动输入需要连接的B客户端ID,选择高级,在地址列表出删掉dynamic,输入中继服务器地址(relay://example.com:22067)

B客户端

  1. 运行syncthing程序
  2. 在web GUI界面依次选择右上角的操作-设置-连接,在协议监听地址填入服务端第四步的中继服务器地址(relay://example.com:22067)
  3. 回到web GUI首页,点击右下角的添加远程设备,如果没有显示任何远程设备,则手动输入需要连接的A客户端ID,选择高级,在地址列表出删掉dynamic,输入中继服务器地址(relay://example.com:22067)

到此设置基本就结束了,官方文档对客户端的设置提的很少。

最后,我不太确定长时间运行下是否dynamic是否能够自动识别,至少我填了协议监听地址之后等了半个小时都没能识别出远程设备,手动输入也不行,最后是在设备高级中显式填入了地址才可以连接。

5. 参考资料

官方文档

  1. relay-server 官方文档链接
  2. discovery-server 官方文档链接
  3. relay-server 下载地址

[[replyMessage== null?"发表评论":"发表评论 @ " + replyMessage.m_author]]

account_circle
email
web_asset
textsms

评论列表([[messageResponse.total]])

还没有可以显示的留言...
[[messageItem.m_author]] [[messageItem.m_author]]
[[messageItem.create_time]]
[[getEnviron(messageItem.m_environ)]]
[[subMessage.m_author]] [[subMessage.m_author]] @ [[subMessage.parent_message.m_author]] [[subMessage.parent_message.m_author]]
[[subMessage.create_time]]
[[getEnviron(messageItem.m_environ)]]
目录