[TOC]

0x00 前言简述

1.Rsync 介绍

描述: Rsync(remote synchronize)是一个提供快速增量文件传输的开源实用程序, rsync是根据GNU通用公共许可证免费提供的,目前由Wayne Davison维护。

Tips : 通过 rsync 可以解决对实时性要求不高的数据备份需求,例如定期的备份文件服务器数据到远端服务器,对本地磁盘定期做数据镜像等

Rsync 特点

  • 安全性高、备份迅速、支持增量备份


Rsync 应用
描述: 随着应用系统规模的不断扩大,对数据的安全性和可靠性也提出的更好的要求,rsync在高端业务系统中也逐渐暴露出了很多不足,首先rsync同步数据时,需要扫描所有文件后进行比对,进行差量传输。如果文件数量达到了百万甚至千万量级,扫描所有文件将是非常耗时的。而且正在发生变化的往往是其中很少的一部分,这是非常低效的方式

其次 rsync不能实时的去监测、同步数据,虽然它可以通过linux守护进程的方式进行触发同步,但是两次触发动作一定会有时间差,这样就导致了服务端和客户端数据可能出现不一致,无法在应用故障时完全的恢复数据。基于以上原因rsync+inotify组合出现了!

Tips : rsync 服务器可以独立运行,也可由 Xinetd 运行.

1
2
Centos 6.x 需要依托与xinetd服务
Centos 7.x 可直接独立运行


官方地址: https://rsync.samba.org/
官方文档: https://rsync.samba.org/documentation.html


2.Inotify 介绍

描述:Inotify 是一种强大的、细粒度的、异步的文件系统事件监控机制(基于inode的),它是 Linux内核2.6.13 (June 18, 2005)版本新增的一个子系统(API), ,它满足各种各样的文件监控需要,可以监控文件系统的访问属性、读写属性、权限属性、删除创建、移动等操作,也就是可以监控文件发生的一切变化 ,并可以将相应的事件通知给应用程序。

inotify是一个API,需要通过开发应用程序进行调用,对于大多数用户来讲这有着许多不便,inotify-tools的出现弥补了这一不足,inotify-tools是一套组件,inotify-tools是一个C库和一组命令行的工作提供Linux下inotify的简单接口,这些命令行工具可用于通过命令行或脚本对某文件系统的事件进行监控。

Tips: 该机制由著名的桌面搜索引擎项目beagle引入用于替代此前具有类似功能但存在诸多缺陷的dnotify

Tips : FreeBSD 和 Mac OS X 提供一个类似于 inotify 的 kqueue,在 FreeBSD 机器上输入 man 2 kqueue 获取更多信息,本文基于 Ubuntu Desktop version 8.04.1(即 Hardy),它运行在 Mac OS X version 10.5 Leopard 的 Parallels Desktop version 3.0。


Inotify 应用
描述: Rsync可以实现触发式的文件同步,但是通过crontab守护进程方式进行触发,同步的数据和实际数据会有差异,而inotify可以监控文件系统的各种变化,当文件有任何变动时,就触发rsync同步,这样刚好解决了同步数据的实时性问题。

企业中常常以rsync Damon方式运行rsync来同步服务器之间数据,一般以Damon 方式与inotify结合时候运行在备份服务器端 而客户端则不需要以Damon运行,只需要安装rsync即可.

Tips : Inotify 是内核的集成功能,其可用在很多方面,此处与rsync结合只是为了实现文件同步

Tips : Inotify 是基于rsync的push模型,需要安装在没有运行rsync damon的一端,用来监视服务器需要与其他节点同步的文件变化将服务器文件推向Rsync服务端备份节点。

Tips : inotify既可以监控文件也可以监控目录, 当监控目录时,它可以同时监控目录及目录中的各子目录及文件的,此外,inotify 使用文件描述符作为接口,因而可以使用通常的文件I/O操作select、poll和epoll来监视文件系统的变化,幸好自动化 shell 脚本、使用 Nagios 等工具进行监控、通过常见的 cron 进行任务调度可以减轻这个负担。


Inotify 参数说明
描述: 在 inotify-tools 安装后会得到 inotifywaitinotifywatch 这两条命令:

  • inotifywait: 通过inotify API等待被监控文件上的相应事件并返回监控结果,默认情况下,正常的结果返回至标准输出,诊断类的信息则返回至标准错误输出,它可以在监控到对应监控对象上指定的事件后退出,也可以进行持续性的监控
  • inotifywatch: 通过inotify API收集被监控文件或目录的相关事件并输出统计信息


inotify 可以监视的文件系统常见事件包括:

1
2
3
4
5
6
7
8
9
10
11
12
IN_ACCESS:文件被访问
IN_MODIFY:文件被修改
IN_ATTRIB,文件属性被修改
IN_CLOSE_WRITE,以可写方式打开的文件被关闭
IN_CLOSE_NOWRITE,以不可写方式打开的文件被关闭
IN_OPEN,文件被打开
IN_MOVED_FROM,文件被移出监控的目录
IN_MOVED_TO,文件被移入监控着的目录
IN_CREATE,在监控的目录中新建文件或子目录
IN_DELETE,文件或目录被删除
IN_DELETE_SELF,自删除,即一个可执行文件在执行时删除自己
IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动自己

Tips : inotify定义了下列的接口参数,可以用来限制inotify消耗kernel memory的大小, 由于这些参数都是内存参数,因此可以根据应用需求,通过/proc接口中的如下参数设定inotify能够使用的调节内存大小:

1
2
3
4
5
6
7
8
# 应用程序调用inotify时需要初始化inotify实例,并时会为其设定一个事件队列,此文件中的值则是用于设定此队列长度的上限;超出此上限的事件将会被丢弃;
/proc/sys/fs/inotify/max_queue_events

# 此文件中的数值用于设定每个用户ID(以ID标识的用户)可以创建的inotify实例数目的上限;
/proc/sys/fs/inotify/max_user_instances

# 此文件中的数值用于设定每个用户ID可以监控的文件或目录数目上限;
/proc/sys/fs/inotify/max_user_watches

Tips : 根据以上在32位或者64位系统都可以执行如下命令

1
2
echo 104857600 > /proc/sys/fs/inotify/max_user_watches 
echo 'echo 104857600 > /proc/sys/fs/inotify/max_user_watches' >> /etc/rc.local


官方地址
它由Rohan McGovern开发,其项目网址为http://inotify-tools.sourceforge.net
inotify-tools项目地址:https://github.com/rvoicilas/inotify-tools inotify-tools


0x01 安装配置

1.Centos 7.x 安装Rsync

描述: CentOS7.x后则可以独立运行,即通过yum安装完成后即可以通过systemctl start rsync来启动,对于负荷较重的 rsync 服务器应该使用独立运行方式.

  • Step 1.rsync 基础安装配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    # 通过 yum 软件包管理工具进行安装 Rsync (客户端与服务端都安装)
    yum -y install rsyncd

    # 默认配置文件存在于 /etc/rsyncd.conf
    uid = rsync #设置运行rsync 进程的用户
    gid = rsync
    use chroot = no #是否可以切换根目录
    max connections = 4
    # pid file = /var/run/rsyncd.pid #CentOS7中yum安装 不需指定pid file 否则报错
    lock file = /var/run/rsyncd.lock
    log file = /var/log/rsyncd.log #此文件定义完成后 系统会自动创建
    exclude = lost+found/
    transfer logging = yes
    timeout = 900
    ignore nonreadable = yes #同步时跳过没有权限的目录
    dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 #传输时不压缩的文件

    [rsynctest] #此名字即客户端使用rsync来同步的路径
    path = /tmp/rsynctest #实际需要同步的路径
    comment = Test Rsync #备注
    ignore errors = yes
    read only = yes #表示可以pull
    write only = no #表示可以push
    hosts allow = 192.168.133.130 #只允许得ip地址连接
    hosts deny = *                  #拒绝得ip地址连接
    list = false
    uid = rsync #获取文件的身份
    gid = rsync
    auth users = rsyncuser #客户端获取文件的身份 此用户并不是本机中确实存在的用户
    secrets file = /etc/rsyncd.passwd #用来认证客户端的秘钥文件 格式 USERNAME:PASSWD 此文件权限


  • Step 2.安全配置认证文件和相应用户与目录创建
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    vim /etc/rsyncd.passwd    # rsyncuser:123456
    # 属主必须与运行rsync的用户一致
    chown nobody:nobody /etc/rsyncd.passwd
    # 权限设置为600
    chmod +600 /etc/rsyncd.passwd
    # 指定不能登录Shell
    usermod rsync -s /sbin/nologin
    # 安全起见,应新建目录,也可以用已经存在的
    mkdir /tmp/rsynctest
    # 文件夹得宿主
    chown -R nobody.nobody /tmp/rsynctest


  • Step 3.服务启动其默认监听在tcp 873 端口( 注意查看防火墙允许通过873/TCP)。
    1
    systemctl start rsyncd.service


  • Step 4.客户端使用 rsync 演示
    1
    2
    3
    4
    5
    6
    # 注意: 只需要服务器 rsyncd.passwd 中的密码
    echo 123456 >> /etc/rsyncd.passwd
    chmod 600 /etc/rsyncd.passwd

    # 注意: 若要在crontab中添加自动同步,则必须指定--password-file 且rsyncuser一定为rsyncd.passwd中定义的,rsynctest 为服务器端 [ ] 中定义的.
    rsync -auv --password-file=/etc/rsyncd.passwd [email protected]::rstest  /tmp
    WeiyiGeek.rsynctest

    WeiyiGeek.rsynctest

Tips : 配置文件官方解析地址(https://download.samba.org/pub/rsync/rsyncd.conf.html)


源码包方式安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 1.从rsync官网下载rsync-3.1.2.tar.gz
wget https://download.samba.org/pub/rsync/src/rsync-3.1.2.tar.gz

# 2.编译安装
./configure --prefix=/usr/local/rsync
make && make install
# Rsync依赖
yum install mariadb

# 3.建立软连接
ln -s /usr/local/bin/rsync/bin/rsync /usr/bin/rsync # 软连接

# 4.配置 rsync server 配置文件
vi /usr/local/rsync/rsyncd.conf
pid = root
gid = root
use chroot = no
port = 873
max connections = 200
timeout 600
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log file = /var/run/rsyncd.log
motd file = /etc/rsyncd.motd 
ignore nonreadable = yes           
dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2

[test]
path = /test/
comment = ocpyang  test 
ignore errors
read only = true
list = false
hosts allow = *
#hosts deny = 0.0.0.0/32
auth users root  
#该用户系统中存在且对后面指定的备份目录拥有权限
secrets file = /usr/local/rsync/rsyncd.secrets

# 5.此参数允许您指定在每次连接时向客户端显示的“每日消息”
vi /usr/local/rsync/rsyncd.motd 

# 6.建立安全用户
vi /usr/local/rsync/rsyncd.secrets
root:snow01

# 7.配置文件软连接设置与权限配置
ln -s /usr/local/rsync/rsyncd.conf /etc/rsyncd.conf 
ln -s /usr/local/rsync/rsyncd.motd /etc/rsyncd.motd 
ln -s /usr/local/rsync/rsyncd.secrets  /etc/rsyncd.secrets
chmod 600 /usr/local/rsync/rsyncd.secrets 
chown root:root /usr/local/rsync/rsyncd.secrets

# 8.启动守护进程
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
echo "/usr/bin/rsync --daemon --config=/etc/rsyncd.conf" >> /etc/rc.d/rc.local

# 9.查看启动情况
netstat -lntp | grep 873

# 10.客户端新建客户端密码文件(客户端不带用户名)
vi /etc/rsyncd.secrets  # snow01 
chmod 600 /etc/rsyncd.secrets

# 从服务器上拉取数据到本地
rsync -vzrtopg --progress --delete --password-file=/etc/rsyncd.pwd [email protected]::test /weiyigeek/


2.Centos 7.x 安装 inotify-tools

描述: 在安装前查看当前系统内核是否支持inotify功能(现在系统一般都是支持的因为现在发行版的内核>=2.6.13) 但是我们还是可以使用下面的方式进行验证。

1
2
3
4
5
6
7
8
9
10
# 查看系统内核是否支持inotify功能
uname -r

# 查看允许监视的最大文件描述符是否存在
$ ls -l /proc/sys/fs/inotify/
-rw-r--r-- 1 root root 0 Jul 14 15:28 max_queued_events
-rw-r--r-- 1 root root 0 Jul 14 15:28 max_user_instances
-rw-r--r-- 1 root root 0 Jul 14 15:28 max_user_watches
$ cat /proc/sys/fs/inotify/max_queued_events
16384

Tips : 若由此则说明系统内核支持inotify的实现软件一般有inotify-tools 和sersync 一般inotify-tools性能更优而sersync功能更强大。


  • Step 1.下载 inotify 与 编译安装inotify

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 若没有安装gcc则请继续这步。
    yum groupinstall "Development Tools"
    wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
    tar -xzf inotify-tools-3.14.tar.gz
    ./configure --prefix=/usr/local/inotify         
    make && make install

    # 建立软连接可直接命令行补齐:
    ln -s /usr/local/inotify/bin/inotifywait /usr/bin/inotify
  • Step 2.设置同步脚本示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash
    # 此脚本 只会当inotify监控到/tmp/目录下每当有一个文件发生改变时即通知rsync去同步,而不用扫描整个目录
    #注意push同步时备份服务器的目录必须让rsyncuser有写权限否则出错
    cmd="/usr/local/inotify/bin/inotifywait"
    $cmd -mrq --format '%w%f' -e create,close_write,delete /tmp/ |\
    while read line
    do
    [ ! -e "$line" ] && continue
    rsync -az --delete $line [email protected]::rsynctest --password-file=/etc/rsyncd.passwd #会直接同步远程备份服务器上同改同建,就是不能同删除/
    done

    Tips: 此脚本每次只会更新inotify监控的新增的文件,对于监控到删除的文件,则不会在备份服务器删除,因为rysnc源没有扫描整个目录,只是 rsync -az --delete $line, inotifywait 命令用来监视需要备份的文件 若有变化则会通知。

WeiyiGeek.示例脚本

WeiyiGeek.示例脚本

  • Step 3.改进后此脚本完全扫描服务器端监控目录服务器的inotify目录无论增删改都完全与备份服务器同步。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    host=192.168.111.243
    src=/tmp # source,表来源
    dst=rsynctest # destination,表目的
    user=rsyncuser
    rsync_passible=/etc/rsyncd.passwd
    inotify_home=/usr/local/inotify/
     
    if [ ! -e "$src" ]\
       || [ ! -e "$rsync_passible" ]\
       || [ ! -e "$inotify_home/bin/inotifywait" ]\
       || [ ! -e "/usr/bin/rsync" ]
    then
    echo "File is not enough to run inotify!"
       exit 9
    fi
      ${inotify_home}/bin/inotifywait -mrq  --format "%w%f" -e close_write,delete,create $src |\
      while read line
              do
         [ ! -e $line ] && continue
          echo '$line'=$line
           cd $src && rsync -aruz -R --delete ./ --timeout=104 $user@$host::$dst --password-file=${rsync_passible} >/dev/null  2>&1
          done
    exit 0
WeiyiGeek.rsync-test

WeiyiGeek.rsync-test


3.Ubuntu 20.04 安装 inotify-tools

描述: 上面演示了使用源代码编译安装的方式进行,下面将使用apt方式进行安装。

  • Step 1.apt 安装 inotify-tools 查看其版本
    1
    2
    3
    4
    5
    6
    7
    $ apt install inotify-tools

    $ inotifywait --help
    inotifywait 3.14

    $ inotifywatch --help
    inotifywatch 3.14

0x02 命令与配置解析

rsync 命令 - 文件同步解析

描述: rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进行分析说明,

语法&参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# - 语法
rsync [-avrlptgoD] [-e ssh] [[email protected]:/remote/dir] [/local/path]
rsync [OPTION] ... rsync://[[email protected]]HOST[:PORT]/SRC [DEST]

# - 参数
-v, --verbose 详细模式输出,
-q, --quiet 精简输出模式,(基本无用,什么都不输出)
-c, --checksum 打开校验开关,强制对文件传输进行校验,
-a, --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD,
-r, --recursive 对子目录以递归模式处理,
-R, --relative 使用相对路径信息,
-b, --backup 创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为~filename,可以使用--suffix选项来指定不同的备份文件前缀,
--backup-dir 将备份文件(如~filename)存放在在目录下,
-suffix=SUFFIX 定义备份文件前缀,
-u, --update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件,不覆盖更新的文件,
--copy-unsafe-links 仅仅拷贝指向SRC路径目录树以外的链结,
--safe-links 忽略指向SRC路径目录树以外的链结,
-l, --links 保留软链结,
-L, --copy-links 想对待常规文件一样处理软链结,
-H, --hard-links 保留硬链结,
-p, --perms 保持文件权限,
-o, --owner 保持文件属主信息,
-g, --group 保持文件属组信息,
-D, --devices 保持设备文件信息,
-t, --times 保持文件时间信息,
-z, --compress对备份的文件在传输时进行压缩处理,
-S, --sparse 对稀疏文件进行特殊处理以节省DST的空间,
-n, --dry-run现实哪些文件将被传输,
-w, --whole-file拷贝文件,不进行增量检测,
-x, --one-file-system 不要跨越文件系统边界,
-B, --block-size=SIZE 检验算法使用的块尺寸,默认是700字节,
-e, --rsh=command指定使用rsh、ssh方式进行数据同步,
--rsync-path=PATH 指定远程服务器上的rsync命令所在路径信息,
-C, --cvs-exclude 使用和CVS一样的方法自动忽略文件,用来排除那些不希望传输的文件,(和rsyncd.conf配置文件效果相同)
--existing 仅仅更新那些已经存在于DST的文件,而不备份那些新创建的文件,
--delete 删除DST目标中,在SRC源中没有的文件, (受DST在前和在SRC在前的影响)
--delete-excluded 同样删除接收端那些被该选项指定排除的文件,
--delete-after 传输结束以后再删除,
--ignore-errors 及时出现IO错误也进行删除,
--max-delete=NUM 最多删除NUM个文件,
--partial 保留那些因故没有完全传输的文件,以是加快随后的再次传输,
-P 表示代替-partial和-progress两者的选项功能
--force 强制删除目录,即使不为空,
--numeric-ids 不将数字的用户和组id匹配为用户名和组名,
--timeout=time ip超时时间,单位为秒,
-I, --ignore-times 不跳过那些有同样的时间和长度的文件,
--size-only 当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间,
--modify-window=NUM 决定文件是否时间相同时使用的时间戳窗口,默认为0,
-T --temp-dir=DIR 在DIR中创建临时文件,
--compare-dest=DIR 同样比较DIR中的文件来决定是否需要备份,
--progress 显示备份过程,在传输时现实传输过程,进度.
--exclude=PATTERN 指定排除不需要传输的文件模式,
--include=PATTERN 指定不排除而需要传输的文件模式,
--exclude-from=FILE 排除FILE中指定模式的文件,
--include-from=FILE 不排除FILE指定模式匹配的文件,
--version 打印版本信息,
--address 绑定到特定的地址,
--config=FILE 指定其他的配置文件,不使用默认的rsyncd.conf文件,
--port=PORT 指定其他的rsync服务端口,
--blocking-io 对远程shell使用阻塞IO,
--stats 给出某些文件的传输状态,
--log-format=formAT 指定日志文件格式,
--password-file=FILE 从FILE中得到密码,
--bwlimit=KBPS 限制I/O带宽,KBytes per second,KB每秒
-e 使用协议通道,例如 -e ssh [email protected]:/remote/dir

Tips: rsync 同步或者异步同步数据。


用法示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 0) 连接 Rsync 服务器以及显示更多文件信息
rsync ip::
rsync -av 115.29.246.254::

# 1) 默认端口连接(指定端口)和password文件来查看rsync服务中默认的项目目录。
# 从远程rsync服务器中拷贝文件到本地机当SRC路径信息包含"::"分隔符时启动该模式。
rsync --password-file=/etc/rsyncd.passwd [email protected]::
rsync --password-file=/etc/rsyncd.passwd --port=8733 [email protected]::
rsync --password-file=/etc/rsyncd.passwd rsync://[email protected]:873/backup/www

# 2) 本地主机中将 /etc/ 内复制到 /tmp/etc 目录中。
# 从本地主机中当SRC(源地址)和DES(目标地址)destination 路径信息都不包含有单个冒号":"分隔符时就启动这种工作模式。
rsync -av /etc /tmp

# 3) 将通过ssh将远程主机主机中的 /etc 复制到本地 /tmp。
# 使用一个远程shell程序rsh命令、ssh命令来实现将本地机器的内容拷贝到远程机器当DST路径地址包含单个冒号":"分隔符时启动该模式。
rsync -av -e ssh [email protected]:/etc /tmp

# 4) 从本地机器拷贝文件到远程rsync服务器中当DST路径信息包含"::"分隔符时启动该模式。
rsync -av /databack [email protected]::www

# 5) 列远程机的文件列表类似于rsync传输不过只要在命令中省略掉本地机信息即可。
rsync -v rsync://[email protected]:8733/
rsync -v rsync://[email protected]/www

WeiyiGeek.rsync

WeiyiGeek.rsync


1
2
3
4
5
6
7
8
9
10
11
12
# 6) 删除本地终端(Des)在(服务器)Src中没有的文件
rsync -av --delete rsync://[email protected]:8733/backup /tmp/
rsync -avz --delete --progress --password-file=/etc/rsyncd.passwd [email protected]::backup /tmp/
# receiving/Sending incremental file list 接收增量文件列表

# 7) 文件的上传与下载(注意文件夹的宿主)
rsync -vzrtopg --progress ./sxx.php 172.17.16.24::www/back
rsync -va --progress172.17.16.24::hosts_sync/dump.sh /root/ # 同步数据到本地

# 8) 目录的上传和下载 (注意文件夹的宿主)
rsync -r /root/mydir weiyigeek.top:remote/uploadfile # (代表将本地的目录mydir上传到服务上(注意上传文件的路径,是dir目录下的全部上传到远程目录))
rsync -r weiyigeek.top:remote/downloadfile /root/mydir   # 代表将服务器上的目录下载到本地,最后的.代表当前目录
WeiyiGeek.文件的上传与下载

WeiyiGeek.文件的上传与下载


WeiyiGeek.目录的上传和下载

WeiyiGeek.目录的上传和下载


1
2
3
4
5
6
# 9) 可以同步客户端和服务器的对应目录,注意两个/都不能省而且一般使用-a参数替代-r, -a只能同步在客户端新创建的文件,而有时候本地还会删除一些文件需要服务器也做相应删除除了
rsync -r --delete mydir/ weiyigeek.top:mydir/
rsync -r --delete weiyigeek.top:mydir/ mydir/

rsync -r --progress /tmp/www/units/ --password-file=/etc/rsyncd.passwd [email protected]::backup/units/
rsync -r --password-file=/etc/rsyncd.passwd [email protected]::backup/units/ /tmp/www/units/
WeiyiGeek.实时同步

WeiyiGeek.实时同步


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 10) 在客户端使用rsync命令来备份服务端上的数据,比如通过SSH方式是通过系统用户来进行备份的。
rsync -vzrtopg --progress --delete -e ssh [email protected]:/www/* /tmp/www/units/

# 11) 远程同步到本地( 远程同步 ), 但这样也是有风险的 一般在上面命令后再加一个 `--dry-run` 会开启验证
rsync -avzH [email protected]:wwwroot /var/www/html
rsync -avzH --delete [email protected]:wwwroot /var/www/html
rsync --dry-run -av --delete mydir/ weiyigeek.top:mydir/

# 12) 可以将本地完全同步到远程服务器中, 当服务器的数据出现问题,那么这时需要客户端的数据对服务端进行恢复,但前提是服务端允许客户端有写入权限,否则也不能在客户端直接对服务端进行恢复,使用rsync对数据进行恢复的方式如下:
rsync -avz --progress /tmp/www/units/ [email protected]:www

# 13) 完全同步同增同改
rsync -auz -R --delete ./ [email protected]::backup/www/units/
rsync -avz --progress /tmp/www/units/ [email protected]::backup/www/units/

# 14) 将SRC远程中在DES本地中没有的文件将被删除
rsync -avz --progress --delete /tmp/www/units/ [email protected]::backup/www/units/

# 15) 利用find的一种巧妙方式可以用这种方法列出需要备份的文件列表,这种方法似乎比较少人用到。
rsync -avR remote:'`find /home -name "*.[ch]"`' /tmp/
WeiyiGeek.rsync命令

WeiyiGeek.rsync命令


inotifywait 命令 - 等待监听事件的发生

描述: inotifywait尤其适用于在脚本中等待某事件的发生, 并可基于特定的事件执行相应操作, 如将其用于脚本中监控某指定目录中的文件上的修改、新建、删除、属性信息的改变,而后使用rsync命令将某事件对应的文件同步至其它主机上。

语法参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 语法
Usage: inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]

# Options - 参数说明
@<file> 从监视中排除指定的文件。
--exclude <pattern> 排除与扩展正则表达式<pattern>匹配的文件上的所有事件。
--excludei <pattern> 不区分大小写
-m, --monitor inotifywait的默认动作是在监控至指定文件的特定事件发生一次后就退出了,而使用此选项则可实现持续性的监控
-d,--daemon 与--monitor相同,只是在后台运行,将事件记录到--outfile.Implies--syslog指定的文件中。
-r, --recursive 递归监控指定目录下的所有文件,包括新建的文件或子目录;如果要监控的目录中文件数量巨大,则通常需要修改`/proc/sys/fs/inotify/max_users_watchs`内核参数因为其默认值为8192;
--fromfile <file> 从<file>或-for stdin读取要监视的文件。
-o|--outfile <file> 将事件打印到<file>而不是标准输出。
-s|--syslog 将错误发送到syslog而不是stderr。
-q, --quit 即静默模式
-qq Print nothing (not even events).
-c|--csv Print events in CSV format.
-e, --event :指定要监控的特定事件,默认是监控所有的事件;此处包括 access(访问), modify(修改), attrib(属性), close_write, close_nowirte, close(关闭), open(打开), moved_to, moved_from, move(移动), create(创建), delete(删除), delete_selt等(前面已有详细说明)
* access file or directory contents were read
* modify file or directory contents were written
* attrib file or directory attributes changed
* close_write file or directory closed, after being opened in writable mode
* close_nowrite file or directory closed, after being opened in read-only mode
* close file or directory closed, regardless of read/write mode
* open file or directory opened
* moved_to file or directory moved to watched directory
* moved_from file or directory moved from watched directory
* move file or directory moved to or from watched directory
* create file or directory created within watched directory
* delete file or directory deleted within watched directory
* delete_self file or directory was deleted
--timefmt :当在--format选项中使用%T时,--timefrt选项则可以用来指定自定义的符合strftime规范的时间格式,此时间格式可用的格式符可以通过strftime的手册页获取;常用的参数是 '%d/%m/%y %H:%M'(25/06/17/13:11);
--format :自定义inotifywait的输出格式,如--format '%T %w %f';常用的格式符如下:
* %T:使用--timefmt选项中自定义的时间格式;
* %w:显示被监控文件的文件名;
* %f:如果发生某事件的对象是目录,则显示被监控目录的名字;默认显示为空串;
-t|--timeout <seconds> 收听单个事件时,请在等待事件<seconds>秒。如果<seconds>为0,inotifywait将永远不会超时。


# 退出状态
0 - 您要求观看的事件已收到。
1 - 收到了一个您没有要求监视的事件(通常是删除或卸载),或者发生了一些错误。
2 - 提供了--timeout选项,并且在指定的时间间隔内未发生任何事件。


基础示例:

  • 1.以特定的格式输出其modify,delete,create,attrib属性改变的文件。

    1
    2
    #!/bin/bash 
    /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y/%H:%M' --format '%T %w %f' -e modify,delete,create,attrib $1
  • 2.监控/tmp/test目录及其内部所有文件上发生的create,delete,modify,close_write事件,则使用如下命令:

    1
    2
    3
    4
    5
    6
    7
    8
    # 此命令在监控到某文件上第一次事件后就会退出
    inotifywait -r --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e create,delete,modify,close_write /tmp/test

    # 此命令会一直监控不会第一次事件后退出
    inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e create,delete,modify,close_write /tmp/test

    # 由于修改,创建,与属性的更改则显示了三次目录
    inotifywait -mrq --format '%w%f' -e modify,attrib,create,close_write,delete /tmp/
WeiyiGeek.inotifywait

WeiyiGeek.inotifywait


0x05 安全配置

描述: 安全配置其防御,一是限定访问的IP,另一个是不允许匿名访问添加用户口令。

(1) 限定IP地址访问两种方式:

  • 1.IPTables防火墙,给rsync的端口添加一个iptables, 例如只希望能够从内部网络(192.168.101.0/24)访问:
    1
    2
    iptables -A INPUT -i eth0 -p tcp -s 192.168.101.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT
  • 2.除此之外也可以在/etc/rsyncd.conf中的hosts allow也可以设置只允许来源ip。
    1
    hosts allow = X.X.X.X # 允许访问的IP

(2) 添加用户认证
描述: 添加rsync用户权限访问注意配置是在rsyncd.conf中的:

1
2
secrets file = /etc/rsyncd.secrets #密码文件位置,认证文件设置,设置用户名和密码
auth users = rsync #授权帐号,认证的用户名,如果没有这行则表明是匿名,多个用户用,分隔。


示例1.CentOS 6.X 之 Rsync 远程安全访问同步设置

  • 服务端
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    # 测试文件:
    echo "www.weiyigeek.top" > /var/www/html/index.html

    # Rsyncd配置文件:
    vim /etc/rsyncd.conf
    uid = nobody
    gid = nobody
    use chroot = yes
    address = 192.168.100.1
    port 873
    log file = /var/log/rsyncd.log
    pid file = /var/run/rsyncd.pid
    hosts allow = 192.168.100.0/24

    [wwwroot]
    path = /var/www/html
    comment = Document Root of www.gateway.com
    read only = yes
    dont compress = *.gz *.bz2 *.tgz *.zip *.rar *.z
    auth users = baker
    secrets file = /etc/rsyncd_users.db

    # 设置rsync登录账户和密码:
    vim /etc/rsyncd_users.db # baker:123
    chmod 600 rsyncd_users.db

    # 刷新服务:
    service xinetd restart
  • 客户端
    1
    2
    3
    4
    5
    6
    # baker 用户的 rsync 密码
    vim /etc/rsyncpasswd # 123
    chmod 600 /etc/rsyncpasswd

    # 从远程wwwroot同步数据到本地 /var/www/html
    rsync -avzH --password-file=/etc/rsyncpasswd [email protected]::wwwroot /var/www/html

0x06 FAQ 你问我答

Q:如何通过ssh进行rsync,而且无须输入密码?
A:可以通过以下几个步骤

  1. 通过ssh-keygen在server A上建立SSH keys,不要指定密码,你会在~/.ssh下看到identity和identity.pub文件
  2. 在server B上的home目录建立子目录.ssh
  3. 将A的identity.pub拷贝到server B上
  4. 将identity.pub加到~[user b]/.ssh/authorized_keys
  5. 于是server A上的A用户,可通过下面命令以用户B ssh到server B上了
    e.g. ssh -l userB serverB
    这样就使 server A上的用户A就可以ssh以用户B的身份无需密码登陆到server B上了


Q:如何通过在不危害安全的情况下,通过防火墙使用rsync?

A:解答如下:通常有两种情况一种是服务器在防火墙内,一种是服务器在防火墙外。无论哪种情况,通常还是使用ssh,这时最好新建一个备份用户,并且配置sshd仅允许这个用户通过RSA认证方式进入。
如果服务器在防火墙内,则最好限定客户端的IP地址,拒绝其它所有连接。如果客户机在防火墙内,则可以简单允许防火墙打开TCP端口22的ssh外发连接就ok了。


Q:我能将更改过或者删除的文件也备份上来吗
A:当然可以:你可以使用如:rsync -other -options -backupdir = ./backup-2000-2-13 这样的命令来实现。

这样如果源文件:/path/to/some/file.c改变了,那么旧的文件就会被移到./backup-2000-2-13/path/to/some/file.c,

这里这个目录需要自己手工建立起来


Q:我需要在防火墙上开放哪些端口以适应rsync
A:视情况而定rsync可以直接通过873端口的tcp连接传文件,也可以通过22端口的ssh来进行文件传递,但你也可以通过下列命令改变它的端口:

1
2
3
rsync –port 8730 otherhost::
或者
rsync -e 'ssh -p 2002' otherhost:


Q:我如何通过rsync只复制目录结构,忽略掉文件呢?
A:rsync -av –include ‘/’ –exclude ‘’ source-dir dest-dir


Q:为什么我总会出现”Read-only file system”的错误呢?
A:看看是否忘了设”read only = no”了


Q:为什么我会出现’@ERROR: invalid gid’的错误呢?
A:rsync使用时默认是用uid=nobody;gid=nobody来运行的,如果你的系统不存在nobody组的话,就会出现这样的错误,可以试试gid =nogroup或者其它


Q:绑定端口873失败是怎么回事?
A:如果你不是以root权限运行这一守护进程的话,因为1024端口以下是特权端口,会出现这样的错误。你可以用–port参数来改变。


Q:为什么我认证失败?
A:从你的命令行看来:
你用的是:

bash$ rsync -a 144.16.251.213::test test
Password:
@ERROR: auth failed on module test
I dont understand this. Can somebody explain as to how to acomplish this.
All suggestions are welcome.
应该是没有以你的用户名登陆导致的问题,试试rsync -a [email protected]::test test


Q:当rsync遇到ssh不是标准端口时
If ssh port is not 22, how does rsync specify this in command line?
A:rsync要借助ssh来运行,那么当ssh的端口不是默认的22怎么办?
把选项中的-e ssh 换成 -e ssh -p 12345
这里12345是ssh的端口号



0x0n 入坑出坑

描述: 我们可以通过各种工具对rsync运行时错误日志查看与解决,主要在/var/log/rsyncd.log里面或.err文件里面。

问题1.报@ERROR: chroot failed错误

  • 错误信息:
    1
    2
    3
    $ rsync -auzv --progress --password-file=/etc/rsync.pas [email protected]::backup /home/ 
    @ERROR: chroot failed 
    rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.3]
  • 错误原因: 服务器端的目录不存在或无权限
  • 解决办法: 创建目录并修正权限可解决问题。
  • 注意情况: windows下面我们需要给SvcwRsync用户,管理同步目录的所有权限基本上这样就可以了。


问题2.报@ERROR: auth failed on module tee错误

  • 错误信息:
    1
    2
    @ERROR: auth failed on module tee 
    rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.3]
  • 错误原因: 服务器端该模块(tee)需要验证用户名密码,但客户端没有提供正确的用户名密码,认证失败。
  • 解决办法: 提供正确的用户名密码解决此问题。


问题3.报@ERROR: Unknown module 'tee_nonexists'错误。

  • 错误信息:
    1
    2
    @ERROR: Unknown module 'tee_nonexists' 
    rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver=3.0.3]
  • 错误原因:服务器不存在指定模块
  • 解决办法: 提供正确的模块名或在服务器端修改成你要的模块以解决问题。


问题4.在client上遇到问题报could not open password file "/etc/rsync.pas": No such file or directory (2)错误

  • 错误信息:
    1
    2
    3
    4
    5
    $ rsync -auzv --progress --password-file=/etc/rsync.pas [email protected]::backup /home/ 
    rsync: could not open password file "/etc/rsync.pas": No such file or directory (2) 
    Password: 
    @ERROR: auth failed on module backup 
    rsync error: error starting client-server protocol (code 5) at main.c(1506) [Receiver=3.0.7]
  • 错误原因: client 端 没有设置 /etc/rsync.pass 这个文件, 其次是该文件中用户:密码错误不对应。
  • 解决方式: 因为在使用 rsync 命令的时候加了 --password-file=/etc/rsync.pass 参数。


问题5.在client上遇到问题报rsync: write failed on "/home/backup2010/": No space left on device (28)错误

  • 错误信息:
    1
    2
    3
    4
    5
    6
    rsync: write failed on "/home/backup2010/": No space left on device (28) 
    rsync: recv_generator: mkdir "/home/backup2010/" failed: No space left on device (28)
    *** Skipping any contents from this failed directory ***
    rsync error: error in file IO (code 11) at receiver.c(302) [receiver=3.0.7] 
    rsync: connection unexpectedly closed (2721 bytes received so far) [generator] 
    rsync error: error in rsync protocol data stream (code 12) at io.c(601) [generator=3.0.7]
  • 错误原因: 磁盘空间不够所以无法操作,可以通过df /home/backup2010来查看可用空间和已用空间。
  • 解决办法: 清理文件腾出空间或者添加磁盘空间。


问题6.报skipping non-regular file错误。

  • 错误信息:
    1
    2
    3
    4
    eceiving incremental file list
    skipping non-regular file “vendor/bin/doctrine”
    skipping non-regular file “vendor/bin/doctrine.php”\
    sent 1990 bytes received 489209 bytes 327466.00 bytes/sec total size is 182515746 speedup is 371.57
  • 错误原因: source源文件有软链接。
  • 解决方法: 修改为 rsync -va 其中 -a == -rlptgoD (no -H,-A,-X) 或者 rsync -rvltOD 也可以。


问题7.报@ERROR: module is read only错误。

  • 错误信息:
    1
    2
    3
    4
    5
    sending incremental file list
    ERROR: module is read only
    rsync error: syntax or usage error (code 1) at main.c(866) [receiver=3.0.6]
    rsync: read error: Connection reset by peer (104)
    rsync error: error in rsync protocol data stream (code 12) at io.c(759) [sender=3.0.6]
  • 错误原因: Source源服务器端权限设置read为only只读权限。
  • 解决方法: read only = false


问题8.报password file must not be other-accessible错误。

  • 错误信息:
    1
    2
    password file must not be other-accessible
    continuing without password file
  • 错误原因: 因为 rsyncd.pwd rsyncd.secrets 的权限不对。
  • 解决办法: 设置上述文件权限为600。
    1
    chmod 600 rsyncd.pwd


问题9.报rsync: failed to connect No route to host错误。

  • 错误信息: rsync: failed to connect to 192.168.1.10: No route to host (113) rsync error: error in socket IO (code 10) at clientserver.c(104) [receiver=3.0.6]
    1
    2
    3
    4
    5
    rsync: failed to connect to 10.10.10.170: Connection refused (111) 
    rsync: failed to connect to 96.44.169.178 (*inet_ntop failed*): Connection timed
    out (116)
    1 [main] rsync 3468 exception::handle: Exception: STATUS_ACCESS_VIOLATION
    740 [main] rsync 3468 open_stackdumpfile: Dumping stack trace to rsync.exe.s
  • 错误原因:对方没开机、防火墙阻挡、通过的网络上有防火墙阻挡都有可能。
  • 解决方法: 在 iptables 中开放该端口,rsync 默认端口 873,其实就是把tcp udp的873端口打开。
    1
    2
    3
    4
    5
    6
    7
    # iptables
    vi /etc/sysconfig/iptables
    iptables -A INPUT -m state –state NEW -m tcp -p tcp –dport 873-j ACCEPT

    # firewall-cmd
    firewall-cmd --zone=public --add-port=873/tcp --permanent
    firewall-cmd --reload


问题10.报rsync error: error starting client-server protocol错误。

  • 错误信息: rsync error: error starting client-server protocol (code 5) at main.c(1524) [Receiver=3.0.6]
  • 错误原因: /etc/rsyncd.conf 配置文件内容有错误
  • 解决办法: 请正确核对配置文件。


问题11.报rsync: chown "" failed: Invalid argument (22)错误。

  • 错误信息: sync: chown "" failed: Invalid argument (22)
    1
    rsync: opendir "/kexue" (in dtsChannel) failed: Permission denied (13)  # 注意查看同步的目录权限是否为755
  • 错误原因: 权限无法复制去掉同步权限的参数即可。(这种情况多见于Linux向Windows的时候)


问题12.报@ERROR: daemon security issue — contact admin错误。

  • 错误信息: @ERROR: daemon security issue — contact admin rsync error: error starting client-server protocol (code 5) at main.c(1530) [sender=3.0.6]
  • 错误原因: 同步的目录里面有权限不足的软连接文件
  • 解决办法: 在服务器端的 /etc/rsyncd.conf 中修改入键值 use chroot = yes


问题13.报rsync: read error: Connection reset by peer (104)

  • 错误信息: rsync: read error: Connection reset by peer (104) rsync error: error in rsync protocol data stream (code 12) at io.c(794) [receiver=3.0.6]
    1
    2
    3
    4
    5
    receiving incremental file list
    rsync: read error: Connection reset by peer (104)
    rsync error: error in rsync protocol data stream (code 12) at io.c(769) [receiver=3.0.8]
    rsync: connection unexpectedly closed (60 bytes received so far) [generator]
    rsync error: error in rsync protocol data stream (code 12) at io.c(610) [generator=3.0.8]
  • 问题原因:
    • 磁盘挂载是用异步的(async)然后检查了/etc/fstab ,去掉async参数
    • 我在服务器上查看日志看到有这么一行:rsync: unable to open configuration file “/etc/rsyncd.conf”: No such file or directory于是我:ln -s /etc/rsyncd/rsyncd.conf /etc/rsyncd.conf
  • 解决办法: 很大可能是服务器端没有开启 rsync 服务,开启服务 rsync --daemon --config=/etc/rsyncd.conf 对于centos 6.x及以下。


问题14.报@ERROR: failed to open lock file错误。

  • 错误信息: @ERROR: failed to open lock file rsync error: error starting client-server protocol (code 5) at main.c(1495) [receiver=3.0.6]
  • 解决版本:在配置文件 rsync.conf 中添加 lock file = rsyncd.lock 即可解决。


问题15.报rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(544)错误。

  • 错误信息:
    1
    2
    rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(544) [receiver=3.0.5] 
    rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(544) [generator=3.0.5]
  • 问题原因: 由于 Ctrl+C 或者 大量文件导致。


问题16.报@ERROR: invalid uid nobody错误。

  • 错误信息: rsync error: error starting client-server protocol (code 5) at main.c(1516) [Receiver=3.0.8]
  • 问题原因: UID 不对 默认 是 nobody
  • 解决方法:
    1
    2
    uid = 0
    gid = 0


问题17.在同步文件数较多的目录同步时出错rsync: writefd_unbuffered failed to write 4 bytes to socket [sender]: Connection reset by peer (104)错误。

  • 错误信息:在批处理中加上-v参数,看到错误信息如下:
    1
    2
    3
    rsync: writefd_unbuffered failed to write 4 bytes to socket [sender]: Connection reset by peer (104)
    rsync: read error: Connection reset by peer (104)
    rsync error: error in rsync protocol data stream (code 12) at io.c(768) [sender=3.0.6]
  • 问题原因: 原以为是文件太多,缓冲区不够引起,但看这个解决方案,似乎是转换编码方面的bug了。
  • 解决办法: 在samba.org上找到解决方案, 可以在客户端命令行中加上–no-iconv参数就可以了。在rsync的文档中描述如下:http://rsync.samba.org/ftp/rsync/rsync.html
    1
    2
    --iconv=CONVERT_SPEC
    Rsync can convert filenames between character sets using this option. Using a CONVERT_SPEC of "." tells rsync to look up the default character-set via the locale setting. Alternately, you can fully specify what conversion to do by giving a local and a remote charset separated by a comma in the order --iconv=LOCAL,REMOTE, e.g. --iconv=utf8,iso88591. This order ensures that the option will stay the same whether you're pushing or pulling files. Finally, you can specify either --no-iconv or a CONVERT_SPEC of "-" to turn off any conversion. The default setting of this option is site-specific, and can also be affected via the RSYNC_ICONV environment variable.


问题18.在window上rsync同步数据报错:rsync error: some files/attrs were not transferred (see previous errors) (code 2 3) at main.c(1052) [sender=3.0.8]

  • 问题原因:
    • 因为rsync服务端执行的用户对同步的文件没有写入权限。
    • 默认rsync是以SvcCWRSYNC此用户运行的,而一般同步的文件此用户是没有写入权限的。
    • SvcCWRSYNC默认归属于User组,将rsync的服务器端SvcCWRSYNC此用户隶属于加到administrator组就可以解决上面的报错。


问题19.如果在使用inotifywait中出现error while loading shared libraries: libinotifytools.so.0: cannot open shared object file: No such file or directory

解决方法:

1
2
32位系统:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib/libinotifytools.so.0 
64位系统:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib64/libinotifytools.so.0