本帖最后由 z377409011 于 2021-4-14 09:58 编辑
一、为啥要用Syncthing,不用Drive
Syncthing是一款类似于Synology Drive、Seafile、NextCloud、ownCloud、BT Sync (Resilio Sync) 的文件同步软件。免费且开源,跨平台支持 Windows、Mac、Linux、Android 、IOS(有个三方客户端fsync)等主流平台,还提供了中文界面的支持。Syncthing 最大的特色是采用了与 Resilio Sync (BitTorrent Sync) 类似的 P2P 分布式技术,无需中心服务器,即可让多台设备互相实时同步文件,用过 Resilio Sync 的朋友都明白这种同步方式的优势了,Drive同步必须保证NAS一直在线,NAS一旦掉线,同步就没法进行了,但Syncthing可以设备间各自同步,在NAS掉线时,仍能保证设备间的同步能正常进行,这就是我用Syncthing而暂时没用Drive的原因。
Syncthing虽然无需中心服务器,可以直接在设备上直接设置使用,但整个同步网络中,如果有一个设备长期在线的设备,可以优化同步体验(其实我认为这也是有中心服务器方案的优势)。举个下班后在家里加班的例子:如果NAS没有加入同步,下班后,不能关闭单位电脑,到家后开机后,要慢慢等待以外网传输速度传输今天一整天修改的文件,然后再继续工作。如果不想回家还要慢慢等同步,那么家里电脑就不能关机,那不正是该给NAS干活吗?如果NAS部署了Syncthing,改完A文件,再改B文件的时候,A文件基本就同步到NAS了,文件的同步过程就基本上无感了,下班前基本上只剩最后操作的那个文件没有同步完,文件小的话,很快就同步完了,直接关机,文件稍大,设置个延迟关机就可以了,回家后直接挂载NAS,继续工作或者也部署了内网速度从NAS上同步,快了很多很多。
二、文件权限的坑和解决办法
Syncthing方案虽好,但文件权限的问题是个大坑,一个人用的时候,可能还好,如果要同步几个人的文件,又想实现不同账号的权限的时候,就遇到各种各样因为权限导致的问题,其实三方软件都有这个问题!
坑1、docker程序读写权限的问题
为了docker程序能读取共享文件夹及里面的数据,很多大佬的教程都教的是无脑给“777”权限,即Everyone可读写。而且共享文件夹就需要给777权限,如此一来,每个用户都可以读写你的同步的资料,非常不安全。折腾了好久,Syncthing一直报权限错误,除非是空的文件夹,从最开始就从其他设备获取文件。难道docker程序,只能搞一些电影、电视剧这些丢了不心疼的文件?后面发现给所有文件、文件夹设置System完全控制权限:
Syncthing就可以读写共享文件夹了,子文件夹给755权限(chmod 755 * -R),有数据的目录、重装系统或syncthing配置丢失的情况下,扫描文件就不报错了。再后面又折腾了一下发现原来docker的环境变量PUID、PGID,这两个就是docker程序的用户和用户组,因为默认都是1000,一般情况下,1000对应的用户和用户组都不存在,所以才出错的。所以只要使用ssh中使用“id”命令查询,管理员用户之后输入即可,只要这里配置好了,文件本身的权限没有问题,docker程序拥有的权限就是对应账户的权限了,就肯定可以访问。
如我的synology账户:uid=1026(synology) gid=100(users) groups=100(users),101(administrators)
为了方便其他用户能读写文件,我就设置的PUID=1026,用户组“PGID=100”(即users),其实用户组ID对syncthing来讲影响不大,因为文件权限的坑还没解决完!而且这也只是docker程序设置的问题,都没管UID和GID,全部直接无脑给777权限了。其他的docker程序也可以参考。
这样可能有的程序还是会报权限错误(就比如syncthing),原因是权限信息中,账户没有直接访问权限,账户是靠继承所属的用户组的权限,文件的权限信息并没有针对用户本身来申明,就导致有的软件可以访问,有的软件就无法获取到权限,解决办法很简单,要么docker程序GID也改成administrator的101(不好),要么在控制面板账户设置中,把账户对文件夹的权限申明一次(打勾)。
靠继承用户组权限,群晖自带程序可以访问,acl权限没有针对用户申明,某些三方程序还是没办法读写。
即使用户组已经可读写了,还是再勾选可读写,这样acl权限中,就增加了用户读写权限的申明,程序只要UID正确,就能读写。
坑2、群晖文件监视数量的问题
群晖默认的max_user_watches参数设置的非常小,貌似好像只有8192还是81920,使用下面的命令修改就可以了。但是重启会失效,所以最好设置个计划任务,开机自动执行。
- sh -c '(sleep 10 && echo 204800 > /proc/sys/fs/inotify/max_user_watches)&'
复制代码
坑3、第三方程序创建的文件,非管理员账户无法访问或不显示的问题
经过坑一的折腾,第三方程序可以读写本机已有文件了。但是有第三方程序创建的文件(如下载的文件、同步的文件、修改后另存的新文件...),owner属性基本都是程序运行的用户和用户组,默认权限一般都是700、711、750或者755。导致其他非管理员用户,经常出现FileStation无法访问文件或目录,要么就是WebDAV里面直接不显示文件或目录等问题。要解决这个问题,就要再讨论下Linux权限管理的问题了(我也不是很专业哈,名词可能不对哈,只是按我个人的理解解释的): 群晖实际支持两种权限定义,一种就是默认的linux权限,还有一种acl权限。我们在DSM界面中设置的更新的基本都是acl权限,一些自带程序程序也是通过acl权限来控制不同用户、用户组权限的,但如Syncthing等第三方程序创建的文件,通常默认都是linux权限(一般是700,711,750或者755),就会导致一些程序获取不到acl权限信息,导致无法访问或者不显示。
左(第一张):linux权限 右(第二张):acl权限
所以还要折腾权限,但是很少有软件可以设置由它生成的文件的默认权限,要解决的话,思路无非是syncthing等第三方程序创建文件后,再更新一次文件的权限即可。
更新linux权限:
将子文件和目录权限设置为777,共享文件夹权限不变,这样有访问共享文件夹权限的账户应该就可以访问该目录下的全部子目录和文件了,同时权限管理还时基本有效的,文件还是相对安全的。因为虽然子文件所有用户都可以访问,但是你首先得有权限访问共享文件夹,跟家里锁上入户门,但开着房间门一个道理。方法很简单:定期在下载、同步文件夹下面执行一次 chmod 777 * -R即可(其实这个方法其他用户通过FileStation访问没问题了,WebDAV是否正常我还没试过,我主要还是更新文件的acl权限)。
更新acl权限:
DSM界面设置方式:
用管理员账户登录DSM,打开FileStation,找到要同步、下载的文件夹,右键→属性→权限,勾选“应用到这个文件夹、子文件夹及文件”后,点击保存即可。前提时,文件夹本身的权限是正确的。
例如:
/downloads/PT/电影/xxxxx/xxxx.mkv
/Syncthing/项目/2021年项目/xxx工程/xxxx.dco
如果红色是更新的文件,或者文件夹,你可以选中红色路径之前的任意一个权限正确文件夹,来执行更新子文件夹的权限的操作,甚至是共享文件夹。
通过命令设置的方式(为了方便使用脚本):
群晖是提供了文件acl权限管理的cli程序的“synoacltool”,帮助文件如下;
- Usage: synoacltool
- SYNOPSIS
- synoacltool -h
- synoacltool -check PATH [ACL Perm]
- synoacltool -get PATH
- synoacltool -getace PATH
- synoacltool -get-perm PATH USERNAME
- synoacltool -add PATH [ACL Entry]
- synoacltool -replace PATH [ACL Entry Index] [ACL Entry]
- synoacltool -get-archive PATH
- synoacltool -set-archive PATH [ACL Archive Option]
- synoacltool -del-archive PATH [ACL Archive Option]
- synoacltool -del PATH [ACL Entry Index]
- synoacltool -del PATH
- synoacltool -copy PATH_SRC PATH_DST
- synoacltool -set-owner PATH [user|group] NAME
- synoacltool -set-eadir-acl PATH
- synoacltool -enforce-inherit PATH
- synoacltool [-stat|-cstat|-fstat|-lstat|-utime] PATH
- -h: show help
- -check: check acl permission of file
- -get: get syno acl of file
- -getace: get syno ACEs with uid/gid of file
- -get-perm: extract windows permission from acl or linux permission
- -add: add syno ace into file
- -replace: replace specified ace by index number
- -del: delete syno acl of file
- -get-archive: get ACL archive bit
- -set-archive: set ACL archive bit
- -del-archive: delete ACL archive bit
- -stat, -cstat, -lstat, -fstat: get stat/archive bit
- -utime: set current time into file
- -copy: copy ACL from source to destination, only works when ACL exists
- -set-eadir-acl: set ACL for EA dir
- -enforce-inherit: enforce ACL inheritance
- OPTIONS
- ACL Entry Index: >= 0
- ACL Option: [inherit|single]
- ACL Archive Option: is_inherit,is_read_only,is_owner_group,has_ACL,is_support_ACL
- ACL Entry: [user|group|owner|everyone|authenticated_user|system]:name:[allow|deny]:permissions:inherit mode
- Example: user:root:allow:rwx-d---RWc--:fd--
- Example: owner:*:allow:rwx-d---RWc--:fd--
- Fields
- name: user/group name
- ACL Perm: rwxpdDaARWcCo
- r: (r)ead data
- w: (w)rite data (create file)
- x: e(x)ecute
- p: a(p)pend data (create dir)
- d: (d)elete
- D: (D)elete child (only for dir)
- a: read (a)ttribute (For SMB read-only/hidden/archive/system)
- A: write (A)ttribute
- R: (R)ead xattr
- W: (W)rite xattr
- c: read a(c)l
- C: write a(c)l
- o: get (o)wner ship
- inherit mode: fdin
- f: (f)ile inherited
- d: (d)irectory inherited
- i: (i)nherit only
- n: (n)o propagate
复制代码 acl权限可以更细致的划分,每个用户和用户组的权限,也是群晖默认采用的权限控制方式。主要是用-get(查看权限)、-add(则更加权限)、-copy(复制权限)、-enforce-inherit(强制继承权限)4个参数。我主要用-copy和-enforce-inherit来更新权限。
-copy,即复制权限的方法:
命令:synoacltool -copy PATH_SRC PATH_DST
PATH_SRC=权限是符合你要求的路径
PATH_DST=你要修改的文件或目录路径
如;synoacltool -copy /volume1/syncthing/项目1/ /volume1/syncthing/项目2/
这样就可以把“项目2”文件夹的权限,设置来和“项目1一样”。
-enforce-inherit,即强制继承权限的方法
命令:synoacltool -enforce-inherit PATH
PATH=你要修改的文件或目录路径
synoacltool -enforce-inherit /volume1/syncthing/项目/
这样就可以把“项目”文件夹的权限修改来和上一级目录“syncthing”一样,如果使用:
synoacltool -enforce-inherit /volume1/syncthing/项目/*
这样就可以把“项目”下面的文件/文件夹的权限设置来和“项目文件夹”一致。
一般来讲,同步目录和下载目录自己的权限一般来讲都是正确的,所以我一般都是使用强制继承的方法来更新权限。但需要注意的是,synoacltool不支持遍历修改子文件/夹(或许是我没有发现),需要配合其他命令来使用。
我是搭配的find命令来执行:
刷新全部子文件/文件夹权限:
- find "<font color="#ff0000">/volume1/syncthing/项目/</font>"* -print0 | xargs -0 -i synoacltool -enforce-inherit {}
复制代码 刷新最近半天(360分钟)内,修改过的文件的权限:
- find "<font color="#ff0000">/volume1/syncthing/项目/</font>"* -mmin -360 -print0 | xargs -0 -i synoacltool -enforce-inherit {}
复制代码 “/volume1/syncthing/项目/”改成你的路径即可。我是把命令放进了一个sh脚本里面,在计划任务里面添加了每一段时间执行一次。我是搞了两个脚本,一个是刷新最近半天修改的文件,每15分钟执行一次(时间间隔有点问题,可以自己修改),另一个是刷新全部文件的权限,防止有漏网之鱼,每周执行一次。有几个目录需要修改,就重复几次上面的命令,更改路径就可以了。
|