惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
The Register - Security
The Register - Security
Recorded Future
Recorded Future
D
Docker
I
InfoQ
Recent Announcements
Recent Announcements
MongoDB | Blog
MongoDB | Blog
Microsoft Azure Blog
Microsoft Azure Blog
A
About on SuperTechFans
N
Netflix TechBlog - Medium
H
Hackread – Cybersecurity News, Data Breaches, AI and More
云风的 BLOG
云风的 BLOG
Spread Privacy
Spread Privacy
AWS News Blog
AWS News Blog
F
Full Disclosure
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threatpost
C
Cisco Blogs
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
Security Latest
Security Latest
The Hacker News
The Hacker News
Microsoft Security Blog
Microsoft Security Blog
B
Blog
IT之家
IT之家
Latest news
Latest news
D
DataBreaches.Net
T
Tor Project blog
Scott Helme
Scott Helme
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Threat Research - Cisco Blogs
博客园 - 司徒正美
S
SegmentFault 最新的问题
宝玉的分享
宝玉的分享
Project Zero
Project Zero
T
The Exploit Database - CXSecurity.com
P
Privacy International News Feed
Last Week in AI
Last Week in AI
C
CERT Recently Published Vulnerability Notes
WordPress大学
WordPress大学
博客园 - 【当耐特】
C
Cybersecurity and Infrastructure Security Agency CISA
G
GRAHAM CLULEY
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

atpX

自建 S3 兼容对象存储服务 Garage 听风的歌 偶尔是深夜就好了 新玩具 AirPods Pro 3 公交车上的时间 从 WHOIS 到 RDAP 通过 WireGuard 访问 NFS 共享文件 自建音乐串流服务探索 我停止了探索 Fediverse 互联网背景噪音 我的数字生活降级 小城与确定性的墙 一只特立独行的猪 Fediverse 与社交 承认的勇气 mediaX - 轻量书影音记录管理工具 我的博客写作流程 网站新增 Misc 页面 擅长对线的鲍勃 再见 JavaScript 当我玩博客时我在玩什么 为什么我的博客没有友链页面 小熊猫与大熊猫 (HDR 照片测试) 是时候为网站开启 HTTP/3 支持了吗 使用 AdGuard Home 搭建自用 DoH 服务 谈谈读书与消遣 2023 年终总结 西安两日游 从 AirPods「升级」到 EarPods Docker 搭建去中心化的微博客平台 Mastodon 聊聊 iPhone 15 Pro 使用感受 能否将 TOTP 二次验证存放在密码管理器里 认识史蒂夫·乔布斯 与“锤哥”克里斯·海姆斯沃斯一起养生 逃离爆炸的信息 你想活出怎样的人生 重温《龙珠》动画 为什么关闭评论 从域名注册商到 DNS 服务,找到自己的组合 如何提高用户网页阅读体验 从 Typecho 迁移到 Hugo 个人博客的最终归宿是静态网站吗 我选择了放弃 jQuery 关于我的小破站折腾速度优化这件事 记一次家庭网络折腾 贴一些 SmokePing 记录 我的域名邮箱选择 不存在的语录 Typecho 评论验证插件 CaptchaPlus 谈谈写字这件事 新的网站 Logo 探索 曲线解决 Typecho 图片占位抖动问题 自建 vaultwarden / bitwarden_rs 密码管理器 使用 Plausible 自建网站流量统计分析工具 如何优雅地徒手剥开火腿肠 简单的集中隔离生活记录 新玩具 M2 MacBook Air 使用 acme.sh 申请 Google 公共证书 Docker 搭建去中心化的微博客平台 Misskey 搭建 Lsky Pro 兰空图床 折腾树莓派系统的一天 我的吉卜力之旅 使用 Uptime Kuma 自建服务器/网站在线率监控 Spartan Host Review - Best Hosting & Service Support Debian 下 Nginx 配合 Fail2Ban 减少恶意扫描和攻击 升级 Typecho 到最新开发版本 v1.2.0 Linux rm 命令详解 Debian 系统安装 Docker 教程 BandwagonHost - Reliable Blog and Business VPS Hosting 使用 Isso 为 Hugo/Hexo 等静态网站添加评论功能 推荐 5 款免费开源的网站流量分析统计工具 搭建 Shynet 网站流量统计分析工具 聊聊 DDoS 攻击那些事 Hugo 使用 Fancybox 实现图片灯箱/放大功能 从 Debian 10 升级到 Debian 11 教程 使用 Umami 自建网站流量统计分析工具 Linux 一次执行多个命令的 3 种方式 Typecho 修改永久链接后旧链接 301 跳转到新链接 从不同需求推荐几家稳定可靠的 VPS 服务商 Build EchoIP service with Docker 浅谈一下这些年折腾过的 VPS 单线复用解决一根网线同时 IPTV 和宽带问题 不完全吃灰的树莓派 开发一个自己的 Telegram Bot 使用 Nginx 实现 TCP 四层反向代理 画画真难 我读村上春树 使用 acme.sh 自动签发和更新证书 卡拉马佐夫式悲剧 安装 File Browser 轻量网盘工具 新玩具树莓派到手 Linux 定时自动备份数据到 OneDrive/Google Drive 记一次服务器崩溃 使用 rsync 同步文件 短信的消失 幻灭的艺术家 新玩具戴尔 S2721DGF 开箱 蝴蝶 用 Docker 整合 SeafilePro 搭建私人云盘 搭建自己的 kms 服务器
在 Chroot 环境下使用 Rsync 同步
ATP · 2024-05-06 · via atpX

我平时在备份或者同步服务器文件时一般会用到 rsync 工具,rsync 本身使用起来很方便,也比较可靠,但备份任务主要是通过密钥文件进行连接,不管是从 A 同步到 B 还是将 B 拉取 A,如果任一个服务器出现漏洞导致密钥泄漏,可能会导致另一个服务器买一送一。虽然一般会限制同步用户的权限,不一定会造成严重后果,但还是应该尽可能将 rsync 任务限制在更安全的环境下执行。

限制同步文件的 SSH 用户只能访问指定的文件目录似乎是个不错的解决方案。一开始想到的方法是直接使用 Docker,只映射需要同步的目录,这样可以简单粗暴的进行隔离。果然万能的 linuxserver.io 有现成的项目 docker-openssh-server 可以使用。在尝试中虽然遇到了一些问题,好在最后测试成功,也算实现了目的。但总感觉这种方式不够优雅,后了解到可以使用通过 chroot jail 的方式限制 SSH 用户在指定目录下活动,看起来非常符合需求,值得一试。

简单来说,chroot (change root) 是一种 Unix 操作,它指定一个目录作为某个进程的根目录(该目录称为 chroot jail),从而限制这个进程的权限,使其无法读取或写入该指定目录之外的文件夹和文件。

* 以下操作演示在 Debian 12 系统 root 用户下进行,实现在备份服务器(B)上通过 rsync 命令拉取生产服务器(A)上的文件,因此所有操作都在生产服务器(A)上进行,反之同理。

准备工作

新建一个专门用于 rsync 同步的用户和用户组:

groupadd rsyncuser
useradd rsyncuser -g rsyncuser -s /bin/bash -d /home/rsyncuser

设置用户目录权限,注意 chroot jail 目录的所有者必须为 root 用户,并且普通用户和组没有写入权限:

mkdir /home/rsyncuser
chown root:root /home/rsyncuser
chmod 755 /home/rsyncuser

为该用户生成 SSH 密钥,具体方法可以参考文章:修改 SSH 端口使用密钥登录并配置防火墙,如果后面需要通过 cron 任务自动同步,建议生成密钥对时不设置私钥密码,创建 /home/rsyncuser/.ssh 目录,将公钥添加到该目录下 authorized_keys 文件中。然后设置权限:

chmod 700 /home/rsyncuser/.ssh
chmod 600 /home/rsyncuser/.ssh/authorized_keys
chown -R rsyncuser:rsyncuser /home/rsyncuser/.ssh
# 或者保留 root 对 .ssh 的所有权,允许普通用户读取,两种方式各有利弊:
# chmod 755 /home/rsyncuser/.ssh
# chmod 644 /home/rsyncuser/.ssh/authorized_keys
# chown -R root:root /home/rsyncuser/.ssh

创建一个 rsyncuser 用户可以读写的目录 backup 用来同步文件:

mkdir /home/rsyncuser/backup
chmod 755 /home/rsyncuser/backup
chown rsyncuser:rsyncuser /home/rsyncuser/backup

测试 SFTP 连接(可选)

如果你只需要使用 SFTP 进行同步,可以简单的通过以下几个步骤实现,并保证了最小化权限。确认 /etc/ssh/sshd_config 中下行内容未注释:

Subsystem   sftp    /usr/lib/openssh/sftp-server

然后在文件最后添加:

Match User rsyncuser
    ChrootDirectory /home/rsyncuser
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
    PasswordAuthentication no

保存后重启 SSH 进程:

systemctl restart sshd.service

此时你应该已经可以在其他服务器中通过 sftp 连接本服务器,通过下面命令测试:

sftp -i /path/to/private_key -P <port> rsyncuser@<ip>

配置 rysnc 环境

在 chroot 中运行 rsync 需要一些额外的依赖文件,相比只使用 SFTP 会麻烦一些。在 /etc/ssh/sshd_config 文件最后添加/修改为:

Match User rsyncuser
    ChrootDirectory /home/rsyncuser
    AllowTcpForwarding no
    X11Forwarding no
    PasswordAuthentication no

/bin/bash/usr/bin/rsync 的二进制文件(路径用 which rsync 查看)复制到 chroot 目录中:

mkdir /home/rsyncuser/bin && mkdir -p /home/rsyncuser/usr/bin
cp /bin/bash /home/rsyncuser/bin/
cp /usr/bin/rsync /home/rsyncuser/usr/bin/

使用 ldd 命令查看 bash 和 rsync 依赖的库:

ldd /bin/bash
# linux-vdso.so.1 (0x...)
# libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x...)
# libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x...)
# /lib64/ld-linux-x86-64.so.2 (0x...)
	
ldd /usr/bin/rsync
# linux-vdso.so.1 (0x...)
# libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x...)
# libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x...)
# libpopt.so.0 => /lib/x86_64-linux-gnu/libpopt.so.0 (0x...)
# liblz4.so.1 => /lib/x86_64-linux-gnu/liblz4.so.1 (0x...)
# libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x...)
# libxxhash.so.0 => /lib/x86_64-linux-gnu/libxxhash.so.0 (0x...)
# libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x...)
# libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x...)
# /lib64/ld-linux-x86-64.so.2 (0x...)

其中第一个 linux-vdso* 是虚拟库,不需要考虑。根据你的情况将其他依赖库文件整理后复制到 chroot 目录中:

cd /home/rsyncuser
mkdir lib64 && mkdir -p lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libtinfo.so.6 ./lib/x86_64-linux-gnu/libtinfo.so.6
cp /lib/x86_64-linux-gnu/libc.so.6 ./lib/x86_64-linux-gnu/libc.so.6
cp /lib64/ld-linux-x86-64.so.2 ./lib64/ld-linux-x86-64.so.2

cp /lib/x86_64-linux-gnu/libacl.so.1 ./lib/x86_64-linux-gnu/libacl.so.1
cp /lib/x86_64-linux-gnu/libz.so.1 ./lib/x86_64-linux-gnu/libz.so.1
cp /lib/x86_64-linux-gnu/libpopt.so.0 ./lib/x86_64-linux-gnu/libpopt.so.0
cp /lib/x86_64-linux-gnu/liblz4.so.1 ./lib/x86_64-linux-gnu/liblz4.so.1
cp /lib/x86_64-linux-gnu/libzstd.so.1 ./lib/x86_64-linux-gnu/libzstd.so.1
cp /lib/x86_64-linux-gnu/libxxhash.so.0 ./lib/x86_64-linux-gnu/libxxhash.so.0
cp /lib/x86_64-linux-gnu/libcrypto.so.3 ./lib/x86_64-linux-gnu/libcrypto.so.3

复制完成后的文件目录应该如下:

chroot-folder-tree
/home/rsyncuser 文件夹列表。

完成后,可以先进入 chroot 环境检查 rsync 是否能正常运行:

chroot /home/rsyncuser
rsync --version

然后在 backup 目录下新建一个 1.txt 文件用来测试,在其他服务器上执行 rsync 命令获取 1.txt 文件:

rsync -av -e "ssh -p <port> -i /path/to/private_key" rsyncuser@<ip>:/backup/1.txt /home/1.txt 

如果一切顺利,你的备份服务器上会出现 /home/1.txt 文件,到此就实现了在 chroot 环境下安全的使用 rsync 备份。之后只需要设置一个自动任务将需要备份的文件打包放到 /home/rsyncuser/backup 目录下,再定时同步即可。

虽然使用 chroot 相比直接使用 Docker 的方式复杂一些,但不需要额外安装 Docker,也能节省一些资源占用,总的来说更值得推荐。