[工具]ssh的使用
ssh 是什么
ssh 是一种网络协议,用于计算机之间的加密登录。它具有多种实现,既有商业实现,也有开源实现。
下面讨论的是在 Linux shell 中用 ssh 的场景。
- ssh 的默认端口是 22,使用参数
-p
可以修改端口号
ssh 之所以能够保证安全,原因在于它采用了公钥加密。
ssh 的自定义设置
设置别名
-
在~/.ssh/文件夹下添加config文件
-
在config文件中输入
Host myserver #别名 HostName ip #server ip User user #username Port port #[optional]
之后输入
ssh myserver
即等价于ssh user@ip
ssh 连接远程主机的过程
(1)远程主机收到用户的登录请求,把自己的公钥发给用户。
(2)用户使用这个公钥,将登录密码加密后,发送回来。
(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。
可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么 ssh 的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。
ssh 协议是如何应对的呢?
-
如果是第一次登录对方主机,系统会提示
The authenticity of host 'host (12.18.429.21)' can't be established. RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d. Are you sure you want to continue connecting (yes/no)?
-
意思是,无法确认远程主机的真实性,只知道它的公钥指纹,是否还需要继续连接?
- 要保证安全性,远程主机必须先提供好自己的公钥指纹,用户在第一次连接时需要自行去核对 ssh 提示的信息是否与远程主机提供的一致。
-
继续连接,则意味着接受该公钥指纹,它将会被保存在本机的
$HOME/.ssh/known_hosts
文件中,下次再连接同一台远程主机时,本机系统就会认出它的公钥已保存在本地,从而跳过警告的部分,直接提示输入密码。
免密登录又是如何做到的呢?
通过使用公钥登录:
- 首先用户将自己的公钥存储
key_pub
在远程主机上 - 用户要登录远程主机的时候,远程主机会向用户发送一段随机字符串
str
- 用户接收到该字符串,用自己的私钥加密之后得到
encoded_str
,再发送给远程主机 - 远程主机用用户事先存储的公钥
key_pub
进行解密,如果成功,即decode(encoded_str) == str
,证明该用户是可信的,允许直接登录,不再要求密码。
具体过程如下:
-
本机输入命令
ssh-keygen -t rsa
,生成本机的公钥和私钥- 按照提示输入生成的文件路径等,默认的路径是
~/.ssh/id_rsa
- 假设输入的是
filename
,则在工作目录下有filename
,filename.pub
两个文件,前者是私钥,后者是公钥。 - 注意,最好放在本机的 ~/.ssh 文件夹下,不要放在其他地方。
- 假设输入的是
- 按照提示输入生成的文件路径等,默认的路径是
-
把本机的ssh公钥(.pub后缀的文件) 添加到远程主机的
~/.ssh/authorized_keys
文件中cat filename.pub >> ~/.ssh/authorized_keys
-
【本机是win10的话可能必须要弄这一步!】在本机的
.ssh/config
文件里面,相应远程主机的配置块中,加上一行IdentityFile: "$filepath"
filepath
是本机的 ssh 私钥文件的路径 -
然后就可以直接免密登录,输入
ssh username@host
即可【没有 username 是不可以的吧?。。
其他使用
putty远程连接 ssh 设置免密登录
copy ssh公钥并设置私钥即可
- 先用PuttyGen生成本机的ssh 私钥和公钥,保存成文件
- 把生成的ssh public key(字符串)拷贝到要登录的远程机器的用户目录 ~/.ssh/authorized_keys文件中
- 在Putty session为ssh 设置登录用户名以及私钥
- Done!
git 设置免密登录
用 http 地址 clone 远程仓库到本地时,每次在本地 push到远程或是从远程 pull,都需要再输入用户名和密码登录一遍 github,虽然可以设置记住用户名和密码,但是以明文的形式保存在本地文件;
用 ssh 则只需刚开始的时候添加本地的 ssh key到远程仓库即可,不需要每次重新输入用户名和密码
-
首先在本地通过
ssh-keygen
命令生成 ssh key -
将 公钥 添加到 github 账户
打开个人账户的
Settings->SSH key
,把公钥文件的内容拷贝进去 -
【如果私钥文件名不是默认的
~/.ssh/id_rsa
的话】,将 私钥 添加到本地的 ssh两种方式:
-
临时地,用
ssh-add
添加私钥 [ 每次换了个命令行窗口都要再执行一遍 ]eval `ssh-agent -s` #先运行 ssh-agent #注意不要同时运行多个,可通过 ps aux | grep agent 查看是否有多余的 ssh-agent 进程,并通过 kill 杀掉 ssh-add ~/.ssh/github_rsa #添加私钥文件
ssh-agent
是用于管理SSH private keys的, 长时间持续运行的守护进程(daemon). 唯一目的就是对解密的私钥进行高速缓存。ssh-add
提示并将用户的使用的私钥添加到由ssh-agent
维护的列表中. 此后, 当使用公钥连接到远程 SSH 或 SCP 主机时,不再提示相关信息.ssh-add 作用是把你指定的私钥添加到 ssh-agent 所管理的一个 session 当中。
ssh-agent 是一个用于存储私钥的临时性的 session 服务,系统重启后,ssh-agent 服务也就重置了。
- 貌似在另外一个 命令行的窗口都不行哦。
-
永久地,在本地的
~/.ssh
路径中的config
文件(如果没有就新建),设置IdentityFile
属性,即私钥的路径Host github.com HostName github.com User git IdentityFile ~/.ssh/github_rsa #与git连接的私钥文件的路径
~/.ssh/config
中 Host 与 HostName 的关系:最简单的版本:
Host
is the actual hostname & there's noHostName
OR
Host
is the nickname of the host &HostName
is the actual hostname.
感觉最省事的方法是, Host 与 HostName 保持一致。
如果设置了
Host=github
,HostName=github.com
,那么使用ssh
的时候应该是ssh -T git@github
,这样就可以连接上了。猜测它在解析命令的时候,是基于
Host
属性进行比较。如果还设置了HostName
属性,则把地址替换为HostName
再进行后续的操作。
-
-
测试是否成功
ssh -T git@github.com
参考:http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html