35

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

 4 years ago
source link: https://www.tuicool.com/articles/Fr6Nr2U
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我写过一个工具(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 功能的时候,会重点记录一些。

aYbieiq.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK