
1. 先把需求想清楚SSH Server 在 Ubuntu 上到底扮演什么角色很多人第一次接触 Ubuntu 装机流程卡住的地方不是装系统本身而是装完之后怎么进去用。尤其是把 Ubuntu 装在虚拟机、老笔记本、闲置小主机或者开发板上的时候你不可能每次都搬个显示器键盘过去敲命令。这时候 SSH Server 就是那把钥匙——它让一台 Ubuntu 从必须坐在它面前才能操作变成在同一网络里任何一台电脑都能远程操作。我自己第一次装 Ubuntu 是给一台旧台式机装的 22.04当时为了改一行配置来回插拔键鼠折腾了半小时后来才意识到装个 SSH Server 就能省掉全部物理接触。这篇内容就是把这套流程从能不能装上到装完能不能安全长期用完整讲一遍包括在线安装、离线安装、配置加固、客户端连接、故障排查。适合三类人刚装完 Ubuntu 想远程管理的新手、在虚拟机里做开发的程序员、以及需要给多台机器做批量运维的运维人员。基础要求很低会打开终端、会敲命令就行。1.1 一句话说透 SSH 的价值SSH 的全称是 Secure Shell直译就是安全的壳。这个比喻其实很贴切它给你的远程操作套了一层加密的壳你在里面敲的每一个字符、传的每一个文件在网络里都是密文。早期大家用 Telnet 做远程登录账号密码是明文的同一个局域网里随便一个抓包工具就能看到你在输什么现在没人敢这么干了。SSH 的工作方式可以类比成打电话找人办事客户端先拨号建立 TCP 连接双方核对暗号密钥交换和主机指纹验证确认对面确实是你要找的那台机器然后才开通话加密通道建立之后你说的话只有对面能听懂。整个过程分两层加密一层用来协商出会话密钥一层用来加密实际数据。Ubuntu 上我们常说的装 SSH Server本质就是安装 OpenSSH 的服务端组件openssh-server它提供sshd这个后台进程监听 TCP 22 端口默认负责接受连接、验证身份、分配 shell。对应地客户端组件叫openssh-client提供ssh、scp、sftp、ssh-keygen这些命令。桌面版 Ubuntu 默认只装了客户端服务端要自己装——这也是很多人ssh localhost失败的原因。1.2 和 VNC、RDP、图形远控工具怎么选新手常有疑问我要远程控制 Ubuntu为什么不装 VNC 或者直接远程桌面这取决于你要干什么。方案传输内容带宽占用适用场景主要短板SSH纯文本终端 文件通道极低几百 Kbps 足够命令行运维、部署、编译、改配置不直接支持图形界面操作VNC完整桌面画面高视分辨率而定需要看图形界面、跑 GUI 程序画面传输有延迟配置繁琐xrdp完整桌面画面RDP 协议中高Windows 客户端直连 Ubuntu 桌面会话管理容易出问题图形化远控工具完整桌面画面中高临时协助、跨网段依赖第三方中转我的实际经验是日常 90% 的操作——装软件、改配置、跑脚本、看日志、传文件——SSH 全都能干而且快得多。只有在必须操作图形界面比如调某个 IDE 的窗口布局时才需要 VNC 之类的方案。很多老手的做法是 SSH 常驻开VNC 按需开用完就关。顺便提一句如果你手头是 Windows 机器想被远程连也有对应的服务端方案比如 Bitvise SSH Server 这类 Windows 平台的 SSH 服务端工具思路和 Ubuntu 上是一样的装服务端、开端口、配认证。但 Linux 这套是原生的配置文件和权限模型更干净出问题也更好查。1.3 动手前必须确定的三件事在敲第一条命令之前先把这三件事定下来能省掉后面 80% 的返工第一这台 Ubuntu 的 IP 会不会变。如果是 DHCP 自动获取重启一次 IP 就换了你昨天记的地址今天就失效。解决办法是在路由器里做 IP 绑定或者在 Ubuntu 里配置静态 IP。第二从哪台机器连过来。同一局域网内直连还是需要跨网段这决定了要不要额外做端口映射和访问控制。第三用密码登录还是密钥登录。密码登录配起来快但暴力破解风险高密钥登录前期麻烦一点后期省心得多。我的建议是先密码登录验证通路跑通之后立刻切密钥然后关掉密码登录。注意不要在还没验证密钥能登录成功的时候就把PasswordAuthentication改成 no否则你会把自己锁在门外只能去物理机上救场。2. 安装前的环境盘点与网络规划环境盘点这一步经常被跳过但它是后面所有排查工作的基准。你得知道自己这台机器的系统版本、架构、网络配置、以及有没有别的服务占了 22 端口。这些信息在出问题的时候就是对照表——你有基准才能判断哪里变了。2.1 三行命令摸清系统底细打开终端依次执行lsb_release -a uname -m ip -4 addr show第一条看发行版和版本号输出里的Description会告诉你是不是 Ubuntu 22.04 LTS 或者 24.04 LTS。这一步很重要因为不同版本的配置方式有差异——比如 Ubuntu 22.10 之后sshd开始支持/etc/ssh/sshd_config.d/这个目录做配置分片24.04 里默认就带了Include指令你直接在sshd_config末尾追加参数可能会被后面的 include 覆盖。第二条看 CPU 架构。输出x86_64是常见的 64 位 Intel/AMDaarch64是 ARM 64 位树莓派、部分开发板、Apple 芯片虚拟机常见。架构决定了你要下载哪个版本的安装包离线安装时这个特别关键装错了会报 wrong architecture。第三条看 IPv4 地址。输出里通常会看到两个接口lo本地回环127.0.0.1和ens33/eth0/enp3s0之类的物理或虚拟网卡。你要关注的是后者比如192.168.1.105/24前面那个 IP 就是别人连你时用的地址。如果没有拿到 IP先解决网络问题再谈 SSH。再补两条常用命令ip route | grep default ss -tlnp | grep :22第一条看默认网关判断网络通不通第二条看 22 端口有没有被占用输出为空说明没人监听可以放心装。2.2 虚拟机网络模式NAT、桥接、仅主机怎么选如果你是在 VMware、VirtualBox 这类虚拟机里跑 Ubuntu网络模式直接决定了外面能不能连进来。这是新手最容易踩的坑我见过太多人装好了 SSH 却怎么都连不上最后发现是 NAT 模式的问题。网络模式虚拟机 IP 来源宿主机能否直连局域网其他机器能否直连适用场景NAT虚拟网卡分配的私有网段一般不能直接连不能只上网、不需要被外部访问桥接路由器 DHCP 分配与宿主机同网段能能需要被远程访问推荐仅主机虚拟网卡内网段能不能隔离测试环境结论很直接如果你希望从别的电脑 SSH 连进虚拟机用桥接模式。桥接之后虚拟机会像一台独立设备一样出现在你的局域网里路由器给它分一个和宿主机同网段的 IP192.168.1.x这种。这时候你在宿主机或者其他电脑上ping一下就能通。NAT 模式下也不是完全没办法可以通过虚拟机的端口转发功能把宿主机的某个端口映射到虚拟机的 22 端口。但这种做法多一层转发排查问题时链路变长除非有特殊需求否则我不推荐。切换模式的步骤以 VMware 为例关闭虚拟机 → 右键虚拟机 → 设置 → 网络适配器 → 选择桥接模式 → 勾选复制物理网络连接状态 → 开机。开机后用ip -4 addr show确认拿到的是同网段地址。2.3 IP、端口与账号的规划表在动手之前我习惯先在纸上或者备忘录里写一张规划表。这不是形式主义而是当你同时管理好几台机器的时候没有这张表你一定会记混。项目建议值说明主机 IP静态绑定如 192.168.1.105避免重启后地址漂移SSH 端口22 或自定义如 2222自定义端口能过滤掉大量扫描登录账号普通用户如 devuser不用 root 直接登录认证方式密码过渡→ 公钥长期验证通路后立即切换允许来源固定网段如 192.168.1.0/24通过防火墙限制端口要不要改这取决于你的环境暴露程度。如果只在家庭局域网里用22 端口完全没问题改端口反而增加记忆负担。如果这台机器有公网可达性那改成高位端口能减少大量自动化扫描带来的噪声——注意这只是减少噪声不是安全手段真正的安全靠密钥和访问控制。关于sshd的端口计算有个小细节常用端口范围是 0-1023需要 root 绑定和 1024-65535普通用户可绑定。sshd以 root 身份启动所以理论上哪个端口都能用但建议选 1024 以上、避开已知服务端口比如 2222、2022、20022 这类冲突概率低。3. Ubuntu 安装 OpenSSH Server 的完整过程准备工作做完进入正题。安装方式分两种能联网就用 apt干净利落不能联网就离线包安装稍微绕一点但也不难。我两种都实际跑过很多次下面把完整过程写清楚。3.1 联网环境apt 一条链路装完最标准的流程是三条命令sudo apt update sudo apt install -y openssh-server sudo systemctl status ssh第一条刷新软件包索引。这一步不能省很多人直接装然后报无法定位软件包就是因为本地索引里没有这个包的信息。如果刷新时卡住或者报错说明源有问题先解决网络和软件源。第二条安装openssh-server。安装过程中 apt 会自动处理依赖openssh-client、openssh-sftp-server、libwrap0这些会被一并装上。-y是自动确认脚本化部署时很有用手动操作时去掉它会让你看到将要安装和升级哪些包更稳妥。第三条看服务状态。正常输出里会看到Active: active (running)以及一行Loaded: loaded (/lib/systemd/system/ssh.service; enabled; ...)。注意 Ubuntu 上的服务名是ssh而不是sshd虽然它实际上是ssh.service对sshd.service的别名。你敲systemctl status sshd大概率也能用但status ssh是标准写法。安装完成后Ubuntu 通常会自动启动服务并设置开机自启。但如果你用的是某些精简镜像或者容器环境可能不会自动启动需要手动来一下sudo systemctl enable --now ssh--now这个参数是启用并立即启动的简写比分开写enable和start少敲一次命令我基本都用这个。3.2 离线环境dpkg 装包的顺序与依赖处理内网机器、开发板、隔离环境里没有外网就得离线装。这里有个关键认知离线装 SSH Server 不是只装一个 .deb 文件那么简单依赖要按顺序来。获取离线包的思路是找一台同架构、同版本、能联网的 Ubuntu把包下载下来apt-get download openssh-server openssh-client openssh-sftp-server \ libwrap0 libssl3 libc6 libpam0g libselinux1 libsystemd0或者更省事的办法是用apt-get install --download-only加上--reinstall把依赖一起拉到缓存目录sudo apt-get install --download-only --reinstall openssh-server ls /var/cache/apt/archives/*.deb把这一堆 .deb 拷到目标机器上然后按依赖顺序安装。最稳的方式是用一条命令让 dpkg 自己处理sudo dpkg -i *.deb sudo apt-get install -f第一遍dpkg -i大概率会报依赖错误这是正常的第二遍apt-get install -f会尝试修复依赖关系。如果完全没网-f也可能失败这时候需要手动按依赖顺序装一般顺序是基础库libc6、libssl3、libpam0g→ 通用库libwrap0、libsystemd0→ openssh-client → openssh-sftp-server → openssh-server。注意离线装机最容易翻车的地方是版本不匹配。源机器的 Ubuntu 版本和目标机必须一致架构也必须一致。x86_64的包装到aarch64上会直接报架构错误而且这个错误信息有时候不太直观。装完之后同样用sudo systemctl status ssh确认。离线安装不会自动做 systemd 单元文件的 enable记得手动执行sudo systemctl enable --now ssh。3.3 服务启停、开机自启与状态确认日常运维里这几个命令会反复用到我把它们整理在一起sudo systemctl start ssh # 启动 sudo systemctl stop ssh # 停止 sudo systemctl restart ssh # 重启改完配置常用 sudo systemctl reload ssh # 重载配置更温和 sudo systemctl status ssh # 看状态 sudo systemctl is-enabled ssh # 看是否开机自启restart和reload的区别值得说清楚。restart是彻底杀掉进程再起一个新的会断开所有现有连接reload是给主进程发信号让它重新读配置不断开现有连接但不是所有配置项都支持热重载——比如修改监听端口这种reload可能不生效必须用restart。我的习惯是改完配置先用sshd -t做语法检查通过了再决定用reload还是restart。sudo sshd -t这条命令会返回配置文件的语法错误如果什么都不输出就说明语法没问题。这一步极其重要因为如果配置有语法错误重启之后sshd会直接起不来而你现在可能正通过 SSH 连在上面——一旦断开就连不回去了。养成先测试再重启的习惯能避免大量尴尬。关于开机自启Ubuntu 的 systemd 里enable会创建一个符号链接让服务在系统启动时自动拉起。你装完openssh-server之后它一般是自动 enable 的但容器、云镜像、定制系统里可能不是。用systemctl is-enabled ssh检查输出enabled才对。3.4 三层验证进程、端口、本机自连服务启动不代表能连上。我习惯做三层验证层层递进出问题时能快速定位是哪一层坏了。第一层进程在不在。ps -ef | grep sshd正常应该看到至少一行/usr/sbin/sshd -D或者带-D参数的进程。如果什么都没有说明服务没起来去看sudo journalctl -u ssh -n 50的日志。第二层端口听没听。ss -tlnp | grep :22正常输出类似LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:((sshd,pid1234,fd3))。这里有两个关键信息0.0.0.0:22表示监听所有网卡如果是127.0.0.1:22那只有本机能连外部连不上——这是很多人遇到的隐藏坑原因通常是配置文件里写了ListenAddress 127.0.0.1。第三层本机能不能自连。ssh localhost如果这一层就失败问题一定在本机服务没起、端口不对、配置有问题跟网络无关。如果本机能连但外部连不上问题就在网络层防火墙、网段、虚拟机模式。这个二分法能省很多时间。三层都过了才轮到从客户端连。这个顺序千万别颠倒否则你会同时面对是不是网络问题和是不是服务问题两个怀疑排查效率直接减半。4. sshd_config 配置拆解与安全加固装完能用只是第一步配置得当才能长期用。/etc/ssh/sshd_config是 SSH 的核心配置文件几百行注释占了一多半。真正需要动的其实就那么十几个参数但每个都值得搞清楚为什么。这一章我把配置结构、关键参数、密钥登录、防火墙这几块拆开讲。4.1 配置文件的分层结构与生效顺序Ubuntu 22.10 之后SSH 配置变成了分层结构。打开/etc/ssh/sshd_config你会在顶部或底部看到这样一行Include /etc/ssh/sshd_config.d/*.conf这意味着除了主配置文件系统还会读取/etc/ssh/sshd_config.d/目录下的所有.conf文件。生效顺序是关键SSH 的规则是第一次出现的值生效后面重复的会被忽略。这带来一个非常隐蔽的坑。比如 Ubuntu 24.04 的云镜像会在/etc/ssh/sshd_config.d/50-cloud-init.conf里写一行PasswordAuthentication yes而你在主配置文件末尾改成了 no这时候因为 include 在前面实际生效的是 yes——你以为改完了其实没改。我的做法是两条第一修改之前先看看 include 目录里有什么。ls -l /etc/ssh/sshd_config.d/ grep -rn PasswordAuthentication /etc/ssh/第二要覆盖的话直接在那个.conf文件里改或者新建一个编号更大的配置文件比如99-custom.conf但要注意编号大的不一定优先因为按文件名字典序读取第一次出现生效意味着编号小的反而先被读。所以最省心的做法是直接改已有的那个 conf 文件不要新增。改完必须验证实际生效值sudo sshd -T | grep -i passwordauthsshd -T会输出所有最终生效的配置项这是判断我改的到底生效没有的唯一可靠方法。别靠猜。4.2 高频参数逐条拆解下面这张表是我在实际运维中最常调整的参数每一条都标注了建议值和理由。参数默认值Ubuntu建议值作用与理由Port2222 或自定义监听端口改后记得同步防火墙ListenAddress注释掉即全部保持注释或指定网卡 IP限定监听范围注释表示全监听PermitRootLoginprohibit-passwordno禁止 root 直接登录用普通用户 sudoPasswordAuthenticationyesno密钥配好后关闭密码登录杜绝暴力破解PubkeyAuthenticationyesyes启用公钥认证PermitEmptyPasswordsnono禁止空密码千万别改成 yesMaxAuthTries63单次连接最多尝试 3 次认证LoginGraceTime12030认证超时从 2 分钟缩到 30 秒ClientAliveInterval0300每 300 秒发一次保活探测ClientAliveCountMax33连续 3 次无响应则断开AllowUsers注释掉你实际的用户名白名单机制只有列出的用户能登录X11Forwardingyes按需需要转发图形程序就留 yes纯服务器可关UseDNSnono保持关闭开启会拖慢登录重点解释两个参数。ClientAliveInterval配合ClientAliveCountMax解决的是SSH 连接莫名其妙断开的问题。很多路由器、防火墙会清理长时间空闲的连接导致你挂着 SSH 去泡杯茶回来发现断了。设置成 300 秒发一次保活包连接就能一直挂着编译大项目的时候特别有用。LoginGraceTime缩短到 30 秒是因为在认证阶段尚未建立的连接会占用资源攻击者可以用大量半开连接消耗你的服务端。缩短这个时间窗口能减少被拖垮的可能。30 秒对正常用户完全够用你输密码不会超过 30 秒。配置修改的完整流程我固定成这么几步# 1. 备份永远先备份 sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date %F) # 2. 编辑用你顺手的编辑器 sudo vim /etc/ssh/sshd_config # 3. 语法检查关键一步 sudo sshd -t # 4. 查看最终生效值 sudo sshd -T | grep -E passwordauth|permitroot|port|maxauth # 5. 重载或重启 sudo systemctl reload ssh注意第 3 步报错就绝对不要执行第 5 步。带着语法错误重启sshd服务会起不来你的 SSH 连接会在退出后彻底断开只能去物理机或者虚拟机控制台救。4.3 密钥登录从生成到落地的完整流程密钥登录是 SSH 安全性的核心。原理很简单你生成一对密钥公钥放在服务器上私钥留在自己电脑上。登录时服务器用公钥出一道只有对应私钥能解的题你解出来就通过验证。私钥从不离开你的机器所以就算服务器的authorized_keys文件泄露别人也拿不到私钥无法登录。第一步在客户端生成密钥对。ssh-keygen -t ed25519 -C my-laptop-2024 -f ~/.ssh/id_ed25519_ubuntu参数解释-t ed25519指定算法这是目前推荐的算法密钥短、速度快、安全性好-C是注释写清楚这个密钥是谁的、在哪台机器上生成的将来管理多个密钥时能一眼分清-f指定保存路径不指定的话默认是~/.ssh/id_ed25519已经有的话会问你要不要覆盖。如果你的环境不支持 ed25519极老的系统可以用 RSAssh-keygen -t rsa -b 4096 -C my-laptop-2024-b 4096是密钥长度。RSA 至少用 4096 位2048 位现在已经不太够看了。执行过程中会问你要不要设置 passphrase口令。我的建议是设置一个这样即使私钥文件被盗没有口令也用不了。配合ssh-agent可以把口令缓存起来不用每次都输。第二步把公钥传到服务器。ssh-copy-id -i ~/.ssh/id_ed25519_ubuntu.pub devuser192.168.1.105ssh-copy-id会自动登录一次用密码然后把公钥追加到服务器的~/.ssh/authorized_keys里并设置好权限。这个命令在 Ubuntu、macOS、Windows 的 PowerShell 里都有很方便。如果没这个命令手动来也行cat ~/.ssh/id_ed25519_ubuntu.pub | ssh devuser192.168.1.105 \ mkdir -p ~/.ssh chmod 700 ~/.ssh cat ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys第三步验证密钥登录。ssh -i ~/.ssh/id_ed25519_ubuntu devuser192.168.1.105如果不提示输密码就进去了说明成功。第四步关闭密码登录。服务器上编辑配置把PasswordAuthentication改成nosshd -t检查然后reload。顺序不能反一定要先验证密钥能进再关密码。权限问题是这块最常见的坑。OpenSSH 对权限非常敏感如果以下任一条件不满足密钥认证会被静默拒绝日志里才看得到原因~/.ssh目录权限必须是 700~/.ssh/authorized_keys权限必须是 600用户家目录不能被 group 或其他用户写不能是 777、775修复命令chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 755 ~ # 或者 750只要不给 group/other 写权限我见过最离谱的一次是家目录被设成了 777密钥怎么都认证不过日志里翻半天才看到Authentication refused: bad ownership or modes for directory /home/devuser。4.4 防火墙放行与暴力破解防护服务监听对了、认证配好了还要过防火墙这一关。Ubuntu 上常见的是 ufw也可能有 iptables 规则或者云服务商的安全组。检查 ufw 状态sudo ufw status verbose如果显示Status: inactive说明防火墙没开不用管。如果active就要确保 22 端口或你自定义的端口放行sudo ufw allow 22/tcp # 或者更语义化的写法 sudo ufw allow OpenSSH改过端口的记得换成实际端口比如sudo ufw allow 2222/tcp。这里有个经典翻车场景改完端口忘了开防火墙重启 SSH 之后连不上又因为连不上没法改回去只能物理机救场。所以改端口的正确顺序是先放行新端口再改配置最后删旧端口规则。另外提醒一句如果你在云服务器上除了系统防火墙还有一层云平台的安全组规则两个都要放行。很多人在云主机上折腾半天最后发现是控制台里的安全组没开。接下来是暴力破解防护。即使关了密码登录日志里还是会看到大量扫描尝试装个 fail2ban 能让日志干净不少sudo apt install -y fail2ban sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local然后编辑/etc/fail2ban/jail.local在[sshd]段里配置[sshd] enabled true port ssh filter sshd logpath /var/log/auth.log maxretry 5 findtime 600 bantime 3600意思是10 分钟内失败 5 次封禁 1 小时。改完重启sudo systemctl restart fail2ban sudo fail2ban-client status sshd最后一条命令能看到当前被封禁的 IP 列表。我自己的机器上跑了一个月列表里躺了几百个 IP效果很直观。5. 客户端连上去Windows、macOS、移动端实操服务端配好了接下来是从客户端连进去。不同系统的操作略有差异但底层都是同一个 SSH 协议。5.1 命令行连接与首次指纹确认最基础的连接命令ssh devuser192.168.1.105如果改过端口ssh -p 2222 devuser192.168.1.105第一次连接会看到类似这样的提示The authenticity of host 192.168.1.105 (192.168.1.105) cant be established. ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxx. Are you sure you want to continue connecting (yes/no/[fingerprint])?这是在问你要不要信任这台主机。SSH 用主机密钥来识别服务器防止中间人替换。你输入yes之后这个指纹会被记到~/.ssh/known_hosts里下次连接不再询问。输入yes而不是y写全三个字母这是 SSH 的固执设计。如果某台服务器的指纹变了比如重装了系统、重新生成了主机密钥会报一个大大的警告WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!这时候不要盲目删 known_hosts。先确认这次变更是你自己造成的比如刚重装系统确认之后再删ssh-keygen -R 192.168.1.105Windows 10/11 自带了 OpenSSH 客户端直接在 PowerShell 或 CMD 里就能用ssh命令不需要额外安装。macOS 和 Linux 更是原生自带。所以客户端这块其实门槛很低。5.2 图形化 SFTP 客户端的配置要点命令行传文件用scp和sftp很好用但如果你需要浏览目录、拖拽传输图形化客户端更直观。这类工具比如 WinSCP、FileZilla、MobaXterm 这类配置的核心就四个字段字段填写内容常见错误协议SFTP不是 FTP选成 FTP 会连不上 22 端口主机Ubuntu 的 IP填了 127.0.0.1端口22 或自定义改过端口没同步认证私钥文件 / 密码私钥格式不对PuTTY 需要 ppk最容易踩的坑是私钥格式。OpenSSH 生成的密钥是 PEM 格式而某些 Windows 客户端需要 PuTTY 格式的.ppk。转换方法是用 PuTTYgen 工具加载私钥后另存为 ppk。反过来也有工具能从 ppk 转回 OpenSSH 格式。另一个常见问题是 SFTP 子系统没装。现在的 Ubuntu 上openssh-server会依赖openssh-sftp-server一般不会缺。如果报 subsystem request failed检查配置里有没有Subsystem sftp /usr/lib/openssh/sftp-server如果你只需要传几个文件命令行其实更快# 上传本地文件到服务器 scp -P 2222 ./local.txt devuser192.168.1.105:/home/devuser/ # 从服务器下载 scp -P 2222 devuser192.168.1.105:/home/devuser/remote.txt ./ # 传整个目录 scp -r -P 2222 ./myproject devuser192.168.1.105:/home/devuser/注意scp的端口参数是大写-P而ssh是小写-p这个不一致经常让人敲错。5.3 配置文件与免密登录的省事写法如果你要管好几台机器每次都敲完整命令很烦。~/.ssh/config就是干这个的Host devbox HostName 192.168.1.105 User devuser Port 2222 IdentityFile ~/.ssh/id_ed25519_ubuntu ServerAliveInterval 60 Host testvm HostName 192.168.1.120 User ubuntu Port 22 IdentityFile ~/.ssh/id_ed25519_test配好之后连接只需要ssh devbox传文件也一样scp ./file.txt devbox:/home/devuser/这个配置文件支持通配符、跳板机ProxyJump、本地端口转发等高级用法是 SSH 里性价比最高的一个功能。ServerAliveInterval 60表示每 60 秒发一次保活效果等同于服务端的ClientAliveInterval但作用在客户端侧两边都配上更保险。免密登录也就是密钥登录前面已经讲过。补充一个小技巧如果你觉得每次都要输私钥口令太麻烦用 ssh-agenteval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519_ubuntu这样口令只需要输一次在 agent 存活期间一直有效。macOS 上可以加到钥匙串里Windows 上是自动启动的 ssh-agent 服务。6. 连不上怎么办故障排查实录这一章是我攒下来的实战经验基本都是自己或者同事踩过的坑。SSH 连不上看起来症状都一样实际上原因分层必须有条理地排查否则就是瞎试。6.1 分层排查法从网络到认证我把排查分成四层从下往上依次验证。每一层确认通过再往上走不要跳。第一层网络通不通。ping 192.168.1.105不通的话问题在 IP、网段、虚拟机网络模式。检查两边是不是同网段ip -4 addr show # 在 Ubuntu 上执行看 IP 和掩码 ipconfig # Windows 客户端上看 IP如果 IP 是192.168.1.x和192.168.56.x这种明显不同段的基本就是虚拟机用了 NAT 或者仅主机模式。第二层端口能不能到。# Linux / macOS nc -zv 192.168.1.105 22 # Windows PowerShell Test-NetConnection 192.168.1.105 -Port 22这一步能区分连接被拒绝和连接超时。拒绝说明 IP 到了但端口没开服务没起或被防火墙 reject超时说明包根本没到防火墙 drop、网络不通、IP 错了。第三层服务状态。回到 Ubuntu 本机用前面 3.4 节的三层验证法检查进程、端口、本机自连。第四层认证问题。如果前三层都过了能显示密码提示或者密钥认证提示但认证失败问题就在账号、密码、密钥权限、authorized_keys上。看服务端日志sudo tail -f /var/log/auth.log这个日志会明确告诉你失败原因比如Failed password、Invalid user、Authentication refused: bad ownership。排查认证问题一定要看日志不要靠猜信息全在里面。6.2 常见报错速查表报错信息最可能原因处理办法Connection refused服务未启动 / 端口不对systemctl status ssh检查 Port 配置Connection timed out防火墙拦截 / 网络不通 / IP 错误检查 ufw、云安全组、ping 通不通Permission denied (publickey)密钥未部署 / 权限不对检查 authorized_keys 和目录权限Permission denied (password)密码错误 / 密码登录被禁确认账号密码检查 PasswordAuthenticationHost key verification failed主机指纹变化确认后ssh-keygen -R hostToo many authentication failures客户端尝试了太多密钥用-i指定密钥或在 config 里IdentitiesOnly yesConnection closed by remote host认证失败次数超限 / 服务异常看 auth.log检查 MaxAuthTrieskex_exchange_identification: Connection closed网络中间设备干扰检查是否有设备拦截或用-v看协商过程Too many authentication failures这个错误特别值得说。原因是你的~/.ssh/目录下有一堆密钥SSH 客户端会挨个尝试服务端默认MaxAuthTries是 6试到第 6 个还没成功就被踢了。解决办法是在 config 里明确指定用哪个密钥并加上IdentitiesOnly yes告诉客户端只用指定的这一个别乱试。6.3 虚拟机与双系统场景的特有坑虚拟机场景有几个专属问题都是我自己踩过的。坑一NAT 模式下外部连不进来。前面讲过解法是切桥接或者做端口转发。切桥接后必须重启虚拟机网络光点应用有时候不生效。坑二宿主机能 ping 通但 SSH 超时。这种情况通常是 VMware 的虚拟网卡配置有问题或者 Windows 防火墙拦了虚拟网卡。检查 Windows 防火墙的入站规则确保虚拟网卡所在的网络类别公用/专用没被拦。坑三Ubuntu 装好但没有 IP。桥接模式下如果路由器没分到 IP说明 DHCP 出问题。可以手动配置静态 IP用 netplansudo vim /etc/netplan/01-netcfg.yaml内容参考network: version: 2 renderer: networkd ethernets: ens33: dhcp4: no addresses: - 192.168.1.105/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: [192.168.1.1, 223.5.5.5]注意网卡名字要换成你实际的用ip a看配置完执行sudo netplan trynetplan try会在 120 秒后自动回滚如果配置导致断网你会自动恢复比直接apply安全得多。这个功能强烈推荐。坑四双系统下 Ubuntu 装完连不上网。常见原因是网卡驱动问题尤其是一些新款笔记本的无线网卡。用lspci | grep -i network看网卡型号再搜对应的驱动。有线网卡一般没问题。坑五双系统共享 Windows 的 IP 导致冲突。如果 Windows 和 Ubuntu 配了同一个静态 IP切换系统后会冲突。要么都用 DHCP要么分配不同地址。6.4 其他零碎问题速查还有些小问题不常见但很烦人一起列出来。改配置后连接断了再也连不上。大概率是配置有语法错误导致服务起不来。去虚拟机控制台或者物理机上执行sudo sshd -t看错误改回来再启动。改了端口但连不上。检查三处sshd_config里的 Port、防火墙规则、客户端-p参数。三处必须一致。登录后马上断开。检查用户的家目录是否存在、shell 是否正常。grep devuser /etc/passwd看 shell 是不是/usr/sbin/nologin或者/bin/false这两种会导致登录即退出。中文乱码。客户端和服务端的 locale 不一致导致。可以在 Ubuntu 上检查locale或者客户端设置编码为 UTF-8。一般 Ubuntu 默认就是 UTF-8问题多半出在老旧的 Windows 终端上。连接很慢要等好几秒才出密码提示。经典原因是UseDNS yes或者服务端在做反向 DNS 查询。Ubuntu 默认已经是 no如果是自己改的记得改回来。另外GSSAPIAuthentication yes在有些环境下也会造成延迟可以尝试关掉。磁盘满了导致登录失败。这个很隐蔽。根分区满了之后sshd无法写日志和临时文件会拒绝登录。用df -h检查清一清/var/log和/var/cache/apt。时间不同步导致认证问题。如果用了基于时间的认证机制两边时间差太大会出问题。装个时间同步sudo apt install -y systemd-timesyncd sudo systemctl enable --now systemd-timesyncd7. 我踩过的坑与长期维护心得前面讲的都是流程和方法这一章说点更实在的东西——那些文档里不会写、只有自己栽过跟头才会记住的经验。7.1 几条血泪经验第一条改任何 SSH 配置之前先开第二个连接。这是我用最惨痛的方式学会的。正确做法是开两个终端一个用来改配置另一个保持连接不动。如果改完配置后新连接连不上那个老连接还在可以立刻改回来。这个习惯值一个下午的救场时间。第二条sshd -t是保命命令每次都要用。它只检查语法不影响正在运行的服务。语法通过不代表逻辑正确但语法不通过一定起不来。这两道关卡分开能把风险降到最低。第三条备份配置文件带上日期。cp sshd_config sshd_config.bak.2024-06-10这种。用sshd_config.bak的话改几次之后你就忘了哪个是哪个版本了。第四条别急着关密码登录。一定要先用新开一个终端验证密钥能进去确认无误再关。我见过太多次关了密码登录结果密钥没配好的事故。第五条公钥文件名不代表用途注释才是。id_ed25519这种默认名字半年后你完全想不起来是哪台机器上的。养成用-C写注释的习惯或者干脆在文件名里带上机器标识像id_ed25519_office_pc。第六条端口修改只是降噪不是安全措施。很多人以为改个端口就安全了其实扫描器全端口扫一遍也就几秒钟的事。真正的安全来自密钥认证、访问白名单、失败封禁这几项的组合。第七条一定要在能物理接触机器的时候做安全配置。你在 SSH 里把自己锁在门外的概率远比你想象的高。所有涉及登录方式的改动尽量在虚拟机控制台或者物理机前完成改完再从远程验证。7.2 日常维护清单配置好之后不是一劳永逸我给自己定了几条定期检查的习惯跑起来也不费事。每周看一眼登录日志。sudo grep Failed password /var/log/auth.log | tail -20 sudo grep Accepted /var/log/auth.log | tail -20前者看有没有异常爆破后者确认正常登录来源。如果Accepted里出现了你不认识的 IP那就得警惕了。每月检查一次系统更新包括 openssh 的安全补丁。sudo apt update sudo apt list --upgradable | grep -i openssh sudo apt upgrade openssh-serveropenssh 的安全问题修正很频繁尤其是暴露在公网上的机器一定要及时跟。每季度审一次授权密钥和用户。cat ~/.ssh/authorized_keys sudo cat /etc/passwd | grep -v nologin把不用的公钥删掉把离职或者项目结束的账号清理掉。这是很多团队容易忽视的地方一堆历史遗留账号挂在那里全是风险点。留意磁盘空间。df -h du -sh /var/log/*日志目录是最容易涨的地方。可以配 logrotate 限制大小或者定期清理旧日志。前面说过磁盘满会导致 SSH 登录失败这是很典型的平时没事、出事很急的故障。给关键主机做配置快照。如果你在虚拟机上跑定期做个快照出问题能回滚。物理机上就定期备份/etc/ssh/整个目录出问题直接恢复。这套流程我自己用了很久从最初的装完能连就行到现在装完还要能长期可靠地连中间踩的坑基本都写在这里了。如果你只是想快速跑通1、3、5 三章足够了如果要长期跑在生产或者团队环境里4、6、7 三章值得花时间细看。SSH 这东西的特点是入门很快、细节很多用得越久越会发现配置项背后都有它的道理遇到不懂的就去读man sshd_config那个手册写得相当详细比网上很多二手的教程靠谱得多。