Skip to content

Commit 247c41e

Browse files
committed
Create 给新服务器配 SSH 免密-它其实只是在认一把钥匙.md
1 parent a6d0c7f commit 247c41e

1 file changed

Lines changed: 126 additions & 0 deletions

File tree

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
title: 给新服务器配 SSH 免密:它其实只是在认一把钥匙
3+
subtitle: 不是把密码藏起来,而是让服务器提前认识你的公钥
4+
date: 2026-07-08
5+
author: June
6+
tags:
7+
- 技术
8+
- 技术/运维
9+
- 技术/工具
10+
---
11+
12+
新服务器到手后,第一件事通常不是装环境,而是把 SSH 登录整理干净。
13+
14+
密码登录能用,但它不适合每天敲。容易输错,也容易让人心里没底:这台机器到底配过没有?免密登录听起来像是“把密码省掉”,其实不是。它更像是提前给服务器留一张名单:这把公钥我认识,拿着对应私钥的人可以进。
15+
16+
## 先把原理想明白
17+
18+
SSH key 是一对东西:私钥留在本机,公钥放到服务器。
19+
20+
登录时,服务器不会让你把私钥发过去。它只是出一道题,让本机用私钥签名。签名能被服务器上的公钥验证通过,就放行。
21+
22+
所以整个过程真正要做的是三件事:
23+
24+
1. 本机生成一对 key;
25+
2. 把公钥追加到服务器的 `~/.ssh/authorized_keys`;
26+
3. 在本机的 `~/.ssh/config` 里写一个好记的别名。
27+
28+
私钥不能发给别人,也不要贴进聊天记录。公钥可以公开一些,但也没必要到处扔。
29+
30+
## 为什么加了公钥,还是要密码
31+
32+
这个坑很常见。
33+
34+
`authorized_keys` 里有你的公钥,不代表服务端一定会用它。OpenSSH 还有自己的配置开关。如果服务器上 `PubkeyAuthentication` 是 `no`,客户端再努力也没用,服务端会直接说:这里只接受密码。
35+
36+
排查时我一般不猜,直接看两边。
37+
38+
本地用 `-vvv` 看客户端有没有拿出正确的 key;服务器上用 `sshd -T` 看真实生效的配置。注意是 `sshd -T`,不是只看配置文件里写了什么。因为 `/etc/ssh/sshd_config.d/` 下面的小配置也可能覆盖主配置。
39+
40+
这一步有点像修灯。灯泡没坏,不代表墙上的开关是开的。
41+
42+
## 境外服务器先处理网络
43+
44+
如果服务器在境外,另一件事也要先想清楚:代理。
45+
46+
SSH 登录本身通常不需要在服务器上开代理,它只要端口能连通就行。但登录进去之后,你很可能要装软件、拉 GitHub 仓库、下载 Docker 镜像、访问包管理源。网络不顺的时候,报错会很像“命令坏了”,其实只是连不上。
47+
48+
我的习惯是先把基础代理或镜像源准备好,再继续装环境。不要一上来就怀疑 `apt`、`git`、`curl`。服务器网络是第一层地板,地板不平,后面每一步都跟着晃。
49+
50+
## 别名比记 IP 舒服
51+
52+
直接敲 `ssh <User>@<Your_IP>` 可以用,但用久了很烦。IP 不好记,端口、用户、私钥路径也容易敲错。
53+
54+
`~/.ssh/config` 的意义就在这里。你给这台机器起一个别名,以后只敲:
55+
56+
```powershell
57+
ssh <Host_Alias>
58+
```
59+
60+
背后的用户、IP、端口、私钥,全部写进配置。这样也方便给不同服务器用不同 key,不会把所有机器都混在一把钥匙里。
61+
62+
## 最后一组命令
63+
64+
下面这组是通用模板,按自己的情况替换占位符就行。
65+
66+
先在本机生成专用 key:
67+
68+
```powershell
69+
ssh-keygen.exe -t ed25519 -a 100 -f "$env:USERPROFILE\.ssh\<Key_Name>" -C "<Host_Alias>"
70+
```
71+
72+
如果不想每次登录都输入私钥口令,`Enter passphrase` 的时候直接回车两次。更稳一点的做法是设置 passphrase,然后用 `ssh-agent` 缓存。不过个人小服务器图省心的话,无口令 key 也常见,前提是私钥文件别乱放。
73+
74+
把公钥写到服务器:
75+
76+
```powershell
77+
Get-Content -Raw -Encoding UTF8 "$env:USERPROFILE\.ssh\<Key_Name>.pub" |
78+
ssh.exe -o PreferredAuthentications=password -o PubkeyAuthentication=no <User>@<Your_IP> "umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys; chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys"
79+
```
80+
81+
如果服务端关了公钥登录,进服务器改:
82+
83+
```bash
84+
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d-%H%M%S)
85+
sudo nano /etc/ssh/sshd_config
86+
```
87+
88+
确认有这一行:
89+
90+
```sshconfig
91+
PubkeyAuthentication yes
92+
```
93+
94+
检查配置并重载:
95+
96+
```bash
97+
sudo sshd -t
98+
sudo systemctl reload ssh || sudo systemctl restart ssh
99+
```
100+
101+
本机写别名:
102+
103+
```sshconfig
104+
Host <Host_Alias>
105+
HostName <Your_IP>
106+
User <User>
107+
Port 22
108+
IdentityFile ~/.ssh/<Key_Name>
109+
IdentitiesOnly yes
110+
```
111+
112+
最后测试:
113+
114+
```powershell
115+
ssh <Host_Alias>
116+
```
117+
118+
如果还有问题,就别急着重来。先看 debug:
119+
120+
```powershell
121+
ssh.exe -vvv -o IdentitiesOnly=yes -i "$env:USERPROFILE\.ssh\<Key_Name>" <User>@<Your_IP>
122+
```
123+
124+
能看懂两行就够了:本地有没有 `Offering public key`,服务端有没有继续允许 `publickey`。这比凭感觉改配置靠谱多了。
125+
126+
免密不是魔法,也不是把密码藏到了什么地方。它只是把“我是谁”从一串要背的字符,换成了一把本机保存的钥匙。机器认钥匙,人少受罪。

0 commit comments

Comments
 (0)