资讯动态

Linux rsync远程同步带密码认证:SSH与daemon模式实战

发布时间:2026/9/16 21:09:44 来源:尧图企业网站定制
1. 弄懂rsync远程同步与密码认证的核心矛盾刚接触Linux运维那会儿我最怕的就是跨服务器传文件。用scp吧小文件还行一旦遇到几十GB的日志或者上万个小文件那进度条能让人等到怀疑人生。后来老同事甩给我一条rsync命令从此就离不开了。rsync这个工具在Linux圈子里几乎是文件同步的代名词它的核心本事是增量传输——只传变化的部分而不是傻乎乎地每次全量拷贝。但问题也随之而来一旦要实现远程同步就绕不开身份认证而“带密码”这三个字往往就是新手和老手之间的一道坎。很多人第一次尝试rsync远程同步会直接写rsync -avz /local/path userremote:/remote/path然后终端提示输入密码。手动敲一次没问题可要是放进crontab定时任务里脚本就会卡在密码提示上直到超时失败。这时候搜索解决方案会看到五花八门的关键词sshpass、expect、密钥登录、rsync daemon、secrets file……到底选哪个各自有什么坑这篇文章我就结合自己这些年在内网、公网、混合云环境下的实操经验把“Linux下rsync远程同步带密码”这件事彻底讲清楚。适合阅读的人群很明确负责服务器运维的工程师、需要定期备份数据的开发人员、刚学会Linux常用命令想进一步掌握自动化同步的爱好者。不管你是想临时传一次带密码的文件还是想搭建一套长期稳定运行的同步任务下面的内容都能直接抄作业。我会从最底层的原理讲起把SSH通道和daemon模式两条路都拆开配上完整的配置示例、参数解释和排错记录。尤其会重点说明密码文件权限、路径斜杠陷阱、认证失败排查这些只有实际踩过才知道的细节。1.1 rsync凭什么成为Linux同步的首选工具rsync的高效来自它独特的“滚动校验和”算法。简单说它把文件切成很多小块对每块计算校验和然后对比源端和目标端的校验和只传输不一致的块。这就像你有一本1000页的书对方只有前999页rsync不会把整本书重新寄一遍而是只寄缺失的那一页。这种机制在同步大文件、日志文件、数据库备份时优势极其明显。另外rsync还支持压缩传输-z、保留权限时间戳-a、删除目标端多余文件--delete等功能非常全面。在Linux常用命令大全里rsync的地位和tar、grep、awk是同一梯队的。但rsync本身并不直接处理“密码”这个概念。它依赖底层传输通道要么走远程Shell通常是SSH由SSH负责认证要么走rsync daemon模式由rsync自己通过配置文件里的密码文件来认证。这两种模式在配置方式、安全模型、使用场景上完全不同。很多人混淆了它们导致在错误的方向上折腾。比如你想用--password-file参数却仍然写着userhost:/path的SSH格式那rsync会直接报错因为它根本不知道这个参数在SSH模式下该怎么用。所以第一步必须明确你要走哪条路。1.2 带密码同步的三种真实场景我遇到的“带密码”需求基本可以归为三类。第一类是临时手动同步比如从开发机往测试服务器推一个补丁包不想配置密钥直接输密码最快。第二类是脚本自动化同步每天凌晨把数据库备份推到备份服务器必须无人值守密码要自动提供。第三类是多用户隔离同步公司内网有一台公共文件服务器不同团队只能访问自己的模块需要用rsync daemon配合独立账号和密码。这三种场景对安全性和便利性的要求不同选型也不同。临时手动可以用sshpass凑合但自动化强烈建议SSH密钥或daemon密码文件。多用户隔离则几乎必须用daemon模式。注意任何把密码明文写在命令行里的做法都会留在bash history里。用history命令就能看到这是非常危险的习惯。如果必须用sshpass记得用-f参数从文件读取并且设置文件权限为600。1.3 安全底线密码文件绝不能随意放不管选哪种方案只要涉及密码文件权限就是生命线。rsync对--password-file指定的文件有强制要求文件权限必须是600且属主必须是执行rsync命令的用户。如果权限是644rsync会直接拒绝读取报错ERROR: password file must not be other-accessible。这个设计是为了防止同服务器上其他用户偷看密码。我见过不少人在测试时用chmod 777图省事结果正式环境怎么都跑不通排查半天才发现是权限问题。另外密码文件的内容格式也分两种SSH密钥没有密码文件sshpass的密码文件就是纯文本密码而rsync daemon的secrets file格式是用户名:密码每行一个用户。这些细节后面会逐一展开。2. SSH通道下的rsync带密码同步从临时方案到长期免密绝大多数人第一次用rsync远程同步走的都是SSH通道。因为Linux服务器默认开启SSH服务不需要额外配置rsync daemon命令格式也直观rsync -avz 源路径 用户主机:目标路径。这种模式下rsync本身不处理密码它把认证完全交给SSH。所以你要解决“带密码”的问题本质上是在解决“如何让SSH自动提供密码”。这里有三个层次的方案最粗暴的是sshpass最规范的是SSH密钥对最灵活的是ssh-agent配合配置文件。我按照从快到稳的顺序来讲你可以根据实际场景选择。2.1 使用sshpass传递密码的快速上手与风险sshpass是一个专门用来非交互式提供SSH密码的工具。在Debian/Ubuntu上安装sudo apt install sshpass在CentOS/RHEL上需要先启用EPEL源sudo yum install epel-release sudo yum install sshpass。安装后最简单的用法是sshpass -p 你的密码 rsync -avz /data/ user192.168.1.100:/backup/。这样确实能跑通密码也不会出现在交互提示里。但风险很明显-p参数后面的密码会出现在ps aux的输出中同一台机器上的其他用户可以通过进程列表看到密码。如果一定要用sshpass更安全的方式是-f参数指定密码文件sshpass -f /path/to/passfile rsync -avz ...同时确保chmod 600 /path/to/passfile。实测下来sshpass在临时脚本里应急可以但长期自动化非常不推荐。首先很多生产环境的安全基线扫描会直接告警“检测到sshpass使用”。其次如果SSH服务端配置了PasswordAuthentication nosshpass会直接失效。最后密码一旦修改所有脚本都要跟着改维护成本高。我自己的原则是能不用sshpass就不用除非是内网测试机且生命周期只有几小时。2.2 生成SSH密钥对并配置免密登录SSH密钥认证是Linux下最正统的免密方案也是我强烈推荐的方式。它的原理是客户端生成一对密钥私钥和公钥把公钥放到服务端的~/.ssh/authorized_keys文件里。之后SSH连接时服务端用公钥加密一个挑战客户端用私钥解密验证通过即可登录全程不需要传输密码。生成密钥的命令ssh-keygen -t rsa -b 4096 -C rsync-backup。-t rsa指定算法-b 4096指定长度-C是注释。执行后会提示保存路径默认~/.ssh/id_rsa直接回车即可。然后会问你要不要设置密钥密码passphrase。如果你希望无人值守这里必须留空直接回车如果设置了passphrase每次使用密钥都要输入就需要配合ssh-agent。把公钥复制到服务端ssh-copy-id user192.168.1.100。这个命令会自动把~/.ssh/id_rsa.pub的内容追加到服务端的~/.ssh/authorized_keys并设置正确权限。如果没有ssh-copy-id也可以手动cat ~/.ssh/id_rsa.pub | ssh userhost mkdir -p ~/.ssh cat ~/.ssh/authorized_keys。完成后测试ssh user192.168.1.100如果不再提示密码说明配置成功之后rsync命令就可以直接写rsync -avz /data/ user192.168.1.100:/backup/完全无需密码。注意服务端的~/.ssh目录权限应为700authorized_keys权限应为600。如果权限不对SSH会拒绝使用密钥并且日志里会提示Authentication refused: bad ownership or modes。这个坑我踩过好几次尤其是用root用户时家目录权限被改成777导致密钥登录失效。2.3 ssh-agent与配置文件简化日常操作如果你需要管理多台服务器、多个密钥或者密钥设置了passphrase那么ssh-agent就是救星。ssh-agent是一个密钥管理程序它把解密后的私钥缓存在内存中后续SSH连接自动使用不需要重复输入passphrase。启动agenteval $(ssh-agent -s)然后添加私钥ssh-add ~/.ssh/id_rsa。如果密钥有passphrase此时输入一次即可。之后当前终端会话内的所有rsync命令都能直接使用该密钥直到终端关闭或手动ssh-add -D清除。为了进一步简化可以在~/.ssh/config里配置主机别名。比如Host backup-server HostName 192.168.1.100 User backupuser IdentityFile ~/.ssh/id_rsa_backup Port 22这样rsync命令可以简写成rsync -avz /data/ backup-server:/backup/。~/.ssh/config的权限也必须是600。这种配置方式在管理数十台服务器时非常清爽而且不需要记忆IP和用户名。我个人的习惯是给每台生产服务器单独生成密钥并在config里用有意义的别名比如web-prod、db-backup这样一眼就能看出同步目标是谁。3. rsync daemon模式独立服务与密码文件认证SSH通道虽然方便但它有两个局限第一需要每台客户端都配置密钥或密码用户管理分散第二rsync over SSH会加密所有流量在纯内网高速同步时加密开销反而拖慢速度。这时候rsync daemon模式就更合适。daemon模式让rsync在服务端以独立进程运行监听TCP 873端口客户端通过rsync://协议连接。认证完全由rsync自己管理通过secrets file存放用户名和密码。这种模式特别适合内网文件服务器、多用户隔离备份、以及需要带宽限制的场景。不过daemon模式的配置项较多初学者容易在模块定义、权限、路径上翻车。我把自己搭建过几十次的经验浓缩成下面几个关键点。3.1 服务端rsyncd.conf核心参数解析rsync daemon的主配置文件通常放在/etc/rsyncd.conf。它采用类似INI的格式分为全局段和模块段。全局段配置守护进程的整体行为模块段定义一个个共享目录。一个最简化的配置文件如下uid rsync gid rsync use chroot yes max connections 10 pid file /var/run/rsyncd.pid log file /var/log/rsyncd.log transfer logging yes timeout 300 [backup] path /data/backup comment Backup storage read only no list yes auth users backupuser secrets file /etc/rsyncd.secrets hosts allow 192.168.1.0/24 hosts deny *这里每个参数都有讲究。uid和gid指定rsync进程运行的身份建议专门创建一个rsync系统用户避免用root。use chroot yes会把同步目录锁定在path之下防止路径穿越攻击但如果需要同步软链接指向外部可能要设为no。max connections控制并发连接数防止单个客户端占满资源。auth users指定允许的用户名secrets file指定密码文件路径。hosts allow和hosts deny做IP白名单内网环境务必配置否则暴露在公网非常危险。注意secrets file的权限必须是600且属主为root。如果rsync以非root身份运行该文件需要可读。另外path指定的目录必须存在并且运行rsync的用户对其有读写权限。我见过太多人配置完启动失败就是因为/data/backup目录不存在或权限不足。3.2 创建secrets file与权限设置secrets file的格式很简单每行用户名:密码例如backupuser:MyS3cretPss如果有多个用户就写多行。创建后立即执行chmod 600 /etc/rsyncd.secrets并且chown root:root /etc/rsyncd.secrets。这一步没有商量余地权限不对rsync daemon会启动失败或认证拒绝。密码建议使用强密码避免特殊字符中的冒号因为冒号是分隔符。如果密码里必须有冒号需要转义或改用其他认证方式。另外服务端存储的是明文密码所以这台服务器的安全等级必须足够高最好限制SSH登录只允许rsync端口对外。启动daemon有两种方式临时启动用rsync --daemon --config/etc/rsyncd.conf系统服务方式在CentOS 7用systemctl start rsyncd在Ubuntu/Debian用systemctl start rsync。启动后检查端口ss -tlnp | grep 873或netstat -tlnp | grep 873。如果没监听查看日志/var/log/rsyncd.log常见错误包括配置文件语法错误、权限问题、端口被占用。防火墙也要放行873端口firewall-cmd --add-port873/tcp --permanent firewall-cmd --reload或者iptables -A INPUT -p tcp --dport 873 -j ACCEPT。3.3 客户端如何用--password-file连接客户端使用daemon模式时命令格式变为rsync -avz /local/path backupuser192.168.1.100::backup。注意这里是双冒号::表示走rsync daemon协议而不是SSH的单冒号。如果服务端配置了auth users直接执行会提示输入密码。要实现自动化需要创建客户端密码文件内容只有一行密码不要写用户名MyS3cretPss保存为/home/user/.rsync.pass然后chmod 600 /home/user/.rsync.pass。之后命令加上--password-file/home/user/.rsync.pass参数即可rsync -avz --password-file/home/user/.rsync.pass /local/path backupuser192.168.1.100::backup这样就能无人值守同步了。客户端的密码文件权限同样必须是600否则rsync报错ERROR: password file must not be other-accessible。另外如果服务端模块是read only yes客户端只能拉取不能推送推送会报ERROR: module is read only。需要推送就设为read only no。4. 完整实操搭建一个带密码的rsync同步任务光说不练假把式。下面我以一个真实的备份场景为例从零开始搭建一套带密码的rsync daemon同步任务。假设有两台服务器服务端IP为192.168.1.100用于存放备份客户端IP为192.168.1.101需要把/data/app/logs目录每天同步到服务端。要求自动运行、密码认证、保留权限、删除目标端多余文件、限制带宽不超过10MB/s。我会把每一步的命令和配置都列出来你可以直接复制修改。4.1 服务端配置示例与启动首先在服务端创建专用用户和目录sudo useradd -r -s /sbin/nologin rsync sudo mkdir -p /data/backup/logs sudo chown -R rsync:rsync /data/backup然后编辑/etc/rsyncd.confuid rsync gid rsync use chroot yes max connections 5 pid file /var/run/rsyncd.pid log file /var/log/rsyncd.log transfer logging yes timeout 600 [logs] path /data/backup/logs comment Application logs backup read only no list yes auth users loguser secrets file /etc/rsyncd.secrets hosts allow 192.168.1.101 hosts deny *创建密码文件echo loguser:LogPss2024 | sudo tee /etc/rsyncd.secrets sudo chmod 600 /etc/rsyncd.secrets sudo chown root:root /etc/rsyncd.secrets启动服务sudo systemctl start rsyncd sudo systemctl enable rsyncd sudo systemctl status rsyncd检查端口和日志ss -tlnp | grep 873 tail -f /var/log/rsyncd.log如果服务端有防火墙放行873端口。至此服务端配置完成。4.2 客户端同步命令与参数详解在客户端192.168.1.101上创建密码文件echo LogPss2024 ~/.rsync_logs.pass chmod 600 ~/.rsync_logs.pass先做一次dry-run测试看看哪些文件会被同步rsync -avz --dry-run --delete --password-file$HOME/.rsync_logs.pass /data/app/logs/ loguser192.168.1.100::logs确认无误后执行真实同步rsync -avz --delete --bwlimit10240 --password-file$HOME/.rsync_logs.pass /data/app/logs/ loguser192.168.1.100::logs参数解释-a归档模式保留权限、时间、符号链接等-v详细输出-z压缩传输--delete删除目标端多余文件保持完全一致--bwlimit10240限制带宽为10240KB/s即10MB/s--password-file指定密码文件。注意源路径/data/app/logs/末尾的斜杠很重要有斜杠表示同步目录内容没斜杠表示同步目录本身。这个细节后面会专门讲。4.3 自动化脚本与定时任务把同步命令写成脚本/usr/local/bin/sync_logs.sh#!/bin/bash RSYNC_PASS$HOME/.rsync_logs.pass SRC/data/app/logs/ DSTloguser192.168.1.100::logs LOG/var/log/rsync_logs_sync.log echo $(date %Y-%m-%d %H:%M:%S) start $LOG rsync -avz --delete --bwlimit10240 --password-file$RSYNC_PASS $SRC $DST $LOG 21 if [ $? -eq 0 ]; then echo sync success $LOG else echo sync failed with code $? $LOG fi echo end $LOG赋予执行权限chmod x /usr/local/bin/sync_logs.sh。然后加入crontabcrontab -e # 每天凌晨2点执行 0 2 * * * /usr/local/bin/sync_logs.sh这样一套带密码的自动同步任务就完成了。脚本里记录了每次同步的日志方便事后审计。我习惯把日志按日期切割或者用logrotate管理避免日志文件无限膨胀。另外建议在脚本开头加上set -e但rsync失败时可能返回非零所以用if判断更稳妥。5. 常见问题与排查技巧实录即使配置完全按照文档来实际运行中还是会遇到各种报错。下面这些错误信息我敢说每个搞rsync的人都至少见过一半。我把它们整理成速查表并附上我的排查思路。遇到问题时先看rsync的错误输出再结合服务端日志基本能定位到原因。5.1 认证失败、权限拒绝、模块不存在等错误速查错误信息可能原因解决方法ERROR: auth failed on module logs用户名或密码错误secrets file格式不对检查/etc/rsyncd.secrets内容确认用户名密码匹配无多余空格ERROR: chdir failed模块path目录不存在或权限不足创建目录并确保rsync用户有读写权限ERROR: module is read only服务端模块设置了read only yes改为read only no或仅做拉取操作ERROR: password file must not be other-accessible客户端密码文件权限不是600chmod 600 ~/.rsync.passERROR: Unknown module logs模块名拼写错误或配置未生效检查rsyncd.conf模块名重启服务rsync: failed to connect to 192.168.1.100 (192.168.1.100): Connection refused服务端daemon未启动或防火墙拦截启动rsyncd放行873端口Permission denied (publickey,password)SSH密钥未配置或服务端禁用密码登录用ssh-copy-id部署公钥检查sshd配置rsync: connection unexpectedly closed网络中断或超时检查网络增大timeout值重试这张表基本覆盖了90%的常见问题。我特别要强调ERROR: auth failed这个错误很多时候不是密码错了而是secrets file里多了空格或者换行符。比如用echo user:pass 写入末尾空格会被当成密码的一部分。建议用printf或者编辑器写入然后用cat -A查看不可见字符。5.2 传输中断、速度慢、文件不一致的排查思路传输大文件时最怕中断。如果rsync跑到一半断了重新执行会续传吗默认情况下rsync会重新扫描并对比已经传完的文件不会重传但未完成的临时文件会从头开始。要支持断点续传加上--partial和--append参数。--partial保留部分传输的文件--append让rsync假设文件是追加的只传输末尾部分。但这两个参数要小心使用如果源文件中间被修改过可能导致目标端文件损坏。更稳妥的做法是直接重新执行rsync的增量算法会处理。速度慢的原因通常有三个网络带宽不足、磁盘IO瓶颈、加密开销。内网daemon模式如果速度远低于预期检查--bwlimit是否设得太低或者服务端max connections限制了并发。用iftop、iotop、sar这些工具定位瓶颈。如果是大量小文件可以打包成tar再传传完解压效率会高很多。文件不一致的情况优先检查源路径末尾斜杠、--delete是否误删、排除规则--exclude是否写对。我习惯在正式同步前用--dry-run和--itemize-changes或-i查看每个文件的变更状态。5.3 独家避坑路径斜杠、排除规则、日志查看第一个坑源路径斜杠。rsync -avz /src /dst和rsync -avz /src/ /dst完全不同。前者会在目标端创建/dst/src目录后者直接把/src里的内容放到/dst下。我见过有人同步了一整天结果目标端多了一层目录就是因为少了斜杠。第二个坑排除规则顺序。--exclude是从左到右匹配的如果先排除了整个目录再想包含子文件必须用--include配合--exclude并且--include要放在前面。例如只同步.conf文件--include*.conf --exclude*。第三个坑日志查看。服务端日志/var/log/rsyncd.log会记录每个连接的用户、模块、传输文件数和字节数。如果认证失败日志里会明确写auth failed。客户端加-v或-vv能看到更详细的调试信息但注意-vv输出非常多只适合排查时用。小技巧如果怀疑是SELinux导致权限问题临时用setenforce 0测试如果问题消失就需要配置正确的SELinux上下文而不是直接关闭。用ausearch -m avc -ts recent查看SELinux拒绝日志。6. 安全加固与性能调优建议rsync用起来之后下一步就是让它更安全、更快、更可靠。安全方面密码文件和网络暴露是重点性能方面带宽、压缩、并发都有调优空间。下面这些建议来自我在生产环境中的实际配置不一定适用于所有场景但可以作为起点参考。6.1 密码文件权限与最小权限原则密码文件的安全前面反复强调这里再补充几点。服务端的secrets file权限必须是600属主root。客户端的--password-file权限也必须是600属主是执行rsync的用户。如果使用SSH密钥私钥权限必须是600~/.ssh目录权限700。这些权限要求不是rsync在刁难你而是Unix安全模型的基本规则。另外最小权限原则体现在运行rsync daemon的用户不应该是root而应该是一个专门的系统用户只对备份目录有读写权限。模块配置里read only no只在确实需要推送时开启如果只是拉取设为yes更安全。hosts allow一定要配置只允许信任的IP段访问不要图省事写0.0.0.0/0。如果服务必须暴露在公网建议在前面加一层防火墙或反向代理并且定期轮换密码。6.2 带宽限制、压缩、并发参数调优rsync的性能参数里--bwlimit是最常用的限速参数单位是KB/s。比如限制10MB/s就写--bwlimit10240。如果不限速rsync可能占满带宽影响其他业务。-z压缩适合网络带宽紧张但CPU空闲的场景如果内网带宽充足压缩反而浪费CPU可以去掉。--compress-level可以调整压缩级别默认6范围1-9内网建议用1或关闭。并发方面rsync本身是单线程传输单个文件但可以启动多个rsync进程同步不同模块或者用--max-size拆分大文件。--whole-file参数在本地磁盘之间同步时能跳过校验和计算速度更快但在跨网络时默认会使用增量算法。我一般内网同步用-avz --bwlimit20480公网用-avz --bwlimit5120效果比较均衡。6.3 监控与审计如何知道同步是否成功同步任务跑在后台怎么知道它是否正常最直接的是看退出码echo $?0表示成功非0表示失败。在脚本里判断并记录日志。更完善的方案是结合监控系统比如把每次同步的结果写入日志然后用grep统计成功失败次数或者通过邮件、钉钉机器人发送告警。rsync本身支持--log-file参数在客户端记录日志服务端日志在/var/log/rsyncd.log。我习惯在同步脚本里加上文件数量和大小的统计比如rsync -avz --stats输出会包含传输文件数、总字节数、压缩比等信息。如果某次同步传输的文件数突然异常比如平时每天几十个突然变成几千个可能意味着源端产生了大量新文件需要关注。审计方面rsyncd.log会记录客户端IP、用户、模块、时间戳满足基本的审计需求。最后分享一个我经常用的小技巧在正式同步前用rsync -avz --dry-run --itemize-changes配合--password-file跑一遍输出会列出所有将要同步的文件和变更类型新建、修改、删除。这个命令不会实际传输数据但能提前发现路径错误、排除规则失效、权限不足等问题。我每次调整同步策略后都会先dry-run确认输出符合预期再执行真实同步能避免很多误操作。另外如果同步任务很重要建议在目标端保留多个历史版本可以用--backup --backup-dir/path/to/backup_$(date %Y%m%d)实现这样即使误删文件也能找回。这些经验都是踩坑踩出来的希望对你有所帮助。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价