原木素材游戏活动站 - 沙盒建造最新资讯

原木素材游戏活动站 - 沙盒建造最新资讯

深入了解SSH

Home 2026-02-13 23:23:15 深入了解SSH

深入了解SSH

学习:深入了解SSH ssh 有商业和开源版本,其中openssh是开源中最流行的。 ssh历史 1995 年 7 月, 芬兰学者Tatu Ylonen 以免费软件的形式将一套保护

  • admin 创意工坊
  • 2026-02-13 23:23:15

学习:深入了解SSH

ssh

有商业和开源版本,其中openssh是开源中最流行的。

ssh历史

1995 年 7 月, 芬兰学者Tatu Ylonen 以免费软件的形式将一套保护信息传输的程序(也就是 SSH )发布出去。程序很快流行,到年底已经有两万用户,遍布五十国家。所以在年底时,他创立了 SSH 通信安全公司来继续开发和销售 SSH,所以它变成了专有软件。在 1999 年,瑞典程序员基于 SSH 最后一个开源的版本 1.2.12 开发了 OSSH,之后 OpenBSD 开发者在 OSSH 的基础上进行大量修改,形成了 OpenSSH,它是目前唯一一种最流行的 SSH 实现,成为了所有操作系统的默认组件。

用法

生成密钥

ssh-keygen

用生成、管理和转换身份验证密钥。

参数说明:

-b bits 指定要创建的秘钥中的位数,默认 2048 位,值越大,密码越复杂

-C comment 注释,在 id_rsa.pub 中末尾

-t rsa/dsa等 指定要创建的秘钥类型,默认为 RSA

-f filename 指定公私钥的名称,会在 $HOME/.ssh 目录下生产私钥 filename 和公钥 filename.pub

-N password 指定使用秘钥的密码,使得多人使用同一台机器时更安全

常用命令:

# 生成公私钥,默认文件为 ~/.ssh/id_rsa

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

id_rsa:私钥

id_rsa.pub:公钥

管理私钥

ssh-agent和ssh-add

用于管理私钥,一般情况下会使用ssh-keygen生成的(没有密码的)私钥作为默认私钥,此时没有必要使用ssh-agent,当出现以下两种情况时则需要使用:

使用不同的私钥连接不同的主机时,需要手动指定对应的私钥。(ssh-agent能帮助选择对应的私钥进行认证)

当私钥设置了密码时,又需要频繁的使用私钥进行认证。(ssh-agent能帮助免去重复输入密码)

# 启动代理

eval `ssh-agent`

# 关闭代理

ssh-agent -k

# 在 ~/.bashrc 中加入以下来实现登陆自动启动 ssh-agent,退出自动 kill 掉程序

eval $(ssh-agent -s) > /dev/null

trap 'test -n "$SSH_AGENT_PID" && eval `/usr/bin/ssh-agent -k` > /dev/null' 0

# 查看代理中的私钥

ssh-add -l

# 查看代理中私钥对应的公钥

ssh-add -L

# 移除指定的私钥

ssh-add -d /path/of/key/key_name

# 移除所有的私钥

ssh-add -D

发送公钥

ssh-copt-id

在登陆时,将公钥放在(绑定)要登陆的服务器上。(云服务器大都默认关闭密钥登陆 PasswordAuthentication no)

# 发送公钥的两种方式(等价)

ssh-copy-id -i ~/.ssh/id_rsa.pub user@host

ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub

登陆

登陆配置

SSH 登陆服务器需要知道服务器的主机地址(主机名或主机 IP 地址),用户名和密码,有时还要指定端口号(默认 22 ),一般使用的登陆命令如下:

# 登陆目标服务器( 172.17.132.120 )

ssh -p 58422 user@172.17.132.120

# 通过跳板机登陆目标服务器( 172.17.132.120 )

ssh -p 58422 user@jumper.example.com ssh user@172.17.132.120

# 端口映射

ssh -p 58422 user@jumper.example.com -fNL 5433:172.17.132.120:5432 -N

通过设置$$HOME/.ssh/config$ ,可以使用别名直接登陆。

# 登陆目标服务器( 172.17.132.120 )

ssh target

# 通过跳板机登陆目标服务器( 172.17.132.120 )

ssh jump_target

# 端口映射

## 登陆时通过 LocalForward 配置

ssh jump_target

## 使用-L来实现本地端口映射

ssh -C -N -g -L 5433:127.0.0.1:5432 jump_target

# 通用配置,所有配置都使用

Host *

AddKeysToAgent yes # 将私钥添加到ssh-agent中

UseKeychain yes # 保存密码到agent中

ServerAliveInterval 10 # 连接心跳间隔10s

ServerAliveCountMax 3 # 重连次数为3

# target配置

Host target

HostName 172.17.132.120

User user

Port 58422

IdentityFile ~/.ssh/id_rsa

# 跳板机配置

Host jumper

HostName jumper.example.com

User user

Port 58422

IdentityFile ~/.ssh/id_rsa

Host jump_target

HostName 172.17.132.120

User user

Port 22

IdentityFile ~/.ssh/id_rsa

ProxyCommand ssh user@jumper -W %h:%p 2>/dev/null

LocalForward 5433 localhost:5432 # 本地5433映射到jump_target的5432

一般在做远程开发时,VS Code 的 Remote 插件会读取本地的配置文件 $HOME/.ssh/config,所以可以在本地匹配好,直接登陆。

首次登陆

一般在 $HOME/.ssh 目录下除了公私钥文件,config 配置文件,authorized_keys 认证文件外,还有一个 known_hosts 文件, 这个文件记录了远程主机 ip 和远程主机对应的公钥指纹。

我们在第一次登陆(密码或秘钥登陆)服务器时,会有如下的提示界面:

### SSH 首次登陆的提示

The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.

ECDSA key fingerprint is SHA256:HosOqhcUmbB7QG81yCuDPkvxTgot+vpple+czXPrEug.

ECDSA key fingerprint is MD5:fd:d7:e1:2c:42:4e:b4:2d:a3:21:4d:d1:c4:74:64:2d.

Are you sure you want to continue connecting (yes/no)?

此时 known_hosts 并没有 127.0.0.1 这台机器的指纹信息,所以显示这个提示来让我们确认这个指纹是否是目标机器的 ECDSA 算法的指纹。 当我们输入 yes 确认后,在下次登录的时候,远程主机发送过来的公钥指纹,直接和 known_hosts 文件中对应 ip 的公钥指纹比较即可。

# 本机查看服务器 172.17.132.120 的所有公钥(要与服务器上 /etc/ssh 下面的公钥 *.pub 一致)

ssh-keyscan -p 22 172.17.132.120

# 查看服务器公钥 ecdsa 的指纹 -E md5/sha256 指纹 hash 算法

ssh-keygen -E md5 -lf /etc/ssh/ssh_host_ecdsa_key.pub

## 256 MD5:84:3d:9c:6e:75:f2:6b:b2:0b:40:aa:d6:29:2f:b4:40 no comment (ECDSA)

## 256 SHA256:ZoGnph63gnKLC9wQYrHYVU8ROTf6+K9LKAjn+jrXB2o no comment (ECDSA)

# 从客户端查看服务器公钥 ecdsa 的指纹(初次登陆时要验证的指纹)

ssh-keyscan -t ecdsa -p 22 172.17.132.120 |ssh-keygen -lf -

# 公钥转换成特定指纹 hash 算法的指纹

awk '{print $2}' /etc/ssh/ssh_host_ecdsa_key.pub | base64 -d|openssl sha256 -binary |base64

known_hosts 这个文件是客户端验证服务端身份的重要依据。每次客户端向服务端发起连接请求时,不仅服务端要验证客户端的合法性,客户端也需要验证服务端的身份。

客户端就是通过 known_hosts 中的公钥指纹来验证服务器是否发生了变化,它在一定程度上能避免中间人攻击,除了第一次登陆,因为那时 known_hosts 中还没有服务器的身份信息,所以对于首次提示的登陆指纹信息还是需要和服务器比对,最安全保险的做法是第一次登陆就使用秘钥登陆。

登录流程

版本号协商阶段

密钥和算法协商阶段

认证阶段

会话请求阶段

会话交互阶段

登陆方式分为密码登陆和密钥登录。

密码登陆

客户端使用密钥和算法协商阶段生成的会话密钥加密账号和密码(口令)、认证方式,将结果发送给服务器。

服务端使用获得的会话密钥解密报文,得到账号和口令。

服务端对这个账号和口令进行判断,如果失败,向客户端发送认证失败报文,其中包含了可以再次认证的方法列表。

客户端从认证方法列表中选择一种方法进行再次认证。

这个过程反复进行,直到认证成功或者认证次数达到上限,服务端关闭本次TCP连接。

密钥登录

客户端使用密钥和算法协商阶段生成的会话密钥加密账号、认证方法、id_rsa.pub,将结果发送给服务端。

服务端使用会话密钥解密报文,得到账号、id_rsa.pub。服务端在 $HOME/.ssh/authorized_keys 中找对应的公钥,如果没有找到,发送失败消息给客户端;如果找到,比较客户发送过来的这个公钥和找到的公钥,如果内容相同,服务端生成一个随机的字符串,简称“质询”,然后使用找到的公钥加密这个质询,然后使用会话密钥再次加密。

服务端把这个双重加密的数据发送给客户端。

客户端使用会话密钥解密报文,然后使用 id_rsa 再次解密数据,得到质询。

客户端使用会话密钥加密质询,发送给服务端。

服务端使用会话密钥解密报文,得到质询,判断是不是自己生成的那个质询,如果不相同,发送失败消息给客户端,如果相同,认证通过。

免密安全传输

scp/rsync/sftp 都可以基于 SSH 来进行免密安全传输。

# 从本地同步 src.tar.gz 文件到远程服务器 jump_target 的目录 /path/to/des/

scp src.tar.gz jump_target:/path/to/des/

rsync -avz src.tar.gz jump_target:/path/to/des/

sftp登录 & lcd src.tar.gz /path/to/des

# 从远程服务器 jump_target 的文件 /path/to/src.tar.gz 到本地

scp jump_target:/path/to/src.tar.gz .

rsync -avz jump_target:/path/to/src.tar.gz .

sftp登录 & put /path/to/des/src.tar.gz

  • 读稿讲话怎样断句?
Copyright © 2088 原木素材游戏活动站 - 沙盒建造最新资讯 All Rights Reserved.
友情链接