SSH(Secure SHell)是一种基于加密算法的网络安全协议, 其在TCP/IP协议的基础上通过非对称公钥算法对用户身份进行验证. SSH在网络中有广泛的应用, 比如平常在远程登录时就会用到SSH, Github的代码仓库提交也会基于SSH协议来验证提交者的合法性, 而对常年生活在局域网内的人来说, SSH更多的用途则是搭建穿越防火墙的VPN实现网络自由.
一台服务器如果有公共域名或者IP地址, 只需要事先将客户端的公钥放到服务器上就可以正常登录, 但如果服务器本身位于防火墙之外(比如某个端口被禁)或者位于NAT(Network Address Translation)网关之后, 这个方法就不起作用了. 用过VPN的同志应该比较清楚, 穿透防火墙或者某个局域网的NAT网关, 一般要用到SSH隧道技术(SSH tunneling);SSH隧道技术也被称为端口转发(port forwarding).简单来说, 建立SSH隧道大致有两个流程:
- 由位于局域网的设备A向服务器PC发起SSH连接, 建立一个安全加密的通信通道, 并基于该通道监听某个特定的端口
- 接着, 服务器基于已有的加密通道再建立一个SSH通信链路,基于这个通道服务器就可以登录到大屏, 执行交互指令
SSH隧道技术的端口转发具体说有两种, 一种叫本地端口转发(local port forwarding), 就是在客户端做端口转发;一种叫远端端口转发(remote port forwarding), 就是在服务端做端口的数据转发, 这篇文章用到的技术是后一种.
这里就来看看如何通过SSH隧道技术来实现对局域网内某个服务器的登录: 局域网内有一台设备A(服务端), 只有私有IP地址, 通过NAT网关访问外部网络, 设备B(客户端)是外部网络的一个PC, 现在要通过该PC(设备B)正常登录到设备A.
实现SSH隧道功能
在开启SSH隧道功能之前, 确保客户端/服务器都正常配置了ssh(SSH的客户端程序)/sshd(SSH守护进程):
- ssh: ssh登录的客户端, 负责发起ssh登录请求, 其配置一般放在
/etc/ssh/ssh_config
- sshd: sshd是服务端的守护进程, 负责监听来自客户端的请求, 其配置放在
/etc/ssh/sshd_config
为了确保ssh可以正常进行端口转发, 需要打开AllowTcpForwarding
:
- 设置
AllowTcpForwarding
为yes
, 确保能够使用端口转发功能
另外SSH密钥交换时要用到主机的密钥(host key), 可以通过ssh-keygen
产生, 对于Ubuntu系统来说, 主机密钥一般放在/etc/ssh
目录下.
为了避免每次ssh登录都要输入密码, 可以事先分别在客户端/服务器产生一个rsa密钥对, 并将公钥放到服务器/客户端的/.ssh/authorized_keys
中保存下来, 并在执行ssh指令时指定对应的私钥文件, 这样身份验证就会在密钥验证阶段完成无需再输入用户密码了.
启动sshd
配置完成后, 如果没有sshd
进程, 需要在设备A(服务端)/设备B(用户端)都启动sshd:
1 | sshd -ddd -h /etc/ssh/ssh_host_rsa_key -f /etc/ssh/sshd_config |
其中参数-ddd
用于输出调试信息, -h
指定host密钥文件, -f
指定sshd
的配置;启动完成后, 设备就可以正常收到来其他ssh客户端的请求了.
启动ssh远程登录
在大屏输入如下指令, 尝试与设备A(客户端)建立SSH链接:
1 | ssh -vvv -TN -i <identity_file> -R 8989:localhost:22 user_name@remote_host |
-vvv
参数用于输出debug信息, ``-TN告诉ssh在登录后不要开启终端执行指令而是监听某个指定的端口, -i
制定身份验证的密钥文件目录, 参数-R
指定了远端转发端口的规则: 将来自远端8989
的数据都转发到本地的22
端口; 执行该命令后, 身份验证通过, 可能会输入服务器密码, 然后我们就可以看到ssh会一直在监听8989
这个端口, 接着在设备A(服务器)输入指令:
1 | ssh -vvv -i <identity_file> -p 8989 root@localhost |
身份认证完成后, 就可以看到一个输入shell指令的命令窗口, 就算登录完成了.
参考资料
- https://www.ssh.com/ssh/tunneling
- https://www.booleanworld.com/guide-ssh-port-forwarding-tunnelling/
- http://arondight.me/2016/02/17/%E4%BD%BF%E7%94%A8SSH%E5%8F%8D%E5%90%91%E9%9A%A7%E9%81%93%E8%BF%9B%E8%A1%8C%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/
- https://en.wikipedia.org/wiki/Secure_Shell
- The Secure Shell (SSH) Protocol Architecture
man ssh/sshd/sshd_config