前言

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

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


更新历史

2022年04月27日 - 增加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
8
# -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
28
29

#生成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
5

#复制公钥到无密码登录的服务器上,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
16
#编辑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
7
# RHEL/CentOS系统
service sshd restart
# Ubuntu系统
service ssh restart
# Debian系统
/etc/init.d/ssh restart

手动增加管理用户

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

1
2
3
4
5
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
- hosts: all
gather_facts: no

tasks:
- name: Set authorized key took from file
authorized_key:
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
user: root
state: present

grep过滤井号查看配置

grep命令-v参数(反向选择)分别去掉所有以#(井号)和;(分号)开头的注释信息行,对于剩余的空白行可以再用^$来表示并反选过滤

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
28
# ssh服务端
cat sshd_config | grep -v "#" | grep -v ";" | grep -v "^$"

Port 22
Protocol 2
LogLevel INFO
PermitRootLogin yes
HostbasedAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
MaxAuthTries 4
ClientAliveInterval 300
ClientAliveCountMax 0
PasswordAuthentication yes

# ssh客户端
cat ssh_config | grep -v "#" | grep -v ";" | grep -v "^$"

Host *
SendEnv LANG LC_*
HashKnownHosts yes
StrictHostKeyChecking no
GSSAPIAuthentication yes

保持ssh服务连接不断开的方法

修改客户端配置
/etc/ssh/ssh_config
~/.ssh/config

1
2
3
4
5
6
7
8
vim ~/.ssh/config

ServerAliveInterval 10
ServerAliveCountMax 5

# 使用命令行参数
ssh -o ServerAliveInterval=60 root@xx.xx.xx.xx

SSH使用小技巧

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 为跳板机配置ssh公钥
ssh-keygen
ssh-copy-id root@10.249.69.128

# 配置ssh config
cd ~/.ssh/
vim config

StrictHostKeyChecking no
CheckHostIP no

Host 192.168.*
HostName 10.249.69.128
User root
Port 22

# 直接跳转登录
ssh root@192.168.8.0


# 使用ProxyCommand或者ProxyJump
vim ~/.ssh/config

# ProxyCommand
Host X
HostName 10.251.252.53
User root
Port 22
IdentityFile ~/.ssh/id_rsa

Host xfljump
HostName 10.249.69.128
User root
Port 22
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh X -W %h:%p

# ProxyJump
Host xfljump
HostName 10.249.69.128
User root
ProxyJump root@10.251.252.53

https://liwanggui.com/posts/ssh-tips/
https://bugwz.com/2019/10/09/ssh-proxycommand/
https://blog.nediiii.com/ssh-note/
https://www.xiebruce.top/650.html
https://deepzz.com/post/how-to-setup-ssh-config.html

文章目录
  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信任关系
  6. 6. grep过滤井号查看配置
  7. 7. 保持ssh服务连接不断开的方法
  8. 8. SSH使用小技巧