前言

无论是个人的 VPS 还是企业允许公网访问的服务器,如果开放 22 端口的 SSH 密码登录验证方式,被众多黑客暴力猜解捅破菊花也可能是经常发生的惨剧。企业可以通过防火墙来做限制,普通用户也可能借助修改 22 端口和强化弱口令等方式防护,但目前相对安全和简单的方案则是让 SSH 使用密钥登录并禁止口令登录。

ssh 密钥登录是相对安全的登录管理方式


更新历史

2019 年 01 月 31 日 - 更新 ssh 基础知识讲解和 ansible authorized_key 示例
2015 年 08 月 13 日 - 增加 Bash Shell 自动修改脚本
2015 年 07 月 07 日 - 初稿

阅读原文 - https://wsgzao.github.io/post/ssh/

扩展阅读

SSH 原理与运用 - http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html
Linode - https://www.linode.com/docs/networking/ssh/use-public-key-authentication-with-ssh


ssh 登录服务器的两种方式

如果是一个比较喜欢折腾的人,在某个云平台购买了一台云主机,除了通过云平台提供的 web 页面上的命令行工具,其实也可以在本地电脑上面通过 ssh 进行登录。具体地又可以分成两种:

  1. ssh 用户名密码登录
  2. ssh 证书(免密码)登录

需要说明一下,后者的安全性高于前者,因此一般会默认不启用第一种登录方式,只允许第二种登录方式。

SSH 为 Secure Shell 的缩写,是建立在应用层基础上的安全协议,利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。ssh 分成服务端与客户端,其中服务端运行在被登录的机器上面,客户端运行在操作的机器上面。

用户名密码登录

通常 openssh-server 默认允许用户名密码登录,但是不排除为了安全考虑云上的服务器上禁止开启 ssh 的这种登录方式,毕竟用户名加密码的方式很容易被爆力破解。如果大家理解其中的厉害关系,可以检查修改 /etc/ssh/sshd_config(sshd 的配置文件)中 PasswordAuthentication 这一项配置为 yes(一般默认是 yes )。修改完配置重启 sshd 服务就可以使用用户名和密码登录了。

1
2
3
4
# -l 指定用户名为 wangao
# -p 指定端口为 2222,默认为 22
# 输入下面的命令后根据提示输入密码就可以登录到对应的服务器了
ssh -l wangao -p 2222 192.168.56.101

ssh 免密登录

所谓免密登录,也就是说不需要人工再输入用户名和密码了,但这并不意味着没有了鉴权的动作,服务器毕竟是自己的,不能随便允许别人登录到上面去搞破坏。ssh 免密登录通过证书进行鉴权。

这里的证书分为公钥与私钥,我们可以简单地理解为:公钥 = 锁;私钥 = 钥匙。

流程基本是这样的:如果我们想要从 A 免密登录到 B,就需要把公钥(锁)放到 B 的特定位置,而 A 拥有私钥(钥匙)的完整副本。当 A 拿着私钥去访问 B 的时候,B 发现自己身上有一把锁(B 可能有很多公钥)可以被 A 的私钥打开,于是给 A 放行,A 就成功登录到 B 了。

如何得到证书(公钥与私钥)
上面提到的证书可以通过两种方式获取得到。
第一种是向服务器管理员索取,一般索取得到的是私钥,这样就可以免密登录到任何存放了公钥的服务器了。
第二种是自己生成证书(比如使用 ssh-keygen),然后把公钥放到对应的服务器的特定位置,就可以免密登录到对应的服务器了。

1
2
3
4
5
# 通过 ssh-keygen 可以生成需要的证书 
# 根据提示一路按 RETURN(ENTER) 即可
# 默认情况下会生成 id_rsa 和 id_rsa.pub
# id_rsa 为私钥,id_rsa.pub 为公钥
ssh-keygen

公钥放置位置

linux 系统允许多用户登录同一台服务器,一般情况下 /home 目录会有非常多的用户目录。可以把公钥放置在任何一个用户目录的 $HOME/.ssh/authorized_keys 文件中,比如 cat id_rsa.pub >> /home/wangao/.ssh/authorized_keys ,这样就可以使用私钥以 wangao 的名义登录对应的服务器了。

1
2
3
4
5
6
7
# -i 指定私钥,默认条件下使用 ~/.ssh/id_rsa
# -l 指定用户名
# -p 指定端口,默认为 22
ssh -i ~/.ssh/id_rsa -p 2222 -l wangao 192.168.56.101

# 上面的命令等同于
ssh -p 2222 wangao@192.168.56.101

ssh 免密码登录一般流程

生成 PublicKey

建议设置并牢记 passphrase 密码短语,以 Linux 生成为例

Linux:ssh-keygen -t rsa
[私钥 (id_rsa) 与公钥 (id_rsa.pub)]
Windows:SecurCRT/Xshell/PuTTY
[SSH-2 RSA 2048]

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
26
27

# 生成 SSH 密钥对
ssh-keygen -t rsa

Generating public/private rsa key pair.
# 建议直接回车使用默认路径
Enter file in which to save the key (/root/.ssh/id_rsa):
# 输入密码短语(留空则直接回车)
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:
aa:8b:61:13:38:ad:b5:49:ca:51:45:b9:77:e1:97:e1 root@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
| .o. |
| .. . . |
| . . . o o |
| o. . . o E |
|o.= . S . |
|.*.+ . |
|o.* . |
| . + . |
| . o. |
+-----------------+

复制密钥对

也可以手动在客户端建立目录和 authorized_keys,注意修改权限

1
2
3
4

# 复制公钥到无密码登录的服务器上, 22 端口改变可以使用下面的命令
#ssh-copy-id -i ~/.ssh/id_rsa.pub "-p 10022 user@server"
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.15.241

修改 SSH 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 编辑 sshd_config 文件 
vi /etc/ssh/sshd_config

# 禁用密码验证
PasswordAuthentication no
# 启用密钥验证
RSAAuthentication yes
PubkeyAuthentication yes
# 指定公钥数据库文件
AuthorsizedKeysFile .ssh/authorized_keys

sed -i "s/^PasswordAuthentication.*/PasswordAuthentication no/g" /etc/ssh/sshd_config
sed -i "s/^#RSAAuthentication.*/RSAAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#PubkeyAuthentication.*/PubkeyAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#AuthorizedKeysFile.*/AuthorizedKeysFile .ssh\/authorized_keys/g" /etc/ssh/sshd_config

重启 SSH 服务前建议多保留一个会话以防不测

1
2
3
4
5
6
# RHEL/CentOS 系统 
service sshd restart
# Ubuntu 系统
service ssh restart
# Debian 系统
/etc/init.d/ssh restart

手动增加管理用户

可以在 == 后加入用户注释标识方便管理

1
2
3
4
echo 'ssh-rsa XXXX' >>/root/.ssh/authorized_keys

# 复查
cat /root/.ssh/authorized_keys

使用 Ansible 添加 ssh 信任关系

使用 ansible authorized_key module 即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
- hosts: all
remote_user: root
gather_facts: false

tasks:
- name: authadd root
authorized_key:
user: root
state: present
key: "{{ lookup('file','/root/.ssh/id_rsa.pub') }}"
path: /root/.ssh/authorized_keys
manage_dir: no
tags:
- root
文章目录
  1. 1. 前言
  2. 2. 更新历史
  3. 3. ssh 登录服务器的两种方式
    1. 3.1. 用户名密码登录
    2. 3.2. ssh 免密登录
  4. 4. ssh 免密码登录一般流程
    1. 4.1. 生成 PublicKey
    2. 4.2. 复制密钥对
    3. 4.3. 修改 SSH 配置文件
    4. 4.4. 手动增加管理用户
  5. 5. 使用 Ansible 添加 ssh 信任关系