SSH使用小记

0、是什么

SSH(Secure Shell)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。(更多详情可参阅维基百科 https://zh.wikipedia.org/wiki/Secure_Shell
SSH协议基于的传输层协议为TCP,默认端口22。(与Telnet的区别,Telnet明文传输内容故不安全。默认端口FTP 2一、SSH 2二、Telnet 23)html

 

大多数现代操做系统(包括macOS、大部分Linux、OpenBSD、FreeBSD、Solaris等系统)都提供了SSH协议的实现程序,但Windows系统未自带SSH程序。Windows用户可使用Cygwin来创建SSH服务。(补注:从 Win10 1809 和 Windows Server 2019 开始 Windows 已支持 OpenSSH Server)linux

SSH命令参数说明:Linux下可经过 man ssh 命令查看(中文翻译版可参阅 http://linux.51yip.com/search/ssh

web

一、SSH登陆原理及免密登陆设置

先验知识算法

ssh登陆须要用到公钥、秘钥,它们用于对文本内容进行加密或解密。一般用RSA加密方式,其是一种对称加密,由公钥加密的内容私钥可解密、由私钥加密的内容公钥也可解密。公钥能够对外公开,私钥则不能。关于RSA加密可参阅:RSA算法原理-阮一峰浏览器

 

经过ssh登陆远程主机一般有两种登陆方式:安全

一、输密码登陆:每次登陆都要输密码。内部原理:登陆时服务端发送服务端本身的公钥给客户端,客户端用该公钥加密密码并发送到服务端,服务端用对应的私钥解密,检查密码是否正确以肯定是否登陆成功。bash

第一次登陆时会警告公钥是否可信任,以防止中间人攻击返回的是中间人的公钥,若用户确认信任之则公钥会保存到客户端的$HOME/.ssh/known_hosts文件里,之后再登陆就不会有警告了。服务器

二、秘钥登陆(免密码登陆):预先配置好秘钥,以后每次登陆无需输密码。方法是在一台机器上生成公钥/私钥对并将其中一个秘钥放到另外一个机器上。有两种:网络

2.一、公钥登陆:事先将客户端的公钥放到服务端上(本质上至关于配置免密登陆白名单)。内部原理:登陆时服务端发送一个随机字符串给客户端,客户端用本身的私钥加密并发送到服务端,服务端根据是否有事先存储的公钥能进行解密以肯定是否登陆成功。并发

2.二、私钥登陆:事先将服务端的私钥放到客户端上,每次登陆时须要指定私钥,可见此时私钥至关于服务端的临时密码。

前一种方式须要对服务端进行配置,若要免密登陆的客户端不少,则须要频繁修改服务端配置;后一种能够避免频繁更改服务端,但比较不安全由于私钥是不宜外泄的,这种模式只要有私钥的人就能访问服务器,可是例如阿里云服务器就是这种访问方式。

 

这里介绍公钥登陆的配置方法(假设机器A登陆机器B须要密码,但不想每次登陆都需输密码):

一、A上生成密钥对:  ssh-keygen  ,会在当前用户目录 ~/.ssh/ 下生成 id_rsa、id_rsa.pub 两个文件,里面内容分别为私钥、公钥

二、将公钥(id_rsa.pub里的内容)追加到到B上 ~/.ssh/authorized_keys 文件中,文件不存在则新建。也可在A上经过命令完成该效果:  ssh-copy-id -i ~/.ssh/id_rsa.pub <username of B>@<host of B>  

三、重启B上的ssh服务:  sudo service sshd restart 

四、以后若还不行,可检查B上的/etc/ssh/sshd_config文件,确认以下内容没被注释:

  RSAAuthentication yes
  PubkeyAuthentication yes
  AuthorizedKeysFile .ssh/authorized_keys

 

参考资料:http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html

 

二、SSH远程操做

可经过SSH执行远程命令而不须要登陆远程主机,示例:(更多可参阅:http://www.javashuo.com/article/p-ofwmixvl-dg.html

# 主要命令格式
ssh
user@10.5.6.47 "ls /home; pwd " # 执行基本命令,可有多个 ssh -t user@10.5.6.47 " top " # 对于须要交互(须要tty)的命令,经过ssh远程执行时不会为此会话分配tty,故ssh当即退出远程主机从而须要交互的命令当即结束。经过 -t 参数显示声明须要为会话分配tty以解决之 ssh user@10.5.6.47 " bash -s " < test.sh helloworld # 远程执行本地主机上的脚本,参数为往脚本传的参数 ssh user@10.5.6.47 /home/user/test.sh helloworld # 远程执行远程主机上的脚本,参数为往该脚本传的参数

# 其余trick示例
cd && tar czv src | ssh user@host 'tar xz' # 将$HOME/src/目录下面的全部文件,复制到远程主机的$HOME/src/目录
ssh user@host 'tar cz src' | tar xzv # 将远程主机$HOME/src/目录下面的全部文件,复制到用户的当前目录

 

三、SSH端口转发

3.一、是什么

SSH是安全的,会自动加密和解密全部 SSH 客户端与服务端之间的网络数据。此外,SSH 还提供了一个很是有用的功能——端口转发:它可以将其余 TCP 端口的网络数据经过 SSH 链接来转发,并自动提供了相应的加密及解密服务。因 SSH 为其余 TCP 链接提供了一个安全的通道来进行传输,故也被称做SSH隧道(SSH Tunnel)。例如,Telnet,SMTP,LDAP 这些 TCP 应用均可以从中得益,避免了用户名,密码以及隐私信息的明文传输。而与此同时,若是工做环境中的防火墙限制了一些网络端口的使用但容许 SSH 链接,则也可经过 TCP 端口转发来使用 SSH 进行通讯。

总的来讲,SSH 端口转发能提供两大功能:

一、加密SSH Client与SSH Server间传输的数据

二、突破防火墙限制以间接完成一些以前没法创建的 TCP 链接

 从效果上看,端口转发至关因而反向代理。

 

3.二、类型

SSH端口转发为没法直接任意互通但能经过SSH访问的两个网络或机器间提供了一个互通的桥梁。分为 本地端口转发远程端口转发动态端口转发三种。

  • 本地端口转发与远程端口转发的区别在于负责执行端口转发的是所创建的SSH会话中的SSH Client仍是SSH Server(SSH Client指执行SSH命令的机器,下同
  • 前两种把对转发端口的请求转发到目的机的特定端口、而最后一种则至关于一个代理功能——设置为该代理后会把对任意端口的请求转发到目的机的相应端口。

这里设想一种场景,假设有机器A、B、C、D,其间关系为:A、B间可互通,C、D间可互通,AB与CD间不能自由互通(因设置了防火墙、白名单等,只有B能经过SSH访问C、反之则不可。(想象AB、CD分别在不通的网段、两个网段间只有B能经过SSH访问到C且C只对B开放SSH的22端口)。

 

3.2.一、本地端口转发

命令: ssh -L <forward port>:<target host>:<target port> <SSH server addr> 

  • 四个参数分别表示转发的端口(注意非管理员无权绑定熟知端口0~1023)、目标host、目标主机端口、SSH server地址(如 zsm@10.5.6.47)。若target host与SSH Server是同一个机子则target host可写为 "localhost",缘由见下面的原理部分
  • 对于IPV4,前三个参数用冒号 ":" 分隔,对于IPv6则用斜杠 "/" 分隔。
  • 为了容许其余机子链接转发端口(不然只有转发端口所在机器能链接该端口),能够加  -g  参数(listen 0.0.0.0:tarport和listen 127.0.0.1:tarport的区别);SSH链接默认会登陆到SSH server(退出登陆后转发功能会失效),可加 -fN 参数让命令在后台执行以免登陆到SSH server。

功能:将对SSH Client所在机器<forward port>端口的请求转发到指定机器的指定端口(即 <target host>:<target port> )

原理:SSH Client所在机器分配一个 socket 监听 <forward port> 端口,一旦此端口上有了链接,该链接就经安全通道转发出去,同时SSH server所在机器和 <target host>:<target port> 创建链接。(请求的内部走向是SSH Client -> SSH Server -> 目标机,返回时原路返回)

应用场景:使得“内网”(SSH Client所在的)能访问到不能直接访问的其余"网络"

示例:假设D上有个web服务监听8080端口,显然,A、B都没法直接访问到该服务但C能够。而B能够经过SSH访问C,此时在B上执行: ssh -g -fN -L 1000:hostD:8080 hostCSshAddr ,则A或B经过访问B的1000端口就能访问到D的web服务(内部走向是B -> C -> D)。

若没有-g参数,则A访问不了B的1000端口,只有B本身能够。

若web服务在SSH server上(即目标主机与SSH服务端是同一个),则命令可简为: ssh -g -fN -L 1000:localhost:8080 hostCSshAddr ,可见这里的localhost是相对于SSH server而言的。

 

3.2.二、远程端口转发

(与本地端口转发几乎同样,只不过转发端口在SSH Server且请求的内部走向相反)

命令: ssh -R <forward port>:<target host>:<target port> <SSH server addr>  ,注:不支持 -g 参数

  • 若target host与SSH Client是同一个机子则target host可写为 "localhost",缘由见下面的原理部分

功能:将对SSH Server所在机器<forward port>端口的请求转发到指定机器的指定端口(即 <target host>:<target port> )

原理:SSH Server所在机器分配一个 socket 监听 <forward port> 端口,一旦此端口上有了链接,该链接就经安全通道转发出去,同时SSH Client所在机器和 <target host>:<target port> 创建链接。(请求的内部走向是SSH Server -> SSH Client -> 目标机,返回时原路返回)

应用场景:使得"外网"能访问到"内网"(SSH Client所在的)

示例:若上述web服务在A,显然,C、D没法直接访问该服务但B能够。而B能够经过SSH访问C,此时在B上执行: ssh -fN -R 1000:hostA:8080 hostCSshAddr ,则C可经过访问其1000端口就能访问到A的web服务(内部走向是C -> B -> A)。

注:远程端口转发不支持-g参数故这里没法像本地端口转发那样经过 -g 参数让D能访问到A的web服务。解决:在SSH Server(即C)的/etc/ssh/sshd_config添加一行并重启SSH服务: GatewayPorts yes 

 

3.2.三、动态端口转发

命令: ssh -D <foward port> <SSH server addr>  ,可用参数与本地端口转发的同样

功能及原理:与本地端口转发同样,将对SSH Client所在机器<forward port>端口的请求转发到SSH Server上,只不过设置时不用指定目的机器的host和port。SSH Client成为一个反向代理,应用设置代理为SSH Client后,应用发起请求时请求的内部走向也是SSH Client -> SSH Server -> 目标机,收到SSH Client转发来的请求时SSH Server会与该请求的目标机链接。SSH 动态端口转发是经过 Socks 协议实现的,建立动态端口转发时 SSH 服务器就相似一个 Socks 代理服务器,因此这种转发方式也叫 Socks 转发

应用场景:

做为代理:把全部请求都转发到目的机,以突破防火墙等限制。

提升安全性:让那些不加密的网络链接,所有改走SSH链接,从而提升安全性。

示例: 做为反向代理——在本节首所述场景下,在B执行: ssh -g -fN -D 1000 hostCSshAddr ,至关于启动了个反向代理服务。以后在A或B上设置Sockets代理(如在浏览器设置Sockets代理),地址为 hostB:1000,则C、D上的服务均能被A或B访问到。如A访问服务hostD:8080,请求会经过 SSH Client B -> SSH Server C -> hostD:8080,由C完成对D的请求后原路返回结果。

 

注:

SSH 端口转发是经过 SSH 链接创建起来的,故必须保持这个 SSH 链接以使端口转发保持生效。一旦关闭了此链接,相应的端口转发也会随之关闭。

只能在创建 SSH 链接的同时建立端口转发,而不能给一个已经存在的 SSH 链接增长端口转发。

 

参考资料:

http://www.javashuo.com/article/p-sibzutlz-ke.html ssh端口转发

http://www.ruanyifeng.com/blog/2011/12/ssh_port_forwarding.html

相关文章
相关标签/搜索