转自:绛洞花主敏明 什么是SSH 以及常见的ssh 功能_绛洞花主敏明的博客-CSDN博客_ssh功能
一、SSH
SSH只是一种协议,存在多种实现,既有商业实现,也有开源实现。本文针对的实现是OpenSSH,它是自由软件,应用非常广泛。这里只讨论SSH在Linux Shell中的用法。如果要在Windows系统中使用SSH,会用到另一种软件PuTTY,这需要另文介绍。
SSH之所以能够保证安全,原因在于它采用了公钥加密
整个过程是这样的:
(1)远程主机收到用户的登录请求,把自己的公钥发给用户。
(2)用户使用这个公钥,将登录密码加密后,发送回来。
(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,
但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。
可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。
再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。
这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。
二、ssh的安装
SSH分客户端openssh-client和openssh-server
如果你只是想登陆别的机器的SSH只需要安装openssh-client(ubuntu有默认安装,如果没有则sudoapt-get install openssh-client),如果要使本机开放SSH服务就需要安装openssh-server。
sudo apt-get install openssh-client
sudo apt-get install openssh-server
启动ssh服务
sudo /etc/init.d/ssh start
停止和重启ssh服务的命令如下:
sudo /etc/init.d/ssh stop #server停止ssh服务
sudo /etc/init.d/ssh restart #server重启ssh服务
三、ssh中的四个文件
id_rsa:私钥
id_rsa.pub:公钥
known_hosts:存储的是远端主机的公钥(例子中的主机A,主动发起连接者,保存B的公钥)
authorized_keys:存储的远端主机的公钥(例子中的B,被动连接者,保存A的公钥)-是授权文件,是在ssh-copy-id命令之后,保存的A的公钥,否则一般不会保存A的公钥。
例:A通过ssh首次连接到B,B会将公钥1(host key)传递给A,A将公钥1存入known_hosts文件中,以后A再连接B时,B依然会传递给A一个公钥2,OpenSSH会核对公钥,通过对比公钥1与公钥2 是否相同来进行简单的验证,如果公钥不同,OpenSSH会发出警告, 避免你受到DNS Hijack之类的攻击。
两者之间的区别:
这里面要明确known_hosts和authorized_keys两个文件的区别:
known_hosts文件是存放已经主机的公钥,也就是说当你使用别的主机连接本台机器的时候,例如hadoop@slave01$ ssh master的时候,如果第一次连接,known_hosts为空,此时会发生warning信息,提醒是否连接,确定连接才会让你输入密码连接,然后便会把master的公钥添加到known_hosts中,下次只需要直接输入master密码连接即可。
而authorized_keys文件是实现真正无密码连接,即为授权文件,当把master的公钥添加到authorized_keys文件中后,下次连接直接输入ssh master即可,不需要再次输入密码
四、ssh中口令登录
口令登录非常简单,只需要一条命令,命令格式为: ssh 客户端用户名@服务器ip地址
ssh ldz@192.168.0.1
如果需要调用图形界面程序可以使用 -X 选项
ssh -X ldz@192.168.0.1
如果客户机的用户名和服务器的用户名相同,登录时可以省略用户名。
ssh 192.168.0.1
还要说明的是,SSH服务的默认端口是22,也就是说,如果你不设置端口的话登录请求会自动送到远程主机的22端口。我们可以使用 -p 选项来修改端口号,比如连接到服务器的1234端口:
ssh -p 1234 ldz@192.168.0.1
如果是第一次登录远程主机,系统会给出下面提示:
在这里插入图片描述
意思是,该远程主机的真实性无法确定,其公钥指纹为 SHA256:FFobshqrGOachj7Xp4LsJ9+xkNBlyyOe8ZIPl7K+qQI,确定想要继续连接吗?
输入yes即可。这时系统会提示远程主机被添加到已知主机列表。(known_hosts)
在这里插入图片描述
然后会要求我们输入远程主机的密码,输入的密码正确就可以成功登录了。命令提示符会修改为远程主机的提示符,现在开始,终端中输入的命令都将在服务器中执行。
以后在每次通过这种方式进行登陆时,在输入账号密码时,远程主机会将起存储的公钥发送过来与该主机的主机列表known_hosts报错的远程主机的公钥进行比对,如果正确则可以进行直接输入账号密码进行连接,此时不会再弹出警告。但是仍然需要输入账号密码。
注意:远程主机不会存储master主机的公钥,除非是下边的公钥登陆方式。
五、ssh中公钥登录
每次登录远程主机都需要输入密码是很不方便的,如果想要省去这一步骤,可以利用密钥对进行连接,还可以提高安全性
1、在本机生成密钥对
使用ssh-keygen命令生成密钥对
ssh-keygen -t rsa #-t表示类型选项,这里采用rsa加密算法
此时也可以直接用ssh-keygen 命令,不增加后边的参数,是一样的效果
然后根据提示一步步的按enter键即可(其中有一个提示是要求设置私钥口令passphrase,不设置则为空,这里看心情吧,如果不放心私钥的安全可以设置一下),执行结束以后会在 /home/当前用户 目录下生成一个 .ssh 文件夹,其中包含私钥文件 id_rsa 和公钥文件 id_rsa.pub。
2、将公钥复制到远程主机中
使用ssh-copy-id命令将公钥复制到远程主机。ssh-copy-id会将公钥写到远程主机的 ~/ .ssh/authorized_key 文件中
ssh-copy-id ldz@192.168.0.1
经过以上两个步骤,以后再登录这个远程主机就不用再输入密码了。
六:应用
反向端口转发:例子1
相信很多人都会有这样的需求:我实验室的机器和宿舍的机器都处在局域网中,但我需要在宿舍访问实验室的机器,或者反过来。这个时候,你需要一台处在公网的机器,如果没有的话,可以考虑腾讯云或者阿里云的学生优惠。
假设现在你有一台处在公网的机器 jumpbox,这台机器是在任何地方都能访问到的;你在实验室也有一台机子 lab,这台机子只能在实验室内部访问,但他可以访问公网,你希望能在任何地方都能访问这台机器。使用 ssh -R 可以轻松地做到这个事情。
lab$ ssh -R 10022:localhost:22 jumpbox
jumpbox$ ssh user@localhost -p 10022
lab$
如果上面这个过程成功了,就说明在你执行 ssh -R 10022:localhost:22 jumpbox 之后,你成功地将 lab 上的 22 端口反向转发到了 jumpbox 的 10022 端口。只要保持这个 ssh 不断,任何一台机器都可以首先连接到 jumpbox,然后通过 ssh user@localhost -p 10022 连回到 lab。可以看到,这里 jumpbox 起到了一个跳板的作用,所以我们把它称作跳板机。
不过上面这么做并不稳健,如果因为网络波动导致 ssh -R 那个连接断了,那么从 jumpbox 就完全失去了到 lab 的控制。万幸的是,有一个叫做 autossh 的软件,可以自动的检测断线,并在断线的时候重连。在 Ubuntu 上你可以使用 sudo apt-get install autossh 来安装,在 Mac 上则是 brew install autossh。
lab$ autossh -NfR 10022:localhost:22 jumpbox
上面这句话里面 -N 表示非不执行命令,只做端口转发;-f 表示在后台运行,也就是说,这句话执行之后 autossh 就在后台默默工作啦;-R 10022:localhost:22 就是把本地的22端口转发到远程的10022端口。
现在,任何一台电脑先连上跳板机,就可以连回内网的机子啦!
你甚至可以将这句话设置为开机时运行:在 /etc/rc.local 里面 exit 0 这句话之前加上
su - user -c autossh -NfR 10022:localhost:22 jumpbox
其中 user 是你的用户名。需要注意的是,如果你需要开机时运行 autossh,你需要配置公钥登入,因为开机运行的时候是没有交互界面让你来输入密码的。
这里顺带说一句,你可以绑定1024到65535之间的任意端口,只要这个端口之前没有程序在用就行。
反向端口转发:例子2
还是反向端口转发,再举一个很常见的例子:我在本地跑了一个网站,我想临时把我的网站发给朋友看看。你可以很容易的复现这个实验:在本地运行 python -m SimpleHTTPServer 即可在本地的8000端口启动一个网站,你可以在浏览器中通过 http://localhost:8000/ 看到。下面我们想让远方的朋友看到这个网站。
local$ ssh -NR 0.0.0.0:18000:localhost:8000 jumpbox
远方的朋友即可通过 http://jumpbox:18000/ 看到了。注意到这里和上面的命令有一个小小的不同,就是多了 0.0.0.0,这告诉 ssh,要把18000端口绑定在远端的所有IP上。如果像之前那样省略的话,缺省值是只绑定在 localhost,也就是只有在 jumpbox 本机才可以访问,而其他人都不能访问。
反向端口转发:例子3
比方说在本地的127.0.0.1:1080运行了HTTP代理服务,现在我想让另一台机子 remote 也能够使用这个HTTP代理。
local$ ssh -NR 11080:localhost:1080 remote
local$ ssh remote
remote$ export http_proxy=http://127.0.0.1:11080/
remote$ export https_proxy=http://127.0.0.1:11080/
remote$ curl http://ifconfig.co
看看返回的IP,是不是 remote 也用上了代理?
正向端口转发
反向端口转发是把本机的端口转发到远程的机子上;与之对应,正向端口转发则是把远程的端口转发到本地。
比方说,之前我们把 lab 的22端口反向转发到了 jumpbox 的10022端口,现在我想把它转发到本机的20022端口,只需要执行 ssh -L 就行了,例如:
local$ ssh -NL 20022:localhost:10022 jumpbox
local$ ssh localhost -p 20022
lab$
用作 SOCKS5 代理
要是想要在家访问公司内网的一些网站,但是公司又没有提供进入内网的VPN,那怎么办呢?通过 ssh -D 可以在本地建立起一个 SOCKS5 代理:
local$ ssh -ND 1080 workplace
如果 workplace 处在内网,不要忘记前面讲到可以用反向端口转发和跳板机来解决这个问题。现在,你可以在浏览器的设置里面,把代理服务器设成 socks5://127.0.0.1:1080,然后你就可以看到 workplace 能看到的所有网站啦。
传递图形界面
上面我们都是在运行命令行程序,那如果远程有一些程序是不得不用图形界面的话,是不是无解了呢?实际上,恰恰相反,X11的设计天生就支持这样的行为。
首先,我们需要在本机装上 X Server:Linux 桌面用户本身就已经有了 X Server,Windows 用户可以使用 Xming,Mac 用户需要使用 XQuartz。
安装好了 X Server 之后,我们通过 ssh -X 进行连接,例如:
local$ ssh -X remote
remote$ xeyes
现在你应该会看到一对傻傻的眼睛,这就说明成功了,注意,这个眼睛是跑在远程的,而输入和输出都是在本地。这个方法几乎可以运行任何图形界面的程序,比如你可以试试看运行 nautilus 或者 firefox。
————————————————
版权声明:本文为CSDN博主「绛洞花主敏明」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39852676/article/details/123722581