ssh远程服务器免密登录

发布时间 2024-01-09 18:37:48作者: Joey-Wang

免密登录远程主机

远程登录主机:键入 ssh user_name@ip_address 命令,然后输入密码。

若将本地机器 SSH Key 的公钥放到远程主机,就能无需密码直接远程登录远程主机。

1 获取本机的 ssh key

在用户主目录下,查看有无 .ssh 目录,若有,再查看该目录下有无文件 id_rsa 和 id_rsa.pub。若有,可直接跳到下一步。

$ ls ~/.ssh/
config		id_rsa		id_rsa.pub		known_hosts
  • config:配置文件
  • id_rsa、id_rsa.pub:本机的 SSH Key 的秘钥对, id_rsa 是私钥, id_rsa.pub 是公钥,私钥不能泄露出去。
  • know_hosts:SSH 会将本机访问过的所有远程机器的公钥都记录在该文件中,下次访问相同计算机时,OpenSSH 会核对公钥。如果公钥不同,OpenSSH 会发出警告, 避免受到 DNS Hijack 之类的攻击。

若没有,则需通过 ssh-keygen 命令创建 SSH Key:

$ ssh-keygen -t rsa -C "youremail@example.com"  # -C 是用来添加注释的

需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。

一切顺利的话,就能在用户主目录下找到 .ssh 目录,并找到 id_rsa 和 id_rsa.pub 文件。

2 将公钥复制到远程主机

SSH 登录远程主机后,将本机的 id_rsa.pub 复制到远程主机的 ~/.ssh/authorized_keys 中。该文件记录了所有授权登录该机器的公钥。

也可直接使用 ssh-copy-id 命令。

$ ssh-copy-id user_name@ip_address
# 该命令作用约等于:
# scp ~/.ssh/id_rsa.pub user_name@ip_address:~/.ssh/authorized_keys # scp命令在主机间复制文件,缺点是会将远程机器已有文件内容覆盖

3 测试免密登录

键入 ssh user_name@ip_address 命令,应该无需密码就能登入远程主机。

通过跳板机登录远程主机

OpenSSH 的客户端有一个 ProxyCommand 的选项,用于 SSH 客户端与服务器之间的隧道通信(tunneling)。所谓的隧道技术,也称代理技术,是网络通信技术的一个普遍概念,就是把一条信道建立于另外一条信道之上。

SSH 会话基于一个 TCP 连接,如果我们把连接的两个端口各自的出口 (也即入口) 进行截获,就可以用其它的信道来传输。而且 SSH 仍然认为它用的是和另一端连接一条 TCP 连接。

ProxyCommand 指定一个命令 (称为 Proxy),SSH 客户端将通过标准输入输出和这个命令启动后的进程进行正常的 SSH 通信,而 Proxy 连接着 SSH 服务器 (一般是一个 Server Proxy,再由该 Server Proxy 连接服务器)。Proxy 和 Server Proxy 之间组成了一条隧道,如果两者之间用 HTTP 协议进行通信,则整个系统便称为tunneling SSH over HTTP,当然也可以使用 UDP、TCP、IP 以及其它任意的可行的协议。

SSH ProxyCommand 相对于 SOCKS、HTTP 或者其它的 Proxy 技术来说更简单。因为它工作在进程间的 文件 IO 通信,用任何支持 socket 的编程语言,都能轻易地编写出一个可用的 Proxy,复杂度只落在隧道本身。想一想,如果没有 ProxyCommand,你需要改变或侵入操作系统的 TCP 子系统才能实现 SSH 隧道。ProxyCommand 提供了方便应用隧道的接口,网络程序都应该提供这样的接口,而不是完全依赖于 socket。

因为一个会话就会启动一个 ProxyCommand 进程,所以只有在会话依赖于连接的协议上才能使用这种技术。

1 设置跳板机

在本机的 ~/.ssh/config 中添加配置:

Host JumpMachine
 Hostname 跳板机的IP
 Port 跳板机的端口    # 默认22,如果是非22的需要填写
 User 跳板机的用户    # 默认root,如果非root的需要填写

Host TargetMachine
 Hostname 目标机的IP
 Port 目标机的端口    # 如果是非22的需要填写
 User 目标机的用户    # 默认root,如果非root的需要填写
 ProxyCommand ssh -W %h:%p JumpMachine

%h 表示要连接的目标机,也就是 Hostname 指定的 ip 或者主机名,%p 表示要连接到目标机的端口。这儿可以直接写死固定值,但是使用 %h 和 %p 可以保证在 Hostname 和 Port 变化的情况 ProxyCommand 这行不用跟着变化。

本机会 ssh 到跳板机,建立一条连接,然后 -W 命令会从跳板机发起连接到目标机。跳板机直接将本机到目标机和目标机到本机的数据透传,最后的效果就相当于从本机直接到目标机了。

image-20240109181928610

ssh -W 参数在OpenSSH 5.4及之后的版本才支持,参考官方的 Release 信息

在使用-W之前,通常都是使用nc选项,nc允许你转发TCP/UDP数据包到指定(备用)位置并且基本上与ssh -W相同。

设置完成后,就能登录目标机,但是要先输入跳板机密码,再输入目标机密码。

2 设置免密登录

如果要达到免输入两次密码,只需将本机的 id_rsa.pub 复制到跳板机和目标机的 ~/.ssh/authorized_keys 中即可。

可以分别远程登录两台机器,进行人工复制,也可以直接使用 ssh-copy-id 命令。

$ ssh-copy-id user_name@jump_machine_ip_address
$ ssh-copy-id user_name@target_machine_ip_address

PS 题外话

使用 SSH 的 ProxyCommand,可以方便的透过跳板机进入到环境里面的机器。实际上,跳板机可以不止一层,通过不断的累加跳板机和ProxyCommand,理论上可以透过任意层数的跳板机。如下是两层跳板机的配置。

Host JumpMachine1
 Hostname 跳板机1的IP
 Port 跳板机1的端口    # 默认22,如果是非22的需要填写
 User 跳板机1的用户    # 默认root,如果非root的需要填写

Host JumpMachine2
 Hostname 跳板机2的IP
 Port 跳板机2的端口    # 默认22,如果是非22的需要填写
 User 跳板机2的用户    # 默认root,如果非root的需要填写
 ProxyCommand ssh -W %h:%p JumpMachine1

Host TargetMachine
 Hostname 目标机的IP
 Port 目标机的端口    # 如果是非22的需要填写
 User 目标机的用户    # 默认root,如果非root的需要填写
 ProxyCommand ssh -W %h:%p JumpMachine2