# 如何安全地连接 Linux 服务器（不暴露密码）

> 目标：实现“可审计、可复用、尽量无密码”的 SSH 连接方式；避免把密码写进聊天、脚本、命令行参数或日志。

## 0. 基本原则

- **永远不要在聊天/工单/代码仓库里粘贴密码**（包括截图里、终端录屏里）。
- **不要把密码写进命令行参数**（会进入 shell history，且可能被 `ps`/审计日志看到）。
- **优先用 SSH Key + passphrase + ssh-agent**；实在需要密码，只在交互式终端里手动输入。
- 首次连接要**校验主机指纹（host key fingerprint）**，避免被中间人攻击。

## 1. 首次连接：核对主机指纹

首次 `ssh user@server` 通常会提示：

```
Are you sure you want to continue connecting (yes/no/[fingerprint])?
```

推荐做法：

1. 通过**可信渠道**（机房/云控制台/已信任的跳板机/面对面）确认服务器的 SSH 指纹。
2. 在提示中输入 `fingerprint` 查看，再与可信渠道对比；一致才输入 `yes`。

不推荐做法：

- 为了“省事”设置 `StrictHostKeyChecking=no`（会绕过校验，风险高）。

## 2. 推荐：使用 SSH Key（不需要在连接时输入密码）

### 2.1 在本机生成密钥（建议带 passphrase）

```bash
ssh-keygen -t ed25519 -C "yourname@yourdevice" -f ~/.ssh/id_ed25519
```

建议：给私钥设置 **passphrase**（丢电脑时更安全）。

### 2.2 安装公钥到服务器（只需要这一步可能要输一次密码）

```bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22 USER@SERVER_IP
```

然后测试：

```bash
ssh -i ~/.ssh/id_ed25519 -p 22 USER@SERVER_IP
```

### 2.3 使用 ssh-agent（避免每次输入 passphrase）

```bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
```

之后正常 `ssh` 会自动用 key（仍然不会暴露密码）。

## 3. 用 ~/.ssh/config 固化配置（减少手敲出错）

编辑 `~/.ssh/config`：

```sshconfig
Host my-server
  HostName SERVER_IP
  User USER
  Port 22
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  ServerAliveInterval 30
  ServerAliveCountMax 3
```

连接：

```bash
ssh my-server
```

执行远程命令（可用于运维脚本，且不会触发密码交互）：

```bash
ssh -o BatchMode=yes my-server "uname -a"
```

> `BatchMode=yes` 的意义：如果 key 不可用，SSH 会直接失败，不会弹出密码提示，避免脚本“卡住”等人输入。

## 4. 需要密码时：只在交互式终端输入，不要“自动化注入”

允许的方式：

- `ssh USER@SERVER_IP` 后出现 `password:` 提示时，在**本机终端里手动输入**（不会回显）。

强烈不建议：

- `sshpass -p 'xxx' ssh ...`（密码会进入 history/进程列表/日志）
- `echo 'xxx' | ssh ...`、`echo 'xxx' | sudo -S ...`（极易泄漏）
- 把密码写到脚本、环境变量、CI 变量后再打印/回显

## 5. 进一步加固（服务器侧建议，减少密码入口）

在你确认“key 登录可用”之后，再做以下加固（以 Debian 为例）：

1) 新建普通用户 + sudo（尽量不要日常用 root 直连）  
2) 修改 SSH 配置，**禁用密码登录**：

- 常见配置项（位置可能在 `/etc/ssh/sshd_config` 或 `sshd_config.d/*.conf`）：
  - `PasswordAuthentication no`
  - `PubkeyAuthentication yes`
  - （可选）`PermitRootLogin no` 或 `PermitRootLogin prohibit-password`

3) 校验并重载 SSH：

```bash
sshd -t
systemctl reload ssh || systemctl reload sshd
```

> 注意：改完再开一个新终端测试能否 key 登录，确认无误后再关闭旧会话，避免把自己锁在门外。

## 6. 快速自查清单

- [ ] 没有把密码发到任何聊天/工单/文档
- [ ] 用的是 ed25519 key，并且私钥有 passphrase
- [ ] `~/.ssh/config` 已配置 Host 别名，避免敲错端口/用户
- [ ] 首次连接核对过主机指纹
- [ ] 服务器侧已禁用 `PasswordAuthentication`（可选但推荐）

