CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Linux 服务器入门/课时/SSH 与密钥
RawBlame
课时目录12 节

Linux 服务器入门

  1. 01Linux 是什么
  2. 02Shell 与 Bash
  3. 03文件系统与权限
  4. 04常用命令
  5. 05编辑器与配置
  6. 06进程与服务
  7. 07用户与 sudo
  8. 08包管理
  9. 09SSH 与密钥
  10. 10防火墙与端口
  11. 11部署 CodeRoadMap
  12. 12综合练习

SSH 与密钥

ssh、scp、authorized_keys、宝塔 SSH。

30 分钟

SSH 与密钥

这一课你将能做到

  1. 生成 ed25519 密钥对并部署到服务器(ssh-copy-id 或手动 authorized_keys),实现免密登录,并说清私钥/公钥各自的权限要求
  2. 用 ~/.ssh/config 给服务器起别名(ssh prod 一键登录),指定用户、端口、私钥
  3. 用 scp/rsync 向服务器传产物(JAR、前端 dist),并完成「禁用 root 密码登录」的安全加固

为什么要学

SSH 是你与生产服务器之间唯一的门。这扇门如果只有密码,等于每天在全球公网上被人试锁——云厂商日志里每天有成千上万次针对 22 端口的暴力破解。密钥登录(公钥锁、私钥钥匙)让攻击者没有钥匙永远进不来,还顺便让你免输密码、让 CI(GitHub Actions)能自动部署。

本课的产出直接决定部署课的顺畅度:ssh prod 秒连、scp backend.jar prod: 秒传——这是后端工程师每天摸的路径。

先建立图像

密钥登录的原理(非对称加密)

你本机                                服务器
┌──────────────────┐                ┌─────────────────────────┐
│ id_ed25519      │  私钥=钥匙      │ ~/.ssh/authorized_keys   │
│ (永不离开本机)   │                │ (门上贴的锁,公钥列表)      │
│                  │    握手验证      │                         │
│ id_ed25519.pub ──┼──公钥=锁──拷贝──►│ www@server 可登录          │
└──────────────────┘                └─────────────────────────┘

登录时服务器用公钥出一道「只有对应私钥能解的题」,你本机用私钥作答。私钥全程不出本机,所以没有密码在网络里飞,抓包也没用。

权限是 SSH 安全模型的一半

~/.ssh/                必须是 700
~/.ssh/id_ed25519      必须是 600   ← 宽了 ssh 直接拒绝使用:UNPROTECTED PRIVATE KEY
~/.ssh/authorized_keys 必须是 600(且属主=登录用户)

跟着做

步骤 1:本机生成密钥对

在本机终端(Windows 用 PowerShell,自带 OpenSSH;macOS/Linux 用 Terminal):

# ed25519:现代算法,密钥短、快、安全(取代 rsa 2048)
ssh-keygen -t ed25519 -C "leebf@coderoadmap"
# 三个提示都可直接回车:
#   保存路径:默认 ~/.ssh/id_ed25519
#   passphrase:可留空(本机受信环境);留空=免密一键连

ls ~/.ssh/
# id_ed25519      私钥(谁拿到谁能登你的服务器,绝不外传)
# id_ed25519.pub  公钥(贴到服务器上的锁)
cat ~/.ssh/id_ed25519.pub    # 一行内容:ssh-ed25519 AAAA... leebf@coderoadmap

老系统需要 rsa 时的兼容写法:ssh-keygen -t rsa -b 4096(云厂商老镜像、某些跳板机可能只认 rsa)。

步骤 2:把公钥装到服务器上

方式 A(推荐,一条命令):

ssh-copy-id deploy@你的服务器IP
# 输最后一次 deploy 的密码,之后就再也不用了

方式 B(手动,理解文件本质;Windows 无 ssh-copy-id 时用):

# 本机看公钥内容并复制:
cat ~/.ssh/id_ed25519.pub

# 服务器上(先用密码 ssh 登一次):
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "ssh-ed25519 AAAA...你的公钥... leebf@coderoadmap" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

验证:新开一个终端 ssh deploy@服务器IP——不再问密码即成功。

步骤 3:~/.ssh/config 别名——从长命令到两个字

本机编辑(没有就新建):vim ~/.ssh/config(Windows 在 C:\Users\你\.ssh\config):

Host prod
    HostName 你的服务器IP
    User deploy
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60        # 每 60s 发心跳防断连

Host test
    HostName 192.168.1.100
    User deploy
    Port 22
    IdentityFile ~/.ssh/id_ed25519
chmod 600 ~/.ssh/config           # config 过宽也会被拒
ssh prod                          # 等价于 ssh -i ~/.ssh/id_ed25519 deploy@IP

从今天起,所有连接、传输命令都用别名:ssh prod、scp x prod:~/——这就是效率。

步骤 4:scp 与 rsync——传文件的两种刀

# scp:简单直接,适合单文件/小目录(在【本机】执行)
scp backend.jar prod:/www/wwwroot/coderoadmap/          # 本机 → 服务器
scp prod:/var/log/nginx/error.log ./                    # 服务器 → 本机
scp -r dist prod:/tmp/dist                              # -r 传目录

# rsync:增量同步,适合目录/大文件/重复发布
rsync -avz dist/ prod:/www/wwwroot/coderoadmap/platform/
# -a 保留权限时间戳 -v 过程可见 -z 压缩传输
# 第二次执行只传差异,快得多 —— CI 部署前端产物就用它

# 排除某些文件再同步:
rsync -avz --exclude 'node_modules' --exclude '.env' dist/ prod:/www/wwwroot/coderoadmap/platform/

选择口诀:单文件 scp,目录与重复同步 rsync。

步骤 5:安全加固——关掉密码与 root 登录

密钥能登录之后,密码通道就该关了(先确认至少一个密钥会话能通,再动配置):

ssh prod                          # 确认免密可用!
# 然后 sudo vim /etc/ssh/sshd_config,确认/修改三行:
#   PasswordAuthentication no     # 禁密码登录
#   PermitRootLogin prohibit-password   # root 只许密钥(更狠:no)
#   PubkeyAuthentication yes
# Ubuntu 22.10+ 还要检查 /etc/ssh/sshd_config.d/*.conf 里有没有覆盖项(50-cloud-init.conf 常见)
sudo sshd -t                      # 语法检查(改错不重启才安全)
sudo systemctl restart ssh        # Ubuntu 服务名叫 ssh(CentOS 叫 sshd)

验证顺序是保命的关键:保持当前会话不退出 → 新开窗口 ssh prod 确认密钥能进 → 再用 ssh -o PubkeyAuthentication=no deploy@IP 验证密码确实被拒 → 一切正常再关旧会话。配错把自己锁在外面,就只能走云控制台 VNC 救援了。

步骤 6:常用的 SSH 周边命令

# 远程执行单条命令(不进交互 shell,脚本/CI 必备):
ssh prod "sudo systemctl restart coderoadmap-backend"
ssh prod "df -h && free -m"

# 远端多行(引号包裹整段):
ssh prod "cd /www/wwwroot/coderoadmap && tail -20 logs/backend.log"

# 查看/调试连接问题(-v 逐级加到 -vvv):
ssh -v prod 2>&1 | tail -20       # 卡在哪一步一目了然

# 断线重连不丢会话(可选神器):
sudo apt install -y mosh          # UDP 20100-20100+,漫游网络不冻屏

讲清楚要点

  1. 私钥=身份本体:它加密存于本机,权限 600,不进聊天窗、不进 Git、不进网盘。泄露的处置:把对应公钥从所有服务器 authorized_keys 删掉 + 换新密钥对。
  2. authorized_keys 是「门上的锁列表」:一行一把锁,按用户挂在各自家目录。追加=发钥匙,删行=收钥匙。wc -l ~/.ssh/authorized_keys 数一数你有几把锁——很多被入侵的机器就是多了陌生行。
  3. SSH 权限检查是双向的:本机私钥 600/700,服务器 .ssh 700 + authorized_keys 600 且属主必须是登录用户。ssh 对权限的容忍度为零——这是特性不是 bug(宽权限=可能被篡改)。
  4. sshd_config 生效链:改文件 → sshd -t 校验 → restart。Ubuntu 22.10+ 的 sshd_config.d/*.conf 会覆盖主文件(Include 在前),排障时两个地方都要看。
  5. scp 是「一次性搬运」,rsync 是「对齐两端」:rsync 校验大小与修改时间、只传差异、支持 --delete 做镜像、断了能续——发布产物、备份数据库目录(配合快照)都是 rsync 的主场。
  6. CI 部署的 SSH 就是本课知识的自动版:GitHub Actions 里把私钥放 Secrets,配 known_hosts(避免交互确认指纹),然后 ssh -i key deploy@host "systemctl restart ..."。 fingerprints 首次连接问 yes 的那一步,本质是防中间人。

你可能会懵的地方

  • id_rsa 和 id_ed25519 都在 ~/.ssh 里,连接时用哪个? 默认按 config 里的 IdentityFile 指定;没指定时 ssh 依次尝试 ~/.ssh/id_ed25519、id_rsa 等。多把钥匙并存时(公司 GitLab 一把、服务器一把),一定要用 config 分 Host 指定,否则「时好时坏」。
  • passphrase 留空安全吗? 私钥文件本身在本机被偷才需要 passphrase 保护。笔记本加密盘 + 不共享账号的环境下留空可接受;更稳的做法是设 passphrase 并用 ssh-agent 缓存(每次开机输一次)。原则:私钥离开本机的可能性越大,越要设 passphrase。
  • known_hosts 是什么?提示 host key changed 怎么办? known_hosts 记录你连过的服务器的指纹,防 DNS 劫持/中间人。重装系统后指纹变了会报 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED——确认是重装后:ssh-keygen -R 服务器IP 清掉旧记录再连。如果不是你重装的,立即停下排查。
  • 多台服务器要发同一把钥匙吗? 同一把公钥贴多台服务器可以(管理简单),但私钥一丢全军覆没。分级实践:个人日常一把;CI/自动化单独一把(权限白名单只够 restart 服务);高敏感机器独立钥匙。
  • SSH 端口改成 2222 能防扫描吗? 能减少噪音扫描(机器人只扫 22),但不是安全边界(端口扫描一样能发现)。真正的防线是密钥 + 防火墙白名单(下一课)+ fail2ban(自动封爆破 IP)。改端口属于「锦上添花」,本课的密钥加固才是「雪中送炭」。

错法对照

错法问题正解
把私钥提交进 Git 仓库等于把家门钥匙发到公开场合私钥只存本机/Secrets;.gitignore 拦住
私钥权限 644 还硬连ssh 拒用:UNPROTECTED PRIVATE KEYchmod 600 私钥、700 .ssh
authorized_keys 属主是 root密钥登录静默失败(PermitRootLogin 无关)chown 登录用户: ~/.ssh -R
关密码登录前没验证密钥配错全员锁死先确认密钥会话可进,再关密码
scp 传目录忘 -r报 not a regular filescp -r 或改用 rsync
rsync 尾斜杠乱写多一层目录或覆盖错位明确:src/ 同步内容,src 连目录一起拷
重装系统后直接 -o StrictHostKeyChecking=no绕过中间人检查成习惯ssh-keygen -R IP 后正常重连

卡点急救

  1. Permission denied (publickey):五连查——① 服务器上 cat ~/.ssh/authorized_keys 是否真有你的公钥;② .ssh 700、authorized_keys 600、属主对(ls -la ~/.ssh);③ 本机 ssh -v prod 看它尝试了哪把钥匙(Offering public key...);④ config 的 IdentityFile 是否指对;⑤ 服务器 /var/log/auth.log | tail 看拒绝原因(Ubuntu)。
  2. 配完 sshd_config 后所有连接被拒:走云控制台 VNC 登录恢复——改回 PasswordAuthentication yes 或修语法(sshd -t 会告诉你第几行错)。教训:改 sshd 前永远留一个已连接的会话不退出。
  3. 连接卡住超时(Connection timed out):网络层问题——安全组 22 没放行、服务器没开机、IP 写错、本机代理干扰。与密钥无关,密钥问题报的是 permission denied。
  4. Windows 找不到 ssh-copy-id:用方式 B 手动追加公钥;或 PowerShell 一行流:type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh deploy@IP "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"。
  5. 每次都提示输 passphrase:设了 passphrase 又没 agent。Linux/macOS:eval $(ssh-agent) + ssh-add ~/.ssh/id_ed25519;Windows:ssh-agent 服务设为自动启动后 ssh-add。

面试常问

  • SSH 密钥登录的原理?比密码好在哪? 非对称加密:服务器持公钥发起挑战,客户端用私钥应答,私钥全程不传输。优势:① 不可暴力破解(2048 位以上熵 vs 人类密码);② 无密码在网络飞,抗嗅探;③ 天然支持免密与自动化(CI);④ 随时可吊销(删 authorized_keys 行)。密码可另加二次因素,密钥+禁密码是最小安全闭环。

  • authorized_keys 需要什么权限?为什么这么严格? .ssh 700、authorized_keys 600、属主必须是登录用户。sshd 设计上:若 authorized_keys 可能被他人篡改(组/他人可写),信任链断裂,直接拒绝使用该文件。这不是玄学,是把「文件系统完整性」作为认证前提。

  • scp 和 rsync 的区别?部署时怎么选? scp 基于 SSH 的一次性整文件拷贝,简单可靠;rsync 增量算法(校验大小+修改时间,可校验块级差异)只传变化部分,支持 --delete 镜像、断点续传、--exclude 排除。部署选择:单个 JAR 用 scp;前端构建产物目录、日志备份用 rsync -avz。

  • 如何加固一台新服务器的 SSH? 标准清单:① 密钥登录配置好并验证;② PasswordAuthentication no、PermitRootLogin no(或 prohibit-password);③ 改用低权用户+sudo(用户课);④ 防火墙/安全组只放 22(或改端口+白名单来源 IP);⑤ fail2ban 封爆破;⑥ last/auth.log 定期审计登录记录。

  • GitHub Actions 里怎么安全地 SSH 到服务器部署? 专用部署密钥对:公钥上服务器(对应 deploy 用户,sudoers 只许 restart 本服务),私钥放 GitHub Secrets;workflow 里写 known_hosts(ssh-keyscan 预先取指纹)避免交互;然后 ssh -i 私钥 deploy@host 执行上传(rsync/scp)与重启命令。私钥不过代码、不过日志。

自测三问

  1. 私钥、公钥分别放在哪?各承担什么角色?本机与服务器的权限要求分别是什么?
  2. 新装的服务器,写出「生成密钥 → 部署公钥 → 配别名 → 关闭密码登录」的完整命令序列与验证点。
  3. rsync -avz --exclude 'node_modules' dist/ prod:/www/wwwroot/app/ 中尾斜杠去掉会怎样?

小结一句话

SSH 密钥登录 = 本机私钥(600)作答 + 服务器公钥(authorized_keys,600)出题,配好 ~/.ssh/config 别名后「ssh prod」两字直达;密钥通了就关密码——这是生产服务器的第一道也是最硬的一道门。

延伸

  • OpenSSH 官方手册(sshd_config 各项含义)
  • GitHub 官方 — 使用 SSH 连接
  • 下一课预告:防火墙与端口——22 留外,80/443 对客,3306/6379/8080 全部绑回环:一张图 + ufw/firewalld 两把刀,把服务器的门只开该开的缝。
加载本节练习…
← 上一课包管理下一课 →防火墙与端口