原文链接:http://www.gaoxuan1989.com/2018/04/13/scp_file_between_two_linux_server/
前言
在工作中,经常需要发布代码到服务器,之前使用rz的方式上传zip的压缩包,可还是有些不智能,于是想到怎么通过scp的方式上传到服务器。
于是我就想到使用git bash的scp方法来操作,使用过scp的都知道需要指定远端服务器的帐号并手动输入密码,下面就讲一下如何避免每次都需要输入密码这个操作。
建立ssh的信任关系
在这里先介绍两个概念:SSH公钥(~/.ssh/id_rsa.pub)和公钥授权文件(~/.ssh/authorized_keys),这两个文件的作用具体可以参考ssh的man手册:
~/.ssh/id_rsa.pub
Contains the public key for authentication. These files are not sensitive and can (but need not) be readable by anyone.
~/.ssh/authorized_keys
Lists the public keys (DSA/ECDSA/RSA) that can be used for logging in as this user. The format of this file is described in the sshd(8) manual page. This file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others.
从描述中我们可以知道,~/.ssh/id_rsa.pub文件中包含了认证的公钥信息,而且该文件可以被任何人读取;而~/.ssh/authorized_keys文件中则列举了登录用户的公钥信息(换句话说就是使用这些公钥信息可以登录当前设备),而为了安全考虑,该文件一般建议只有本用户可以有读写权限(这条信息很关键,后面会讲)。
公钥和私钥
提到公钥对应的就会有私钥,在谈这两个概念之前我们先了解另外一组概念:加密和认证。
- 加密是对数据进行处理,添加保护信息,如果非法用户得到被加密过的数据,也无法获取到原始的有效数据内容,所以加密的重点在于数据的安全性。
- 认证是对数据进行处理,添加鉴权信息,如果在传输的过程中被非法篡改,接收方就会校验失败并丢弃该非法数据,所以认证的重点在于数据的合法性。
上面是从业务概念来上描述了加密和认证的区别,但是从具体技术实现上,认证使用的是加密中的非对称加密算法来实现鉴权和认证的操作。
- 对称加密算法在加密和解密时使用的是同一个秘钥;
- 非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。
下面就分别描述一下,采用非对称算法(即使用公钥和私钥)的加密和认证各自的过程。
基于公钥和私钥的加密过程
有两个用户Alice和Bob,Alice想把一段数据加密后发送给Bob(注意这里强调的是数据的安全性),那么如何保证除了Bob之外的人即使窃取了数据也无法解密得到原始的数据?基于公钥和私钥的加密可以完成这个需求,具体流程如下:
- Bob将他的公钥发送给Alice
- Alice用Bob的公钥加密需要传输的数据然后发送给Bob
- Bob用他的私钥解密Alice的消息
基于公钥和私钥的认证过程
还是Alice和Bob,Alice想把一段数据发送给Bob(注意这里并不强调数据的安全性),当Bob收到数据时如何判断该数据确实是Alic发送的且传输过程中没有被篡改?基于公钥和私钥的认证可以完成这个需求,具体流程如下:
- Alice用她的私钥对数据加密(或者对于数据的哈希值进行加密作为签名)
- Alice将加密后的数据(或者明文数据+签名)发送给Bob
- Bob用Alice的公钥解密数据(或校验签名),如果解密(校验)成功则可以保证数据的发送方肯定是Alice
基于公钥和私钥的信任关系
了解了公钥/私钥以及加密/认证这些概念后,我们就可以在scp中使用公钥/私钥来建立一个信任关系,从而在数据传输时完成自动认证而无需输入密码。
- User在A主机将SCP请求使用自己的私钥进行加密,然后传输给B主机
- B主机在收到SCP请求时,使用User的公钥进行解密
- 如果解密成功,则表示该请求确实是User发送的请求,则允许操作;如果解密失败,则表示该请求无效,直接丢弃
所以这里的需要做的就是:
- User在A主机上需要创建一个公私钥对
- 在B主机上,将User在A主机的公钥加入到ssh的信任公钥列表中(即公钥授权文件)
创建公私钥对
在Linux上使用ssh-keygen工具来生成公私钥对,在man手册中关于ssh-keygen工具的说明如下:
ssh-keygen : authentication key generation, management and conversion
-t type
Specifies the type of key to create. The possible values are 'rsa1' for protocol version 1 and 'dsa', 'ecdsa', 'ed25519', or 'rsa' for protocol version 2.
在上面提到了ssh-keygen支持rsa1、dsa、ecdsa、ed25519和rsa这几种非对称加密算法,其中最常用的就是RSA和DSA,比如使用RSA算法来生成公私钥对的过程如下:
nfer@nfer-VirtualBox:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/nfer/.ssh/id_rsa):
Created directory '/home/nfer/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/nfer/.ssh/id_rsa.
Your public key has been saved in /home/nfer/.ssh/id_rsa.pub.
The key fingerprint is:
16:77:45:71:31:7c:67:4f:91:09:07:74:4d:30:83:48 nfer@nfer-VirtualBox
The key's randomart image is:
+--[ RSA 2048]----+
| .E..*@XO|
| . ..oBB|
| . . . o+|
| o . .|
| S |
| . |
| |
| |
| |
+-----------------+
nfer@nfer-VirtualBox:~$
注意上面有三处需要输入信息,分别是:
- 存储公私钥的文件夹位置,如果不输入,则默认为~/.ssh/,文件名则默认是id_rsa和id_rsa.pub
- 使用该公私钥时是否需要密码,如果不输入则表示不需要密码
- 再次确认是否需要密码
将User在A主机的公钥加入到ssh的信任公钥列表中
将刚才创建的~/.ssh/id_rsa.pub文件中的内容拷贝添加到B主机上的~/.ssh/authorized_keys文件中(如果没有则创建一个),这个时候就建立了一条A-->B的信任关系。注意这个信任关系是有方向性的,如果要建立从B-->A的信任关系,则操作步骤和上面的类似,只不过要反过来。
注:上面讲过,.ssh文件建议只给只有本用户可以有读写权限,所以需要执行权限设置的命令,否则会不成功:
chmod -R 700 ~/.ssh/
chmod 600 ~/.ssh/authorized_keys
建立好信任关系后,这个时候使用任何ssh相关的工具则都无需输入远端的登陆密码(如果在创建公私钥对时输入了密码,那么这个时候还需要输入这个密码才能使用公私钥对)。