本页内容
- 1 安装 rsync
- 2 在 server1.example.com 上创建非特权用户
- 3 测试 rsync
- 4 在 mirror.example.com 上创建密钥
- 5 配置 server1.example.com
- 6 在 mirror.example.com 上测试 rsync
- 7 创建 Cron 任务
- 8 相关链接
本教程将向你展示如何把你的网站从主 Web 服务器镜像到一台备份服务器,当主服务器发生故障时,备份服务器可以接管。我们使用 rsync 这个工具来完成,并通过一个 cron 任务来运行它——该任务每隔 x 分钟检查镜像上是否有需要更新的内容。因此,当备份服务器需要接管时,它通常都是最新的。
rsync 只更新发生变化的文件,因此你不必在每次运行 rsync 时都传输 5 GB 的数据。它只镜像新增/变化的文件,并且还能删除镜像上那些已在主服务器上被删除的文件。此外,它还能保留被镜像的文件和目录的权限与所有者信息;为了保留所有者信息,我们需要以 root 身份运行 rsync,这正是我们在本教程中所做的。如果主服务器上的权限和/或所有者发生变化,rsync 也会在备份服务器上相应地进行更改。
在本教程中,我们将通过 SSH 来隧道传输 rsync,这样更安全;这也意味着你无需为 rsync 在防火墙中开放另一个端口——只要 22 端口(SSH)是开放的即可。问题在于,SSH 登录需要密码,而如果你想把 rsync 作为 cron 任务来运行,这就不太合适了。需要密码就意味着需要人工交互,而这并不是我们想要的效果。
但幸运的是,有一个解决方案:使用公钥。我们在备份服务器 mirror.example.com 上创建一对密钥,其中一把保存在远程系统 server1.example.com 的一个文件中。之后,我们在运行 rsync 时就不会再被要求输入密码了。这也包括 cron 任务,而这正是我们想要的。
正如你从前面的内容中可能已经猜到的那样,我们的思路是:直接从 mirror.example.com 发起对 server1.example.com 的镜像;server1.example.com 不需要做任何事情就能被镜像。
这里我将使用如下配置:
- 主服务器:server1.example.com(server1)——IP 地址:192.168.0.100
- 镜像/备份服务器:mirror.example.com(mirror)——IP 地址:192.168.0.175
- 待镜像的网站位于 server1.example.com 的 /var/www 目录下。
rsync 仅用于镜像文件和目录;如果你想要镜像你的 MySQL 数据库,请改用 MySQL 镜像/复制(replication)。
我想先说明,这不是搭建此类系统的唯一方式。实现这一目标有很多方法,但这将是我所采用的方式。
第一步是登录你的系统或成为 root 用户。在 Debian 和 CentOS 上,使用:
su -
如果你登录的不是 root 用户。在 Ubuntu 上,使用:
sudo -s
代替。
1 安装 rsync
首先,我们必须在 server1.example.com 和 mirror.example.com 上都安装 rsync。对于 Debian 和 Ubuntu 系统,操作如下:
server1/mirror:
(我们以 root 身份执行此操作!)
apt install rsync
在其他 Linux 发行版上,你会使用 yum / dnf(Fedora/CentOS)或 yast(SuSE)来安装 rsync。
在 CentOS / Rocky Linux 或 AlmaLinux 上,使用:
dnf install rsync
2 在 server1.example.com 上创建非特权用户
现在我们在 server1.example.com 上创建一个名为 someuser 的非特权用户,mirror.example.com 上的 rsync 将使用该用户来镜像 /var/www 目录(当然,someuser 必须对 server1.example.com 上的 /var/www 拥有读取权限)。
server1:
(我们以 root 身份执行此操作!)
sudo useradd -d /home/someuser -m -s /bin/bash someuser
这将创建用户 someuser,其主目录为 /home/someuser,登录 shell 为 /bin/bash(someuser 必须拥有一个有效的登录 shell,这一点很重要——类似 /bin/false 的 shell 是无法工作的!)。现在为 someuser 设置一个密码:
passwd someuser
3 测试 rsync
接下来,我们在 mirror.example.com 上测试 rsync。我们以 root 身份执行如下操作:
mirror:
rsync -avz -e ssh
[email protected]
:/var/www/ /var/www/
你应该会看到类似如下的内容。输入 yes 进行确认:
The authenticity of host 'server1.example.com (192.168.0.100)' can't be established. RSA key fingerprint is 32:e5:79:8e:5f:5a:25:a9:f1:0d:ef:be:5b:a6:a6:23. Are you sure you want to continue connecting (yes/no)?
<-- yes
然后输入 someuser 的密码,你应该会看到 server1.example.com 上的 /var/www 目录已被镜像到 mirror.example.com 的 /var/www。
你可以在两台服务器上这样验证:
server1/mirror:
ls -la /var/www
你应该会看到所有文件和目录都已镜像到 mirror.example.com,并且这些文件和目录的权限/所有者应与 server1.example.com 上保持一致。
4 在 mirror.example.com 上创建密钥
现在我们在 mirror.example.com 上创建私钥/公钥对:
mirror:
(我们以 root 身份执行此操作!)
mkdir /root/rsync
ssh-keygen -t dsa -b 1024 -f /root/rsync/mirror-rsync-key
你会看到类似如下的内容:
Generating public/private dsa key pair. Enter passphrase (empty for no passphrase): [press enter here] Enter same passphrase again: [press enter here] Your identification has been saved in /root/cron/mirror-rsync-key. Your public key has been saved in /root/cron/mirror-rsync-key.pub. The key fingerprint is: 68:95:35:44:91:f1:45:a4:af:3f:69:2a:ea:c5:4e:d7 root@mirror
重要的是不要输入任何密码短语(passphrase),否则镜像在没有人工交互的情况下将无法工作,所以直接按回车即可!
接下来,我们将公钥复制到 server1.example.com:
mirror:
(同样,我们以 root 身份执行此操作。)
scp /root/rsync/mirror-rsync-key.pub
[email protected]
:/home/someuser/
现在,公钥 mirror-rsync-key.pub 应该已经存在于 server1.example.com 的 /home/someuser 中。
5 配置 server1.example.com
现在通过 SSH 以 someuser(不是 root!)身份登录 server1.example.com,并执行如下操作:
server1:
(请以 someuser 身份执行此操作!)
mkdir ~/.ssh
chmod 700 ~/.ssh
mv ~/mirror-rsync-key.pub ~/.ssh/
cd ~/.ssh
touch authorized_keys
chmod 600 authorized_keys
cat mirror-rsync-key.pub >> authorized_keys
通过这一步,我们已经将 mirror-rsync-key.pub 的内容追加到了 /home/someuser/.ssh/authorized_keys 文件中。/home/someuser/.ssh/authorized_keys 的内容应该类似于这样:
server1:
(仍然是 someuser 身份!)
vi /home/someuser/.ssh/authorized_keys
ssh-dss AAAAB3NzaC1kc3MAAA[...]lSUom root@
mirror
现在我们希望只允许来自 mirror.example.com 的连接,并且连接的用户只能使用 rsync,因此我们添加
command="/home/someuser/rsync/checkrsync",from="mirror.example.com",no-port-forwarding,no-X11-forwarding,no-pty
到 /home/someuser/.ssh/authorized_keys 文件的最开头:
server1:
(仍然是 someuser 身份!)
vi /home/someuser/.ssh/authorized_keys
command="/home/someuser/rsync/checkrsync",from="mirror.example.com",no-port-forwarding,no-X11-forwarding,no-pty ssh-dss AAAAB3NzaC1kc3MAAA[...]lSUom root@ mirror
在 from= 之后,你必须使用像 mirror.example.com 这样的 FQDN(完全限定域名)而不是 IP 地址,否则自动镜像将无法工作!
现在我们创建脚本 /home/someuser/rsync/checkrsync,该脚本会拒绝除 rsync 之外的所有命令。
server1:
(我们仍以 someuser 身份执行此操作!)
mkdir ~/rsync
vi ~/rsync/checkrsync
#!/bin/sh
case "$SSH_ORIGINAL_COMMAND" in
*\&*)
echo "Rejected"
;;
*\(*)
echo "Rejected"
;;
*\{*)
echo "Rejected"
;;
*\;*)
echo "Rejected"
;;
*\<*)
echo "Rejected"
;;
*\`*)
echo "Rejected"
;;
rsync\ --server*)
$SSH_ORIGINAL_COMMAND
;;
*)
echo "Rejected"
;;
esac
chmod 700 ~/rsync/checkrsync
6 在 mirror.example.com 上测试 rsync
现在我们必须要在 mirror.example.com 上测试,看是否能够在不被提示输入 someuser 密码的情况下镜像 server1.example.com。我们执行如下操作:
mirror:
(我们以 root 身份执行此操作!)
rsync -avz --delete --exclude=**/stats --exclude=**/error --exclude=**/files/pictures -e "ssh -i /root/rsync/mirror-rsync-key"
[email protected]
:/var/www/ /var/www/
(--delete 选项表示,在 server1.example.com 上已被删除的文件,也应在 mirror.example.com 上被删除。--exclude 选项表示这些文件/目录不应被镜像;例如 --exclude=**/error 表示"不要镜像 /var/www/error"。你可以使用多个 --exclude 选项。我列出这些选项作为示例;你可以根据实际需求调整该命令。请参阅
man rsync
以获取更多信息。)
你现在应该会看到镜像正在进行:
receiving file list ... done sent 71 bytes received 643 bytes 476.00 bytes/sec total size is 64657 speedup is 90.56
而不会被提示输入密码!这正是我们想要的效果。
7 创建 Cron 任务
我们希望将镜像自动化,因此我们在 mirror.example.com 上为其创建一个 cron 任务。以 root 身份运行 crontab -e:
mirror:
(我们以 root 身份执行此操作!)
crontab -e
并创建如下这样的 cron 任务:
*/5 * * * * /usr/bin/rsync -azq --delete --exclude=**/stats --exclude=**/error --exclude=**/files/pictures -e "ssh -i /root/rsync/mirror-rsync-key" [email protected] :/var/www/ /var/www/
这会让 rsync 每 5 分钟运行一次;请根据你的需求进行调整(参见
man 5 crontab
)。我在这里使用了 rsync 的完整路径(/usr/bin/rsync),只是为了确保 cron 知道去哪里找 rsync。你的 rsync 位置可能有所不同。运行
mirror:
(我们以 root 身份执行此操作!)
which rsync
来查明你系统中 rsync 的位置。
8 相关链接
- rsync:https://rsync.samba.org/