SSH基本原理及使用<一>

SSH(Secure shell)是一种安全远程登录的协议,ssh与telnet、ftp等的区别就是安全性, SSH采用非对称加密保证数据安全性。ssh有商用的,开源的,这里使用的是OpenSSH,开源软件。

环境

  • 虚拟机:VMware
  • 本地系统:Red Hat Enterprise Linux Server release 7.6 (Maipo)
  • 云服务器:CentOS Linux release 7.2.1511(阿里云)

概念

加密方式

SSH是一种网络传输协议,在传输之前,需要建立一个安全的传输通道,这个过程就会使用到对称加密算法和非对称加密算法,下面将对这两种算法进行分析。

对称加密算法

对称加密顾名思义就是加加密过程和解密过程使用同一个秘钥,任何拥有该秘钥的人可以加密和解密数据,对称加密的加密强度高,几乎很难破解,但是在使用过程中会面临如何保存秘钥的问题,基本上一个服务器会有很多客户端进行登录,如果有一个人泄露,那么数据也会被泄露,非对称加密就出现了。

非对称加密算法

非对称加密是需要公钥和私钥配合工作,也就是公钥加密,私钥解密。常见的非对称加密算法有rsa和dsa。非对称加密流程如下:

  1. 初次远程Server收到Client的登录请求之后,Server发送公钥到Client。
  2. Client收到公钥之后,验证其公钥是否为Server公钥。
  3. 继续,Client会将密码通过公钥加密,然后发送到Server
  4. Server使用私钥解密后,验证密码的合法性,然后告知Client是否登录成功。

公钥是公开的,我们可以使用公钥加密私钥解密,也可以公钥解密私钥加密,会发现这两个过程很相似。你私钥加密后发出数据,所有知道公钥的人都可以解密,并且公钥是公开的,所以这个过程是有风险的,这也就出现数字签名。

RSA数字签名

数字签名主要是为了证明传输数据的真实性和完整性,通过这个数字签名的验证,可以保障数据真是完整。其实就是对一份数据打个标记,证明发送方本人发送出去的数据,而且数据完整真实。非对称加密算法中,如果私钥加密,公钥解密,就不能保证数据真实完整,这就需要用到数字签名,具体过程如下:

假设A拥有私钥,B有公钥,A要给B发送信息。

  1. A发送信息使用到数字签名,A把要发送的数据使用Hash函数生成摘要,然后使用私钥将这个摘要生成数字签名。
  2. A将数据和数字签名一起发送给B。
  3. B收到数据之后,将数字签名取下,通过公钥解密得到摘要。B将数据通过Hash函数得到摘要,B对比这两个摘要就可以知道数据是否完整真实。

参考网址阮一峰

配置文件

ssh分为客户端和服务器端,Redhat操作系统默认安装客户端和服务器端。具体的配置文件在/etc/ssh下面,ssh_config是对客户端功能配置,sshd_config是服务器端功能配置 。在这两个配置文件里面加#表示默认配置。

客户端配置文件

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

# Host * #表示对能匹配字符串的计算机有效,*代表所有计算机。
# ForwardAgent no #连接是否经过验证代理
# ForwardX11 no #设置X11连接是否被自动重定向到安全的通道和显示集
# RhostsRSAAuthentication no #设置是否使用RSA算法的rhosts的安全验证
# RSAAuthentication yes # 设置是否使用RSA算法安全验证
# PasswordAuthentication yes #设置是否使用口令验证
# HostbasedAuthentication no #
# GSSAPIAuthentication no
# GSSAPIDelegateCredentials no
# GSSAPIKeyExchange no
# GSSAPITrustDNS no
# BatchMode no #批处理模式 ,交互时输入口令提示将被禁止
# CheckHostIP yes #设置ssh是否查看连接到服务器的主机的IP地址,防止DNS欺骗
# AddressFamily any
# ConnectTimeout 0
# StrictHostKeyChecking ask #询问计算机是否将服务器
# IdentityFile ~/.ssh/identity
# IdentityFile ~/.ssh/id_rsa
# IdentityFile ~/.ssh/id_dsa
# IdentityFile ~/.ssh/id_ecdsa
# IdentityFile ~/.ssh/id_ed25519
# Port 22 #连接服务器的端口号,
# Protocol 2
# Cipher 3des #设置加密密码
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
# EscapeChar ~ #设置escape字符
# Tunnel no
# TunnelDevice any:any
# PermitLocalCommand no
# VisualHostKey no
# ProxyCommand ssh -q -W %h:%p gateway.example.com
# RekeyLimit 1G 1h
#

服务器配置文件

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#Port 22   #服务器监听端口号,默认22
#AddressFamily any
#ListenAddress 0.0.0.0 #服务器监听的IP,默认为所有IP
#ListenAddress ::
#Protocol 2 #SSH使用的是SSH2协议
HostKey /etc/ssh/ssh_host_rsa_key #设置服务器秘钥路径
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
#RekeyLimit default none
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO #SSHD日志消息级别
# Authentication: #限制用户必须在指定的时限内认证成功,0 表示无限制。默认值是 120 秒。
#LoginGraceTime 2m #用来设定如果用户登录失败,在切断连接前服务器需要等待的时间,单位为妙
#PermitRootLogin no #是否允许root远程登录,默认不允许,
#StrictModes yes #StrictModes用来设置ssh在接收登录请求之前是否检查用户根目录和rhosts文件的权限和所有权
#MaxAuthTries 6 #设置最大失败尝试登录次数
#MaxSessions 10 #设置ssh最大联机个数,就是登录ssh,没有输入密码时。已经登录的不计算在内。

#PubkeyAuthentication yes #用来设置是否开启公钥验证,如果使用公钥验证的方式登录时,则设置为yes
AuthorizedKeysFile .ssh/authorized_keys #设置公钥验证文件地址
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
#HostbasedAuthentication no
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes #验证的时候是否使用这两个文件
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes #用来设置是否开启密码验证机制,如果用密码登录系统,则设置yes
#PermitEmptyPasswords no #是否密码为空的用户可以登录
# Change to no to disable s/key passwords
ChallengeResponseAuthentication no #是否允许质疑-应答(challenge-response)认证

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes
# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no
UsePAM yes #设置是否通过PAM验证

#AllowAgentForwarding yes
#AllowTcpForwarding yes #置是否允许允许tcp端口转发,保护其他的tcp连接
#GatewayPorts no #设置是否允许远程客户端使用本地主机的端口转发功能,出于安全考虑,建议禁止
X11Forwarding yes #用来设置是否允许X11转发
#X11DisplayOffset 10 #指定X11 转发的第一个可用的显示区(display)数字。默认值是 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes #用来设置sshd是否在用户登录时显示“/etc/motd”中的信息,可以选在在“/etc/motd”中加入警告的信息
#PrintLastLog yes #是否显示上次登录信息
#TCPKeepAlive yes #是否持续连接,设置yes可以防止死连接
#UseLogin no #设置是否在交互式会话的登录过程中使用。默认值是"no"
#UsePrivilegeSeparation sandbox #设置使用者的权限
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS yes #是否使用dns反向解析,验证IP
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server

客户端登录服务器

ssh的安装时,如果需要连接远程服务器,那需要安装Client,如果我们需要本机作为服务器,那么需要安装Server。安装完成之后使用如下命令就可以登录远程服务器:

1
ssh  user@IP  -p 22  (默认情况下,客户端的ssh_config中端口号,要和我们远程服务器监听的端口号一致,也就是ssh_config里面监听的端口号一致)

口令验证

初次登录,客户端发送请求之后,服务器端会将公钥发送到客户端,为了防止中间人攻击,可以将接受到的公钥和服务器的公钥对比,一致则是安全的,继续下一步,输入密码,认证成功就可以。这是客户端接受到的公钥会将其通过MD5之后放在~/.ssh/hnown_hosts文件里面,下次登录不用进行公钥验证。

密钥验证

上面步骤可知,通过输入密码进行登录安全性较低,容易受到中间人攻击。密钥登录也称为免密登录。上面口令验证时候,客户端已经获得服务器的公钥,现在我们客户端也生成一组密匙,将客户端的公钥放到服务器的~/.ssh/authorized_keys ,这样就可以实现免密登录。具体过程如下:

  1. 服务器收到客户端发送的用户名和IP之后,在authorized_keys 需要匹配的公钥,如果匹配就随机生成一个字符串然后通过authorized_keys 里面的公钥加密,发送给客户端。
  2. 客户端收到密文之后使用自己的私钥解密,然后将解密的数据使用服务器的公钥加密,发送给服务器。
  3. 服务器将接收到的字符串解密然后和之前对比,如果相同,则认证成功。

方式一(手动)

  1. 客户端生成密钥对,命令如下:

    1
    ssh-keygen -t rsa
  2. 一路默认执行就可以,然后会在该用户的家目录下生成一个.ssh目录,将里面的id_rsa.pub内容,拷贝到服务器用户家目录~/.ssh/authorized_keys 里面,若不存在,手动创建就可以。(一般root是会禁止直接登录ssh,普通用户又没有authorized_keys(authorized_keys所属用户和组为root)权限,需要sudo,借用root权限)

  3. 完成

方拾二(使用命令)

  1. 执行命令:

    1
    ssh-keygen -t rsa
  2. 家目录会有~/.ssh,会有(id_rsa)私钥和(id_rsa.pub)公钥文件,

  3. 使用命令将公钥Copy到服务器

    1
    ssh-copy-id 用户名@iP    -p  端口号
  4. 注意:由于普通用户没有authorized_keys权限,root禁登录SSH,有可能写入不进去,可以使用密码登录上去,更改其权限,写入完成之后再禁用。

-------------本文结束感谢您的阅读-------------