关于 SSH 的个人总结

目的

在日常学习工作中,早已离不开远程的 Linux 服务器或虚拟机,每次都是借助 Xshell 中保存的用户密码方便的 ssh 登录,偶尔在配置环境中的时候用到了秘钥登录,但是从来没有总结一下相关的内容,每次有问题都是上网查,所以写下这篇个人经验总结的文章。本文将主要介绍 ssh 的安装ssh 免密登录允许 root 登录ssh 登录的一些选项ssh 登录本机等问题。


安装 ssh

基于 Debian/Ubuntu 系统
  • 安装客户端

    1
    sudo apt-get install openssh-client
  • 安装服务端

    1
    sudo apt-get install openssh-server
    基于 RedHat/CentOS 系统
  • 安装客户端

    1
    yum install openssh-clients
  • 安装服务端

    1
    yum install openssh-server

    关于客户端与服务端的区别就是:客户端用于你去登录别人,而服务端则是别人来登录你。


ssh 免密登录

快速实现步骤:
1
2
$ ssh-keygen -t rsa
$ ssh-copy-id -i ~/.ssh/id_rsa.pub username@xxx.xxx.xxx.xxx
说明如下:

Linux系统有一个钥匙环(keyring)的管理程序。钥匙环受到用户登录密码的保护。当你登录Linux系统时,会自动解开钥匙环的密码,从而可访问钥匙环。SSH的密钥和公钥也存储在钥匙环。所以初次使用SSH密钥登录远程Linux服务器时需要输入一次SSH密钥的密码。而将来使用SSH密钥登录时不再输入密码。Ubuntu的钥匙环程序是seahorse。

SSH密钥就好比是你的身份证明。远程Linux服务器用你生成的SSH公钥来加密一条消息,而只有你的SSH密钥可以解开这条消息。所以其他人如果没有你的SSH密钥,是无法解开加密消息的,从而也就无法登录你的Linux服务器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user1/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user1/.ssh/id_rsa.
Your public key has been saved in /home/user1/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:BQeyB4pwfE1L7NAi7hjrTl5X814QW5Gu4dOZx0gIdng user1@ubuntu
The key's randomart image is:
+---[RSA 2048]----+
|... == +.... |
| oo.+o+O E .. |
| ..o.++ =.+. |
|. . .. ++o |
| = oSo= = |
|o . . o+.= o |
|.. . . .... |
|o.. . . . |
|.o . |
+----[SHA256]-----+

$ cd ~/.ssh/
$ ls
id_rsa id_rsa.pub

ssh-copy-id 工具可以把本地主机的公钥复制到远程主机的 authorized_keys 文件上,ssh-copy-id 命令也会给远程主机的用户主目录(home)和~/.ssh, 和~/.ssh/authorized_keys设置合适的权限。

  • 语法

    1
    ssh-copy-id [-i [identity_file]] [user@]machine
  • 选项

    1
    -i:指定公钥文件
  • 实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ ssh-copy-id -i ~/.ssh/id_rsa.pub user1@192.168.1.158

    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user1/.ssh/id_rsa.pub"
    The authenticity of host '192.168.1.158 (192.168.1.158)' can't be established.
    ECDSA key fingerprint is SHA256:Gx0RFwV4EiROc6ymV/BmSLE2zNT9AswZvzq9pc6Srwo.
    Are you sure you want to continue connecting (yes/no)? yes
    /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
    user1@192.168.1.158's password:

    Number of key(s) added: 1

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

root 用户登录

在一些系统上,比如 ubuntu,root 用户是默认禁用的,也就是说通常不允许 root 账号通过网络登录。但是通过适当的配置可以允许 root 用户登录。

  1. 设置 root 用户密码

    1
    $ sudo passwd root
  2. 允许 root 用户远程登录

    1
    2
    3
    4
    5
    # vi /etc/ssh/sshd_config
    ...
    PermitRootLogin yes #取消注释

    # service sshd restart #重启ssh服务

ssh 登录选项

1. 无选项参数运行 ssh

如:

1
ssh 192.168.1.156

这会用你的用户名去 192.168.1.156 这台主机,相当于省略了。如果目标主机上没有和你的用户名同名的,则每次输入密码都是显示密码错误。

2. 指定登录用户

有如下两种方式指定用户名:

1
2
3
ssh -l user1 192.168.1.156

ssh user1@192.168.1.156
3. 指定端口

ssh 默认使用的端口号是 22。大多现代的 Linux 系统 22 端口都是开放的。如果你运行 ssh 程序而没有指定端口号,它直接就是通过 22 端口发送请求的。 当然也可以改变 ssh 的默认端口号,只需要修改 /etc/ssh/sshd_config 文件,找到此行:

1
Port 22

修改成你想要的端口,如 1234。然后重启 ssh 服务:

1
sudo service sshd restart

使用新的端口来访问 ssh 服务:

1
2
3
ssh -p 1234 user1@192.168.1.156

ssh -oPort=1234 user1@192.168.1.156
4. 绑定源地址

如果你的主机有多个 IP,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ ifconfig
eth0 Link encap:Ethernet HWaddr d0:94:66:52:07:57
inet addr:192.168.1.10 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::d294:66ff:fe52:757/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3217625896 errors:0 dropped:1996 overruns:0 frame:0
TX packets:3417264542 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2364841876835 (2.3 TB) TX bytes:2940832952714 (2.9 TB)
Memory:93300000-933fffff

eth1 Link encap:Ethernet HWaddr d0:94:66:52:07:58
inet addr:192.168.1.20 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::d294:66ff:fe52:758/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2387702 errors:0 dropped:2071 overruns:0 frame:0
TX packets:1052 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:275109861 (275.1 MB) TX bytes:100254 (100.2 KB)
Memory:93200000-932fffff

有时,你可能想指定以某个 IP 来登录别的 Linux 主机,则可以使用 -b 选项来指定一个 IP地址。这个 IP 将会用作建立连接的源地址。

1
ssh -b 192.168.1.20 user1@192.168.1.156

在服务端,可以使用 netstat 命令来检查 ssh 服务的连接建立情况。可以看到 IP 为 192.168.1.20 的连接已经建立。

1
2
$ netstat |grep ssh
tcp 0 0 192.168.1.156:ssh 192.168.1.20:43838 ESTABLISHED
5. 公钥检查

什么是公钥检查:

ssh 连接远程主机时,会检查主机的公钥。如果是第一次该主机,会显示该主机的公钥摘要,提示用户是否信任该主机:

1
2
3
4
$ ssh user1@192.168.1.57
The authenticity of host '192.168.1.57 (192.168.1.57)' can't be established.
ECDSA key fingerprint is SHA256:Gx0RFwV4EiROc6ymV/BmSLE2zNT9AswZvzq9pc6Srwo.
Are you sure you want to continue connecting (yes/no)?

当选择接受,就会将该主机的公钥追加到文件 ~/.ssh/known_hosts 中。当再次连接该主机时,就不会再提示该问题了。 如果因为某种原因(服务器系统重装,服务器间IP地址交换,DHCP,虚拟机重建,中间人劫持),该IP地址的公钥改变了,当使用 SSH 连接的时候,会报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
e9:0c:36:89:7f:3c:07:71:09:5a:9f:28:8c:44:e9:05.
Please contact your system administrator.
Add correct host key in /home/jiangxin/.ssh/known_hosts to get rid of this message.
Offending key in /home/jiangxin/.ssh/known_hosts:81
RSA host key for 192.168.0.110 has changed and you have requested strict checking.
Host key verification failed.

上面的警告信息说的是:

  • 服务器公钥已经改变,新的公钥的摘要是:e9:0c:36:89:7f:3c:07:71:09:5a:9f:28:8c:44:e9:05.
  • 该服务器原来的公钥记录在文件 ~/.ssh/known_hosts 中第 81 行。

如果确认不是中间人劫持,需要连接到该服务器,怎么办呢?最简单的就是用 vi 打开 ~/.ssh/known_hosts 文件,定位到 81 行,将该行删除。之后就可以使用 ssh 连接了。

我之前在项目中,基于 OpenStack 来搭建 SDN 网络时经常碰到上面的错误,因为经常会将一些云主机给删掉而将他们的 IP 分给新起的云主机。再用这个 IP 来登录新的主机时就会碰到这个问题,以前还不太明白咋回事,现在有种恍然大悟的感觉。

如何不进行公钥检查:

在首次连接服务器时,会弹出公钥确认的提示。这会导致某些自动化任务,由于初次连接服务器而导致自动化任务中断。或者由于  ~/.ssh/known_hosts 文件内容清空,导致自动化任务中断。 SSH 客户端的 StrictHostKeyChecking 配置指令,可以实现当第一次连接服务器时,自动接受新的公钥。只需要修改 /etc/ssh/ssh_config 文件,包含下列语句:

1
2
Host *
StrictHostKeyChecking no

或者在 ssh 命令行中用 -o 参数:

1
ssh -o StrictHostKeyChecking=no  user1@192.168.1.110

公钥检查确实很烦人,我以前在写自动化登录脚本时就觉得很棘手,导致自动化登录脚本经常出错。早知道是这个问题就好办多了,感觉写博客总结一下这些内容对于自己挺有帮助的。


ssh 登录本机的问题

不试不知道,一试才知道 ssh 登录本机其实和登录其他的主机是一样的,也需要输入密码验证,免密登录也需要将自己的公钥记录在 ~/.ssh/authorized_keys 文件中。ssh 登录本机可以使用本机的任意一个 IP 或者也可以用回环地址 127.0.0.1


完结。。以上内容就是个人在学习工作中关于 ssh 的一些总结,感觉里面的学问真的是太大了,写了这么多其实还有很多很多相关的知识是我不知道不清楚的,不过学习就是这样的,总是由浅入深,不可能一下子就把所有的弄明白,剩下的就以后再慢慢总结啦!