# 2024-bg-217 接入 Linux 记录

## 一、目标与已知信息

让 Windows 设备 **2024-bg-217** 通过 Tailscale 和 SSH 公钥认证，直接连接 Ubuntu 服务器，不输入 Linux 账户密码。

| 项目 | 值 |
| --- | --- |
| Windows 客户端 | `2024-bg-217` |
| Windows 用户名 | `huawei` |
| 客户端 Tailscale IP | `100.106.45.82`（以 `tailscale status` 当前结果为准） |
| Ubuntu 服务器 | `zrh-dracarys` |
| 服务器 Tailscale IP | `100.99.232.7` |
| Linux 用户名 | `zrh` |
| SSH 端口 | `22` |
| 服务器主机 ED25519 指纹 | `SHA256:1KPaatBGKwjQjQu5+5zTEcsCLUYZp5o3J8xkeXDd9so` |

这台 Windows 以前使用过以下 ED25519 公钥：

```text
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDRS0NEHLQX+SgxU/n3scJoNOGLzzSkVNgtDGSnm6cd/ huawei@2024-BG-217
```

对应指纹：

```text
SHA256:d6ZfgKmMikg5sDI4HMoax+hCJ8AzToIKaka0kcQsAeY
```

旧说明中的 `C:\ProgramData\ssh\administrators_authorized_keys`、Windows `sshd` 和本机 22 端口，是用于“其他设备登录 2024-bg-217”的入站服务端配置。本说明处理的是相反方向，即“2024-bg-217 登录 Ubuntu”，因此无需修改这些内容。

> 每台客户端必须使用自己的私钥。不要把 `dracarys` 上的私钥复制给 `2024-bg-217`。服务器只需要保存各客户端的公钥。

---

## 二、在 2024-bg-217 上准备 Tailscale

1. 安装并登录 Tailscale，加入与服务器相同的 tailnet。
2. 打开 PowerShell，确认两端在线：

```powershell
tailscale status
tailscale ping 100.99.232.7
```

成功时应看到来自 `zrh-dracarys (100.99.232.7)` 的 `pong`。如果这里失败，先解决 Tailscale 登录、设备审批或 ACL 问题，不要继续排查 SSH 密钥。

---

## 三、检查旧密钥，必要时生成专用密钥

先在 `2024-bg-217` 上打开 PowerShell，列出已有公钥及其指纹：

```powershell
Get-ChildItem "$env:USERPROFILE\.ssh\*.pub" -File | ForEach-Object {
    Write-Host "=== $($_.FullName) ==="
    ssh-keygen -lf $_.FullName
}
```

### 情况 A：找到旧指纹并且对应私钥存在

如果某个 `.pub` 文件显示指纹 `SHA256:d6Zfg...QsAeY`，去掉文件名末尾的 `.pub` 后检查对应私钥。例如公钥是 `id_ed25519.pub`：

```powershell
$keyPath = "$env:USERPROFILE\.ssh\id_ed25519"
Test-Path $keyPath
```

返回 `True` 才能复用。只有 `.pub` 公钥而没有对应私钥时，不能用它登录。

检查私钥是否为无口令密钥：

```powershell
ssh-keygen -y -P "" -f $keyPath | ssh-keygen -lf -
```

- 成功输出相同指纹：可以直接复用 `$keyPath`，无需生成新密钥。
- 显示 `incorrect passphrase`：密钥可用，但每次需要口令或 SSH Agent；如果目标是完全无人值守，使用下面的情况 B。

### 情况 B：没有可复用的无口令私钥

为 Ubuntu 单独创建无口令密钥，避免影响已有设备：

```powershell
New-Item -ItemType Directory -Force "$env:USERPROFILE\.ssh" | Out-Null
ssh-keygen -t ed25519 -N "" -f "$env:USERPROFILE\.ssh\id_ed25519_zrh" -C "2024-bg-217-to-zrh"
$keyPath = "$env:USERPROFILE\.ssh\id_ed25519_zrh"
```

这里使用空口令，以实现无人值守直接登录。安全性依赖 Windows 账户权限、设备磁盘安全和 Tailscale。生成后：

```powershell
ssh-keygen -lf "$keyPath.pub"
Get-Content "$keyPath.pub"
```

保存显示的 SHA-256 指纹，并复制 `.pub` 文件输出的完整一行。允许传输的只有：

```text
C:\Users\huawei\.ssh\<实际密钥名>.pub
```

严禁发送或复制没有 `.pub` 后缀的私钥：

```text
C:\Users\huawei\.ssh\<实际密钥名>
```

---

## 四、把新公钥加入 Linux 的 zrh 账户

使用已经能够连接服务器的 `dracarys`，登录 `zrh@100.99.232.7`，然后在 Linux 上执行：

```bash
install -d -m 700 "$HOME/.ssh"
nano "$HOME/.ssh/authorized_keys"
```

在文件末尾新建一行，粘贴来自 `2024-bg-217` 的完整公钥。复用旧密钥时，该行以 `huawei@2024-BG-217` 结尾；新建专用密钥时，以 `2024-bg-217-to-zrh` 结尾。

在 nano 中保存并退出：

1. `Ctrl+O`
2. 按 `Enter`
3. `Ctrl+X`

修正权限并验证：

```bash
chmod 700 "$HOME/.ssh"
chmod 600 "$HOME/.ssh/authorized_keys"
chown -R "$(id -un):$(id -gn)" "$HOME/.ssh"
ssh-keygen -lf "$HOME/.ssh/authorized_keys"
```

输出中必须出现第三步记录的 `2024-bg-217` 公钥指纹。不要把密钥写入 `/root/.ssh/authorized_keys`。

---

## 五、首次连接测试

回到 `2024-bg-217` 的 PowerShell，显式指定新密钥：

```powershell
ssh -F NUL -o IdentitiesOnly=yes -i "$keyPath" zrh@100.99.232.7
```

首次连接时，只在服务器指纹为下列值时接受：

```text
SHA256:1KPaatBGKwjQjQu5+5zTEcsCLUYZp5o3J8xkeXDd9so
```

成功标志：

```text
zrh@zrh-dracarys:~$
```

退出测试连接：

```bash
exit
```

---

## 六、配置 Windows OpenSSH 一键连接

用记事本打开配置文件：

```powershell
notepad "$env:USERPROFILE\.ssh\config"
```

追加以下内容：

```sshconfig
Host zrh-server
    HostName 100.99.232.7
    User zrh
    Port 22
    IdentityFile ~/.ssh/<实际密钥名>
    IdentitiesOnly yes
    ServerAliveInterval 30
    ServerAliveCountMax 3
```

验证生效配置：

```powershell
ssh -G zrh-server | Select-String '^(user|hostname|port|identityfile|identitiesonly) '
```

以后直接连接：

```powershell
ssh zrh-server
```

> 不要在 `Host *` 下配置多条 `IdentityFile`。这会让客户端连续提交无关密钥，可能触发 `Too many authentication failures`。

---

## 七、配置 MobaXterm 直接连接

### 方式 A：保存单独会话

新建 `Session → SSH`：

| 设置 | 值 |
| --- | --- |
| Remote host | `100.99.232.7` |
| Specify username | 勾选，填写 `zrh` |
| Port | `22` |
| Advanced SSH settings → Use private key | `C:\Users\huawei\.ssh\<实际密钥名>` |

保存会话名为 `zrh-server`。以后双击左侧会话即可直接进入。

### 方式 B：使用 MobaXterm 内置代理

进入：

```text
Settings → Configuration → SSH
```

1. 勾选 `Use internal SSH agent`。
2. 点击 `+` 添加第三步确认的实际私钥。
3. 重启 MobaXterm。

之后新建 SSH 会话时只需填写服务器地址、用户名和端口。

---

## 八、完成后的安全加固

必须在 `2024-bg-217` 公钥登录测试成功后，才确认服务器保持以下设置：

```text
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin no
```

检查并重载配置：

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

建议仅允许 Tailscale 接口访问 SSH：

```bash
sudo ufw allow in on tailscale0 to any port 22 proto tcp
sudo ufw status verbose
```

不要在确认现有网络规则前贸然执行 `ufw enable`，避免意外阻断正在使用的管理连接。

---

## 九、常见问题定位

### `Connection timed out`

SSH 认证尚未开始。检查：

```powershell
tailscale ping 100.99.232.7
Test-NetConnection 100.99.232.7 -Port 22
```

### `Permission denied (publickey)`

检查用户名是否为 `zrh`、公钥是否追加到了 `/home/zrh/.ssh/authorized_keys`，以及客户端是否指定了正确私钥。

详细日志：

```powershell
ssh -vvv -F NUL -o IdentitiesOnly=yes -i "$keyPath" zrh@100.99.232.7
```

### `Too many authentication failures`

客户端提交了过多无关密钥。使用：

```powershell
ssh -F NUL -o IdentitiesOnly=yes -i "$keyPath" zrh@100.99.232.7
```

并删除 SSH 配置中 `Host *` 下不必要的多条 `IdentityFile`。

### 撤销 2024-bg-217 的访问权

在 Linux 上编辑：

```bash
nano ~/.ssh/authorized_keys
```

只删除本次实际使用的公钥行：旧密钥以 `huawei@2024-BG-217` 结尾，专用密钥以 `2024-bg-217-to-zrh` 结尾。保存后访问权立即失效，不要删除其他客户端的公钥。
