拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SCP/Rsync/SFTP:Linux远程文件传输三工具实战指南

SCP/Rsync/SFTP:Linux远程文件传输三工具实战指南

干了这么多年运维,我几乎每天都要在Linux服务器之间传文件。代码发版要传包,日志备份要取数,数据库迁移要同步数据,碰上半夜线上出问题,拷贝文件更是家常便饭。SCP、Rsync、SFTP这三样,是Linux下最常用的远程文件传输手段,弄熟它们不只是省时间,关键时候能救场。

这三种工具各有各的脾气:SCP简单直接,适合一次性拷完就走;Rsync擅长增量同步,跑第二遍的时候速度优势非常明显;SFTP则更像一个加密的“远程文件管理器”,适合边浏览边操作。新手经常困惑“到底该用哪个”,老手也容易在细节上翻车,比如scp的-P和-p搞混、rsync末尾斜杠不一致导致目录层级错误、CentOS上搭SFTP受限目录被权限问题卡住。这篇文章就把这些场景逐个拆开,把你需要的命令、参数、排查思路都放到一起,照着操作就能解决问题。

1. 三类工具的核心思路与适用场景

1.1 先搞清楚它们之间的本质区别

很多人把SCP、Rsync、SFTP放在一起比较,其实它们底层都走SSH协议,数据在传输过程中都是加密的,从安全性角度看没有本质差别。真正的区别在于各自的定位和设计思路。

SCP全称Secure Copy,是OpenSSH很早就有的一套复制工具。它的命令格式几乎跟本地cp一模一样,只是把目标路径换成“用户名@主机名:路径”,非常简单粗暴。适合的场景是:明确的单次拷贝、文件数量不多、不需要反复执行。它的优势是速度足够快,因为没有额外的校验逻辑,就是纯流式拷贝。劣势也很明显:不支持增量,每次都是全量传;传一半断了,下次得从头再来。

Rsync的全称是remote sync,重点在“同步”两个字。它的核心逻辑不是复制,而是对账:先对比源端和目标端的文件差异,只传输变化的部分。这个机制使它在“反复执行”“大目录迁移”“定时备份”这几类场景里几乎无法替代。此外它还支持压缩传输、限速、断点续传、排除规则、删除同步,功能相当丰富。

SFTP全称SSH File Transfer Protocol,它不是另一个独立的服务,而是SSH协议内置的一个子系统。设计思路更接近FTP:登录后在一个交互式Shell里操作,可以浏览远程目录、查看文件列表、决定下载哪个、上传哪个。适合的场景是:需要人工确认文件列表后操作、想给用户开放一个受限的目录空间但不想给完整Shell权限。因为它基于SSH的子系统,服务端只需要开放22端口,不需要再单独启一个FTP服务端。

1.2 怎么挑选适合当前场景的工具

如果你问我“用哪个最好”,我的答案是:没有最好,只有最合适。给你一个我平时判断的参考表。

工具传输形式增量传输断点续传交互式浏览典型场景
SCP一次性复制不支持不支持不支持传单个文件、临时传包
Rsync同步复制支持支持不支持定时备份、目录迁移、镜像同步
SFTP分步操作不支持手动续传支持浏览远程目录、开放受限访问

简单类比一下:SCP像是拿U盘直接拷文件,省事但每次都得整个拷;Rsync像是网盘同步工具,第一次全量同步,后面每次只上传改动过的内容;SFTP则是打开了一个远程仓库的文件管理器界面,你可以慢慢翻看再决定拿哪个。

有一点必须强调:这三者的安全性其实是一样的,因为底层都是SSH加密通道。选择哪个纯粹看操作方式和效率,而不是看“哪个更安全”。

2. SCP实战:最直接的快速传输

2.1 上下行文件的完整命令与参数解析

SCP基本用法跟cp一致:“scp [选项] 源路径 目标路径”,只不过路径里带上了主机标识。我把日常用得最多的几个命令列在下面。

# 本地上传文件到服务器 scp /home/user/app.tar.gz root@192.168.1.100:/opt/backup/ # 从服务器拉取文件到本地 scp root@192.168.1.100:/opt/backup/app.tar.gz /home/user/ # 指定端口上传(比如SSH端口改成了2222) scp -P 2222 /home/user/app.tar.gz root@192.168.1.100:/opt/ # 保留源文件的修改时间、访问权限等属性 scp -p /home/user/app.tar.gz root@192.168.1.100:/opt/

这里有个几乎是所有新手必踩的坑:指定远端端口用大写-P,保留属性用的小写-p,两者就差一个大小写,含义完全不同。我见过不止一次有人写scp -p 2222,结果不但没指定端口,还把文件属性保留参数给开了,最终连接失败还一头雾水。

从服务器上拉取单个文件的写法跟上传几乎一样,只是把源和目标的位置调换一下。实际操作中我更喜欢先进入本地目标目录,再执行拉取命令,这样路径写起来更短,命令可读性也更好。

cd /home/user/downloads scp root@192.168.1.100:/data/logs/app.log .

注意那个末尾的点代表当前目录,意思是把远程的app.log拉取到当前目录下。很多人第一次用的时候容易漏掉这个“点”,导致命令缺参数直接报错。

2.2 目录批量传输的几个关键选项

单个文件用SCP没什么好说的,但传输整个目录时必须要加-r参数,否则会直接报错“Not a regular file”。这是SCP和cp的差异之一,cp复制目录也需要-r,但SCP这个参数默认不会带上,得手动加。

# 递归复制整个目录 scp -r /data/www/ root@192.168.1.100:/data/ # 保留文件属性,同时启用压缩传输 scp -rpC /data/www/ root@192.168.1.100:/data/

这里推荐组合使用-r、-p、-C三个参数。解释一下原因:-p保留时间戳和权限,能让目标端的文件属性跟源端完全一致,这在部署代码时特别重要,因为时间戳变化会影响一些依赖时间戳判断的构建工具和缓存策略。-C启用压缩,在传输文本类文件(如HTML、CSS、日志)时效果很明显,传输体积能减少一半以上;但如果传的是已经压缩过的包(tar.gz、zip等),压缩参数反而会白白消耗CPU,这时候就别加-C。

如果哪天你需要把服务器上的目录“拉”下来,命令同样简单,把源和目标调换即可。

scp -r root@192.168.1.100:/data/www/ /home/user/backup/

很多搜索“如何通过scp把文件夹拉下来”的朋友,本质上就是在找这条命令。你要记住一个核心:源路径是远程、目标路径是本地,就是拉;反过来就是推。

2.3 通过跳板机完成跨网段传输

实际生产环境里经常有这样的场景:目标服务器处在内网,并不直接暴露SSH端口,只能通过一台跳板机中转访问。以前大家的做法是先scp到跳板机,再在跳板机上scp到目标机,完全是折磨人的操作。幸而OpenSSH 7.3以后支持了ProxyJump参数,可以直接通过跳板机穿透到内网目标。

scp -o ProxyJump=ops@10.0.0.5 /home/user/app.tar.gz root@192.168.1.100:/opt/

这样做的原理是:本地SSH客户端先跟跳板机建立加密连接,然后在这个连接之上再跟目标服务器建立另一层加密连接,数据从头到尾都处于加密状态,不会在跳板机上有明文落盘。相比“先传到跳板机再转发”的做法,省掉了中间环节的存储和二次操作,效率高得多。

如果你的OpenSSH版本过老,不支持ProxyJump,那也可以用老式的ProxyCommand方式实现同样的效果,只不过配置稍微复杂一点。

scp -o "ProxyCommand ssh ops@10.0.0.5 -W %h:%p" /home/user/app.tar.gz root@192.168.1.100:/opt/

其中-W参数的意思是让跳板机把数据转发到目标主机的指定端口。两种方式效果接近,新版本系统直接用ProxyJump就行。

3. Rsync实战:增量同步与断点续传

3.1 rsync底层同步逻辑与高频参数

Rsync跟SCP最本质的区别在于它的“增量”能力,而这个增量能力来自它两轮校验的设计。第一轮,它会比对源端和目标端每个文件的“大小+修改时间”,不一致的列入待传清单;第二轮,对于这些待传文件,它把文件切分成固定大小的数据块,用弱校验和和强校验和做对比,找出两端真正不同的块,只传输这些差异块。

这就是为什么你第二次跑rsync的时候,哪怕目录里有一两万个文件,它也能在几秒钟内完成校验并告诉你“nothing to send”。相比之下,SCP每次都是老老实实把整个文件重传一遍,完全没有这种效率。

我日常使用rsync最频繁的参数组合是-avz,这三个字母包含的意义非同小可。

rsync -avz /data/www/ root@192.168.1.100:/data/www/

-a是归档模式,等于“-rlptgoD”的组合,意思是递归传输、保留符号链接、保留权限、保留时间戳、保留属主和组信息;-v是verbose,输出详细信息;-z是传输时压缩。这套组合适合绝大多数文件同步场景,你基本上可以把它当作默认选项。

如果你还要观察传输进度,可以加上--progress或--human-readable,后者的可读性更好。下面是我实际用过的进度输出示例:

rsync -avz --progress /data/www/ root@192.168.1.100:/data/www/

它会在每个文件传输时打印百分比、速率和剩余时间,让你对整个过程心里有数。特别是大批量文件同步时,没有进度显示心里总是不踏实。

3.2 本地目录与远程目录双向同步的姿势

Rsync同步有两个方向:把本地目录推送到远程(push),或者把远程目录拉取到本地(pull)。命令格式分别是:

# 推:本地的/data/www推送到远程服务器的/data/www rsync -avz /data/www/ root@192.168.1.100:/data/www/ # 拉:远程的/data/backup拉取到本地备份 rsync -avz root@192.168.1.100:/data/backup/ /home/user/backup/

这里有个细节必须留意:路径末尾是否带斜杠,含义完全不一样,而且这个坑相当隐蔽,很多老手也会偶尔翻车。

rsync -avz /data/www/ root@...:/data/www/ 表示把/data/www目录里的内容同步到目标的/data/www目录里,结果就是目标目录下直接是源目录中的各个子目录和文件。

rsync -avz /data/www root@...:/data/www/ 表示把/data/www这个目录本身同步到目标的/data/www/目录下,最终结果是目标目录下多了一层名为www的子目录,即/data/www/www。

因为一条命令差一个斜杠,最终目录结构就多套了一层。如果你打算用脚本做自动化同步,建议统一用一个约定,我自己的习惯是“源目录带不带斜杠取决于想同步目录内容还是目录本身,目标目录统一不带斜杠”。这个困惑很多人都会遇到,逐一说明下:在同步命令里,源路径末尾带/表示只同步目录内的内容,不带/表示同步整个目录本身;目标路径末尾带不带斜杠对是否嵌套目录不起决定作用,起决定作用的始终是源路径。

3.3 SSH端口不是22时的rsync写法

Rsync使用SSH作为传输通道时,如果SSH端口不是默认的22,就需要通过-e参数指定ssh命令及端口。

rsync -avz -e "ssh -p 2222" /data/www/ root@192.168.1.100:/data/www/

如果你还需要通过跳板机,那就在-e参数里加上ProxyJump配置,跟前面scp的写法异曲同工。

rsync -avz -e "ssh -p 2222 -o ProxyJump=ops@10.0.0.5" /data/www/ root@192.168.1.100:/data/www/

3.4 排除规则、删除同步与备份模式

处理超大目录时,我们往往并不需要全量同步所有内容。比如同步网站目录时,日志、缓存、临时文件通常没必要一起传。Rsync提供--exclude参数,支持多次使用,也支持通配符后缀。

# 排除所有.log文件以及cache目录 rsync -avz --exclude="*.log" --exclude="/cache/" /data/www/ root@192.168.1.100:/data/ # 从文件读取排除规则,适合大量排除场景 rsync -avz --exclude-from=/home/user/exclude.txt /data/www/ root@192.168.1.100:/data/

exclude.txt里每行一条规则,比如:

*.log /tmp/ /cache/

如果你的目标是让目标端跟源端完全一致,那就需要用到--delete参数。它的含义是:删除目标端有而源端没有的文件。这个参数很有用,但也极其危险,必须谨慎使用。

rsync -avz --delete /data/www/ root@192.168.1.100:/data/www/

有多少人因为对--delete理解不深,一条命令下去把目标端多余的重要文件全部删了个精光,追悔莫及。我的建议是:先用不带--delete的dry-run模式跑一遍,查看它会做什么,确认没问题再真正执行。

rsync -avz --delete --dry-run /data/www/ root@192.168.1.100:/data/www/

加--dry-run(或-n)后,rsync只做模拟演示,把将要做的事情列出来,但不会真正执行任何传输和删除操作。这是任何涉及删除操作前的必备动作,永远不会多余。

另外还有一个非常实用的备份组合:--backup参数会在覆盖或删除目标文件前,先把老文件备份到指定目录,这样即使同步出错也能恢复。

rsync -avz --delete --backup --backup-dir=/data/rsync_backup/$(date +%F) /data/www/ root@192.168.1.100:/data/www/

用日期作为备份目录名称,每天同步前自动把将被覆盖的文件存到当天的备份目录里。这个模式特别适合那种“既要完全同步,又担心误删”的运维场景,是我给重要业务目录做镜像的标配。

3.5 断点续传与带宽限制实战

Rsync支持断点续传,这个能力在SCP身上是完全没有的。大文件传到一半,网络断了或者你手动中断了,SCP直接留下一个残缺文件,接下来要么删掉重传,要么眼睁睁看着进度从头再来。Rsync则不会这样,“--partial”参数让它保留已传输完毕的部分,下次再跑同一命令时,会基于这些残留部分继续传。

rsync -avz --partial /data/bigfile.tar.gz root@192.168.1.100:/data/

实际效果是:一个10GB的文件传到了63%时网络断了,再次执行同一条命令,它不会从头开始,而是直接从上次中断的位置继续往下传。这个体验用一句话概括就是“传输完成后目标端文件与源文件完整体一致”,中途的断点并不会导致文件损坏,因为rsync会做完整校验。

另一个高频场景是带宽控制。生产环境里的备份或迁移任务,往往会占满带宽,影响在线业务。rsync提供了--bwlimit参数,单位为KB/s。

# 限制传输带宽为每秒5MB rsync -avz --partial --bwlimit=5000 /data/ root@192.168.1.100:/data/

我通常会在白天业务繁忙时段限速在1000-2000KB/s,深夜业务低峰再放开到5000KB/s甚至不限速。这样既能把数据迁移对线上业务的影响降到最低,又不会让同步任务拖成“蜗牛工程”。

结合crontab做一个定时增量备份的脚本也非常简单。比如每天凌晨2点把web目录同步到备份机:

0 2 * * * rsync -avz --partial --delete /data/www/ root@192.168.1.100:/data/backup/www/ >> /var/log/rsync_www.log 2>&1

这里建议一定要加--partial,因为你根本无法预测凌晨的网络状况。如果你还想更稳一点,可以再加--timeout=30,设置空闲超时时间为30秒,连接假死时自动断开,避免一个job卡死在那里占用资源。

4. SFTP实战:交互式管理远程文件

4.1 SFTP的底层机制与登录方式

SFTP并没有单独的服务端进程,它依赖的是SSH服务端的Subsystem配置。简单来说,SSH不仅负责远程登录Shell,它还可以通过内部子系统提供文件传输功能。你不需要额外安装OpenSSH之外的任何软件,只要本地有SSH服务端,就天然具备SFTP能力。

登录方式是:

sftp root@192.168.1.100

如果端口不是22,用-oPort参数,注意这里是字母o,不是scp的大写P。或者直接用sftp -oPort=2222 root@192.168.1.100,效果一样。

登录成功后,你会看到sftp>提示符,这表示你已经进入SFTP交互界面,可以执行后续的各种文件操作命令。这个会话全程加密,与SSH共用认证机制(密码或密钥),比传统FTP裸奔式的明文传输安全一个量级。

4.2 常用交互命令与本地目录切换

SFTP的交互命令跟Linux Shell有很多相似之处,但也有一组以l开头的本地命令,这是很多新手容易弄混的地方。我把最常用的命令整理了一下。

分类命令作用
远程操作ls、cd、pwd查看远程目录列表、切换目录、当前路径
本地操作lls、lcd、lpwd查看本地目录列表、切换本地目录、本地当前路径
下载get 文件下载远程文件到本地
下载get -r 目录递归下载整个远程目录
上传put 文件上传本地文件到远程
上传put -r 目录递归上传整个本地目录
批量mget / mput匹配通配符批量下载或上传
管理rm、mkdir、rename删除、创建目录、重命名远程文件

实际操作的体验是这样的:

sftp> lcd /home/user/downloads sftp> lpwd Local working directory: /home/user/downloads sftp> cd /data/logs sftp> get app.log Fetching /data/logs/app.log to app.log sftp> get -r /data/www/ /home/user/backup/

很多人问“如何把服务器上整个文件夹拉下来”,用sftp get -r一条命令就搞定了,不需要再装其他工具。递归下载时,如果目标文件已经存在,SFTP默认会直接覆盖,但如果文件在上次传输中不完整,建议先删除残缺文件重新下载。

mget和mput支持通配符批量操作,比如:

sftp> mget *.txt sftp> mput *.tar.gz

注意mget在下载之前会逐个文件询问确认,如果不想被烦,可以执行prompt命令关闭交互确认。

4.3 CentOS 7下搭建受限目录的SFTP环境

这里要单独讲讲“CentOS 7配置SFTP受限目录”这件事,因为很多需求并不是给自己用的,而是给同事、给客户开放一个专属目录,让他们只能在这个目录里上传下载文件,不能登录Shell执行其他命令。

首先明确思路:我们要借助sshd_config里的Match Group或Match User规则,对特定用户组的SFTP会话进行ChrootDirectory(即把它禁锢在指定目录下)和ForceCommand internal-sftp(强制使用内置SFTP进程,丢弃Shell登录能力)限制。

步骤一:创建用户组和专属用户。

groupadd sftpusers useradd -g sftpusers -s /sbin/nologin -d /data/sftp/alice alice echo "alice:你的初始密码" | chpasswd

这个用户shell设为/sbin/nologin,表示它无法通过SSH登录到Shell,只能被用于SFTP这类非交互式会话。

步骤二:创建目录并设置权限。

mkdir -p /data/sftp/alice chmod 755 /data/sftp chown root:root /data/sftp chown alice:sftpusers /data/sftp/alice chmod 755 /data/sftp/alice

这里有个关键细节:ChrootDirectory指定的根目录必须由root用户拥有,并且权限不能超过755,否则连接会被拒绝。也就是说,你只能把用户实际可写空间的根目录往上延伸一层。常见的目录结构是:

/data/sftp/ (root:root,755) /data/sftp/alice/ (alice:sftpusers,755)

其中/data/sftp/alice这个用户目录可以被alice读写,但它没法进入/data/sftp这个层级去操作其他用户的内容,更没法往上跳出这个目录。

步骤三:修改/etc/ssh/sshd_config。在文件末尾追加如下配置。

Subsystem sftp internal-sftp Match Group sftpusers ChrootDirectory /data/sftp/%u ForceCommand internal-sftp X11Forwarding no AllowTcpForwarding no

然后重启SSHD服务。

systemctl restart sshd

步骤四:用客户端测试。

sftp alice@192.168.1.100

登录成功后,你看到的根目录就是/data/sftp/alice,用户无法切换到/目录去浏览系统其他文件。这就完成了“受限SFTP环境搭建”。

4.4 客户端工具排查与“没有SFTP按钮”的常见原因

有朋友问“Tabby使用SSH连接到服务器后,怎么没有SFTP按钮”,这类问题其实很常见。Tabby、VS Code Remote SSH、FinalShell这类终端工具,通常默认只是建立SSH会话,SFTP面板属于可选功能。你需要在设置里找到SFTP/文件传输相关的开关,手动启用;或者直接新建连接时选择SFTP协议,而不是SSH。

更值得先做的一步是,在命令行里直接执行sftp命令验证:如果服务器的SFTP子系统能正常连接,那就是客户端配置的问题;如果连sftp命令都报错,那问题多半出在服务端的sshd_config配置。比如Subsystem sftp internal-sftp这一行被误删或写错格式,SFTP服务就会无法工作。

还有一类情况是SSH服务端配置了ForceCommand internal-sftp但限制范围有误,导致普通用户SFTP时直接被拒。最常见的表现就是前面提到的ChrootDirectory权限问题,用户所属目录不是root或权限超过755,连接就被拒绝。这时候查看/var/log/secure日志通常能看到类似“Bad ownership or modes for chroot directory”的报错,照着纠正目录权限即可。

5. 常见问题与排查技巧实录

5.1 连接不通与端口连不上的排查顺序

文件传不上去,第一反应不该是怀疑命令写错了,而是先确认网络层通不通。排查顺序我通常是这样的:

先用ping确认主机在线,再用telnet或nc确认端口是否开放。

ping 192.168.1.100 telnet 192.168.1.100 22 nc -vz 192.168.1.100 22

如果端口不通,就看服务端sshd是否启动、监听在哪个端口,以及防火墙有没有放行。

systemctl status sshd ss -tlnp | grep 22 firewall-cmd --list-all

如果是云服务器,还要检查安全组的入站规则。我曾经排查过一整天才发现是云控制台安全组里根本没放行22端口以外的自定义SSH端口,跟服务器内部防火墙完全无关。

5.2 SCP传输卡顿或速度过慢的深度原因与对策

SCP传文件速度慢,未必就是带宽不够。常见原因有两个:一个是网络MTU设置太大,导致大包被分片或丢弃重传;另一个是SSH连接阶段进行反向DNS解析超时。

MTU问题最直观的现象是小的文件传输正常,一旦传大文件速度骤降甚至卡死。可以尝试在SSH配置里把MTU降低:

scp -o "IPQoS=cs1" -o "ServerAliveInterval=30" /data/bigfile.tar.gz root@192.168.1.100:/data/

更彻底的方法是在服务端的/etc/ssh/sshd_config里加上UseDNS no,把连接阶段的反向解析关掉。这个参数默认是yes的时候,sshd会尝试把客户端的IP解析成主机名,DNS超时可能导致连接或传输卡顿。改成no之后效果立竿见影。

echo "UseDNS no" >> /etc/ssh/sshd_config systemctl restart sshd

另外,如果你确认网络本身没问题,就是纯粹嫌SCP慢,可以换用rsync加压缩和并行参数。Rsync本身就采用增量传输,传输效率通常明显优于SCP全量拷贝。

5.3 “收到了太大的SFTP包”报错如何处理

有一次我遇到了一个特殊的报错“Received message too big”,或者你在日志里看到“sftp packet too large”这类提示。这个问题的本质是SFTP协议对包大小有限制,而某次传输中数据包超过了上限。常见诱因有几种:客户端和服务端的SFTP实现不兼容、网络中间设备(防火墙/负载均衡)改动了报文、MTU不一致导致重组异常。

排查思路先从最简单的做起:换一个客户端试试。如果你用的是某个GUI工具,换回命令行sftp直接传输,往往就能排除客户端实现差异。如果命令行也报错,再检查链路MTU,尝试在SSH配置里加:

sftp -o "IPQoS=cs1" -o "ServerAliveCountMax=2" alice@192.168.1.100

如果还不行,就要考虑是否是代理或中间设备的报文重组干扰,必要时把MTU调小一些。这个属于比较冷门的报错,多数情况下并非服务器配置错误,而是网络链路干扰或客户端差异导致的兼容性问题。

5.4 传输中断、断点续传与文件完整性

SCP本身不具备断点续传能力,传输中断后残留的残缺文件非常具有迷惑性:它的大小跟源文件不一样,下次再传输时SCP不会自动跳过或续传,只会直接覆盖。所以在使用SCP传大文件时,我建议传输完成手动检查一下大小。

ls -lh /data/app.tar.gz

真正需要断点续传的场景,建议一开始就用rsync --partial,它能自动保留中断进度并在下一次继续。如果不小心用scp传了一半断了,最简单的方法是把残留文件删掉重来,避免一个不完整的文件被当成完整文件使用,这个坑在业务数据迁移时尤其危险。

另外要提醒一点:SFTP断网后,已完成的文件不会丢失,但正在传输的那个文件会残留。重新登录后,用resume命令可能因客户端实现差异而不可用,最简单的办法是删除残缺文件后重新get。这也是我对“SFTP适合轻量操作、Rsync适合重量级同步”理解加深的来源。

5.5 权限与认证问题速查

权限问题是文件传输失败的重灾区,很多看似莫名其妙的现象最终都指向权限。我整理了一张速查表,方便大家按图索骥。

现象可能原因处理方式
Permission denied (publickey)SSH密钥不匹配或权限错误检查私钥权限是否为600,公钥是否添加到目标机authorized_keys
Permission denied (password)密码错误或服务端禁用了密码登录确认密码,或在sshd_config中允许PasswordAuthentication yes
Permission denied (publickey,password)用户shell被禁用(/sbin/nologin)确认为SFTP用户时强制internal-sftp,或调整shell
Bad ownership or modes for chroot directoryChrootDirectory属主不是root或权限超755chown root:root /data/sftp && chmod 755 /data/sftp
目录无法写入目标目录缺少属主写权限确认用户对目标目录有w权限,SELinux状态也值得查看
连接超时防火墙、安全组、sshd未启动逐层排查16: ping、端口、防火墙、安全组

还有两个隐藏较深的原因:SELinux和文件系统挂载选项。CentOS上如果SELinux处于Enforcing状态,有时候普通的目录权限看起来没问题,但SELinux策略拦截了sshd的写入行为。临时排查可以用getenforce查看,但长期使用还是要配置正确的SELinux布尔值,比如setsebool -P httpd_can_network_connect 1这类,具体根据业务场景选择。

最后再分享一个我在实际使用中的体会:日常小文件传输,图快就直接scp;反复要同步的目录,一律rsync加--partial;需要给别人开分目录权限,就搭个受限SFTP。如果哪天发现文件传不顺畅,先查网络、端口和权限,这三块覆盖了九成以上的故障。文件传输这件事,工具越用越熟,坑踩得多了,后面自然就顺了。

返回列表