rsync,依然很有生命力的Linux工具

我写过一个工具(certbot-letencrypt-wildcardcertificates-alydns-au,地址见文末连接),用于自动申请和续期letsencrypt证书,目前还缺少了一个非常重要的功能,很多业务的服务器可能不止一台,如何将更新的证书同步到多台服务器上,并重启相应的web服务呢?

为了提供这个功能,近期在思考解决方案,最先想到的方法就是ssh+rsync,rsync 用于传输证书文件到服务器上,而ssh则能自动化重启web服务,更巧妙的是rsync还能结合ssh一起使用。

最近几天温习了下rsync,有很多收获,将自己感兴趣的写下来,并分享给大家。

rsync大部分人都知道,也经常使用,官方是这样定义它的,a fast, versatile, remote (and local) file-copying tool。

一个快速,功能齐全,可远程拷贝文件,local同步到remote(或相反),但remote和remote之间不能传递文件,从官方定义来说,可用于备份文件或做镜像,但由于可以网络传输文件,所以rsync可发挥的空间非常大。

rsync牛逼之处在于它有个非常高效的算法,它通过比较本地和远程文件的差异,让最小量的数据在网络上传播,所以效率很高,很容易进行中断续传,增量备份。

rsync主要有三种运行模式:

1:本地传输

就是没有服务器端,可以在一台机器上传输文件,类似于cp工具,比如:

# 将 /src/file 文件拷贝到 /desc 目录下
$ rsync -av /src/file /desc

2:rsync以daemon的方式提供服务

这是非常典型的一种B/S运行模式,在远程主机让rsync以dameon方式运行,默认绑定 873 端口,等待客户端的连接,一旦有新的连接产生,它就会启动一个新端口dameon用于与客户端进行数据传输。

在服务器端可以通过两种方式启动 dameon,第一种就是 stand-alone 手动的方式,比如运行:

$ rsync --daemon --port 873  --config /etc/rsync.conf

或者以 inetd 服务器的方式启动 daemon,在 Ubuntu 中,具体可参考 /etc/init.d/rsync,然后以 service rsync start 的方式启动。

如果以 daemon 方式运行,rsync 客户端使用 host::moudlersync://host/dodule 的语法进行文件传输。

daemon 方式的 rsync 会读取一个配置文件(默认 /etc/rsync.conf),该文件有很多控制项,具体可参考 man rsyncd.conf

配置文件一旦更新,不用重启 daemon,在每个 rsync 客户端连接的时候,会重新读取。

rsync daemon 文件大概如下:

pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
port = 873 

[data0]
uid = root
gid = root
use chroot = no
path = /data0
read only = no
list = no 
auth users = u1 
secrets file=/etc/rsyncd/rsyncd.secrets
pre-xfer exec = file.sh 
post-xfer exec = file.sh 
hosts allow = ip1,ip2
timeout = 100

参数分为全局控制参数和模块参数(可以有多个模块,每个模块用[]符号分隔)。

全局参数很好理解,比如 pid 进程文件,daemon 监听地址和端口等等。

而模块指令参数有很多,比如 path 表示模块对应的目录,rsync 客户端调用模块的时候,会将文件传输到 path 目录下。

可以设置 uid 和 gid 参数,表示用那个用户的身份传输数据,需要注意权限的问题。

pre-xfer 和 post-xfer 两个参数很有意思,就是 rsync 在实际传输前和完成后可以执行 shell,但 shell 的执行权限必须注意。很容易想到,是不是 rsync letsencrypt 证书后,可以启动 web 服务器? 这是一个很好的想法

hosts allow 参数有点类似防火墙,指定的 ip 主机才能传输文件,这对于 rsync 安全很有好处,以前遇到很多 rsync 被攻击的情况(开放外网),如果加上这个参数,则能够保证一定的安全。

timeout 参数很容易理解,网络 I/O 超时参数,避免 rsync 客户端无限时间等待下去。

当我们 rsync ip:: 的时候,默认会显示主机上所有的模块,但在生产环境下,可能比较危险,所以可以设置 list 参数为 no,隐藏特定模块。

如果 read only 参数值为 yes,则客户端只能查看对应模块下的文件,而不能上传文件到该模块。

如果 use chroot 参数设置为 yes,则在传输之前,daemon 会先 chroot path 目录下,这能保证一定的安全,该参数值生效的前提条件是 daemon 以 root 用户的身份运行。

rsync daemon 默认允许客户端匿名传输文件,也就是说对客户端没有任何的验证,为了弥补这一缺陷,可以使用 auth users 和 secrets 参数,这个 user 是虚拟的,不是 Linux 主机上的用户,而 secrets 对应的文件用于存储口令。那么 rsync 客户端如何进行用户认证呢,一般运行如下:

# user 就是 rsyncd.conf 中的 auth user
$ rsync --password-file=/etc/rsync-password user@ip::moudle

3:remote shell

rsync remote shell 模式是我重点推荐的,使用 dameon 方式能够解决很多问题,但最大的弊端在于文件传输是不加密的,很容易被截获,虽然有 auth 验证机制,但数据还是明文传输的。

rsync remote shell 则解决了这个问题,比如可以使用 ssh,具体的工作原理很简单,rsync 客户端和远程主机构建了一个 ssh 通道,在这条通道上数据都是加密保护的,文件传输到远程主机后,rsync 的源和目的机器就是同一台机器了,相当于本地传输。

也就是说如果你的主机完全使用 remote shell 方式,则远程主机无须启动一个 daemon(rsync — daemon),当 ssh 隧道建立后,远程主机会单独启动一个传输 daemon,该 daemon 也会读取 rsyncd.conf 文件。

使用这种方式,很多 rsync daemon 的功能就无法用了,即 rsyncd.conf 中的很多参数不会生效,比如 chroot 等等。

具体怎么使用呢?推荐 ssh 密钥对文件方式验证(推荐看 《ssh密钥对登录安全吗?原理篇》 ),比如:

$ rsync -e 'ssh -i /home/root/.ssh/id_rsa ' root@ip::data0

以 remote shell 方式运行,也可以使用 user 验证的模式,比如下面这条命令

$ rsync -e "ssh -i /home/root/.ssh/id_rsa -l ssh-user" rsync-user@host::module /dest

什么意思呢?连接主机使用 ssh-user 连接,而 user 验证则使用虚拟帐号 rsync-user。

这篇文章没有说任何 rsync 的使用技巧,后面在具体实现 certbot-letencrypt-wildcardcertificates-alydns-au 功能的时候,会重点记录一些。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章