
1. 这不是rsync手册是我在生产环境里用血泪换来的排错清单“rsync踩过所有的坑错误解决记录”——看到这个标题你大概率正对着终端里一行红色报错发呆rsync: failed to connect to xxx: Connection refused (111)或者更绝望的rsync error: error in rsync protocol data stream (code 12) at io.c(235)。别急着Google也别立刻重装、重启、关防火墙。我干了十年Linux系统运维和自动化部署从IDC机房到云上K8s集群rsync用得比SSH还勤但恰恰是这个看似最简单的工具在真实场景里埋的雷最多、最隐蔽、最反直觉。它不报错则已一报就是组合拳SELinux策略卡死、873端口被静默拦截、Docker容器内权限链断裂、甚至磁盘配额超限都伪装成网络超时。今天这篇不讲原理不列命令只讲我亲手复现、亲手验证、亲手绕过的每一个真实故障现场。关键词就四个rsync、错误解决、873端口、SELinux、防火墙——它们不是孤立存在的而是像齿轮一样咬合在一起一个没调对整个同步链就崩。适合谁看刚配完rsync服务却连不上的人在Docker里跑rsync报Permission denied却查遍chmod无果的人systemctl status firewalld显示running但telnet host 873就是不通的人还有那些把setsebool -P samba_export_all_ro1当万能膏药乱贴结果越贴越堵的人。下面每一条都是我截图存档、日志备份、反复验证过的实战记录你可以直接抄作业但请务必理解背后那个“为什么”。2. 错误根源不是rsync本身而是它暴露的系统底层信任链断裂2.1 rsync协议栈的三层信任模型网络层→系统层→安全策略层很多人以为rsync出错就是命令写错了其实完全相反——rsync本身极其健壮它的报错90%以上是上游依赖环节失败后的被动反馈。我把rsync的运行依赖拆成三个必须同时通过的“信任关卡”缺一不可第一关网络可达性873端口这是最表层的检查但也是最容易被误导的。telnet host 873通 ≠ rsync能连。因为rsync daemon默认监听的是0.0.0.0:873但实际连接时可能走的是IPv6地址、localhost回环、或特定网卡绑定IP。我遇到过最典型的案例客户服务器firewall-cmd --list-ports显示873已开放ss -tlnp | grep :873也确认进程在监听但客户端始终报Connection refused。最后发现是rsyncd.conf里写了bind_addr 192.168.1.100而客户端尝试连接的是公网IP流量根本没走到rsync进程被内核路由直接丢弃。关键点rsync daemon的bind_addr和address参数必须与客户端发起连接的目标IP完全一致否则网络层就断在SYN包阶段连TCP三次握手都完成不了。第二关系统级权限用户/组/文件权限rsync daemon以指定用户身份运行通常是rsync或nobody这个用户必须对配置文件中定义的path目录有读执行x权限。注意是“执行”权限不是“写”。因为Linux下进入目录需要x权限而rsync列出文件列表本质就是chdir操作。我见过太多人给/data/backup设chmod 755却忘了父目录/data只有750导致rsync用户无法cd /data报错却是模糊的rsync: opendir . failed: Permission denied (13)。更隐蔽的是SELinux上下文——即使ls -lZ显示目录属主正确如果SELinux类型是default_t而非rsync_etc_t或rsync_var_t同样会拒绝访问。实操验证法切换到rsync服务用户手动执行cd /your/rsync/path ls -la能进能列才是真通。第三关安全策略层SELinux 防火墙协同拦截这是真正让新手崩溃的“黑盒”。SELinux和firewalld不是并列关系而是嵌套拦截firewalld先决定“包能不能进来”SELinux再决定“进来的包能不能被rsync进程处理”。举个真实案例某CentOS 7服务器firewall-cmd --permanent --add-port873/tcp后reloadtelnet通了但rsync仍报ERROR: chroot failed。查/var/log/audit/audit.log发现大量avc: denied { search } for pid1234 commrsync namebackup devsda1 ino56789 scontextsystem_u:system_r:rsync_t:s0 tcontextunconfined_u:object_r:default_t:s0 tclassdir。原来firewalld放行了端口但SELinux的rsync_t域没有search权限去访问default_t类型的目录。解决方案不是关SELinux而是用semanage fcontext -a -t rsync_var_t /data/backup(/.*)? restorecon -Rv /data/backup重打标签。记住firewalld管“门”SELinux管“门内房间的钥匙”两者必须同时配对生效。2.2 为什么873端口成为故障高发区——它不是普通端口而是rsync的“信任锚点”873端口在rsync生态里有特殊地位它是rsync daemon的唯一官方注册端口IANA编号873但恰恰因为“官方”反而成了策略冲突的焦点。很多企业安全基线要求“禁用所有非标准端口”于是管理员一刀切封掉873改用其他端口如8730。这看似合理却埋下三个深坑客户端兼容性陷阱rsync rsync://host/module语法强制使用873端口。如果你把daemon绑在8730必须显式写成rsync rsync://host:8730/module漏写:8730就默认连873必然失败。而rsync userhost::module这种ssh模式不受影响导致同一套脚本在不同环境下表现不一致。SELinux策略绑定RHEL/CentOS的SELinux策略包selinux-policy-targeted中rsync_port_t类型只允许绑定到873端口。如果你强行rsync --port8730启动SELinux会拒绝绑定日志里出现avc: denied { name_bind } for ... port8730。解决方案只有两个要么用semanage port -a -t rsync_port_t -p tcp 8730手动添加端口映射要么老老实实用873。防火墙规则冗余风险当管理员为“安全”开放8730时往往忘记清理旧的873规则。结果firewall-cmd --list-ports显示两个端口都开着但实际ss -tlnp只监听8730造成“端口开着却连不上”的假象。我的建议除非有强合规要求否则永远用873。它不是历史包袱而是经过十年验证的最小信任面。2.3 SELinux不是“开关”而是rsync权限的精细雕刻刀把SELinux当成“开/关”二元选项是绝大多数rsync故障的根源。SELinux对rsync的控制粒度远超想象它不只管“能不能连”更管“连上了能干什么”。核心SELinux类型有三个rsync_exec_trsync二进制文件的类型决定进程能否被启动rsync_etc_t/etc/rsyncd.conf等配置文件的类型决定进程能否读取配置rsync_var_trsync数据目录如/var/lib/rsync的类型决定进程能否读写数据。最常踩的坑是混淆rsync_var_t和default_t。当你用cp -r /old/data /new/backup复制数据目录后新目录继承的是default_t而rsync daemon以rsync_t域运行默认没有read/write权限访问default_t。此时restorecon -Rv /new/backup不会生效因为restorecon只恢复文件系统默认上下文而/new/backup的父目录可能被标记为default_t。正确解法是semanage fcontext -a -t rsync_var_t /new/backup(/.*)? restorecon -Rv /new/backup。注意(/.*)?这个正则它确保子目录和文件全部递归打标。另一个隐形杀手是rsync_disable_trans布尔值。默认为off意味着rsync进程会从rsync_t域切换到rsync_exec_t域执行。但在某些加固环境中管理员会setsebool -P rsync_disable_trans on来禁止域切换结果rsync daemon启动失败日志里只有Failed to start LSB: Starts rsync daemon.。验证方法getsebool rsync_disable_trans若为on且rsync无法启动立即setsebool -P rsync_disable_trans off。这不是后门而是SELinux设计的正常流程。3. 八大高频错误现场还原与逐行修复指南3.1 错误代码111Connection refused —— 网络层的“幽灵拦截”现象$ rsync rsync://backup.example.com/backup rsync: failed to connect to backup.example.com: Connection refused (111) rsync error: error in socket IO (code 10) at clientserver.c(127) [Receiver3.1.3]根因分析这不是rsync的问题而是TCP连接在SYN阶段就被拒绝。常见原因有三rsync daemon未运行或监听地址不匹配防火墙iptables/firewalld明确DROP了873端口云服务商安全组未放行873端口比本地防火墙更优先。逐行诊断与修复确认服务状态# 检查进程是否存活 systemctl status rsyncd # 若未运行启动并设开机自启 systemctl start rsyncd systemctl enable rsyncd验证监听地址# 查看rsync实际监听的IP和端口 ss -tlnp | grep :873 # 输出示例LISTEN 0 128 *:873 *:* users:((rsync,pid1234,fd4)) # 注意*:*表示监听所有IP若显示127.0.0.1:873则只能本机连检查防火墙规则# firewalld用户 firewall-cmd --list-ports | grep 873 # 若无输出添加并重载 firewall-cmd --permanent --add-port873/tcp firewall-cmd --reload # iptables用户CentOS 6/7早期 iptables -L INPUT -n | grep 873 # 若无规则添加 iptables -I INPUT -p tcp --dport 873 -j ACCEPT service iptables save云平台安全组检查登录阿里云/腾讯云控制台找到对应ECS实例的安全组确认入方向规则包含协议类型TCP端口范围873/873授权对象0.0.0.0/0测试用或指定IP段提示telnet host 873成功≠rsync成功。telnet只验证TCP层rsync还需通过SELinux和文件权限校验。务必按顺序排查网络层→系统层→安全层。3.2 错误代码13Permission denied —— SELinux与文件权限的双重绞杀现象$ rsync rsync://backup.example.com/backup ERROR: chroot failed rsync error: error starting client-server protocol (code 5) at main.c(1671) [Receiver3.1.3] # 或 rsync: opendir . failed: Permission denied (13)根因分析错误13表面是权限问题但根源在SELinux上下文或文件系统权限链断裂。chroot failed几乎100%指向SELinux因为rsync daemon默认启用chroot在rsyncd.conf中use chroot yes而chroot操作需要sys_chroot能力该能力受SELinux严格管控。逐行诊断与修复快速验证是否SELinux导致# 临时禁用SELinux仅用于验证 setenforce 0 # 再试rsync若成功则确定是SELinux问题 rsync rsync://backup.example.com/backup # 验证后立即恢复 setenforce 1检查SELinux上下文# 查看rsync配置目录 ls -ldZ /etc/rsyncd.conf # 正常应为-rw-r--r--. root root system_u:object_r:rsync_etc_t:s0 /etc/rsyncd.conf # 若为unconfined_u:object_r:default_t:s0则修复 semanage fcontext -a -t rsync_etc_t /etc/rsyncd.conf restorecon -v /etc/rsyncd.conf修复数据目录SELinux标签# 假设数据目录为 /data/backup ls -ldZ /data/backup # 若tcontext显示default_t执行 semanage fcontext -a -t rsync_var_t /data/backup(/.*)? restorecon -Rv /data/backup检查文件系统权限# rsync用户如rsync必须对目录有x权限 ls -ld /data /data/backup # /data 权限至少为755/data/backup至少为755 # 若权限不足修正 chmod 755 /data /data/backup chown rsync:rsync /data/backup注意restorecon -Rv是递归修复但只作用于已定义的fcontext规则。若semanage fcontext -l | grep rsync无输出说明规则未添加restorecon无效。3.3 错误代码12Error in rsync protocol data stream —— 协议层的“静默截断”现象$ rsync -avz /local/dir/ rsync://backup.example.com/backup receiving file list ... rsync: connection unexpectedly closed (0 bytes received so far) [Receiver] rsync error: error in rsync protocol data stream (code 12) at io.c(235) [Receiver3.1.3]根因分析这是最棘手的错误表面是协议流中断实则是数据传输过程中被中间设备防火墙/NAT/IDS主动重置连接。常见于防火墙开启ALGApplication Layer Gateway功能对rsync协议解析错误企业级防火墙如深信服、H3C将rsync识别为“未知协议”并阻断NAT设备会话超时长连接被强制断开。逐行诊断与修复关闭防火墙ALG功能在防火墙管理界面查找“应用识别”、“协议检测”、“ALG设置”关闭rsync、FTP、SIP等ALG模块。这是企业网最常见原因比修改rsync配置更有效。调整rsync超时参数# 客户端增加超时和重试 rsync -avz --timeout300 --contimeout300 /local/dir/ rsync://backup.example.com/backup # --timeout数据传输超时秒 # --contimeout连接建立超时秒禁用rsync压缩排除干扰# 添加--compress-level0禁用压缩排除压缩算法兼容性问题 rsync -avz --compress-level0 /local/dir/ rsync://backup.example.com/backup使用ssh通道替代daemon模式# 绕过873端口和防火墙ALG走ssh加密隧道 rsync -avz -e ssh -p 22 /local/dir/ userbackup.example.com:/remote/backup/实测心得在金融、政务类网络中90%的code 12错误源于防火墙ALG。与其花时间调rsync参数不如直接联系网络管理员关闭ALG——这是最短路径。3.4 Docker容器内rsync权限错误UID/GID映射的迷宫现象# 在Docker容器中执行 $ rsync -avz /data/ host:/backup/ rsync: failed to set times on /backup/: Operation not permitted (1) rsync: mkstemp /backup/.file.XXXXXX failed: Permission denied (13)根因分析Docker容器的root用户在宿主机上是随机UID如1001而rsync daemon以rsync用户UID 98运行。当容器内root尝试写入宿主机目录时宿主机内核拒绝UID 0写入非root目录触发Operation not permitted。这不是rsync bug而是Linux capability机制的正常行为。逐行诊断与修复确认宿主机目录所有权# 在宿主机执行 ls -ld /backup # 若属主不是root且容器内用root运行必失败方案一容器内降权运行推荐# Dockerfile中指定非root用户 RUN groupadd -g 98 rsync useradd -u 98 -g rsync rsync USER rsync CMD [rsync, -avz, /data/, host:/backup/]方案二宿主机目录授权# 在宿主机将目录属主改为容器内root映射的UID # 查看容器内root UID通常为0但Docker可能映射为其他值 docker exec -it container id cat /proc/1/status | grep Uid # 假设映射UID为1001则 chown -R 1001:1001 /backup方案三挂载时指定UID/GID# 启动容器时强制映射UID docker run -v /host/backup:/backup:rw \ --user 98:98 \ your-rsync-image关键原则Docker容器内不要用root操作宿主机敏感目录。用--user参数或DockerfileUSER指令让权限映射清晰可控。3.5 “ERROR: invalid uid” —— rsync daemon用户配置的致命拼写现象$ rsync rsync://backup.example.com/backup ERROR: invalid uid rsync error: error starting client-server protocol (code 5) at main.c(1671) [Receiver3.1.3]根因分析rsyncd.conf中uid和gid参数必须指向真实存在的系统用户和组。常见错误uid rsync但系统无rsync用户id rsync报错uid nobody但nobody用户被禁用/etc/passwd中shell为/sbin/nologin拼写错误如uid sync少了个r。逐行诊断与修复验证用户存在性# 检查uid参数指定的用户 id rsync # 若报“no such user”则创建 useradd -r -s /sbin/nologin rsync检查用户shell权限# rsync daemon不需要登录shell但shell不能为false grep rsync /etc/passwd # 正确示例rsync:x:98:98::/var/lib/rsync:/sbin/nologin:/bin/bash # 若为/sbin/false修改为/sbin/nologin usermod -s /sbin/nologin rsync检查rsyncd.conf语法# 用rsync自带工具验证配置 rsync --daemon --config/etc/rsyncd.conf --no-detach --log-file/dev/stdout # 若配置错误会立即报错并退出注意uid和gid必须同时存在且有效。单独创建用户不创建组或组不存在都会触发此错误。3.6 “rsync: readlinkstat” failed —— 符号链接与chroot的冲突现象$ rsync rsync://backup.example.com/backup rsync: readlinkstat /backup/symlink failed: Permission denied (13)根因分析当rsyncd.conf中设置use chroot yes时rsync daemon会将自身chroot到模块path目录。此时目录内的符号链接若指向chroot外部路径如/etc/passwd则无法解析报readlinkstat failed。这是chroot的安全机制不是bug。逐行诊断与修复确认chroot状态# 查看rsyncd.conf中模块配置 grep -A 5 \[backup\] /etc/rsyncd.conf # 若含use chroot yes则此问题必然发生方案一禁用chroot简单粗暴[backup] path /data/backup use chroot no # 改为no方案二使用绝对路径符号链接# 在chroot目录内创建指向内部路径的软链 cd /data/backup ln -sf ./internal_data symlink # 避免指向/etc/、/usr/等外部目录方案三用bind mount替代软链# 将外部目录挂载到chroot内 mount --bind /external/data /data/backup/external_data安全提醒use chroot no会降低安全性但对内部可信网络可接受。生产环境建议用方案二或三保持chroot隔离性。3.7 “No space left on device” —— 磁盘配额伪装的rsync错误现象$ rsync -avz /large/file.iso rsync://backup.example.com/backup rsync: write failed on /backup/file.iso: No space left on device (28) rsync error: error in file IO (code 11) at receiver.c(393) [Receiver3.1.3]根因分析错误28表面是磁盘满但实际可能是目标文件系统inode耗尽df -i查看用户磁盘配额quota限制rsync临时文件.filename.XXXXXX写入失败。逐行诊断与修复检查inode使用率df -i /data/backup # 若Use%接近100%则需清理小文件或扩大inode数量检查磁盘配额# 查看rsync用户配额 quota -u rsync # 若显示“disk quotas on”且soft/hard limit已超需扩容 edquota -u rsync指定rsync临时目录# 避免/tmp空间不足指定大空间目录 rsync -avz --temp-dir/data/tmp /large/file.iso rsync://backup.example.com/backup实操技巧rsync传输大文件前先用df -h /target和df -i /target双检查比报错后排查快10倍。3.8 “protocol version mismatch” —— rsync版本不兼容的隐性战争现象$ rsync -avz /local/ rsync://old-server/backup protocol version mismatch — is your shell clean? (see the rsync manpage for an explanation) rsync error: protocol incompatibility (code 2) at compat.c(66) [sender3.2.3]根因分析rsync协议版本由两端rsync二进制版本决定。3.1.x与3.2.x之间存在不兼容变更。更隐蔽的是shell初始化文件~/.bashrc, ~/.profile中输出的非空字符会污染rsync协议头导致版本协商失败。逐行诊断与修复检查两端rsync版本rsync --version # 客户端和服务端分别执行 # 若版本差大于1如3.1.3 vs 3.2.7需升级低版本端清理shell污染关键# 在服务端rsync用户家目录注释掉所有echo、printf语句 vi ~/.bashrc # 注释掉类似echo Welcome 或 printf Hello # 保存后测试ssh rsyncserver true | hexdump -C # 应无输出强制指定协议版本# 客户端指定兼容版本仅当无法升级时 rsync -avz --protocol30 /local/ rsync://old-server/backup # 30对应rsync 3.0.x协议警告shell污染是最高频的“protocol version mismatch”原因。90%的此类错误只需清空服务端rsync用户的shell初始化文件即可解决。4. 防火墙与SELinux协同配置的黄金法则4.1 firewalld配置rsync的四步精准手术firewalld不是“开个端口”那么简单它有zone、service、port三层抽象。针对rsync必须按以下顺序操作跳步必错确认当前活跃zonefirewall-cmd --get-active-zones # 通常为public若为trusted可跳过后续步骤添加rsync服务推荐非端口# firewalld内置rsync服务定义自动处理873/tcp firewall-cmd --permanent --add-servicersync firewall-cmd --reload # 验证firewall-cmd --info-servicersync 显示端口和协议若需自定义端口必须用port方式# 仅当必须用8730时 firewall-cmd --permanent --add-port8730/tcp firewall-cmd --reload # 并同步更新SELinux端口映射见2.2节验证规则生效# 查看public zone规则 firewall-cmd --zonepublic --list-all # 输出中应含services: ssh rsync 或 ports: 873/tcp注意--add-servicersync比--add-port873/tcp更安全因为它绑定到服务名避免端口冲突。4.2 SELinux策略调试的三板斧audit2why、sealert、ausearch当setenforce 0能解决问题但setenforce 1又失败时别猜用工具实时捕获拒绝日志# 清空审计日志缓冲区 ausearch -m avc -ts recent | audit2why # 或持续监控 tail -f /var/log/audit/audit.log | aureport -f -i生成可执行修复命令# 当audit2why给出建议时用audit2allow生成模块 ausearch -m avc -ts recent | audit2allow -M myrsync semodule -i myrsync.pp用sealert定位具体问题# sealert会分析日志并给出人类可读解释 sealert -a /var/log/audit/audit.log # 输出示例SELinux is preventing rsync from search access on the directory /data/backup.黄金法则audit2why告诉你“为什么错”sealert告诉你“哪里错”audit2allow给你“怎么修”。三者配合10分钟定位90% SELinux问题。4.3 防火墙黑白名单的rsync实践何时该放行何时该拒绝rsync不是Web服务不需要0.0.0.0/0开放。生产环境必须遵循最小权限原则白名单策略推荐# 只允许备份服务器IP访问 firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.168.10.5 port port873 protocoltcp accept firewall-cmd --reload黑名单策略慎用# 禁止特定IP段如公网扫描器 firewall-cmd --permanent --add-rich-rulerule familyipv4 source address203.0.113.0/24 reject动态IP处理若客户端IP不固定如云函数用--add-source加IP段或改用ssh模式rsync -e ssh -i key.pem利用SSH密钥认证替代IP白名单。重要提醒防火墙规则顺序很重要。--add-rich-rule插入到规则链顶部--add-port插入到底部。混合使用时用firewall-cmd --list-all --verbose查看实际顺序。5. 常见问题速查表与独家避坑技巧问题现象根本原因快速验证命令一键修复命令避坑技巧Connection refused (111)rsync daemon未运行或监听地址不匹配systemctl status rsyncd ss -tlnp | grep :873systemctl start rsyncd firewall-cmd --reload永远先ss -tlnp再telnet最后rsyncERROR: chroot failedSELinux阻止chroot操作ausearch -m avc -ts recent | audit2whysetsebool -P rsync_full_access onrsync_full_access布尔值比手动打标更稳妥rsync: connection unexpectedly closed防火墙ALG干扰tcpdump -i any port 873 -w rsync.pcap关闭防火墙ALG模块在抓包中看到RST包90%是ALG问题Operation not permittedDocker容器UID映射失败docker exec container id iddocker run --user 98:98 ...容器内永远用非root用户避免权限地狱No space left on deviceinode耗尽df -i /targetfind /target -xdev -type f | head -1000 | xargs rmrsync前必查df -h和df -i双指标protocol version mismatchshell初始化文件输出垃圾ssh rsynchost true | hexdump -C注释~/.bashrc中所有echo语句服务端rsync用户shell必须纯净独家避坑技巧实录技巧1rsync配置文件语法检查神器别用手动grep用rsync --daemon --config/etc/rsyncd.conf --test它会加载配置并报告语法错误比rsync --help有用10