为SSH设置密钥登录

Linux服务器登录方法

一般我们会通过账户、密码的方式远程运维Linux服务器,但是密码有被暴力破解的可能,所以一般采用下述两种方式:

  1. 禁用22端口,启用其他端口用于 SSH 登录,或禁用 root 账户;
  2. 为服务器设置密钥,通过密钥登录。

原理:利用密钥生成器制作一对密钥:公钥和私钥,将公钥添加到服务器的某个账户上,将私钥下载到本地;然后在客户端利用私钥进行认证和登录。也可以将公钥复制到其他账户甚至主机,使用同一个私钥登录。

注意:本文所有命令基于 CentOS 7.8 操作

加固 SSH 账户密码登录

修改默认端口

例:此处将远程登录端口修改为3389

1、查看端口是否已被占用,无返回结果表示没有被占用

1
2
[root@ostak02 ~] netstat -anp | grep 3389
[root@ostak02 ~] yum install net-tools # 如果上述命令执行失败,则需要安装 net-tools

2、修改 SSH 端口为 3389,此处可以保留 22 端口,避免修改失败导致无法登录。

1
2
3
4
5
6
7
8
[root@localhost ~] vim /etc/ssh/sshd_config
# If you want to change the port on a SELinux system, you have to tell SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
Port 22
Port 3389 # 增加3389端口
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

该配置文件 sshd_config 中其他参数的作用:

  • PermitRootLogin no // 禁止 Root 用户登录
  • MaxAuthTries 3 // 输入密码最大失败次数为 3
  • PasswordAuthentication no // 禁用密码登录
  • PubkeyAuthentication yes // 允许密钥认证

3、防火墙开放对应端口

1
2
3
4
5
6
[root@localhost ~] firewall-cmd --zone=public --add-port=3389/tcp --permanent      # 开放 3389 端口
success
[root@localhost ~] firewall-cmd --reload # 重新读取防火墙配置
success
[root@localhost ~] firewall-cmd --zone=public --query-port=3389/tcp # 查看端口是否添加成功
yes

4、在SELinux中添加对应的 SSH 端口

如果没有 SELinux 的管理工具 semanage 需要先安装:

1
2
[root@localhost ~] yum provides semanage
[root@localhost ~] yum install policycoreutils-python # semanage的依赖工具包

此时可以正常使用 semanage 命令了:

1
2
3
4
5
[root@localhost ~] semanage port -l | grep ssh                 # 查询当前 ssh 服务端口
ssh_port_t tcp 22
[root@localhost ~] semanage port -a -t ssh_port_t -p tcp 3389 # 向 SELinux 中添加 ssh 端口
[root@localhost ~] semanage port -l | grep ssh
ssh_port_t tcp 3389, 22

5、重启SSH服务,登陆验证

重启 sshd 服务后就可以使用新添加的端口登录了,可以看到成功登陆了,最后不要忘了把 22 端口注释掉哦

1
2
3
4
5
[root@localhost ~] systemctl restart sshd.service              # 重启 ssh 服务
# 此处使用另外一台 Linux 登录测试:
[root@ostak01 ~] ssh root@192.168.60.143 -p 3389
Last login: Wed Jun 3 00:36:14 2020 from 192.168.60.1
[root@localhost ~]

使用密钥免密登录

生成密钥对

首先需要通过密码登录服务器,生成的密钥默认存放于当前账户的家目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@ostack02 ~] ssh-keygen   # 创建密钥
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): # 直接回车,使用默认名称
/root/.ssh/id_rsa already exists.
Enter passphrase (empty for no passphrase): # 直接回车,密码滞空
Enter same passphrase again: # 确认密码,直接回车
Your identification has been saved in /root/.ssh/id_rsa. # 私钥
Your public key has been saved in /root/.ssh/id_rsa.pub. # 公钥
The key fingerprint is:
SHA256:8AbiBv9sGvbeGthI9gHHZ8D4of0NivCLnXoPnsp2ySk root@ostack02
The key's randomart image is:
+---[RSA 2048]----+
| o. |
| ..o. |
| . o+=.o |
| .+.+o*. |
| o*..oSo |
| +oB.o. . |
| +*=B |
| .EoXB o |
| .+*+o=.. |
+----[SHA256]-----+

然后就会在 ~/.ssh 目录下生成一对 2048 位无密码的 ras 密钥,ssh-keygen 的常用参数如下:

  • -t:指定生成密钥的类型,默认使用SSH2d的rsa
  • -f:指定生成密钥的文件名,默认id_rsa(私钥id_rsa,公钥id_rsa.pub)
  • -b:指定密钥长度(bits),RSA最小要求768位,默认是2048位;DSA密钥必须是1024位(FIPS 1862标准规定)
  • -C:添加一个注释

在此提醒,私钥 id_rsa 非常重要,需要妥善保存!

公钥的安装

安装至当前服务器

将公钥安装在当前服务器 ostack02 中,就可以使用私钥在本地免密登录 ostack02 了。

1
2
3
4
5
6
7
8
[root@ostack02 ~] cd ~/.ssh
[root@ostack02 .ssh] cat id_rsa.pub >> authorized_keys
[root@ostack02 .ssh] ll # 注意文件权限, .ssh 目录为700
total 16
-rw-r--r--. 1 root root 2357 Jun 3 23:17 authorized_keys
-rw-------. 1 root root 1675 Jun 3 23:09 id_rsa
-rw-r--r--. 1 root root 395 Jun 3 23:09 id_rsa.pub
-rw-r--r--. 1 root root 176 Jun 2 00:42 known_hosts

安全至远程服务器

如果想通过同一个私钥登录另一台服务器 ostack01 或想通过 ostack02 登录 ostack01 怎么办呢?可以将公钥也注册到需要登陆的服务器,这里以 ostack01(192.168.60.142) 为例:

1
2
3
4
5
6
[root@ostack02 .ssh] ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.60.142
[root@ostack02 .ssh] cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPjXkFWHAphIzxduIQbLumViWfI2bs8gm2WPj7Y2vERNOfwHIjUqtKExrYKNDwO4etbxJ8opY1wKWdbFLAd7uwLOJc0uP37hdY3WOsj+W7X0i+MTIRmek0oM5xzAbXVWjLsuzK0Djzv0TE8I8L2nOOcehz7DxgXdW7+GRmF6w+T6M18aTmltKh7SHEEbBToq5SNlP2VDo3fmVWh3/v58Q5KPZDHNnpdQ4L9RuiGcwcR3jbIbrKymqJfTPlfOiuiYDBb6wfsQ9+rB20bEKXMSNAGs5yF5KB69lIHSadnN3Ef8YjTTAO/mKZrkx42xZaYuVuSIwJ0DXUHz1MnqvfJ8Pz root@ostack02
# 此时登录 ostack01,会在 /root/.ssh/ 下生成 authorized_keys 文件,通过查看比对发现和公钥是一致的
[root@ostak01 .ssh] cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPjXkFWHAphIzxduIQbLumViWfI2bs8gm2WPj7Y2vERNOfwHIjUqtKExrYKNDwO4etbxJ8opY1wKWdbFLAd7uwLOJc0uP37hdY3WOsj+W7X0i+MTIRmek0oM5xzAbXVWjLsuzK0Djzv0TE8I8L2nOOcehz7DxgXdW7+GRmF6w+T6M18aTmltKh7SHEEbBToq5SNlP2VDo3fmVWh3/v58Q5KPZDHNnpdQ4L9RuiGcwcR3jbIbrKymqJfTPlfOiuiYDBb6wfsQ9+rB20bEKXMSNAGs5yF5KB69lIHSadnN3Ef8YjTTAO/mKZrkx42xZaYuVuSIwJ0DXUHz1MnqvfJ8Pz root@ostack02

私钥的使用

SSH 软件使用私钥登录服务器

将私钥提取至本地,用于后续登录,这里以Xsheel为例:

1
2
3
4
5
6
7
8
[root@ostack02 .ssh] sz /root/.ssh/id_rsa
[root@ostack02 .ssh] yum install lrzsz # 如果没有 sz 命令,可通过 yum 安装
使用说明:
1. sz命令发送文件到本地:
sz filename
2. rz命令本地上传文件到服务器:
rz
执行该命令后,在弹出框中选择要上传的文件即可。

在本地打开 Xsheel 连接服务器,弹出的对话框中选择 Public Key,浏览选中下载的私钥。因为我们没有设置密码,所以直接确定,就可以成功登录该服务器了。

1
[C:\~]$ ssh root@192.168.60.142

ssh_key_01.png

Linux 使用私钥登录服务器

使用 ostack02 登录 ostack01:

1
2
3
[root@ostack02 .ssh] ssh root@192.168.60.142   
Last login: Thu Jun 4 00:46:45 2020 from 192.168.60.1
[root@ostak01 ~]

ssh基于密钥进行认证时,默认会使用~/.ssh/*id_rsa进行认证,当使用非默认名称的私钥进行认证时,需要使用 -i 参数手动指明对应的私钥:

1
2
# 需按照上述步骤添加一个新的密钥 id_rsa_demo
[root@ostack02 .ssh] ssh -i ~/.ssh/id_rsa_demo root@192.168.60.142

关闭 SELinux

虚拟机建议关闭,如果想详细了解什么是SELinux,请转百度百科:SELinux ,这里只介绍关闭的方法:

临时关闭,重启后失效:

1
[root@ostack02 .ssh] setenforce 0

彻底关闭,告别离奇问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@ostack02 .ssh] vim /etc/selinux/config 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
# SELINUX=enforcing # 保留原来的配置
SELINUX=disable # 新复制一行,设置为 disable
# SELINUXTYPE= can take one of three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted

修改 SSH 配置文件

在安装了公钥的服务器上编辑 /etc/ssh/sshd_config 文件,允许密钥登陆、禁用密码登录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@ostak01 ~] vim /etc/ssh/sshd_config

# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

RSAAuthentication yes # 允许 rsa 密钥认证
PubkeyAuthentication yes # 允许密钥认证
PermitRootLogin yes # 此处请留意 root 用户能否通过 SSH 登录,默认为yes:
PasswordAuthentication no # 上面已经验证密钥可以成功登录,可以禁用密码登录。

HostKey /etc/ssh/ssh_host_rsa_key
[root@ostak01 ~] systemctl restart sshd.service # 重启 ssh 服务