ssh和scp(未完)

来源:互联网 发布:魅影剃刀视频数据 编辑:程序博客网 时间:2024/06/08 19:12

简介

ssh是一种用于远程登录的一种协议。通过它我们可以进行远程操作来管理远程主机以及传输文件,同时利用ssh隧道我们也可以突破防火墙。


口令登录

$ ssh [-p port] username@hostname

口令登录的原理

  • localhost(本地主机)发送一个登录请求;
  • remotehost(远程主机)收到请求后会发送自己的public key(公钥)给localhost;
  • localhost用remotehost的public key加密自己登录的password(密码)并且发送回去;
  • remotehost用自己的private key(私钥)解开发送的password并且核对是否正确,如果正确就允许远程登录。公钥和私钥的详情可以参考阮一峰的数字证书和数字签名;
$ ssh alps@192.168.0.105The authenticity of host '192.168.0.105 (192.168.0.105)' can't be established.ECDSA key fingerprint is SHA256:O4DYkK+I3LBeOFsEvb06y+YcSb1wcZi5wXuizETBtg4.Are you sure you want to continue connecting (yes/no)?yes 

这是我们第一次ssh登录的情况,上面提示的意思是只知道remotehost的public key的fingerprint(指纹),是否继续。我们输入yes。

Warning: Permanently added '192.168.0.105' (ECDSA) to the list of known hosts.alps@192.168.0.105's password:Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-29-generic x86_64) * Documentation:  https://help.ubuntu.com * Management:     https://landscape.canonical.com * Support:        https://ubuntu.com/advantage147 packages can be updated.52 updates are security updates.Last login: Tue Jun 21 08:37:04 2016 from 192.168.0.103

可以看到我们输入password后登录成功。根据提示可以看到public key已经被添加到列表,这个列表就放在我们本地的~/.ssh/know_hosts。

$ cat ~/.ssh/known_hosts |1|4++LGU0cmvp8/jBQgC3wzVyaAGQ=|0ZjnEkO/yvmznPSAjJ8pnHDc8tw= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIYW9MlqOuRMr9JYiWlooF9JFC8jZ9b6YbcabG+8wWybMup36OGSGvcyGq4egAz/p6W3k1oHp1QtKYShJmAKvl8=

这样代表我们就信任这个远程主机了,以后登录我们只要输入password,不要输入yes了。每次都要输入password我们还是觉得很麻烦,这个时候我们可以使用公钥加密。


公钥登录

$ ssh-keygen$ ssh-copy-id username@hostname

公钥加密的原理

  • localhost通过ssh-copy-id命令将自己的public key放到remotehost的~/.ssh/authorized_keys;
  • remotehost收到登录请求后向localhost发送一个随机字符串;
  • localhost用自己的private key将随机字符串加密后发回给remotehost;
  • remotehost收到回信后用localhost的public key能够解开这个字符串那么用户身份就确认成功。公钥和私钥的详情可以参考阮一峰的数字证书和数字签名;
$ ssh-keygenGenerating public/private rsa key pair.Enter file in which to save the key (/home/alps/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/alps/.ssh/id_rsa.Your public key has been saved in /home/alps/.ssh/id_rsa.pub.The key fingerprint is:SHA256:LUsZyEqSOc9MpPJkJil9myW/P5QudYghtXYKNsL17jM alps@localhostThe key's randomart image is:+---[RSA 2048]----+|    .            || o =....         ||=.@.=o+..        ||.BoX=B= .+       ||  .oB*.=So.      ||      +o=o.      ||     ..+..       ||      E.o        ||       +..       |+----[SHA256]-----+

ssh-keygen会为我们在~/.ssh下面生成一对public key和private key,分别保存到~/.ssh/id_rsa.pub和~/.ssh/id_rsa。输入命令后一路回车,私钥设置口令(passphrase)如果你可以自主选择设置。然后我们再输入ssh-copy-id将公钥传递到remotehost上面。

$ ssh-copy-id alps@192.168.0.105/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keysalps@192.168.0.105's password: Number of key(s) added: 1Now try logging into the machine, with:   "ssh 'alps@192.168.0.105'"and check to make sure that only the key(s) you wanted were added.

以后我们ssh登录不再需要输入密码了。

crawler@LocalHost:~$ ssh alps@192.168.0.105Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-29-generic x86_64) * Documentation:  https://help.ubuntu.com * Management:     https://landscape.canonical.com * Support:        https://ubuntu.com/advantage147 packages can be updated.52 updates are security updates.Last login: Tue Aug 16 15:02:05 2016 from 192.168.0.103alps@RemoteHost:~$ 

实际上ssh-copy-id就是将本地主机的public key复制到远程主机的~/.ssh/authorized_keys里面,这个过程就是下面这一条命令的执行过程。

$ ssh alps@192.168.0.105 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub

通过ssh远程传送文件

ex1
$ cd && tar czv src | ssh alps@192.168.0.105 'tar xz'src/

复制本地~/src/目录下面的所有文件到远程主机的~/src/目录。

ex2
$ ssh alps@192.168.0.105 'tar cz src' | tar xzvsrc/

复制远程主机~/src/目录下面的所有文件到本地的当前目录。

ex3
$ ssh alps@192.168.0.105 'ps aux' | grep apache2root      6596  0.0  0.1  71568  4588 ?        Ss   16:09   0:00 /usr/sbin/apache2 -k startwww-data  6599  0.0  0.1 360724  5980 ?        Sl   16:09   0:00 /usr/sbin/apache2 -k startwww-data  6600  0.0  0.1 360724  5980 ?        Sl   16:09   0:00 /usr/sbin/apache2 -k start

查看远程主机是否运行进程apache2。


ssh隧道(端口转发)

ex1
$ ssh -D 1080 username@hostname

这条命令可以结合Shadowsocks翻墙来理解,我们将经由本地1080端口的数据全部转发到Shadowsocks远程主机,我们如果用Chrome上网的话可以通过SwitchProxy将浏览器的请求转发到本地1080端口,然后通过本地的Shadowsocks-QT5进行代理。

ex2

现在学校机房禁止我们内网主机连接到外网的213.83.72.215进行ftp,但是我们可以借助外网的93.184.216.34,它可以和213.83.72.215:21进行ftp。这个时候我们可以在192.168.0.103和93.184.216.34之间建立一条双向ssh隧道。我们在本地192.168.0.103执行下面这条命令。

$ ssh -N -f -L 2121:213.83.72.215:21 93.184.216.34

-N和-f参数的作用是使命令在后台运行,-L参数一共接受三个值,分别是”本地端口:目标主机:目标主机端口”,它们之间用冒号分隔。这条命令的意思是将通过本地主机2121端口的数据全部通过ssh隧道传送到隧道另外一边的93.184.216.34,通过93.184.216.34我们来连接213.83.72.215:21的端口。

$ ftp 127.0.0.1 2121

在到本地主机执行ftp命令,通过2121端口的数据通过ssh隧道间接传送到192.168.0.100:21了。

ex3

假设现在192.168.0.103是台内网机器,它可以访问外网的93.184.216.34但是外网的机器却不能访问它。现在我们想让192.168.0.103访问无法直接访问的213.83.72.215进行ftp。解决方法是,既然内网的192.168.0.103能够访问93.184.216.34,那么我们就建立这样一条双向ssh隧道,然后我们192.168.0.103使用这条ssh隧道就可以了。
我们首先在93.184.216.34上执行下面命令.

$ ssh -N -f -R 2121:213.83.72.215:21 192.168.0.103

-R参数也是接受三个值,分别是”远程主机端口:目标主机:目标主机端口”。这条命令的意思是让192.168.0.103监听2121端口,然后将所有数据通过93.184.216.34转发到213.83.72.215。对于93.184.216.34来说192.168.0.103是远程主机,所以这也就做远程主机端口转发。

$ ftp localhost:2121

最后我们在192.168.0.103通过ftp连接本地的2121端口就成功ftp到了213.83.72.215:21。
还有一种情况就是我们只有两台机器,93.184.216.34和192.168.0.103,我们将上面这条命令改为。

$ ssh -N -f -R 2121:127.0.0.1:21 192.168.0.103

这个时候就变为在我们在93.184.216.34和192.168.0.103建立一条ssh隧道,然后通过这条隧道在外网93.184.216.34访问192.168.0.103的21端口。


数字签名和数字证书

Internet通信过程中,我们每一个人都有public key(公钥)和private key(私钥),可以在~/.ssh下面查看,其中每个人的public key在Internet中都是公开的,private key只有我们自己知道。为了保证让接收方确认发信方的身份,由certificate authority(证书机构)诞生了digital signature(数字签名)和digital certificate(数字证书)。

我们首先来看一下只有数字签名而没有数字证书的情况:当A向B发送信息的时候A会先用B的public key加密,这份信息只能由B的private key解开。当B给A回信息的时候,首先调用hash函数生成信息的digest(摘要),然后A用自己的private key对digest加密就生成了digital signature。A收到这份回信后,首先会用B的public key对digital signature解密得到digest,由此证明这封信确实是由B发送的。同时对信件本身使用hash函数也会生成一个digest,如果这个digest和前面那个digest相等,可以证明信息确实没有被修改过。但是这也造成一个问题,如果C将A手中的B的public key替换为自己C的public key,但是A还是会以为自己手中的public key还是B的,这个时候如果C向A发送一份信息,A会以为是B发送的。这个时候我们要做的就是保证public key的身份。

为了避免这种情况,certificate authority就用自己的private key对B的public key和相关信息加密生成digital certificate。B以后向A发送信息,就只要搭上digital signature和digital certificate就可以放心了。A收到B的回信后,用CA的public key得到B的public key,然后和上面一样利用这个public key解密digital signature的得到digest来判断信息是不是由A发送的,因为digital signature就是利用public key加密的。

digital certificate的一个实例就是https协议,首先client向server发送加密request,server向client响应一个自己private key加密的网页和digital certificate。client(browser)的certificate manager(数字证书管理器)有一份合法证书颁布机构的列表,client会根据这份列表的public key解密digital certificate。如果列表记录的网址和你现在访问的网址不一致就会发出一个warning来告诉你这份digital certificate被别人冒用了。还有一种可能就是这份证书没有记载到合法证书颁布机构列表,也会发出另外一种warning。


参考链接

https://chamibuddhika.wordpress.com/2012/03/21/ssh-tunnelling-explained/
http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html
http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html
http://www.ruanyifeng.com/blog/2011/12/ssh_port_forwarding.html

0 0
原创粉丝点击