rsync未授权访问:从匿名文件同步到远程命令执行的安全加固

📅 发布时间:2026/10/21 23:21:38
rsync未授权访问:从匿名文件同步到远程命令执行的安全加固
1. 从一次内网扫描说起为什么rsync会成为突破口先讲个我早年间经历的事儿。某次给一家企业做内网安全评估扫了一圈发现一台备份服务器上开了873端口banner显示是rsync。当时同行的人没太在意觉得rsync就是个文件同步工具能有什么风险。结果我用一条命令直接列了共享模块发现整个备份目录完全开放连匿名用户都能读写。那次经历让我意识到rsync作为Linux世界最常用的文件同步工具之一它的访问控制机制如果配置不当造成的影响远比大多数人想象的要严重。它不是那种花里胡哨的漏洞利用而是“配置即漏洞”的典型代表——你不需要精心构造数据包不需要绕过复杂的防护只要服务端把门敞开了任何人都能直接走进去拿东西。这篇文章我不会去教你如何对某个目标发起攻击那是违法的事儿。但我会把rsync未授权访问的原理、检测思路、加固方法完整讲清楚。对于负责运维和安全的同学来说理解攻击者是怎么想的、是怎么摸到你的服务器的你才知道该在哪些地方堵窟窿。如果你是刚接触Linux安全的新手这篇文章同样适用。我会把涉及的基础知识一并讲透比如rsync的模块机制、权限模型、日志审计让你不光是“知道有这个坑”而是真正理解“这个坑是怎么形成的”以后碰到类似的服务比如NFS、FTP、Redis也能举一反三。2. 洞悉本质rsync的模块机制与匿名访问模型2.1 rsync的守护进程模式是怎么工作的很多人日常用rsync都是命令行模式比如rsync -avz ./data userhost:/backup这种用法走的是SSH通道安全性和认证都由SSH负责。但还有另一种用法就是让rsync以守护进程daemon方式运行监听在873端口由rsync自己来处理连接和文件传输。守护进程模式的核心概念是“模块”module。你可以把模块理解成一块对外暴露的目录区域配置文件/etc/rsyncd.conf里每一个方括号段落都是一个模块比如[backup] path /data/backup comment Backup Storage read only yes当客户端执行rsync rsync://192.168.1.10/backup的时候实际上就是在请求这个名为backup的模块。服务端收到请求后会把path指定的目录映射给客户端。关键问题来了这个模块允许谁来访问谁能读写这就是auth users、secrets file、read only、hosts allow这几个参数决定的。2.2 未授权访问的本质是“没人管门”如果你在配置模块的时候既没有设置auth users也没有设置hosts allow那么这个模块对全网所有IP都是开放的。任何人在任何地方只要网络能到达你的873端口就能执行rsync rsync://目标IP/模块名这条命令会直接列出模块下的文件列表。如果是只读模块攻击者可以批量拉取所有文件如果没有设置只读攻击者还能往里面写文件。为什么会出现这种配置我总结了几类常见原因图省事内网环境觉得“反正外面进不来”干脆不做认证不懂参数把auth users当成可选项以为配置了path就完事了遗留配置之前临时测试用的配置后来忘了清理只设了IP白名单但没设认证某些场景下IP可以伪造或绕过单一防护不够这里要特别强调一个认知误区很多人觉得“rsync是内网服务外网访问不到就安全了”。但内网不等于安全区内网里同样有被攻陷的跳板机、恶意员工、中了马的办公终端。一旦攻击者通过钓鱼或者漏洞打进内网第一件事就是横向扫描开放端口而873端口几乎是一扫一个准的高价值目标。2.3 访客模式下能做什么当rsync模块被匿名访问时攻击者能干的事儿大致分三档第一档信息泄露。用rsync rsync://IP/模块名列出文件列表分析目录结构、文件名、备份策略从中推断业务类型、系统版本、内部网络结构。备份文件里往往藏着数据库导出、配置文件、密钥、源码压缩包这些都属于高敏数据。第二档数据篡改。如果模块不是只读的攻击者可以上传恶意文件。典型手法是在网站根目录模块里放webshell或者替换应用配置文件甚至直接覆盖二进制文件植入后门。由于rsync同步的特性被篡改的文件还会随着下一次同步扩散到其他服务器。第三档利用rsync本身拿权限。这个我会在后面章节细讲思路是利用rsync的写权限修改目标机器的定时任务、SSH公钥等文件实现远程命令执行。所以“未授权访问”四个字听上去不痛不痒实际危害可以类比成“你家大门没锁快递员、小偷、推销员都能进来翻东西”——区别只是来的人想干什么。3. 写权限等于命令执行从文件上传到RCE的路径推演3.1 为什么说“能写文件”就是“能执行命令”这是rsync安全里最重要也最容易被低估的一点。很多人觉得“我只是开了文件写入他又不能执行命令”。但在一台Linux服务器上文件写入权限和命令执行权限之间往往只隔着一层窗户纸。举几个最常见的利用路径路径一写入定时任务。Linux的cron任务目录是/var/spool/cron/或/etc/cron.d/这些目录里的文件如果内容合法就会被cron服务读取并执行。如果rsync模块暴露的path刚好包含这些目录很多备份策略喜欢备份/etc、/var/spool这类系统路径攻击者就能写一个定时任务文件进去内容指定一个反弹shell命令等cron执行即可。路径二写入SSH公钥。如果模块的path指向某个用户的家目录比如备份/home并且该用户开启了SSH登录且目录下有.ssh/authorized_keys攻击者可以向里面追加自己的公钥然后直接用SSH登录该用户。路径三覆盖启动脚本或服务配置。systemd服务单元文件、init.d脚本、环境变量文件如/etc/profile.d/、~/.bashrc如果被篡改等效于直接控制了该用户或服务的运行环境。路径四替换Web目录文件。如果模块暴露的是Web根目录写入一个JSP/PHP脚本就能获得Webshell后续顺着Webshell再提权。需要说明的是上面这些路径的可行性取决于rsync模块的具体配置。如果模块配置了read only yes那么只有读取权限以上都不可行。但很多备份模块为了让客户端能推送数据会设置成可写这就在无意中打开了潘多拉魔盒。3.2 rsync同步机制在攻击中扮演的角色rsync的同步机制和普通的上传下载有个明显区别它支持增量传输和删除操作。如果配置了delete参数客户端同步时会删除服务端多余的文件。这意味着攻击者不只是能“多写几个文件”甚至可以批量删除目标机器上的文件。配合定时任务等目录直接让目标机器起不来服务或者把业务数据删光。这种破坏力比单纯的命令执行更野蛮但造成的业务影响却更直接。所以我在评估一个rsync暴露风险的时候从来不会只看“能不能读”而是把“能不能写”“能不能删”“覆盖了哪些目录”三个维度一起评估。信息泄露、数据破坏、远程控制三条线的危害程度完全不同。3.3 攻击者视角的操作逻辑以攻击者的视角来看拿到一个开放873端口的目标后大致的判断流程是这样的用rsync rsync://IP枚举有哪些模块对每个模块观察配置信息里的只读/可写提示、路径特征如果是可写模块先拉取文件列表确认path名称配置里不一定显示实际路径但文件结构能透露不少信息判断能否把文件写到关键目录cron、ssh、web目录等如果无法判断实际路径就通过拉取/etc/passwd等标志性文件来反推path的根目录位置这个过程提醒我们一个事实rsync未授权访问很少是“单一漏洞利用”它往往是一个侦察和横向移动的入口点。攻击者在这个入口上能待多久、能摸多深完全取决于服务端配置开放了多大面。4. 从配置到加固手把手堵住rsync的每个风险点4.1 安全的rsyncd.conf应该长什么样下面这份配置是我在实际生产环境中长期使用的模板你可以根据业务情况做调整但核心安全项不要删# /etc/rsyncd.conf uid rsync gid rsync use chroot yes max connections 10 lock file /var/run/rsyncd.lock log file /var/log/rsync.log transfer logging yes timeout 300 read only no list no [backup] path /data/rsync/backup comment Internal Backup Module auth users backupuser secrets file /etc/rsyncd.secrets hosts allow 192.168.10.0/24 hosts deny * read only no逐行拆解关键点uid和gid指定rsync进程以专用系统账号运行不要用root。这是最重要的一条即使被入侵权限也被限制在普通用户级别。可以先用useradd -r rsync创建专用账号。use chroot yes在传输文件前把进程禁锢到模块的path目录中防止客户端借助符号链接或路径穿越访问系统其他位置。list no禁止客户端枚举模块列表。这样即使对方知道IP也得先猜模块名。auth userssecrets file启用账号密码认证。secrets文件格式是“用户名:密码”权限必须设置为600。hosts allow/hosts deny只允许内网指定网段访问。注意这不能替代认证只是缩小了暴露面。read only的值需要根据业务定如果只是服务端给客户端分发文件建议read only yes如果允许客户端推送备份数据那至少要把uid设置为非root的专用账号并且path目录的所有者不要设置为该目录的上级敏感路径。4.2 创建密钥文件的细节secrets文件是个容易踩坑的地方。我见过好几次配置完rsync总是认证失败的最后发现是secrets文件权限不对。rsync守护进程对密码文件要求非常严格权限必须是600或更严格属主必须是运行rsync进程的用户否则直接拒绝读取。正确的创建方式# 创建专用账号 useradd -r -s /sbin/nologin rsync # 创建密码文件 echo backupuser:Str0ngPassw0rd /etc/rsyncd.secrets chown root:rsync /etc/rsyncd.secrets chmod 600 /etc/rsyncd.secrets另外客户端连接时如果要免交互输入密码可以用--password-file/etc/rsync.pwd参数指定密码文件。这个文件在客户端也建议设置600权限否则本机其他用户能通过/proc或直接读文件拿到明文密码。4.3 网络层的额外防线除了rsync自身的配置我还建议在网络层做三层防护这属于纵深防御iptables/firewalld只放行特定来源IP访问873端口。比如只允许备份服务器IP访问其他全部DROP。fail2ban监控rsync日志对多次认证失败的IP做临时封禁。虽然rsync未授权访问不涉及“爆破密码”但这个机制能防住针对secrets文件的暴力猜测。不监听公网如果是纯内网使用让rsync只监听内网IP不要用0.0.0.0。在配置里用address 内网IP指定监听地址减小暴露面。4.4 安全基线自检脚本我把自己常用的rsync安全基线检查写成了一个脚本跑一遍就能看到风险项。你可以参照这个思路做成自动化巡检#!/bin/bash # rsync安全巡检脚本 CONF/etc/rsyncd.conf echo 检查rsync配置 # 1. 检查是否启用匿名模块 if grep -vE ^\s*#|^\s*$ $CONF | grep -q auth users; then echo [OK] 已配置认证 else echo [FAIL] 存在未配置认证的模块 fi # 2. 检查是否启用chroot if grep -q use chroot yes $CONF; then echo [OK] chroot已启用 else echo [WARN] 未启用chroot fi # 3. 检查是否允许list if grep -q list no $CONF; then echo [OK] 已禁止列表枚举 else echo [FAIL] 模块可被匿名枚举 fi # 4. 检查uid是否root if grep -qE ^(uid|gid) root $CONF; then echo [FAIL] rsync以root运行 else echo [OK] rsync非root运行 fi # 5. 检查密码文件权限 if [ -f /etc/rsyncd.secrets ]; then PERM$(stat -c %a /etc/rsyncd.secrets) if [ $PERM 600 ]; then echo [OK] 密码文件权限正确 else echo [FAIL] 密码文件权限为$PERM应设为600 fi else echo [WARN] 未找到密码文件 fi # 6. 检查网络暴露情况 echo 端口监听检查 ss -tlnp | grep 873 || echo [INFO] 873端口未监听这套脚本不需要额外依赖放到cron里每周跑一次或者接入监控系统至少能保证关键项不失控。5. 检测发现与日志审计如何知道自己有没有中招5.1 主动检测在攻击者之前发现问题与其等被入侵后才去排查不如站在攻击者的角度主动探测自己的服务。这里提供一个完全合规的自检思路用自己的服务器模拟一次“未授权访问”看能不能枚举模块、能不能匿名拉取文件。首先要明确一点对自己的服务器做检测是合法的安全运维行为但不要对未经授权的目标做同样的事。这个边界是红线绝对不能越。检测命令# 检查873端口是否对外开放 nmap -p873 127.0.0.1 # 枚举模块如果配置了listno这里可能不显示模块名 rsync rsync://127.0.0.1/ # 尝试直接访问常见模块名 rsync rsync://127.0.0.1/backup rsync rsync://127.0.0.1/data注意rsync rsync://IP/尾部没有模块名这是枚举模式。如果服务端配置了list yes这一步会直接列举出所有模块名如果配置了list no则只会返回连接成功的消息不会暴露模块名。从攻击者的角度list no只能提高枚举门槛并不能完全阻止。常见的模块名其实非常容易猜测backup、data、www、upload、files、public等等字典枚举一轮下来总能命中几个。这也是为什么认证配置才是安全的核心list no只是辅助手段。5.2 日志审计连接记录里的蛛丝马迹rsync的守护进程会在日志里记录每一次连接和传输行为。如果你的rsyncd.conf里配置了transfer logging yes日志里会记录客户端的IP、请求的模块、传输的文件数量等信息。默认情况下日志写到syslog或rsyncd.log具体看配置文件里的log file参数。我整理了一份异常特征速查表你可以在审计日志时重点关注这些模式特征说明风险等级同一IP短时间内大量连接可能在进行模块名暴力枚举中连接后长时间无文件传输攻击者可能在探索目录结构中来自非预期网段的连接说明hosts allow可能未生效或网络边界被突破高向非预期模块写入文件备份目录出现了非业务的写操作高连接发生在凌晨业务低峰期自动攻击脚本常选这个时段中手工翻日志的效率太低我更推荐用grep加awk配合监控。比如查看最近谁连过873端口# 查看最近rsync连接记录 grep rsync /var/log/rsyncd.log | tail -100 # 统计各IP连接次数 awk {print $NF} /var/log/rsyncd.log | sort | uniq -c | sort -rn | head -205.3 中招后的应急处理顺序如果不幸发现服务器上的文件被异常访问或篡改处理顺序非常关键。我踩过慌乱的坑也总结过靠谱的流程分享给你立即断网或收紧防火墙先从网络层面阻断可疑IP但不要急着关rsync服务保留现场进程还在便于排查日志。备份日志和配置把/var/log/rsyncd.log、/etc/rsyncd.conf、/etc/rsyncd.secrets原样拷贝一份用stat记录文件的修改时间。检查关键文件篡改痕迹重点看/var/spool/cron/、/etc/cron.d/、.ssh目录、Web目录、系统二进制文件的时间戳。定位webshell和后门如果发现新增的可执行文件不要直接删除先保留样本分析。Web目录里可以用find查找最近修改的脚本文件find /var/www/html -type f -mtime -7 -name *.php -o -name *.jsp | xargs ls -la修改所有相关密码和密钥rsync的认证密码、服务器上Linux用户的密码、SSH密钥全部重新生成。修补配置并部署监控按第四节的安全基线把rsync重新加固同时部署文件完整性监控。6. 扩展思考同类“信任边界”风险与常态化防御研究rsync未授权访问给我最大的启发是它代表了运维中特别常见的一类问题服务本身不是高危漏洞但信任边界画错了。rsync默认信任网络里所有能连到它的人如果没有配置认证的话这类问题不止rsync有。NFS网络文件系统如果exports里写了*(rw)效果和rsync匿名可写模块如出一辙。Redis如果没设密码且监听在0.0.0.0攻击者用一条config set dir就能写cron目录。FTP配置成匿名可写也有类似问题。它们的共同特征是默认配置优先考虑可用性而安全需要使用者主动配置。所以我在评估一个系统安全的时候不再把某个单独服务拎出来看而是看整个系统的“信任模型”这个服务信任谁有没有认证信任的范围是什么允许哪些IP被信任的人能做什么只读还是可写如果信任被滥用影响边界在哪是不是root权限、能不能影响其他服务顺着这几个问题往下排查比单个服务逐个找漏洞高效得多。防御层面我给三条长期建议定期做自我渗透测试不需要搞得很复杂每季度末用扫描器扫一遍内网主动发现873、2049NFS、6379Redis这类常见服务是否暴露在过大的范围。建立配置变更审批机制rsyncd.conf这类文件不能谁想改就改。改动前先review改完自动跑一遍安全基线脚本。接入统一的日志监控平台单机日志很容易被忽略把rsync日志接入ELK这类平台后配合规则引擎做异常检测效率会高得多。最后分享一个经验安全加固这件事最怕的不是技术不够而是“觉得内网里没事”。我见过的几起rsync导致的事故无一例外都是管理员认为“内网嘛没事”结果等真出了事才追悔莫及。所以我的习惯是把每台服务器的对外暴露面当成公网来审视宁可多绑一层认证多限制一段来源IP也不给入侵者留一条捷径。你可以在自己的环境里试试我给的巡检脚本看到输出里有FAIL或者WARN的地方就顺着去改改完再跑一遍。