资讯动态

Ubuntu下SFTP文件传输全攻略:服务端配置、客户端使用与安全实践

发布时间:2026/10/20 10:40:21 来源:尧图企业网站定制
说实话我在日常运维里用得最多的文件传输方式还真不是FTP也不是各种网盘而是SFTP。这东西基于SSH协议一条命令就能把文件从本地扔到远端服务器或者从服务器拉回本地全程加密不需要额外开端口、不用单独装服务端软件安全性也有底。今天这篇就围绕Ubuntu系统里的SFTP文件传输从服务端怎么配、客户端怎么用到权限、密钥、脚本化再到我实际踩过的坑一次性完整梳理一遍。无论你是刚开始接触Linux的新手还是被权限问题折腾过几次的运维这篇都能给你一些可以直接用的东西。1. 为什么是SFTP方案选型的底层逻辑1.1 SFTP到底是什么SFTP全称是SSH File Transfer Protocol注意它和FTPFile Transfer Protocol虽然名字很像但完全是两码事。FTP是基于TCP 21端口、明文传输的古老协议而SFTP是SSH协议的一部分默认走22端口传输过程中所有数据都是加密的。换句话说只要你的服务器开着SSH服务就天然具备SFTP能力不需要安装任何额外的FTP服务器软件。从协议栈的角度看SFTP并不是独立跑在某个端口上的协议而是在SSH连接建立之后通过SSH加密通道里单独开一条会话来做文件操作。所以它的安全模型、认证体系、密钥管理全都复用SSH已有的那一套。这也带来一个非常实际的好处只要服务器能SSH登录SFTP传输大概率就是通的完全不用像传统FTP那样处理主动模式、被动模式、额外端口段开放这类破事。这个特性在日常工作中非常实用。我见过太多人一提到文件传输就想着装一个FTP服务结果折腾半天配置还要担心密码在网络上明文传来传去——抓包工具一看账号密码全裸奔太吓人了。其实换成SFTP这些问题从源头就消失了。1.2 和常见传输方式比一比为了说清楚SFTP的位置我把常用的几种远程文件传输方式放在一起做了个对比方式端口加密特点适合场景FTP21/20否老牌协议兼容性好内网明文传输公共下载站FTPS21/990是FTP加TLS配置复杂对FTP有依赖且需要加密的遗留系统SFTP22是基于SSH配置简单天然加密Linux服务器之间、本地上传下载SCP22是基于SSH只支持文件复制一次性复制单个或整目录文件rsync22走SSH是增量同步断点续传目录镜像、增量备份从这个表能看出来SFTP在加密和易用性之间取得了很好的平衡。SCP虽然也基于SSH但它不支持像SFTP那样交互式浏览远端目录、删除文件、修改权限也不支持断点续传rsync更偏向同步场景而不是我想看看远端目录里有什么文件再决定下载哪个这种交互操作。SFTP最接近传统FTP的使用体验又保住了SSH的安全底座这决定了它在日常运维里不可替代的位置。1.3 适合谁用、解决什么问题SFTP适用的场景非常广把本地的压缩包上传到服务器部署、把服务器上的日志文件拉下来排查问题、在两台Linux机器之间交换文件、给某个项目目录做远程备份这些都能用SFTP稳稳拿下。它对开发者、运维、甚至只用过图形界面的人都友好因为命令行操作足够简单图形客户端也是一抓一大把。我自己用得最多的是三个场景一是服务器维护时上传配置文件、下载日志二是给旧服务器做目录归档备份三是配合密钥登录实现脚本化定时拉取数据。后面这些内容里我会把每个场景对应的操作和配置都拆开讲照着做基本就能复现。2. 服务端准备Ubuntu上把SFTP服务拉起来2.1 安装SSH服务并确认状态绝大多数Ubuntu Server默认不会安装openssh-server所以第一步是装包。在Ubuntu上用apt一条命令就能搞定sudo apt update sudo apt install openssh-server -y装完以后确认服务是否在运行sudo systemctl status ssh正常情况下能看到active (running)。要注意的是Ubuntu里这个服务单元名叫ssh不是sshd有些教程写成sshd会查不到服务。如果没跑起来执行start即可sudo systemctl start ssh sudo systemctl enable sshenable这步非常关键不执行的话服务器重启后SSH服务不会自动启动你的SFTP就彻底失联了。查看监听端口用ss -tlnp | grep sshd看到22端口处于LISTEN状态说明服务已经就绪。顺便说一句ss命令比老的netstat更轻量Ubuntu 18.04以后默认就有不用额外装net-tools。2.2 用户与目录规划SFTP服务的用户管理我推荐的做法是不要直接拿root账号传文件而是在系统里创建专用账号。这里有两种常见方案一种是给个人账号直接开SSH权限正常登录后用SFTP在自己的家目录里操作另一种是创建一个只能SFTP、不能SSH登录的受限账号专门给某个项目或某个目录用。第一种最简单用adduser建一个用户并设置密码即可它默认在/home/用户名下拥有读写权限。第二种更适合给只需要传文件的同事或者外部协作者使用。这类账号我一般这样建sudo adduser sftpuser按提示设置密码、填写用户信息可以直接回车跳过账号就建好了。接下来要把这个账号圈在指定目录里这就涉及目录规划的问题。我习惯把这类用户的根目录统一放在某个专门的数据目录下比如/data/sftp-home而不是散落在/home里。这样隔离、备份、管理都方便。目录结构大概是/data/sftp-home └── incoming # 用户可写入的业务目录根目录给root业务子目录给用户这个分层后面配置权限时至关重要。2.3 限制用户只能SFTP不能SSH登录如果希望这个账号只能SFTP传文件不能登录shell那就需要修改/etc/ssh/sshd_config。我在配置里最常加的是这一段Match Group sftpusers ChrootDirectory /data/sftp-home ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no先说明一下思路。Match Group表示后面的配置只对sftpusers这个用户组生效所以需要先把用户加进组sudo groupadd sftpusers sudo usermod -aG sftpusers sftpuserChrootDirectory的作用是把用户的活动范围限制在指定目录里用户登录后看到的根目录就是这个目录没法跑到系统其它地方去安全隔离效果很好。ForceCommand internal-sftp强制该用户执行SFTP子系统即使尝试SSH登录也会被弹回SFTP环境。AllowTcpForwarding和X11Forwarding关闭是为了禁掉端口转发和图形转发减少攻击面。这样配置之后sftpuser只能在这一个目录里上传、下载、删除文件其它任何系统路径都碰不到对多人协作场景特别实用。2.4 配置项逐条解读这里有几个配置项必须专门讲清楚不然很容易踩坑。Subsystem sftp /usr/lib/openssh/sftp-server这是系统默认的SFTP子系统定义。有些教程会让你改成internal-sftp意思是让sshd内置的SFTP实现来干活少一次外部程序调用也更方便配合ChrootDirectory使用。在上面Match组里已经写了ForceCommand internal-sftp所以一般不用动全局Subsystem行。ChrootDirectory目录的属主必须是root而且这个目录不能被用户写否则SSH服务会直接拒绝连接。这是很多人配置完成后反复报错的头号原因。目录权限建议755属主必须是root:root。如果要在隔离目录里让用户能上传文件ChrootDirectory本身由root拥有且不可写那就在它下面建一个子目录比如/data/sftp-home/incoming把这个子目录的属主改成sftpuser权限设成755或750。用户进来以后只能在incoming里写看到的界面就是一个干净的隔离空间。改完配置一定要先检查语法sudo sshd -t没有输出就代表配置文件没有语法错误然后重载服务sudo systemctl reload ssh重载不影响已建立的连接生产环境里也可以放心用。到这里服务端就已经能提供服务了可以先用本机测试一下sftp sftpuser127.0.0.1能进到sftp提示符就说明服务端OK。3. 客户端实操命令行与图形化两手抓3.1 命令行sftp基础操作Ubuntu自带sftp命令行工具用法和FTP命令很像会一套就能顺手操作另一套。最常见的连接方式sftp userremote_host连接成功后进入sftp交互界面。下面这些命令我几乎每天都要敲整理成一份速查清单ls列出远端当前目录的文件ll列出带详情相当于ls -lcd切换远端目录pwd显示远端当前目录lls列出本地当前目录文件lcd切换本地目录lpwd显示本地当前目录put localfile上传本地文件到远端当前目录get remotefile下载远端文件到本地当前目录mput *.log批量上传匹配通配符的文件mget *.tar.gz批量下载匹配通配符的文件mkdir / rmdir在远端创建/删除目录rm删除远端文件chmod / chown修改远端文件的权限和属主在权限允许范围内!command在本地执行shell命令比如!lsbye / exit退出一个很实用的技巧是在连接命令里直接指定远端路径减少进界面后的目录切换次数。比如sftp userremote_host:/var/log连接后直接进入远端的/var/log目录马上就能ll看日志文件。指定端口连接加-l参数sftp -P 2222 userremote_host注意sftp命令行用的是大写P指定端口和ssh的小写-p不一样。我刚用的时候在这上面栽过跟头连写错两次才意识到。3.2 批量传输与脚本化如果每天都要定时从服务器拉数据手工敲sftp太浪费精力。sftp支持批处理模式把要执行的命令写进一个文本文件然后用-b参数跑sftp -b batch.txt userremote_hostbatch.txt内容示例lcd /home/user/backup cd /data/export mget *.csv bye这样就能一次性把远端/data/export下所有csv文件下载到本地backup目录。写脚本时注意一个细节批处理模式下如果某条命令失败默认会继续往下执行只是返回码可能非零。如果想出错就停在命令前加--mget *.csv表示这条命令出错时终止批处理。还有个更稳妥的做法是用rsync走SSH因为rsync支持增量传输和断点续传适合大文件或频繁同步的场景。比如rsync -avz --partial userremote_host:/data/export/ /home/user/backup/--partial参数很关键它允许rsync保留传输中断的临时文件下次运行可以直接续传。如果传输中途网络断了重新跑一次就能接着来不用从头传。对于需要无人值守的脚本化传输配合SSH密钥登录是最佳方案具体配置我放在第4节单独展开。这里要额外提醒一句千万别用expect之类的工具自动填充密码密码会出现在进程参数或脚本文件里等于把钥匙挂在门上。3.3 图形化客户端的使用不习惯命令行的人Ubuntu桌面环境下可以直接在文件管理器里访问SFTP。打开自带的Files文件管理器在地址栏输入sftp://userremote_host/data/export它会提示输入密码如果配置了密钥则直接进入然后就能像本地文件夹一样浏览和拖拽文件。这个方式非常适合偶尔传几个文件、不想记命令的场景。第三方图形客户端也有很多选择比如FileZilla这类跨平台工具左边本地目录、右边远端目录上传下载直接拖还能排队传多个文件。这类工具本质上也是SFTP协议所以只要服务端配置好了客户端几乎不用额外设置——选择SFTP协议、填上主机名、用户名、密码或密钥即可。我个人的习惯是日常维护和脚本任务用命令行偶尔需要快速浏览远端目录结构、或者要把服务器上的文件拖给同事看就用文件管理器或图形客户端。两条路都顺手也互为备份。命令行出问题时还有图形界面兜底反之亦然。4. 密钥认证与免密传输4.1 生成密钥对每次传文件都要输密码一方面麻烦另一方面脚本里不好处理密码明文存密码更是安全大忌。SSH密钥认证就是为了解决这个问题而存在的。第一步在本地生成密钥对ssh-keygen -t ed25519 -C sftp-backup-key一路回车就行默认生成在~/.ssh/目录下。id_ed25519是私钥绝对不要外传id_ed25519.pub是公钥可以放到服务器上。选ed25519是因为它比传统RSA更短更快安全性也足够。如果远端是比较老的系统只支持RSA就改用ssh-keygen -t rsa -b 4096 -C sftp-backup-key生成时如果设置了passphrase口令短语每次使用私钥都要输入一次。要是担心私钥泄露可以设一个要是想要完全免密自动化就不设。折中方案是用ssh-agent缓存口令这个后面讲。4.2 下发公钥与权限要求把公钥安装到服务器上有标准做法。如果服务器有ssh-copy-id工具直接ssh-copy-id userremote_host它会提示输入一次密码然后把本地公钥追加到远端~/.ssh/authorized_keys里顺便把权限设置好。没有ssh-copy-id就手动来cat ~/.ssh/id_ed25519.pub | ssh userremote_host mkdir -p ~/.ssh chmod 700 ~/.ssh cat ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys这条命令看起来长其实做了四件事在远端创建.ssh目录、设置700权限、把公钥追加到authorized_keys、把authorized_keys设为600。权限搞错的话OpenSSH出于安全考虑会直接忽略这个密钥文件导致认证失败。这是新手最容易忽略的细节。密钥相关的权限要求可以整理成一张表照着核对就行项目路径权限属主远端家目录~755用户远端.ssh目录~/.ssh700用户远端密钥文件~/.ssh/authorized_keys600用户本地私钥~/.ssh/id_ed25519600本机用户4.3 实测效果与注意事项配好密钥后再执行sftp连接就不会提示输入密码sftp userremote_host直接进入sftp提示符非常顺滑。配合cron定时任务就能实现无人值守的文件拉取。需要注意几个点私钥文件权限必须是600或更严格否则ssh会提示bad permissions并拒绝使用。如果本地有多个密钥连接时用-i指定sftp -i ~/.ssh/another_key userremote_host如果生成密钥时设置了passphrase又不想每次输入可以用ssh-agent缓存eval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519之后当前会话内再连sftp就不会反复要口令了。定期检查服务器上的authorized_keys删除不认识的条目。我习惯每季度过一遍把离职人员或废弃设备的密钥清理掉。这个习惯看着琐碎关键时刻能避免安全事件。5. 常见问题与排查技巧实录5.1 连不上服务器的排查路径Connection refused或者超时是出现频率最高的问题。我的排查顺序是固定的从本机到服务器逐层来。第一步确认端口能访问telnet remote_host 22如果提示Connection refused说明服务器上SSH服务没起来或端口不对如果是超时大概率是防火墙挡了。到服务器上检查服务状态sudo systemctl status ssh sudo ss -tlnp | grep :22第二步检查防火墙。Ubuntu上常用ufw确认22端口已放行sudo ufw status sudo ufw allow 22/tcp如果改过端口比如改成2222那就要allow 2222/tcp客户端连接时带-P 2222。第三步用详细日志模式定位认证阶段的问题sftp -v userremote_host-v会输出连接过程中的所有调试信息能看到底是卡在DNS解析、TCP连接、密钥交换还是密码认证哪一步。这个方法在排查服务器感觉能通但就是连不上的诡异问题时尤其好用。有一次我花了一个多小时排查一个客户端的连接问题最后用-v发现是本地DNS解析把目标主机名解析到了内网IP机器在另一个网段自然连不上。5.2 权限报错的根因分析配置了ChrootDirectory后最常见的报错是连接一建立就断开或者提示Received message too long。原因基本就是我前面说的ChrootDirectory目录必须是root所有且不能是用户可写。目录权限不满足要求时sshd会直接拒绝或断开连接。查看系统日志能确认sudo journalctl -u ssh -n 50或者直接看/var/log/auth.log里的sshd记录。看到类似fatal: bad ownership or modes for chroot directory这样的信息就是权限问题无疑。解决办法sudo chown root:root /data/sftp-home sudo chmod 755 /data/sftp-home还有一类权限问题是用户连上了但上传文件时报Permission denied。这时候要检查目标子目录的属主和权限确认用户有没有写权限ls -ld /data/sftp-home/incoming如果是root所有且只读用chown把目录交给sftpuser即可。记住一个核心原则隔离目录chroot根给root业务目录用户可写的实际空间给用户。5.3 传输中断与速度慢的处理思路大文件传一半断网是最让人抓狂的。SFTP本身不支持断点续传这是协议层面的限制所以遇到大文件我一般直接改用rsync走SSH链路加上--partial和--append-verify参数中断后重新执行就能从断点继续。实际测试中一个大文件截断到一半之后重新同步rsync只传输剩余部分效率提升非常明显。速度慢的话先排除网络本身的因素再用压缩和连接复用改善。在SFTP里没有现成的压缩参数但改用rsync时可以加-z参数启用压缩传输对文本类文件效果明显如果是已经压缩过的包就别加-z了反而增加CPU开销。另外在本地~/.ssh/config里开启连接复用能省掉反复握手的时间Host remote_host ControlMaster auto ControlPath ~/.ssh/controlmaster-%r%h:%p ControlPersist 600这样同一时间多开几个sftp会话后续的连接会复用已有连接省去重新握手和认证的时间实测对频繁小文件操作提升特别明显。5.4 文件名编码与特殊字符问题中文文件名在SFTP传输中经常出现乱码尤其是从Windows客户端连Linux服务器时。根因是两端默认字符编码不一致Windows那边常常是GBK/GB2312Linux默认UTF-8。解决思路是让两端统一用UTF-8或者让客户端做编码转换。实测下来FileZilla这类图形客户端在设置里调整字符编码选项能解决大部分乱码问题。如果文件名里带空格或特殊字符命令行下操作时记得用引号包起来get report 2024 final.zip通配符批量操作时也要小心mget按远端shell的通配符规则展开先ll确认一下匹配范围再执行避免误传一堆预期之外的文件。我吃过一次亏mget *.tar把当天的备份包和上个月的备份包全拉下来了本地磁盘差点撑爆。5.5 换端口后的SFTP访问如果不希望用默认22端口暴露SSH服务可以把端口改到高位比如2222。方法是修改/etc/ssh/sshd_configPort 2222然后重载服务。改完之后客户端连接就要带-P参数sftp -P 2222 userremote_host图形客户端在站点管理器里也要填对应端口。改端口确实能降低一部分扫描攻击的噪音但真正的安全靠的是密钥认证和防火墙白名单不要误以为改了端口就万事大吉。另外改端口前务必确认防火墙规则和selinux如果启用的话都允许新端口否则改完把自己锁在外面那就只能去机房或者带外管理口救人了。6. 写在最后几个趁手的习惯做运维这行文件传输是绕不开的日常操作。SFTP好用的地方在于它依托SSH生态服务端、客户端、密钥体系、权限模型全部是现成的你不需要为了传文件专门引入一套新工具、新端口、新协议。我这些年用下来的体会是小文件随手sftp大文件和同步任务交给rsync密钥认证一定要配上ChrootDirectory能隔离就隔离。把这几点做好服务器的文件传输这条链路基本就能安稳跑很久。最后再分享一个小技巧如果经常在服务器和本地之间来回传文件可以在~/.ssh/config里给服务器配一个别名把复杂的连接信息固化起来。比如在本地~/.ssh/config里写Host backup-server HostName 192.168.1.100 User sftpuser Port 22 IdentityFile ~/.ssh/id_ed25519配置之后直接sftp backup-server就能连上不用每次写一长串参数。多台服务器、多个密钥的场景下这个文件能把连接管理得明明白白。我是在第三次因为记错端口而连不上之后才养成的习惯早该这么做。

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

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

免费获取报价 →
↑