我们经常用ssh登录服务器、进行git操作的账号验证。一般操作是生成密钥(id_rsa)、公钥(id_rsa),然后将公钥配置在服务器,本地保持私钥,然后用ssh即可登录。如果直接生成密钥的话,在~/.ssh/
目录下只会有一对密钥。那么我们在连接多个服务器的时候就会很麻烦。OpenSSH
可以允许我们去设置一个config
文件,里面预定义每个服务器对应的密钥文件。来探索下如何去操作。
SSH的基础知识
SSH(Secure Shell)是一个提供数据通信安全、远程登录、远程指令执行等功能的安全网络协议。
SSH的主要特性:
- 加密 避免数据内容泄露
- 通信的完整性 避免数据被篡改,以及发送或接受地址伪装。SSH-2通过
MD5
和SHA-1
实现该功能,SSH-1使用CRC-32
- 认证 识别数据发送者和接收者身份
- 授权 用户访问控制
- 转发 可以通过SSH为
Telent
、FTP
等提供通信安全保障,支持三种类型的转发操作:Port
、Forwarding
、X Forwarding
、Agent Forwarding
。
目前Linux的所有发行版几乎都自带Open SSH
。mac和windows也自带(可能老一点的windows也没有),但两者命令格式有点区别。
SSH 的 config文件
默认是没有config文件的,我们需要创建:
1 | touch ~/.ssh/config |
config配置文件结构如下:
1 | Host hostName1 |
SSH Client config文件是由一节一节的块组成的。每个块需要先声明Host
指令,并包含在与远程SSH服务器建立连接时使用的特定SSH选项。
缩进不是必须的,但是建议加上缩进,这样可以让配置文件更易读。
Host
指令可以是一个模式或一个以空格分隔的模式列表。模式符号有以下几种:
*
匹配0个或多个任意字符。例如:Host *
匹配所有主机,而192.168.0.*
匹配192.168.0.0/24
子网中的所有主机。?
匹配一个字符,例如:Host 192.168.0.?
匹配192.168.0.[0-9]
!
否定匹配,例如:Host 192.168.0.* !192.168.0.1
匹配除过192.168.0.1
的192.169.0/24
子网所有主机。
SSH Client会从头到尾一段段读取配置文件中的配置,如果有多个配置匹配,那么第一个匹配优先级是最高的。因此,应该在文件的开头定义特定主机的声明,在文件最后给出通用的声明。
那我们可以定义哪些ssh的配置信息呢?可以使用命名:man ssh_config
查看,也可以访问ssh config man page查看。
SSH config文件也可以被其他程序读取,比如:scp
,sftp
, rsync
等。
当我们需要连接服务器的时候,我们的命令一般为:
1 | ssh root@192.168.0.1 -p 8080 |
我们可以知道服务器账号是root
,host是192.168.0.1
(当然这里也可以是域名),端口是8080
。如果服务器端口是22
端口,那么也可以省略-p
参数。
现在我们将这个连接放到config
文件中:
1 | Host dev |
然后我们连接服务器的命令可以是:
1 | ssh dev |
多sshkey设置
了解了config的用法后,我们再看如何去配置多账号的ssh。
首先,我们生成ssh密钥的时候,不能让它生成默认文件的名称,而需要特定的名称:
1 | ssh-keygen -t rsa -C 'tony_cs@126.com' -f dev_rsa |
这样生成的密钥文件就是:./dev_rsa
、./dev_rsa.pub
。生成好后文件是在当前目录,我们将它挪到~/.ssh
目录即可。
在服务器中配置公钥。然后客户端这边我们配置config
文件:
1 | Host dev |
然后同样的方式可以配置dev2、dev3等等。
比如我有gitee的ssh和github的ssh,那么我的config
文件配置是这样的:
1 | Host github.com |
其中github和gitee是用来git拉取和推送的,tcs-y.com是我阿里云服务器的域名,我需要登录服务器的shell去做操作,所以有User参数。
端口转发
端口转发用的不多,但前两天也遇到了,这里补充下。
假设我们服务器上启动了一个web服务,用的端口是80端口,我们需要在连接服务器的同时,将本地端口80和服务器端口80做映射,这样我们就可以在本地通过;http://localhost
来访问服务器中运行的服务。
ssh的-L
参数可以设定转发的端口,这个参数接受三个值:本地端口:目标主机:目标端口
,他们之间用冒号分隔。端口转发使得两个机器之间仿佛形成一个数据传输的秘密隧道,因此又称为”SSH隧道”。
那么对应的命令我们可以这样写:
1 | ssh -L 80:localhost:80 root@ServerHost -p 8080 |
这样就并将本机的80端口绑定到服务器的80端口(这里localhost指的是ServerHost
,因为目标主机是相对ServerHost而言的)。
然后我们在本机浏览器访问:http://localhost
就可以看到服务器中的服务了。
奇怪的知识又增加了。🤣