(支持跳板机)免密登录服务器

程序员同学少不了天天登录自己的开发机,但是开发机都是需要密码的,在漆黑的终端中输入密码并不是一个愉快的体验。

因为输入的时候,屏幕上并不会有任何的显性的提示,输入多一位少一位或者输入错误都无法迅速发现,只能在报错之后小心翼翼地重新输入一遍,这也导致我们根本不敢设置太过复杂的密码,因为太容易在登录环节卡住……

所以对我们来说,免密登录就是一个神器,至少能让我们每天在登录开发机时不会因为密码错误而破坏心情。


欢迎大家关注我的个人博客【数洞】 【备用站】

一、ssh-key方案

先给大家演示一下效果:

# dain @ qixizhuangdeMac-Pro in ~ [21:46:50]
$ ssh tc
Last login: Fri Sep 28 23:32:50 2018 from 123.116.144.44

# root @ VM_0_16_centos in ~ [21:47:20]
$

可以看到,我们直接用一个简单的命令就登陆上了我们的服务器,这个过程里不需要输入任何密码。

那接下来我们来演示一遍如何配置。首先,因为我们的这台本地机器已经成功配置了自动登录,所以我们需要还原一下:

# root @ VM_0_16_centos in ~ [21:50:59]
$ cd .ssh    # 进入$HOME下的.ssh目录中,这是ssh程序在每个用户下的默认配置目录

# root @ VM_0_16_centos in ~/.ssh [21:51:01]
$ cat authorized_keys   # 查看本地机器授权的key
ssh-rsa AAAAB3...CSG0P [email protected]
ssh-rsa AAAA...fRDT51B [email protected]
# 此处因为太长,省略了大量字符

从末尾我们看出第二条记录是当前我们使用的设备,所以我们将第二条删除并保存退出。然后我们离开服务器回到本地,同样进入.ssh目录,查看一下现有的文件:

# root @ VM_0_16_centos in ~/.ssh [21:51:20]
$ exit
Connection to 132.232.117.41 closed.

# dain @ qixizhuangdeMac-Pro in ~ [21:57:10]
$ cd .ssh

# dain @ qixizhuangdeMac-Pro in ~/.ssh [21:57:22]
$ ll
total 32
-rw-r--r--  1 dain  staff   762B  9 28 23:26 config
-rw-------  1 dain  staff   1.6K  9 27 23:37 id_rsa
-rw-r--r--  1 dain  staff   412B  9 27 23:37 id_rsa.pub
-rw-r--r--  1 dain  staff   1.4K  9 28 23:32 known_hosts

我们配置自动登录需要的就是上边列出的前三个文件,其中第一个是本地配置文件,第二、第三个文件用于服务器认证本地机器,这两个文件分别是RSA私钥和公钥。.ssh目录下没有上述文件的,可以通过如下命令生成:

# dain @ qixizhuangdeMac-Pro in ~/.ssh [22:01:31] C:130
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/dain/.ssh/id_rsa):
/Users/dain/.ssh/id_rsa already exists.
Overwrite (y/n)?

程序会询问一些选项,直接Enter保持默认即可。现在,我们已经成功生成了RSA公钥和私钥,接下来,我们就需要将公钥传递给我们的服务器,即在服务器的$HOME/.ssh/authorized_keys文件中添加我们的id_rsa.pub中的内容。

# dain @ qixizhuangdeMac-Pro in ~/.ssh [22:07:30]
$ ssh-copy-id -i id_rsa.pub [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:

Number of key(s) added:        1

Now try logging into the machine, with:   "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.


# dain @ qixizhuangdeMac-Pro in ~/.ssh [22:07:46]
$

我们通过这一命令非常快速地将我们的公钥添加到了服务器上,这一过程里需要我们输入服务器上对应的密码。

好了,接下来我们配置本地的config文件:

# Private
Host bd
    HostName 180.xx.171.xxx
    User root
    Port 22

Host tc
    HostName 132.xxx.117.xx
    User root
    Port 22

其中,Host后边填写一个自定义的服务器名称,方便为主,我把百度的服务器命名为bd,腾讯的服务器命名为tc。HostName这里需要配置服务器的地址,User后边配置用户名,Port一般保持默认22即可。

这样配置好之后,我们保存退出,测试一下:

# dain @ qixizhuangdeMac-Pro in ~/.ssh [22:14:24]
$ ssh tc
Last login: Sat Sep 29 22:07:10 2018 from 123.116.144.44

# root @ VM_0_16_centos in ~ [22:17:42]
$

OK,搞定。

二、使用expect命令脚本

事实上,我们还有一种选择,通过自动输入密码来登录服务器,但是这种方法会导致服务器密码明文出现在脚本中,不是特别安全。

#!/usr/bin/expect -f
spawn ssh ${YOUR_NAME}@${YOUR_HOST}
set timeout 30
match_max 100000
expect "*password*"
send -- "${YOUR_PASSWORD}\n"
expect "~]"
interact

这种方法不需要额外的配置,通过匹配服务器的输出来自动进行设定好的下一步输入,这样我们就用脚本模拟了密码登录的过程。事实上,在第一次登录服务器的时候,一般会要求我们将服务器的公钥添加到本地的.ssh/known_hosts文件中,这个过程我们需要输入一个yes。上述脚本并没有考虑这种情况,因此可能会报错退出。因此,假如需要考虑到我们从未登陆过一台服务器的情况,我们可以使用如下脚本:

#!/usr/bin/expect -f
spawn ssh ${YOUR_NAME}@${YOUR_HOST}
set timeout 30
match_max 100000
expect {
    "(yes/no)?" {
        send "yes\n"
        expect "password:"
        send "${YOUR_PASSWORD}\n"
    }
    "password:" {
        send "${YOUR_PASSWORD}\n"
    }
 }

实际使用过程中,将${YOUR_PASSWORD}${YOUR_NAME}等变量替换为实际情况,保存为脚本,并赋予执行权限,移动到系统变量目录中即可。比如我喜欢将自己的工具脚本放入/usr/local/bin或者$HOME/bin目录中。

三、绕过跳板机自动登录

这一过程通过方法一、二都可以轻松实现。

1. 使用expect命令

针对第二种方法,无非就是将expect-send的过程增加一环即可:

#!/usr/bin/expect -f
spawn ssh ${YOUR_NAME}@${YOUR_HOST}
set timeout 30
match_max 100000
expect {
    "(yes/no)?" {
        send "yes\n"
        expect "password:"
        send "${YOUR_PASSWORD}\n"
        expect "~]"
        send "ssh ${YOUR_HOST_2}"
        expect {
            "(yes/no)?" {
                send "yes\n"
                expect "password:"
                send "${YOUR_PASSWD_2}"
            }
            "password:" {
                send "${YOUR_PASSWD_2}"
            }
        }
    }
    "password:" {
        send "${YOUR_PASSWORD}\n"
        expect "~]"
        send "ssh ${YOUR_HOST_2}"
        expect {
            "(yes/no)?" {
                send "yes\n"
                expect "password:"
                send "${YOUR_PASSWD_2}"
            }
            "password:" {
                send "${YOUR_PASSWD_2}"
            }
        }
    }
 }

就是这样,没有技术难度,只是单纯的代码重复。

2. 使用ssh-key

我更推荐这种方式,一个原因是方便快捷,一个原因是不需要堆砌一堆垃圾代码。尤其是当需要配置多个服务器自动登录的时候,这种方法明显更为高效易用。

其实核心思路没有变,依然是将本地的公钥添加到服务器的authorized_keys文件中,只不过这次需要多次添加而已,接下来我描述一下这一过程:

首先,假设本地机器为机器A,跳板机为机器B,开发机为机器C:

  1. 机器A上通过ssh-keygen -t rsa生成公钥私钥

  2. 机器A上通过ssh-copy-id -i .ssh/id_rsa.pub HOST_B机器A的公钥添加到跳板机B

  3. 机器Aid_rsaid_rsa.pub文件复制到机器B:scp -r .ssh/id_rsa* HOST_B:

  4. 登录跳板机Bssh HOST_B

  5. 机器B上生成机器B的公钥私钥:ssh-keygen -t rsa

  6. 机器B上通过ssh-copy-id -i .ssh/id_rsa.pub HOST_C机器B的公钥添加到机器C

  7. 机器B上通过ssh-copy-id -i id_rsa.pub HOST_C机器A的公钥添加到机器C

  8. 截止现在,机器B上有了机器A的公钥,机器C上有了机器A机器B的公钥。事实上这一过程完全可以通过复制粘贴来完成,目标文件是对应机器上的.ssh/authorized_keys,使用追加新的一行的方式粘贴进去即可。

  9. 我们还需要配置下本地机器A$HOME/.ssh/config文件。

下面是我的简略版的配置,其中,capital是我的跳板机的名称,而fs、a0、i1分别是我的三台开发机,他们都需要通过跳板机来登录。

需要注意的是,我们使用ProxyCommand来配置我们访问开发机时自动经由跳板机来访问。在实际使用过程中,你需要将capital替换为你自己命名的跳板机的名称或HOST,其他HostName、User也替换为对应的IP和用户名即可。

# Work
Host capital
    HostName 101.xxx.220.xxx
    User qixizhuang
    Port 22

Host fs
    HostName 10.xx.142.xxx
    User qixizhuang
    Port 22
    ProxyCommand ssh -q -W %h:%p capital

Host a0
    HostName 10.xx.26.xxx
    User qixizhuang
    Port 22
    ProxyCommand ssh -q -W %h:%p capital

Host i1
    HostName 10.xxx.136.xxx
    User qixizhuang
    Port 22
    ProxyCommand ssh -q -W %h:%p capital

好了,这样大多数的登录行为我们都可以免密完成了。大家有问题可以留言,我收到回及时回复,大家一起探讨。

你可能感兴趣的:((支持跳板机)免密登录服务器)