2016/03/07

ssh远程登录


SSH(Secure Shell),简单来说SSH是一种安全网络协议,用于计算机之间的加密登录。用户可以使用SSH协议,从本地计算机登录到远程一台计算机,而且这种登录时安全的,就算被中途截获, 密码也不会泄露。

SSH只是一种协议规则,实现这种协议规则的工具有很多,使用非常广泛的开源自由软件是OpenSSH


口令登录

简单连接远程主机

$ssh user@host

ssh默认端口为22,如果请求远程连接主机的ssh端口不是22,可以使用p参数修改

$ssh -p 32233 user@host

基本流程是:

1.$ssh -p 22 user@host,想远程主机,端口22发送ssh登录请求

2.远程主机收到用户登录请求,把自己的公钥发给用户

2.1.如果用户是第一次登录远程主机,系统会出现确认提示,例如:

$ ssh user@192.168.1.109

The authenticity of host '192.168.1.109 (192.168.1.109)' can't be established.

ECDSA key fingerprint is c8:e1:8f:07:4f:a8:9b:24:70:74:db:41:c0:1f:20:02.

Are you sure you want to continue connecting (yes/no)?

无法确认192.168.1.109这台主机的真实性,只知道它的公钥指纹,问你是否要继续连接?之所以要用户输入yes才能继续,是因为这一过程可能出现中间人攻击。那么只要我们知道远程主机 的公钥指纹是多少,就可以规避中间人攻击问题。(下面说明)

2.2.用户输入yes接受这个远程主机的公钥,系统出现一句提示

Warning: Permanently added '192.168.1.109' (ECDSA) to the list of known hosts.

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

2.3.然后输入密码

user@192.168.1.109's password:

用户使用远程主机提供的公钥,将登录密码加密后,发送回去

3.远程主机用自己的私钥解密登录密码,如果密码正确,就同意用户登录。

Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.16.0-30-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

Last login: Mon Mar  7 11:05:08 2016 from 192.168.1.228
user@hitu-Virtual-Machine:~$

每个用户.ssh/known_hosts文件,保存着永辉可信赖的远程主机的公钥。

在口令登录整个过程中,如果有人截获了登录请求,冒充远程主机,将伪造公钥发给用户,因为不像https协议,ssh协议的公钥是没有证书中心(CA)的,也就是说都是自己签发的。用户没有辨别 真伪的情况下,输入了yes,并提交了登录密码,那么冒充者就成功偷窃了用户登录密码。这种情况就是著名的中间人攻击,所以在2.1步里会给予警告提示,让用户有所警惕。


远程主机公钥纹理

前面说过,只要我们知道远程主机的纹理,就可以避免口令登录过程中被中间人攻击,我们可以通过以下方法获取远程主机公钥纹理:

1.使用ssh-keyscan指令

$ ssh-keyscan -p 22 -t rsa,dsa,ecdsa,ed25519 remote_host > ssh_host_pub_key.pub

然后通过ssh-keygen -lf指令查看公钥的纹理,再与登录警告公钥纹理进行对比

$ ssh-keygen -lf ssh_host_pub_key.pub

2.通过其他办法登录到远程主机,在远程主机上获取公钥纹理:

ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
ssh-keygen -lf /etc/ssh/ssh_host_dsa_key.pub
ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

记录好各种类型公钥纹理,再与登录警告公钥纹理进行对比


公钥登录

口令登录,每次都需要输入密码。SSH提供了公钥登录,可以省去输入密码。公钥登录就是将自己的公钥存放在远程主机上,登录时,远程主机向用户发送一段随机字符串,用户用自己的私钥加密后 发回去,远程主机用事先存放的公钥进行解密,如果解密成功,就证明用户是可信的,直接运行登录sheel,不再需要输入密码。

使用ssh-keygen生成公钥和私钥

$ssh-keygen -t rsa -C yangxuguangvip@163.com -f test

使用ssh-copy-id将本地公钥拷贝存放到远程主机.ssh/authorized_keys

$ ssh-copy-id -i test.pub user@host

现在我们可以通过公钥登录,免去输入密码

ssh -i privatekey user@host

.ssh/authorized_keys用于保存用户的公钥,多个公钥只需在authorized_keys文件尾追加即可。


只允许公钥登录

出于安全考虑,我们需要禁止口令登录,只允许公钥登录。我们在远程主机中,配置ssh,将PasswordAuthentication设置成no

$ vim /etc/ssh/sshd_config

PasswordAuthentication no
$ ssh user@host
The authenticity of host '192.168.1.109 (192.168.1.109)' can't be established.
ECDSA key fingerprint is c8:e1:8f:07:4f:a8:9b:24:70:74:db:41:c0:1f:20:02.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.109' (ECDSA) to the list of known hosts.
Permission denied (publickey).

快捷登录

现在我们可以通过指令ssh -i privatekey -p port user@host来进行登录远程主机。但是我们还是需要输入-i,-p,user@host这些指令,比较繁琐。ssh本身提供一种快捷的方式来解决这个问题,就是在~/.ssh/config配置文件里添加你的远程服务器信息即可。

$ vim ~/.ssh/config

添加文件内容格式如下

Host    alias #自定义别名
    HostName    hostname #远程主机IP或域名
    Port    port #端口 默认22
    User    user #用户名
    IdentityFile    ~/.ssh/id_rsa #公钥

保存文件后,即可通过别名来登录ssh服务器

$ ssh alias

若有多个ssh账号需要配置,只要在~/.ssh/config空行再写即可,如下:

Host    alias.1
    HostName    192.168.1.109

Host    alias.2
    HostName    192.168.1.110

Host    alias.*
    Port    22
    User    test
    IdentityFile    ~/.ssh/id_rsa

ssh连接github

把 id_rsa.pub 添加到你的github账户ssh key中

测试是否可以连通

$ ssh -T git@github.com
Enter passphrase for key '/root/.ssh/id_rsa':
Hi yangxgkem! You've successfully authenticated, but GitHub does not provide shell access.

测试通过,现在可以去github下clone你的项目回来。 eg

git clone git@github.com:yangxgkem/server.git

多账户设置

设置 vim ~/.ssh/config

Host    server.github.com
    HostName    github.com
    User    git
    IdentityFile    ~/.ssh/id_rsa

Host    blog.coding.com
    HostName    coding.com
    User    git
    IdentityFile ~/.ssh/coding_rsa

现在检索github下server项目指令改为:

git clone git@server.github.com:yangxgkem/server.git

参考文章:https://segmentfault.com/a/1190000002627706