SSH

SSH 协议

SSH

SSH(Secure Shell Protocol,安全外壳协议),是建立在应用层和传输层基础上的 一种加密的网络安全传输协议

img

OpenSSH

OpenSSH:是基于 SSH 协议实现使用最广泛的 免费开源软件

优点

  • 安全可靠
  • 便捷

OpenSSH 套件工具

ssh:远程登录

1
2
3
4
5
6
7
8
9
语法:ssh [-l login_name] [-p port] [user@host]

示例:
ssh 192.168.0.11 # 不指定用户,默认使用当前宿主用户的用户名登录
ssh root@192.168.0.11 # 指定用户登录
ssh root@192.168.0.11 -p 2222 # 指定端口,默认端口22
ssh root@192.168.0.11 "ls /usr/local" # 远程登录后执行某命令

备注:配置文件/etc/ssh/sshd_config,修改ssh登录端口和禁止root登录,可以防止被端口扫描

sshd:服务端进程服务

1
2
服务端修改文件配置:vim /etc/ssh/sshd_config 
配置完成之后要重启服务:systemctl restart sshd.service

scp:Secure Copy,远程安全拷贝文件和目录(加密)

1
2
3
4
5
6
7
语法:scp [-P port] [file|folder] [user@host]:[remote_folder]

示例:
scp mysql.sh user@host:/tmp # 本地文件拷贝到远程目录
scp -r mysqldata user@host:/tmp # 本地目录拷贝到远程目录
scp root@host:/tmp file # 文件下载
scp -P 10022 /usr/local/src/mysql-5.7.23-el7-x86_64.tar.gz root@10.200.62.4:/tmp

sftp:Secure File Transfer Protocol,安全文件传输命令行工具,使用方式和 ftp 类似,但它使用 SSH 作为底层传输协议,安全性比 ftp 好很多。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
语法:sftp -oPort=<port> <user>@<host>

常用命令:
help/?:打印帮助信息。
pwd:查看远程服务器当前目录
cd <dir>:将远程服务器的当前目录更改为<dir>
ls:显示远程服务器上当前目录的文件名
ls -l:显示远程服务器上当前目录的文件详细列表
get <file>:下载指定文件 <file>
put <file>:上传指定文件<file>

示例:
[iteblog@www.iteblog.com ~]$ sftp -oPort=22 iteblog@sftp.iteblog.com
Connecting to sftp.iteblog.com...
iteblog@sftp.iteblog.com's password:
sftp> ls /
/iteblog.txt
sftp> ls -l /iteblog.txt
-rw-r--r-- 2 50049 50049 4096 Jun 21 03:23 /iteblog.txt
sftp>

也可以使用 FileZilla 连接 SFTP 服务器:主机 IP 地址、用户名、密码、端口,端口默认为 22

img

ssh-keygen:生成密钥的工具

  • -t:指定生成密钥类型(rsadsa 等)
  • -P:指定 密语,用于确保私钥的安全
  • -f:指定存放密钥的文件(公钥文件默认和私钥同目录下,不同的是存放公钥的文件名需要加上后缀 .pub)
  • -C 用来添加注释

~/.ssh 目录下有四个文件:

  • id_rsa:私钥文件
  • id_rsa.pub:公钥文件
  • authorized_keys:保存已授权的客户端公钥
  • known_hosts:保存已认证的远程主机 ID

img

需要注意的是:一台主机可能既是 Client,也是 Server。所以会同时拥有 authorized_keys 和 known_hosts。

SSH 工作原理

对称加密与非对称加密

对称加密

含义:加密与解密使用同一套秘钥。

问题:考虑到数量庞大的 Client 端,很难保证密钥不被泄露,如何安全的保存密钥 ?

img

img

非对称加密

含义:加密与解决密码不同,存在两个密钥,“公钥”“私钥”

两个密钥的特性:公钥加密后的密文,只能通过对应的私钥进行解密,而通过公钥推理出私钥的可能性微乎其微。

img

1
2
3
4
5
远程 Server 收到 Client 端用户 TopGun 的登录请求,Server 把自己的公钥发给用户。
Client 使用这个公钥,将密码进行加密。
Client 将加密的密码发送给 Server端。
远程 Server 用自己的私钥,解密登录密码,然后验证其合法性。
若验证结果,给 Client 相应的响应。

图解公钥与私钥

公钥:可以通过网络传输,别人可以随意截获的密钥。

私钥:不能通过网络进行传输,也防止别人截获的密钥。

交互过程

(1)鲍勃有两把钥匙,一把是公钥,另一把是私钥。

PubKey1

(2)鲍勃把公钥送给他的朋友们 – 帕蒂、道格、苏珊每人一把

PubKey2

(3)苏珊要给鲍勃写一封保密的信,她写完后用鲍勃的公钥加密,就可以达到保密的效果。

PubKey3

(4)鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。

PubKey4

(5)鲍勃给苏珊回信,决定采用”数字签名”。他写完后先用 Hash 函数,生成信件的摘要(digest)。

PubKey5

(6)然后,鲍勃使用私钥,对这个摘要加密,生成”数字签名”(signature)。

PubKey6

(7)鲍勃将这个签名,附在信件下面,一起发给苏珊。

PubKey7

(8)苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的。

PubKey8

(9)苏珊再对信件本身使用 Hash 函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。

PubKey9

(10)复杂的情况出现了,道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成”数字签名”,写信给苏珊,让苏珊用假的鲍勃公钥进行解密。

PubKey10

(11)后来,苏珊感觉不对劲,发现自己无法确定公钥是否真的属于鲍勃。她想到了一个办法,要求鲍勃去找”证书中心”(Certificate Authority,简称 CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成”数字证书”(Digital Certificate)。

PubKey11

(12)鲍勃拿到数字证书以后,就可以放心了。以后再给苏珊写信,只要在签名的同时,再附上数字证书就行了。

PubKey12

(13)苏珊收信后,用 CA 的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明”数字签名”是否真的是鲍勃签的。

PubKey13

两种安全验证方式

基于口令的安全验证(用户名/密码)

  • 客户端发送登录请求 ssh user@host
  • 服务器接受请求,将服务器的公钥 id_rsa.pub 发送给客户端;
  • 客户端输入密码,密码使用 id_rsa.pub 加密后发送给服务器(敏感信息安全传输);
  • 服务器接受加密后的密码,使用服务器私钥 id_rsa 解密,匹配认证密码是否合法(如果合法!登录成功);
  • 客户端生成会话数据加密 sess_key,使用 id_rsa.pub 加密后传输给服务器(会话密钥);
  • 服务器获取到后使用 id_rsa 解密,得到 sess_key
  • 客户端和服务器通过 sess_key 进行会话数据安全传输。

基于密钥的安全验证

简单地说,就是客户端自己生成公钥私钥(通常采用 ssh-keygen 程序生成),然后将公钥以某种方式(通常是手动添加)保存到服务器 ~/.ssh/authorized_keys 文件中,以后服务器都会接受客户端传过来的经过会话密钥加密过的公钥,然后解密得到公钥之后和本地 authorized_keys 配置的公钥是否相等,如果是则允许登陆。

小结

  • SSH 是安全的加密协议,用于远程连接 Linux 服务器;
  • SSH 的默认端口是 22,安全协议版本是 SSH2
  • SSH 服务器端主要包含2个服务功能 SSH 连接和 SFTP 服务器;
  • SSH 客户端包含 ssh 连接命令和远程拷贝 scp 命令等。

服务器初始化

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
# /bin/bash

if [ $(id -u) != "0" ]; then
errorLog "错误:请用root账户运行此脚本"
exit 1
fi
echo "提升权限..."
if [[ ! `cat /etc/sudoers | grep -v grep | grep haieradmin` ]] ; then
echo "需要提升权限。。。"
sed -i '/## Allow root to run any commands anywhere / a\haieradmin ALL=(ALL) NOPASSWD:ALL' /etc/sudoers
if [[ ! `cat /etc/sudoers | grep -v grep | grep haieradmin` ]] ; then
echo "权限提升失败..."
else
echo "权限提升成功..."
fi
else
echo "haieradmin已经是sudoers"
fi

echo "开启22端口访问..."
firewall-cmd --permanent --zone=public --add-port=22/tcp
firewall-cmd --reload

echo "删除hosts.deny..."
sed -i 's/sshd:all/ /g' /etc/hosts.deny

echo "追加hosts.allow..."
if [[ `cat /etc/hosts.allow | grep -v 10.138.*.*` ]]; then
echo "追加10.138.*.*"
echo "sshd:10.138.*.*" >> /etc/hosts.allow
fi

FAQ

问题:CentOS 7.3 配置 SSH 免密码登录后仍要输入密码的解决方法?

原因分析

1
2
# tail /var/log/secure -n 20
Authentication refused: bad ownership or modes for directory /home/haieradmin

sshd 为了安全,对属主的目录和文件权限有所要求,如果权限不对,则ssh的免密码登陆不生效。

  • .ssh 目录权限为 700
  • rsa_id.pub 及 authorized_keys 权限一般为 644
  • rsa_id 权限必须为 600

解决方法:检测目录权限,把不符合要求的按要求设置权限即可。