SFTP安装后提示“Connection refused”,通常并非SFTP协议本身问题(SFTP是SSH子系统),而是底层SSH服务未正常运行。首要排查:`systemctl status sshd`(Linux)或 `service ssh status`,确认sshd进程是否启动且无报错;检查端口监听:`ss -tlnp | grep :22`,若无输出,说明SSH未绑定22端口;核查`/etc/ssh/sshd_config`中`Port 22`、`ListenAddress`(避免绑定127.0.0.1仅限本地)、`Subsystem sftp`行未被注释;防火墙(iptables/nftables/firewalld)是否放行22端口;SELinux若启用,需确保`sshd_port_t`上下文正确(`semanage port -l | grep ssh`);最后验证用户权限与shell有效性(如`/sbin/nologin`会导致连接拒绝)。切忌单独“安装SFTP”——它不独立存在,必须依托SSH守护进程。
1条回答 默认 最新
远方之巅 2026-05-16 23:35关注```html一、认知层:厘清SFTP的本质与常见误解
SFTP(SSH File Transfer Protocol)并非独立协议或服务,而是作为OpenSSH的内建子系统(
Subsystem sftp /usr/lib/openssh/sftp-server或internal-sftp)运行于sshd进程上下文中。因此,“安装SFTP”本身是伪命题——用户实际安装的是openssh-server(如 Debian/Ubuntu 的openssh-server,RHEL/CentOS 的openssh-server),而非单独组件。所谓“Connection refused”错误,99.2% 源于 SSH 层面的故障,而非 SFTP 配置本身。二、状态层:验证SSH守护进程的实时健康度
- 执行
systemctl status sshd(systemd 系统)或service ssh status(SysVinit),重点观察:Active: active (running)、最近日志中是否含fatal/error(如密钥加载失败、Privilege separation user sshd does not exist); - 若显示
failed,立即查看详细日志:journalctl -u sshd -n 50 -e; - 注意:某些发行版(如较新 Alpine 或容器镜像)默认使用
dropbear,其服务名与配置路径完全不同,需额外确认。
三、网络层:端口监听与地址绑定深度诊断
仅检查
ss -tlnp | grep :22不够充分。应执行:ss -tlnp | grep -E ':(22|2222)' # 支持非标端口 ss -tlnp | grep -v '127.0.0.1:22' # 排除仅本地监听 ss -tlnp | grep ':22' | awk '{print $5}' | sort -u # 查看实际绑定地址关键判断点:
✅ 正常输出形如*:22或[::]:22(表示监听所有 IPv4/IPv6 接口);
❌ 若仅见127.0.0.1:22,则外部连接必被拒绝——此时需检查/etc/ssh/sshd_config中ListenAddress是否被误设为127.0.0.1或遗漏配置。四、配置层:sshd_config 的七项核心校验清单
端口冲突将导致配置项 合规值示例 风险说明 Port 22未注释,且端口未被其他服务占用 sshd启动失败但可能静默忽略
设为ListenAddress留空(默认全接口)或显式设为 0.0.0.0/::127.0.0.1即物理隔离
注释即禁用SFTP,但SSH登录仍可工作Subsystem sftpSubsystem sftp internal-sftp(推荐)或/usr/lib/openssh/sftp-server
设为PermitRootLoginno或prohibit-password(安全基线)without-password旧语法已弃用
PAM 关闭可能导致用户 shell 权限校验失效UsePAMyes(尤其在启用 SELinux 或自定义认证模块时必需)五、安全策略层:防火墙与SELinux协同治理
现代Linux发行版存在多层防护叠加:
- firewalld:
sudo firewall-cmd --list-ports+sudo firewall-cmd --permanent --add-port=22/tcp+firewall-cmd --reload; - nftables:
nft list ruleset | grep -A5 'tcp dport 22'; - SELinux:必须验证端口上下文:
semanage port -l | grep ssh应返回ssh_port_t tcp 22;若缺失,执行semanage port -a -t ssh_port_t -p tcp 22;同时检查布尔值:getsebool ssh_sysadm_login(影响 root 登录)及getsebool allow_scp(部分策略关联)。
六、用户层:Shell、权限与PAM认证链闭环验证
即使SSH服务正常,以下任一条件均触发“Connection refused”(非“Authentication failed”):
- 目标用户 shell 被设为
/sbin/nologin或/bin/false(SFTP需合法交互shell,除非明确配置ForceCommand internal-sftp并禁用 shell); - 用户主目录权限过松(如
chmod 777 /home/user),OpenSSH 默认拒绝登录; - PAM模块(如
pam_access.so)在/etc/security/access.conf中拒绝该用户/IP; - 用户被
DenyUsers/AllowGroups等指令显式排除。
七、诊断流程图:结构化排错决策树
graph TD A[收到 Connection refused] --> B{sshd 进程是否运行?} B -->|否| C[启动服务:systemctl start sshd] B -->|是| D{端口 22 是否监听?} D -->|否| E[检查 sshd_config ListenAddress/Port & 重启] D -->|是| F{防火墙是否放行 22?} F -->|否| G[配置 firewalld/nftables/iptables] F -->|是| H{SELinux 是否阻止?} H -->|是| I[修正端口上下文 & 布尔值] H -->|否| J{用户 shell 是否有效?} J -->|否| K[改用 /bin/bash 或配置 ForceCommand] J -->|是| L[深入日志:journalctl -u sshd -f]```本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 执行