路漫漫其修远兮
吾将上下而求索

ssh原理和配置

也是先来张图镇楼

ssh.png

1、介绍

Secure Shell(缩写为SSH),由IETF的网络工作小组(Network Working Group)所制定;SSH为一项创建在应用层和传输层基础上的安全协议,为计算机上的Shell(壳层)提供安全的传输和使用环境。

传统的网络服务程序,如rsh、FTP、POP和Telnet其本质上都是不安全的;因为它们在网络上用明文传送数据、用户帐号和用户口令,很容易受到中间人(man-in-the-middle)攻击方式的攻击。就是存在另一个人或者一台机器冒充真正的服务器接收用户传给服务器的数据,然后再冒充用户把数据传给真正的服务器。

而SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。通过SSH可以对所有传输的数据进行加密,也能够防止DNS欺骗和IP欺骗。

SSH之另一项优点为其传输的数据可以是经过压缩的,所以可以加快传输的速度。SSH有很多功能,它既可以代替Telnet,又可以为FTP、POP、甚至为PPP提供一个安全的“通道”。

SSH是每一台Linux电脑的标准配置。SSH具备多种功能,可以用于很多场合。有些事情,没有它就是办不成。本文是我的学习笔记,总结和解释了SSH的常见用法,希望对大家有用。虽然本文内容只涉及初级应用,较为简单,但是需要读者具备最基本的"Shell知识"和了解"公钥加密"的概念

2、命令和参数

rpm包列表,openssh-clients是客户端类似于mysql命令,openssh-server是服务端,类似于mysql-server

[root@localhost ~]#rpm -ql openssh-clients
/etc/ssh/ssh_config
/usr/bin/.ssh.hmac
/usr/bin/scp
/usr/bin/sftp
/usr/bin/slogin
/usr/bin/ssh
/usr/bin/ssh-add
/usr/bin/ssh-agent
/usr/bin/ssh-copy-id
/usr/bin/ssh-keyscan

[root@localhost ~]#rpm -ql openssh
/etc/ssh
/etc/ssh/moduli
/usr/bin/ssh-keygen

[root@localhost ~]#rpm -ql openssh-server
/etc/pam.d/ssh-keycat
/etc/pam.d/sshd
/etc/rc.d/init.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd
/usr/libexec/openssh/sftp-server
/usr/libexec/openssh/ssh-keycat
/usr/sbin/.sshd.hmac
/usr/sbin/sshd

ssh – OpenSSH SSH client (remote login program)

ssh [-p port]  [user@]hostname [command]

3、通用示例

SSH主要用于远程登录。假定你要以用户名user,登录远程主机host,只要一条简单命令就可以了。

[root@localhost ~]#ssh user@host

如果本地用户名与远程用户名一致,登录时可以省略用户名。即如果当前用户是root,则登录到远程服务器上面就是root用户,如果当前用户是andy用户,登录到远程服务器上面就是andy用户

[root@localhost ~]#ssh host

SSH的默认端口是22,你的登录请求会送进远程主机的22端口。如果远程主机的ssh端口不是22,可以使用p参数,可以修改这个端口

[root@localhost ~]#ssh -p 2222 user@host

4、密码登录

SSH之所以能够保证安全,原因在于它采用了公钥加密。

整个过程是这样的:(1)远程主机收到用户的登录请求,把自己的公钥发给用户。(2)用户使用这个公钥,将登录密码加密后,发送到远程主机。(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。

这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。

如果你是第一次登录对方主机,系统会出现下面的提示:

当前主机:192.168.175.11,远程主机:192.168.175.12

[root@localhost ~]#ll .ssh/    #当前家目录下的.ssh目录里面是空的
total 0
[root@localhost ~]#ssh 192.168.175.12
The authenticity of host '192.168.175.12 (192.168.175.12)' can't be established.
RSA key fingerprint is ae:9c:1b:2b:fc:80:04:21:e4:7b:44:14:6c:2c:c9:cc.
Are you sure you want to continue connecting (yes/no)? yes

这段话的意思是,无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?

所谓"公钥指纹",是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。上例中是ae:9c:1b:2b:fc:80:04:21:e4:7b:44:14:6c:2c:c9:cc,再进行比较,就容易多了。

很自然的一个问题就是,用户怎么知道远程主机的公钥指纹应该是多少?回答是没有好办法,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对。

假定经过风险衡量以后,用户决定接受这个远程主机的公钥。系统会出现一句提示,表示host主机已经得到认可。

Warning: Permanently added '192.168.175.12' (RSA) to the list of known hosts.
root@192.168.175.12's password: 
Last login: Sun May 14 14:50:47 2017 from 192.168.175.11
[root@localhost ~]#exit    #这里可以成功登录到远程主机,然后退出
logout
Connection to 192.168.175.12 closed.
[root@localhost ~]#ll .ssh/    #当前是:192.168.175.11主机
total 4
-rw-r--r-- 1 root root 396 May 14 14:59 known_hosts
[root@localhost ~]#cat .ssh/known_hosts 
192.168.175.12 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAz9N6173UacXUCwTyHDUrvkHq        #太长了,在这里换行了
NnzGP3LnyV4NaNarIzK4S+lts4tI5NWdXaxmkCU8H0B7NBpIIQdzDSCbzXofWbUgkFe+5X5Cy9/
M9UEwXoy9HwER5xg5polz1UHtxK0cLug0QMpgg7QpPQaHtE60Bsbyvw8kxZI3LnlozoahUiHxXV
402YQb2KPw5mP9Zj4j3jKXbV200Py0mwcZ+/ecZtigJ5nvDOG73WMRxXVFMI5VXsNaDSuxXZEry
+1rJCuytL6s2L/v2Ty4sUNTESSvmcZwITPv0DPBTKIOGoKcxgFeDXQetuEHHJjyeZb+klyX2amsK50i0E5k7J/qyetBGw==

当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。

每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts,保存一些对所有用户都可信赖的远程主机的公钥。

如果是andy用户登录后远程连接的,则上面的文件保存在andy用户的家目录下面

上面访问的远程主机(192.168.175.12)对应的公钥文件在sshd的配置文件:以及对应的公钥文件,和上面的是相同的

主机(192.168.175.12)
[root@localhost ~]#vim /etc/ssh/sshd_config 
#HostKey /etc/ssh/ssh_host_rsa_key

[root@localhost /etc/ssh]#cat ssh_host_rsa_key.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAz9N6173UacXUCwTyHDUrvkHqNnzGP3LnyV4Na
NarIzK4S+lts4tI5NWdXaxmkCU8H0B7NBpIIQdzDSCbzXofWbUgkFe+5X5Cy9/M9UEwXoy9Hw
ER5xg5polz1UHtxK0cLug0QMpgg7QpPQaHtE60Bsbyvw8kxZI3LnlozoahUiHxXV402YQb2KP
w5mP9Zj4j3jKXbV200Py0mwcZ+/ecZtigJ5nvDOG73WMRxXVFMI5VXsNaDSuxXZEry+1rJCuy
tL6s2L/v2Ty4sUNTESSvmcZwITPv0DPBTKIOGoKcxgFeDXQetuEHHJjyeZb+klyX2amsK50i0E5k7J/qyetBGw==

5、公钥登录

使用密码登录,每次都必须输入密码,非常麻烦。好在SSH还提供了公钥登录,可以省去输入密码的步骤。

所谓"公钥登录",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。

这种方法要求用户必须提供自己的公钥。如果没有现成的,可以直接用ssh-keygen生成一个:

[root@localhost ~]#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:
e9:d4:c0:24:5c:3f:f7:3c:0c:2e:6f:f2:9d:c5:42:d1 root@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
|     ...o        |
|      .+ .     . |
|        o o o . E|
|         + + = . |
|        S o . *  |
|       o   o . o |
|        . . o . o|
|           + . + |
|            . o  |
+-----------------+

运行上面的命令以后,系统会出现一系列提示,可以一路回车。其中有一个问题是,要不要对私钥设置口令(passphrase),如果担心私钥的安全,这里可以设置一个。

运行结束以后,在$HOME/.ssh/目录下,会新生成两个文件:id_rsa.pub和id_rsa。前者是你的公钥,后者是你的私钥。

[root@localhost ~]#ll .ssh/
total 12
-rw------- 1 root root 1675 May 14 15:35 id_rsa
-rw-r--r-- 1 root root  408 May 14 15:35 id_rsa.pub
-rw-r--r-- 1 root root  396 May 14 14:59 known_hosts
[root@localhost ~]#cat .ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAwSkMZnb7GjqufBLISp3WjFatDJw1wVzgH9hB/tIvreRkQSg1
zl7kHfOZupjTBwP4fMIRb2HB5uB2tfFw9zGKevNIxooKrOsyAKilQ60rP0xXl21A
UI+0a8dZujSzpKGip8GG0bHpS7uHZSpmI6I8wYZ7cEeFc8tS8RVFW219QmSjqU13
WJBVlvdFF1nKjwaamds/5cmL3oQdKU7mO5k9XMMY2p++4Yc5GmMTUTImeXD46y/F
vRz6/o/GhHwt6XpxRgH34YDWR6+gbS1SrlcDVJWdZDKxRG8wLorljiIwTlmtLH3D
CwlKx/J2hVGUQvlK00UM7jmXR7PDhy1Kfx4cWQIBIwKCAQBYTUd/TFWIVVcUJdfn
mJyX7RvogeywKnUV3zQct9tILeSwEmG9bTUVAaVcnaJMWZYqZ1htboSGzQMRWG4n
3CIMUfViEzgUiMZms36/2iJmFEVMibcAQbGQWyG0NVlv1Nykdbn5deb+DJWqlwoe
6xR1udIHcScQXPK3Wi5VrmUlqYxZc95GBO5bOkxQUokRjDXOtp128U9QXcKHm0fq
Zb3S4+M/29vvDN6MToLSZ6CCApOpNyOMF+77q6kR7w6M70mpe4FGZfCGwamLQErM
v6adIQsOGOrX/mB8DQlvGkgUsVtKN31pxSrMPmagq5anvGX1Tl4PzB3HykzoUruy
ZY6LAoGBAP3aTpU5gfz8o5oHZ/paYmPZ22TO0V5gR108GaVf63T3/h3Zxz49Rq1V
86XkeWSMJf3WJjVSR6+Y3ZrHUo9dWJKJyqJY6Dx9Z+B1APouO6+3Ak0wUMvnxrgC
Bv+3mqxG+Lh5LRjfosKOG9nZ5E1PG+pNCFmsOAWuw0F2YFE8CzzdAoGBAMLLUWvl
448yxCQgPUReQYEL0GKiyE/+b6ZkkZOK7zkncnnlJ4+JVGTxg69AdhLQ5VgS4PKo
YPCfKqnl7q631m2ZeSq+mZujgB0Xj7TgOBcl2wgFC2OkLAUdJ2EzfgZaHP0A90fU
BzqbDhwr9e1k8UF9oUV/cxBz5fnUl/6s1LetAoGAe0zHFUfRbEAyNN8GnivmpYcS
ypBXEJUp+hXgkidGeqRW20yFWL6tTOCa6i0lBPOdbKnYC0U4wwEbLevJA85A9rf0
tUEgV+Uj02wHyfky7vJ9dfLlalqiWWASBy1LIHo+SvkHRpiCQT21wZW4CEr+7iVq
dLK8IARtd5FEub4UFj8CgYEAshj5/D/l/0Rbjr5j5ryTqS9fcB/NFe/xDSi/nNbM
Fv9+m1Ure+tF2KJMgvkbfurgUIZKAm4PfOlLlAVsgnwxw0p9aOjG9LK+RnvxGmaZ
rsOGbbt4IJYZnkaKZ3+JKmEEj4vaxVQj3c+X3z4irSkXF05KTith4ygiuIfbbIDC
fAsCgYBhMJMTHn88YTVNWpAVaFEKXhlJrzuX/vKJS+ttBXWQDMDQe0ZYkAqEme3F
jut1FPNC0E+TvHxWP/K1lyPotsNaq3zaN9vf6KfDuLC3JIW9hvvCtmAIhpyri0lb
wGoxf20SKLu2/PH+PcFU8cZ6uFWciVnhsfvSIjfwVxws0UOQOg==
-----END RSA PRIVATE KEY-----
[root@localhost ~]#cat .ssh/id_rsa
id_rsa      id_rsa.pub  
[root@localhost ~]#cat .ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwSkMZnb7GjqufBLISp3WjFatDJw1wV
zgH9hB/tIvreRkQSg1zl7kHfOZupjTBwP4fMIRb2HB5uB2tfFw9zGKevNIxooKrOsy
AKilQ60rP0xXl21AUI+0a8dZujSzpKGip8GG0bHpS7uHZSpmI6I8wYZ7cEeFc8tS8RV
FW219QmSjqU13WJBVlvdFF1nKjwaamds/5cmL3oQdKU7mO5k9XMMY2p++4Yc5GmMTUT
ImeXD46y/FvRz6/o/GhHwt6XpxRgH34YDWR6+gbS1SrlcDVJWdZDKxRG8wLorljiIwT
lmtLH3DCwlKx/J2hVGUQvlK00UM7jmXR7PDhy1Kfx4cWQ== root@localhost.localdomain

这时再输入下面的命令,将公钥传送到远程主机host上面:此命令的作用就是将:.ssh/id_rsa.pub 里面的内容追加到远程服务器root用户的家目录下的:.ssh/authorized_keys文件中

[root@localhost ~]#ssh-copy-id root@192.168.175.12
root@192.168.175.12's password: 
Now try logging into the machine, with "ssh 'root@192.168.175.12'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

好了,从此你再登录,就不需要输入密码了。修改本机的hostname,依然可以进行正常的操作,不受影响

[root@abc ~]#ssh root@192.168.175.12 "mkdir /tmp/eabc"    #不用输入密码

本地主机之所以能够识别这个私钥是因为ssh的配置文件里面定义了,注意是本机客户端配置文件,不是本机服务端配置文件,如果将此目录修改了,登录的时候ssh检测不到有私钥,会让输入密码

[root@abc ~]#vim /etc/ssh/ssh_config 
 #   IdentityFile ~/.ssh/identity
 #   IdentityFile ~/.ssh/id_r
 #   IdentityFile ~/.ssh/id_dsa

如果还是不行,就打开远程主机的/etc/ssh/sshd_config这个文件,检查下面几行前面"#"注释是否取掉。

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

6、authorized_keys文件

远程主机将用户的公钥,保存在登录后的用户主目录的$HOME/.ssh/authorized_keys文件中。公钥就是一段字符串,只要把它追加在authorized_keys文件的末尾就行了。

这里不使用上面的ssh-copy-id命令,改用下面的命令也可以进行,解释公钥的保存过程:

# ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub

这条命令由多个语句组成,依次分解开来看:(1)"$ ssh user@host",表示登录远程主机;(2)单引号中的mkdir .ssh && cat >> .ssh/authorized_keys,表示登录后在远程shell上执行的命令:(3)"$ mkdir -p .ssh"的作用是,如果用户主目录中的.ssh目录不存在,就创建一个;(4)'cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub的作用是,将本地的公钥文件~/.ssh/id_rsa.pub,重定向追加到远程文件authorized_keys的末尾。

写入authorized_keys文件后,公钥登录的设置就完成了。

7、如果所有配置都正确,但是ssh公钥认证还是不成功,可以尝试修改sshd配置

StrictModes no

StrictModes no #修改为no,默认为yes.如果不修改用key登陆是出现server refused our key(如果StrictModes为yes必需保证存放公钥的文件夹的拥有与登陆用户名是相同的.“StrictModes”设置ssh在接收登录请求之前是否检查用户家目录和rhosts文件的权限和所有权。

未经允许不得转载:江哥架构师笔记 » ssh原理和配置

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址