ARTICLE DETAIL

资讯详情

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

CentOS7搭建SFTP全攻略:从配置到Tabby面板与报错排查

CentOS7搭建SFTP全攻略:从配置到Tabby面板与报错排查 1. SFTP到底是什么为什么你的Tabby找不到SFTP按钮先直接把结论扔给各位SFTP全称是SSH File Transfer Protocol它不是FTP的安全版而是SSH协议自带的一个文件传输子系统。换句话说只要你服务器上开着SSH服务默认22端口你就已经拥有了一个可用的SFTP服务根本不需要额外安装什么“FTP服务端”。所以每次有人问我“如何在CentOS上搭建SFTP”我第一句话都是先确认sshd在跑这才是SFTP的地基。那为什么很多朋友会遇到一个很尴尬的场景用Tabby或者Xshell连上服务器之后左等右等就是看不到SFTP文件面板甚至找不到所谓的“SFTP按钮”这里先讲清楚原理后面我会单独开一节来排查。其实原因是SFTP不是一个独立运行的守护进程它寄生在SSH服务里。SSH连接成功建立之后客户端会主动向服务端请求SFTP子系统服务端配置了对应的Subsystem后两边才会进入文件传输模式。如果你的SSH连接没有正常建立或者客户端压根没发起SFTP子系统的请求界面上自然就不会出现那个文件管理入口。再掰开讲SFTP能做的事很实在远程上传、下载文件删除、改名、建目录查看服务器目录结构断点续传甚至通过它的FXP协议在两台服务器之间直接传文件不过日常用得少。相比老牌的FTP协议SFTP最大的优势是全程走SSH加密通道用户名口令不会被明文截获文件内容和命令也不会裸奔在网络上。之前我帮朋友排查一个FTP被扫号的问题就是因为FTP的21端口口令是明文传输被抓包之后账号密码全暴露了。换成SFTP之后同样的网络环境抓包看到的全是加密密文等于给文件传输上了一道保险。从使用人群来看这篇内容适合三类人刚买云服务器想传文件的新手公司里需要给同事开一个受限上传目录的运维以及那些已经能用SSH连上服务器但搞不定SFTP文件面板的开发者。阅读之前你只需要一个基础认知SSH和SFTP是“同一个服务”的两副面孔你把SSH配好了SFTP自然就通了一半。接下来我以CentOS 7为例从安装、配置、客户端连接到报错排查全程带跑一遍。2. 环境准备与基础认知CentOS 7上先做好这三件事2.1 确认OpenSSH组件在位CentOS 7系统默认自带OpenSSH但不同的最小化安装版本可能缺了sftp-server这个组件。我建议登录服务器后先跑一条命令确认rpm -qa | grep openssh正常情况下应该能看到openssh-server、openssh-clients、openssh这几个包。如果输出为空说明系统装的是精简版执行安装yum install -y openssh-server openssh-clients安装完成后检查sshd是否在运行systemctl status sshd如果没有启动直接用systemctl start sshd拉起来并顺手设置开机自启systemctl enable sshd很多所谓“SFTP连接失败”的问题查到最后就是sshd没启动或者防火墙挡了22端口。2.2 搞清楚SFTP的配置文件在哪里SFTP本身没有独立的配置文件它的全部配置都在sshd的主配置文件里/etc/ssh/sshd_config在这个文件里有两类关键配置。第一类是Subsystem定义决定SFTP子系统由谁来处理Subsystem sftp internal-sftp这里的internal-sftp是OpenSSH内置的SFTP实现相比外部sftp-server进程它更轻量、和权限控制配合得更好。我们配置用户目录限制时基本都会指向它。第二类是Match配置块按用户或用户组精确控制SFTP行为。比如限制某个组的用户只能SFTP、不能SSH登录、只能在自家目录里活动都靠这块配置。2.3 网络和防火墙的坑提前排掉CentOS 7默认防火墙是firewalld有同事经常遇到“明明sshd已经跑起来客户端就是连不上”检查顺序一般是先ping服务器IP通不通再telnet IP 22看端口通不通最后才想到防火墙。直接放行22端口firewall-cmd --permanent --add-servicessh firewall-cmd --reload如果你的服务器用的是云厂商的安全组还要去控制台确认22端口入方向是否放行。这一步我栽过跟头本地防火墙全通了云安全组没放行白折腾一小时。另外SELinux大多数情况下不影响SSH连接但如果你改了非标准端口或者做了特殊目录映射遇到奇怪问题可以临时排查一下getenforce这条命令用来查看SELinux当前状态如果是Enforcing且报错和文件访问有关可以先临时设为Permissive做对照测试但确认是SELinux问题后别图省事建议用chcon或semanage正确打标签。环境这块理清楚后下面进入正题怎么在CentOS 7上搭一个能用的SFTP服务。3. 在CentOS 7上搭建SFTP的完整实操用户隔离与权限配置3.1 先想清楚你的隔离需求搭建SFTP之前先问自己一个问题登录用户到底能不能SSH上服务器如果用户只是需要传文件不应该让他能执行shell命令那就要做用户隔离。我见过不少团队直接把root或者普通账号的SFTP权限开放给业务方结果业务方顺手就把服务器文件改坏了。正确的做法是给这些人开一个“监狱目录”让他们只能看到并操作自己负责的那个文件夹其它目录一律禁止访问。下面我以一个实际场景来演示给一个叫transfer的组创建专用于SFTP的账号这个组里的用户只能通过SFTP访问自己的/home/sftp目录不能SSH登录不能跳转到其它目录。3.2 创建用户组和用户首先创建用户组groupadd sftpusers然后创建用户指定它的家目录为/home/sftpshell设成nologin避免它SSH登录useradd -g sftpusers -d /home/sftp -s /sbin/nologin sftpuser设置密码passwd sftpuser注意这里有个容易被忽略的细节用户登录后会默认进入家目录但家目录本身不能作为SFTP的chroot根目录的属主否则会出现“用户能连上但只能看不能传文件”的权限问题。等一下配置目录归属时我会专门说明。3.3 编辑sshd_config完成核心配置备份原文件已经是基本操作了cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak然后用vim打开找到文件里的Subsystem行确认或改写成Subsystem sftp internal-sftp接着在文件末尾追加以下内容Match Group sftpusers ChrootDirectory /home/sftp ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no逐行解释一下Match Group sftpusers只对sftpusers组里的用户生效不影响其他普通用户和root。ChrootDirectory /home/sftp把用户的根目录锁定在/home/sftp用户只能看到这个目录里的内容。ForceCommand internal-sftp强制用户只能使用SFTP子系统即使它尝试SSH登录也会被重定向到SFTP不会获得shell。AllowTcpForwarding no和X11Forwarding no关闭端口转发和图形转发降低风险。有人会问为什么不用PasswordAuthentication的开关去禁止登录因为ForceCommand internal-sftp已经能把所有SSH会话转成SFTP会话从机制上掐断了shell访问的可能更干净。不过要提醒一点如果你在sshd_config其他位置配置过“Match User root”或者全局的PermitRootLogin相关项记得让Match Group块不要和它打架否则配置可能不生效。3.4 设置目录权限这一步最容易被忽略OpenSSH的ChrootDirectory对目录权限有严格检查。根目录/home/sftp的属主必须是root权限不能超过755。也就是说mkdir -p /home/sftp chown root:root /home/sftp chmod 755 /home/sftp然后在根目录下面创建一个真正的用户工作目录要求属主变为sftpusermkdir -p /home/sftp/upload chown sftpuser:sftpusers /home/sftp/upload chmod 700 /home/sftp/upload这个套路说白了就是ChrootDirectory指定一个用户不可写的根把门锁好用户实际读写操作都在根目录下属于自己的子目录里进行。如果你不做这步会出现经典问题“SFTP能登录成功但上传任何文件都报Permission denied”。我在帮一个同事排这个错时他卡了一下午其实就差一个chown。3.5 检查配置并重启sshd改完配置文件不能直接重启先做语法检查sshd -t没有输出就是配置没问题。再测试重启systemctl restart sshd这里多提一句如果不是用systemd管理的系统也可以用service sshd restart。重启后建议别急着关当前SSH会话新开一个窗口测试确认配置无误再继续防止配置有问题把自己锁在外面。3.6 验证是否能正常登录和上传在本地执行sftp sftpuser服务器IP如果看到sftp提示符说明SFTP服务正常。接着用put上传一个测试文件put /etc/hosts ./test.txt传完cd到upload目录看下文件是不是在顺便用pwd确认当前路径被限制在/home/sftp内。如果用户尝试SSH登录会因为/sbin/nologin和ForceCommand的双重限制被拒之门外这正是我们想要的效果。4. 三种客户端玩法从命令行到Tabby面板排查4.1 命令行SFTP基础操作服务器配置好之后最直接的使用方式就是命令行。以CentOS本机为例sftp usernameserver_ip登录成功后本地操作在前面加llocal远端操作直接输。基础命令我整理成了下表方便对照操作远端命令本地命令说明查看目录lslls查看当前目录下的文件切换目录cd xxxlcd /local/path切换远端 / 本地目录上传文件put localfile无上传到当前远端目录下载文件get remotefile无下载到当前本地目录新建目录mkdir dirnamelmkdir dirname远程 / 本地新建目录删除文件rm filenamelrm删除远端文件退出bye 或 exit无退出SFTP会话日常传一个小文件命令行足够用了。但如果你要批量同步几百个文件命令行敲起来效率太低这时就该上GUI客户端。4.2 WinSCP和FileZilla等GUI客户端连接Windows用户我比较习惯推荐WinSCP界面简单支持断点续传而且能记住会话。连接时选择SFTP协议端口填22主机名、用户名、密码一填登录就能看到文件列表。FileZilla一样支持SFTP只是它的站点协议里要手动选“SFTP - SSH File Transfer Protocol”有的版本默认是FTP容易选错。我自己的经验是SFTP客户端连不上三成是服务器配置问题七成是客户端协议、端口、加密方式没选对。特别是FileZilla第一次连接时如果弹出“未知主机密钥”的提示这不是错误是正常的首次认证确认点击接受即可。4.3 专题排查Tabby连接SSH后为什么没有SFTP按钮这个问题的出现频率真的非常高热词榜上挂了很久。先说结论Tabby本身没有独立的“SFTP按钮”设计它的文件传输功能是依托于SSH会话自动加载的。当你新建一个会话并选择SSH连接类型成功连接后左侧的“文件”面板应该会出现这个面板就是在用SFTP协议操作远程文件。如果你看不到这个面板按下面顺序排查第一种情况你新建会话时选的连接协议不是SSH。Tabby支持很多连接方式如果你误选了Raw Socket或者其他自定义协议它根本不会走SSH自然不会加载SFTP面板。解决方法是重新新建SSH会话host填服务器IPport填22。第二种情况SSH连接虽然弹出了终端但实际认证没有走完面板加载被阻塞。注意观察终端窗口顶部有没有成功提示比如登录shell是否正常如果卡在密码框或者认证失败SFTP面板不会出来。第三种情况面板被折叠了。Tabby左侧有一列图标栏其中一个看起来像文件夹的图标就是文件面板入口如果你没注意到它可能以为“没有SFTP按钮”。点击那个文件夹图标文件树会自动加载。第四种情况Tabby版本过旧。老版本对SFTP子系统的请求逻辑有bug建议直接升级到新版本GitHub Release页下载安装包即可升级不影响已保存的会话配置。第五种情况比较冷门你的服务器sshd配置里把Subsystem sftp注释掉了导致Tabby虽然识别出SFTP子系统但服务端不支持面板加载失败。检查一下服务器上的/etc/ssh/sshd_config里Subsystem sftp那行是否被注释如果有注释符号#去掉后重启sshd。如果你确认以上几种情况都不存在还有一个排查方向等连接稳定后再点一次文件图标有些网络环境下子系统的协商延迟比较大。我在内网连一台配置较差的服务器时遇到过首次加载文件列表要等十几秒看起来像“没按钮”实际上只是慢。5. “收到了太大的SFTP包”这个报错到底是谁的锅5.1 错误本质客户端收到的包超出了预期尺寸我在多个技术社区看到用户反馈用FileZilla或WinSCP连接服务器时日志区出现类似“错误: 收到过大的SFTP包”的提示原文是Received too large SFTP packet。很多人第一反应以为服务器配置有问题但我可以负责任地说这个问题八成都不在服务端而在于客户端在“非SFTP协议端口”上请求了SFTP服务或者通信数据被第三方干扰了。SFTP协议是基于SSH的SSH在传输数据前会先做协议协商协商成功后才会进入SFTP子系统的数据交换阶段。如果客户端在某个端口上想建立SFTP连接但对方返回的内容完全不是SSH协议应有的格式——比如返回了一段HTTP页面、一段明文banner甚至一个telnet登录提示——客户端把这些数据当成SFTP包来解析长度字段就会严重超出预期于是抛出“too large SFTP packet”。5.2 最常见的几种触发场景和解决办法第一种端口填错。有人把FTP的21端口当成SFTP端口来连或 mistakenly 把SSH端口写成了22以外的数字。这时服务器返回的是其他协议的数据客户端自然会报“包太大”。解决方法是检查站点协议是否为SFTP端口是否为22或你自定义的SSH端口。第二种服务器返回了非SSH banner。有些服务为了安全或爱的提示在SSH握手前先输出几行字符串比如“Welcome to xxx server”或者“此服务器仅限授权用户访问”。这些明文内容混进SFTP协商数据里被客户端误读成长度字段后就会爆出“包过大”。如果你确定端口无误可以在服务端的/etc/ssh/sshd_config里检查有没有Banner配置把Banner那行注释掉再重启sshd。这里注意Banner文件路径如果配置在/etc/issue.net等内容会被发送到未认证的连接上对客户端解析影响很大。第三种中间设备干扰。公司网络出口有防火墙、上网行为管理设备或者IDS可能对22端口的报文做内容检查甚至人为插入响应包。这种情况下服务端和客户端之间的数据被篡改客户端解析到异常包就会报错。排查方法是换个网络环境比如用手机热点连一下试试如果热点下一切正常那就说明是本地网络设备的问题。第四种客户端自身版本bug。我以前碰到过一个情况FileZilla老版本对OpenSSH新版返回的扩展信息解析不完善也会出现这类误报。升级FileZilla或者换WinSCP基本能避开。5.3 用抓包思维快速定位如果你手头有服务器登录权限最快的方式是在服务器上临时开一个原始TCP端口测试。比如用nc监听一个端口nc -l 2222然后客户端拿SFTP协议去连2222端口看是否报同样的错。如果报错说明客户端确实是拿SFTP去连了一个非SSH端口问题在产品使用方式上如果同样的报错转移到其它端口就要检查服务端配置和网络路径。另一个实用技巧是使用OpenSSH自带的调试输出在命令行连接时加上-v参数sftp -v sftpuser服务器IP它会打印出整个SSH握手和子系统协商过程的日志你能清楚看到哪一步数据异常。比如日志里有“Received disconnect”或者“Bad packet length”提示那就基本定位到包大小解析异常了。这个报错的坑看起来很深但拆开看就一句话SFTP客户端极其依赖完整的SSH协议协商任何格式不符的数据都会被当成“超大包”拒绝。6. 常见问题排查与实用技巧速查6.1 汇总一张问题速查表把这一年多帮人排查SFTP的典型问题整理成表遇到问题先对着查现象可能原因解决方案SFTP连接被拒绝sshd未启动或22端口未监听systemctl start sshd检查监听状态连接超时安全组/防火墙未放行22端口检查云控制台安全组和firewalld规则登录成功但上传报Permission denied目录归属错误Chroot根目录属主不是root根目录chown root:root用户目录chown给对应用户用户能SSH登录不能SFTP登录sshd_config里Match块配置未生效确认Match Group名称和用户组一致用户上传后看不到别的目录chroot生效这是正常现象如需调整目录结构重新规划Received too large SFTP packet端口/协议不匹配或数据被干扰检查协议类型、端口排除Banner和中间设备Tabby没有SFTP面板会话类型不对、面板折叠、版本过旧选择SSH协议点击左侧文件图标升级Tabby修改sshd_config后sshd起不来配置语法有误用sshd -t先检查再重启6.2 开放目录权限的两种模式实际使用中如果你只是临时开个共享文件夹不做严格隔离可以跳过Match Group配置直接用普通账号登录SFTP。这种情况下用户能访问它的家目录也可以读到全局可读的文件自由度大但风险也大。如果你既要权限控制又要省心第二种做法是用ACL或细分多个Group来实现不同用户不同目录。比如groupadd uploadgroup useradd -g uploadgroup -d /home/sftp/upload -s /sbin/nologin uploader再结合上面的Match Group配置就能做到用户uploader只能操作/home/sftp/upload。只要用户组目录规划清晰这个模式后期扩展新用户非常轻松。6.3 免密登录配置批量传文件不折腾如果你每天都要从本地自动向服务器传文件SSH口令会让你抓狂。配置密钥登录可以一劳永逸。在本地生成密钥ssh-keygen -t rsa -b 4096一路回车即可生成的公钥在~/.ssh/id_rsa.pub私钥在~/.ssh/id_rsa。然后把公钥追加到服务器目标用户的authorized_keysssh-copy-id sftpuser服务器IP之后再用SFTP连接就不需要输入密码了。密钥登录需要服务器sshd_config里有以下配置PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys这个配置默认就是开启的一般不用改。6.4 用SFTP做自动化备份的一个建议既然SFTP本质是SSH子系统那么你在cron里可以直接用sftp批量指令完成备份上传。比如写一个脚本内容如下#!/bin/bash sftp -b batch.txt sftpuser服务器IP其中batch.txt里的内容是sftp命令put /backup/app_$(date %F).tar.gz /backup/ bye这样就能实现定时把本地备份推到远端。配合之前配置的密钥登录整个备份流程可以全自动不需要任何人工干预。我自己的服务器就是每天凌晨把数据库备份打包后SFTP到独立的存储机器上跑了两年没出过大问题。6.5 最后分享一个冷门小技巧SFTP其实支持rename操作你可以在一个会话里直接给远程文件改名。比如rename oldfile.txt newfile.txt这个命令在GUI客户端要右键找“重命名”在命令行里直接输就行。另外当你发现某个文件传不动、怀疑是网络问题时可以用reput命令尝试断点续传。OpenSSH新版本对reput的支持已经比较稳定实测大文件断传后重连它可以从断点处继续传不需要从头再来。我在实际项目里最深的体会是SFTP这种技术谈不上新但它在服务器运维里的地位从来没有被动摇过。只要SSH存在SFTP就永远是一个不用额外装服务、不用开额外端口、配置一次可以稳定跑很多年的文件传输方案。希望这篇从头到尾的实操记录能帮你少踩几个坑特别是Tabby没有文件面板和“收到的太大的SFTP包”这两个老问题按文章里的思路排查基本都能解决。
返回列表