SSH连接与操作全解析
立即解锁
发布时间: 2025-09-01 02:03:13 阅读量: 113 订阅数: 11 AIGC 

# SSH 连接与操作全解析
## 1. SSH 主机密钥概述
当 SSH 客户端首次连接到远程主机时,双方会交换临时公钥,以此对后续通信进行加密,防止信息泄露。客户端在披露更多信息之前,需要确认远程服务器的身份。这是合理的,因为若连接到的是黑客软件,我们肯定不希望泄露用户名和密码。
### 1.1 公钥基础设施的问题
构建公钥基础设施是解决互联网机器身份验证的一种方法。首先要确定证书颁发机构,将其公钥列表安装到所有浏览器和 SSL 客户端中,然后付费让这些机构验证身份并签署 SSL 证书,最后将证书安装到 Web 服务器上。但从 SSH 的角度看,这种方法存在诸多问题。虽然可以创建内部公钥基础设施,自行分发证书并签署服务器证书,但这仍是一个漫长的过程,而且服务器管理员通常希望在不咨询中央机构的情况下快速设置、使用和停用服务器。
### 1.2 SSH 主机密钥的生成与分发
SSH 假定服务器部署时会生成一个未签名的随机公私钥对,采用以下两种密钥分发方法:
- **系统管理员脚本分发**:系统管理员创建脚本收集组织内所有主机的公钥,生成 `ssh_known_hosts` 文件,并保存到每台机器的 `/etc/sshd` 目录,也可提供给桌面客户端。这样,SSH 客户端在首次连接前就知道所有主机密钥。
- **客户端首次连接记忆**:管理员也可让 SSH 客户端在首次连接时记忆主机密钥。当客户端遇到不认识的主机时,会提示用户确认,用户输入 “yes” 后,客户端密钥会保存到 `/.ssh/known_hosts` 文件中。后续连接该主机时,可确保连接到正确的位置。
### 1.3 SSH 命令行提示示例
当 SSH 命令行遇到不熟悉的主机时,会显示如下提示:
```plaintext
$ ssh dns.google
The authenticity of host ‘dns.google (8.8.8.8)’ can’t be
established.
RSA key fingerprint is
85:8f:32:4r:ac:1f:a9:bc:35:58:c1:d4:25:e3:c7:8c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘dns.google 8.8.8.8’ (RSA) to the
list of known hosts.
```
若 SSH 连接到主机后发现密钥不同,会给出警告:
```plaintext
$ ssh dns.google
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-
middle attack)!
```
### 1.4 paramiko 库对主机密钥的处理
`paramiko` 库支持所有涉及主机密钥的标准 SSH 方法,但默认行为较为简单。默认情况下,它不加载任何主机密钥文件,因此首次连接主机时会抛出异常。示例代码如下:
```python
import paramiko
client = paramiko.SSHClient()
client.connect('example.com', username='test')
# 会抛出异常
# Traceback (most recent call last):
# ...
# paramiko.ssh_exception.SSHException: Server ‘example.com’ not
# found in known_hosts
```
为使连接行为像典型的 SSH 命令,连接前需加载系统和当前用户的已知主机密钥:
```python
client.load_system_host_keys()
client.load_host_keys('/home/John/.ssh/known_hosts')
client.connect('example.com', username='test')
```
还可使用 `paramiko` 库选择如何处理未知主机。通过继承 `MissingHostKeyPolicy` 类创建决策类,示例如下:
```python
class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy):
def missing_host_key(self, client, hostname, key):
return
client.set_missing_host_key_policy(AllowAnythingPolicy())
client.connect('example.com', username='test')
```
`paramiko` 库中还有其他决策类:
| 决策类 | 描述 |
| ---- | ---- |
| `paramiko.AutoAddPolicy` | 首次看到主机密钥时,立即将其添加到用户主机密钥存储中,但后续主机密钥更改会导致致命异常。 |
| `paramiko.RejectPolicy` | 连接到具有未知密钥的主机时,抛出异常。 |
| `paramiko.WarningPolicy` | 连接到未知主机时,记录警告,但允许连接继续。 |
## 2. SSH 身份验证
SSH 身份验证有大量相关文档,常见的身份验证方法有三种:
- **用户名和密码**:提供用户名和密码进行身份验证。
- **公钥挑战响应**:提供用户名,通过公钥挑战响应证明拥有隐藏的 “身份” 密钥,而不向远程系统暴露其内容。
- **Kerberos 身份验证**:若远程系统支持 Kerberos,且使用 `kinit` 命令行工具在 SSH 服务器的身份验证域中验证了身份,则可无密码登录。
### 2.1 使用 paramiko 进行身份验证
使用用户名和密码进行身份验证时,在 `connect()` 方法中指定即可:
```python
client.connect('example.com', username='john', password='abc12345')
```
使用公钥进行身份验证时,使用 `ssh-keygen` 生成 “身份” 密钥对,通常保存到 `/.ssh` 目录,可无密码进行身份验证:
```python
client.connect('my.example.com')
```
若身份密钥文件不在标准的 `/.ssh/id_rsa` 目录,可手动指定文件名称或文件名称列表:
```python
client.connect('my.example.com', key_filename=
```
0
0
复制全文
相关推荐









