Secure Shell(SSH 安全外壳协议) 是由 IETF(The Internet Engineering Task Force) 制定的建立在应用层基础上的安全网络协议。它是专为远程登录会话(甚至可以用Windows远程登录Linux服务器进行文件互传)和其他网络服务提供安全性的协议,可有效弥补网络中的漏洞。通过SSH,可以把所有传输的数据进行加密,也能够防止DNS欺骗和IP欺骗。还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。
SSH最初是UNIX系统上的一个程序,后来又迅速扩展到其他操作平台。SSH在正确使用时可弥补网络中的漏洞。
优点:
- 安全
- 方便!两台机器间不用输入账号密码就可验证身份!(通过保存在服务器和客户端上的密钥);
ssh可以传输文本与二进制文件;
主要应用:
- 远程登录(可免密码)、github仓库操作
- 文件传输(如hdfs)
SSH的安全机制
SSH之所以能够保证安全,原因在于它采用了==非对称加密技术(RSA)==加密了所有传输的数据。
传统的网络服务程序,如FTP、POP和Telnet其本质上都是不安全的;因为它们在网络上用明文传送数据、用户帐号和用户口令,很容易受到中间人(man-in-the-middle)攻击方式的攻击。就是存在另一个人或者一台机器冒充真正的服务器接收用户传给服务器的数据,然后再冒充用户把数据传给真正的服务器。
但并不是说SSH就是绝对安全的,因为它本身提供两种级别的验证方法:
- 第一种级别(基于口令的安全验证):只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人攻击”这种方式的攻击。
传统的账号密码验证?
- 第二种级别(基于密钥的安全验证):你必须为自己创建一对密钥,并把公钥放在需要访问的服务器上。如果你要连接到SSH服务器上,客户端软件就会向服务器发出请求,请求用你的密钥进行安全验证。服务器收到请求之后,先在该服务器上你的主目录下(该服务器上你用的账号)寻找你(客户端)的公钥,然后把它和你发送过来的公钥进行比较。如果两个密钥一致,服务器就用公钥加密“质询”(challenge)并把它发送给客户端软件。客户端软件收到“质询”之后就可以用你的私钥在本地解密再把它发送给服务器完成登录。与第一种级别相比,第二种级别不仅加密所有传输的数据,也不需要在网络上传送口令,因此安全性更高,可以有效防止中间人攻击。
使用
- 有没有命令行传文件的例子?传id的是个专门的命令
通常使用的软件工具为OpenSSH,在windows>system下可以看到OpenSSH的众多命令
基于密钥的安全验证-事前准备
常用于免密登录。如果想通过输入密码的方式登录则不需要这步准备。
在本机生成一对密钥(即私钥与公钥):
ssh-keygen -t rsa #-t表示类型选项,这里采用rsa加密算法
# -C 添加注释,如github账号
然后根据提示一步步的按enter键即可(其中有一个提示是要求设置私钥口令passphrase,不设置则为空,这里看心情吧,如果不放心私钥的安全可以设置一下),执行结束以后会在当前用户目录下生成一个 .ssh 文件夹,其中包含私钥文件 id_rsa 和公钥文件 id_rsa.pub。(还有个known_hosts,用于记录曾经连接过的主机域名、ip、?钥)
将公钥复制到远程主机中
使用ssh-copy-id命令将公钥复制到远程主机。ssh-copy-id会将公钥写到远程主机的 ~/ .ssh/authorized_keys文件中
ssh-copy-id 用户名@ip
这样以后登录这台远程主机就不用账号密码了
注: windows环境下没有
ssh-copy-id
命令,如果碰到这种情况我们有两种处理方式,一种是在windows环境下打开git bash控制台(如果已经安装了),然后就可以在里面使用linux命令了;另一种方法就是使用scp等方式,或者手动复制粘贴,总之把自己的公钥添加到远程主机上
关键步骤:将
windows用户文件夹\.ssh\***.pub
文件复制到远程主机(linux为例)的~/.ssh/
文件夹下,修改目录权限为7000,并将文件名修改为authorized_keys,修改文件权限为600,该文件有规定如果属组其他人出现可写则文件就不会生效有些用户远程主机的用户名和当前电脑的用户名不一样,但不影响。虽然上传的公钥是当前用户的,但上传时指定了用户名,免密登录后操作的用户是上传密钥时指定的用户
服务端准备(一般不用管,默认就行)
centos7和windows默认带有SSH工具;可以用一下命令检查:
rpm -qa | grep ssh
首先确认服务器上的ssh-server是否已经启动了
ps -e | grep ssh
SSH默认使用22端口,注意开放端口。
每次使用SSH登录一台新的主机,就会将它添加到本机已知主机列表(known_hosts)。
远程登陆
ssh 用户名@ip [-p 端口号]
口令(密码)级别使用时会提示输入密码;
若不填写用户名,则会默认以当前计算机登录的用户名尝试登录服务器
**退出:**输入logout(linux命令?) 或者exit,或直接关闭终端/进程
1、从服务器上下载文件
scp username@servername:/path/filename /var/www/local_dir(本地目录)
例如scp root@192.168.0.101:/var/www/test.txt 把192.168.0.101上的/var/www/test.txt 的文件下载到/var/www/local_dir(本地目录)
2、上传本地文件到服务器
scp /path/filename username@servername:/path
拓展:
github、码云上的SSH
在网页端操作,为github/gitee账户生成SSH key公钥,这样github/gitee就通过公钥知道是哪个用户在github/gitee上操作;
除了账户SSH key外,仓库也有key,但只供拉取权限;
毕竟仓库拉可以随便拉,推需要验证身份;
这也是SSH相对于https的优越之处:每次fetch和push时不再需要麻烦地输入账号密码(远程登陆也不需要账号密码了;https可以通过在git配置账号密码的方式来免除每次都要输入账号密码的麻烦);
但似乎仓库的贡献者名单还是本地设置的用户,,不知道打卡记录有没有记录
生成ssh key时的random image
The key's randomart image is:
+--[ RSA 2048]----+
| o=. |
| o o++E |
| + . Ooo. |
| + O B.. |
| = *S. |
| o |
| |
| |
| |
+-----------------+
[ssh keygen 中生成的 randomart image 是什么 - 掘金(https://juejin.cn/post/6844903522060730381)
单纯用于方便比较