OpenSSH

SSH

SSH (Secure Shell Protocol),由 IETF 网络工作小组(Network working Group)指定;在进行数据传输之前,SSH先对联机数据包通过加密技术进行加密处理,加密后在进行数据传输。确保了传递的数据安全。

SSH 是专为远程登录会话和其他网络服务提供的安全性协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题,在当前的生产环境运维工作中,绝大多数企业普遍采用 SSH 协议服务来代替传统的不安全的远程联机服务软件,如telnet(23/tcp,非加密)。

默认状态下,SSH 服务监听在应用层协议的 TCP 协议的 22 号端口,建立在应用层和传输层基础上。主要提供了两个服务功能,一个是提供类似 Telnet 远程联机服务器的服务,即 SSH 服务;另一个是类似 FTP 服务的 sftp-server,借助 SSH 协议来传输数据,提供更安全的 SFTP 服务(vsftp,proftp)。

SSH 版本目前有 1.x 和 2.x ,由于 1.x 的漏洞原因,目前使用安全协议 SSH2。SSH 客户端包含 ssh 远程连接命令,以及远程拷贝 scp 命令。

SSH 服务是一个守护进程(daemon),他在后台运行并响应来自客户端的连接请求,SSH 服务端的进程名为 sshd,负责实时监听远程 SSH 客户端的连接请求并进行处理,一般包括公共密钥认证、密钥交换、对称密钥加密和非安全连接等。

认证过程

只要知道用户名和密码,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证正在连接的服务器就是想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人”这种方式的攻击。

SSH 通道(channel)的建立

Server 运行对应的服务 sshd

1
2
3
4
5
6
7
8
9
10
[user1@study ~]$ systemctl status sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2016-03-13 09:57:01 CST; 7h ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 796 (sshd)
CGroup: /system.slice/sshd.service
└─796 /usr/sbin/sshd -D
[user1@study ~]$

/etc/ssh/ 下生成密钥对,私钥是 ssh_host_*_key,公钥是 ssh_host_*_key.pub

1
2
3
[user1@study ~]$ ls /etc/ssh/
moduli ssh_config sshd_config ssh_host_ecdsa_key ssh_host_ecdsa_key.pub ssh_host_ed25519_key ssh_host_ed25519_key.pub ssh_host_rsa_key ssh_host_rsa_key.pub
[user1@study ~]$

Client 向 Server 发起连接请求,Server 接收到请求后将自己对应算法的公钥发送给 Client,当 Client 收到提示信息后输入 yes,验证并接受 Server 的主机公钥,并且 Client 也生成自己的密钥对,用 Server 的公钥加密自己的公钥发送给 Server。接着,安全的 SSH 通道建立

1
2
3
4
5
[root@study ~]$ ssh localhost
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is SHA256:Yn5m2m9aqBfL7PTDMrS0Xh3UGn75PZdAqgYxF0tuRa0.
ECDSA key fingerprint is MD5:e6:49:44:f7:f5:18:04:77:01:e5:ab:48:93:03:0e:86.
Are you sure you want to continue connecting (yes/no)? yes

基于口令的认证

Client 使用 Server 的公钥加密自己的用户名发送给Server

Server 收到信息后使用自己的私钥解密数据得到用户名,确定有此用户则发信息给 Client 要求发送对应用户的密码

1
user1@localhost's password:

Client 用 Server 的公钥加密对应用户的密码发送给 Server 发送给 Server。Server 使用自己的私钥解密并验证登录口令

基于密钥的认证

采用数字签名的方法来认证客户端,在 Linux 设备上可以利用 RSA 和 DSA 两种公共密钥算法实现数字签名

认证过程分为两个步骤:会话密钥生成和用户认证,具体实现过程比较复杂,涉及到一些数学运算,故不再详细阐述

认证流程图

下面是一张基本的通信过程流程图

SSH 服务的常用配置和命令

常用配置

SSH 服务在服务器上以 sshd 运行,对应的配置文件为 /etc/ssh/sshd_config

默认情况下服务器端监听的端口是 22 ,为了提高安全性,建议修改成自定义的端口

1
Port 52113

在对于一些安全要求比较高的情况下,可能不允许 root 直接远程登录,而且不允许空密码登录,这时就需要修改下面的参数

1
2
PermitRootLogin no        # 禁止root远程登录
PermitEmptyPasswords no # 禁止空密码的用户登录

默认情况下客户端试图登录 SSH 服务器时,服务器端会先根据客户端的 IP 地址进行 DNS 的 PTR 反向查询,尝试找出客户端的主机名,然后根据查询出的客户端主机名进行 DNS 的正向 A 记录查询,验证与其原始登录的 IP 地址是否一致,这是防止客户端欺骗的一种措施,但一般我们用到的是动态 IP 不会有 PTR 记录,这就会导致登录过程很慢。因此关闭这个功能是很常用的。

1
UseDNS no  # 从 yes 改为 no

常用命令

ssh

远程登录命令,常用选项:

1
2
3
4
   -b 指定源地址,也可使用 -oBindAddress=
-p 指定端口号,也可使用 -oPort=
-v 显示详细信息
-o StrictHostKeyChecking=no 跳过证书验证,很多情况下都需要输入yes,在一些自动登录的情况下比较多用

命令格式

1
2
3
4
# 登录:
ssh -l user host # 或
ssh user@host # 或
ssh user@host 'command'

ssh-keygen

用来生成公钥和私钥密钥对的工具

常用选项

1
2
3
4
   -t rsa|dsa 加密类型
-f 指定密钥保存文件的路径,一般是 ~/.ssh/id_rsa
-N '' 指定私钥的密码
-P '' 指定私钥的密码

ssh-copy-id

这个命令可以将生成的公钥传输至远程服务器,使用 -i 选项指定公钥的路径,如果远程主机监听 sshd 服务端口不是 22,就需要使用 -p 来指定对应的端口号

ssh-copy-id 是基于 shell 编写的开源脚本,有兴趣的话可以看看源码学习一下

scp

跨主机文件安全复制工具

常用选项

1
2
3
-r  递归拷贝,如果拷贝的是一个目录就需要这个选项
-P 指定端口号
-p 在拷贝前后保持文件或目录属性

命令格式

1
2
scp USERNAME@HOST:/path/to/somefile  /path/to/local
scp /path/to/local USERNAME@HOST:/path/to/somewhere

sftp

ssh服务附带的 sftp 功能命令,用于文件传输

1
2
3
sftp -oPort=52113 root@192.168.247.164
sftp> cd /root
sftp> ?

命令

一台主机为客户端(基于某个用户实现)

1
2
3
4
5
# 1、生成一对密钥
ssh-keygen -t rsa -f a.key -N '' -C"root@zhangsan"
# 2、将公钥传输至服务器端某用户的家目录下的.ssh/authorized_keys文件中
ssh-copy-id -i /root/a.key.pub root@192.168.2.2
# 3、测试登录

ssh 免密登录配置

本机生成密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@study ~]# ssh-keygen 
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:
SHA256:+gGa1NFQrFzQXjWOPrTAp37/HUKglCOWET5MJptwAvU root@study
The key's randomart image is:
+---[RSA 2048]----+
| .o+ ooXo .o |
| = O+* oo . |
| E.@+=+.. |
| .+.=*o.. |
| . o S.+ . |
| . o + .. |
| o . o . . . |
| . o . ...|
| . ... .|
+----[SHA256]-----+
[root@study ~]#

如果你觉着这样被询问比较麻烦,可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@study ~]# ssh-keygen -f /root/.ssh/id_rsa -N ''  -f 指定私钥保存路径,-N '' 指定私钥密码为空,用 -P 亦可
Generating public/private rsa key pair.
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:mLmYT0wzcCXnehcoDawFWxU+oli63iFyM5Pab9MBTvo root@study
The key's randomart image is:
+---[RSA 2048]----+
| .o+.=. |
| ooO . |
| +o+ * . |
| +++ B . . |
| o+..O S . |
| .o.=.= . |
|. O.+.+. |
| * *E+. |
|. ooo.. |
+----[SHA256]-----+

上传公钥到远端主机(待信主机)

1
2
3
4
5
6
7
8
9
10
11
12
[root@study ~]# ssh-copy-id -p 22 192.168.127.159
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/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
root@192.168.127.159's password:

Number of key(s) added: 1

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

[root@study ~]#

登录测试

1
[root@study ~]# ssh -p 22 192.168.127.159
有钱任性,请我吃包辣条
0%