zoukankan      html  css  js  c++  java
  • SSH 端口转发

    在之前 GRE 的文章中,我们知道隧道技术可以解决异种网络的通信问题。在今天这篇文章中,将认识隧道技术的另一应用 - SSH 端口转发。

    首先我们对 SSH 并不陌生,是非常普遍的加密协议,用于在不安全的网络中提供安全的传输环境,常见的用途是用于远程登录。而今天要介绍的端口转发,原理类似。

    端口转发解决的问题:

    1. 增加安全性,加密 Client 到 Server 端的通信数据
    2. 突破防火墙限制,完成一些被禁止的 TCP 连接

    端口转发的类型

    在此之前,我们先了解一下端口转发的概念,端口转发是 SSH 的一种应用,可以理解成在本地 SSH Client 和远程 SSH Server 建立了一条安全的隧道,而这条隧道传输的内容可以是运行的其他 TCP 端口的流量。在隧道传输这些流量时,会进行加密,常见的 Telnet, SMTP, LDAP, HTTP 等等使用 TCP 作为传输层的协议都可以进行端口转发。

    通常来说,端口转发分为三种类型,本地端口转发,远程端口转发,动态不定端口转发。会依次从应用场景和如何实现来介绍。

    本地端口转发

    在给客户部署应用时,通过来说访问的都是客户的内网环境,一般需要我们挂上客户的 VPN 然后通过提供的跳板机来访问目标服务器。但这样的配置,就给在一些 debug 场景带来很大的不便。

    来看这样一个场景:

    这里 Client A 需要依赖于 Server B 上一个 TCP 应用才能进行开发,但是由于防火墙的设置,Client A 的流量会被 Deny 掉。但提供了一台 Server A,而 Server A 到 Server B 却是可达的。这时我们就可以利用端口转发技术,通过 Server A 间接地实现和 Server B 的通信。这时 Server A 也就是常说的 Jump Server.

    可以将 Client A 和 Server A 之间看成一条隧道,而隧道传输的内容就是 Server A 访问 Server B 的流量。

    下面来配置一下:

    ssh -L <local port>:<remote host>:<remote port> <SSH hostname>
    
    # local port 相当于 ssh client 端口
    # remote host 是目标主机 Server B 的地址
    # remote port 是目标主机 Server B 的端口
    # ssh hostname 是跳板机,也就是 Server A 的地址
    
    # 在 Client A 上
    ssh -NfL 65001:10.124.207.152:8000 root@10.124.207.155
    
    -f 表示后台运行
    -N 表示不输入命令
    -L 表示本地端口转发
    

    需要注意的内容:

    • Server A 到 Server B 一定是可达的
    • 另外在绑定端口时,要选择没有被使用的端口
    • 选用 1024-65535 之间的端口,之前的端口是给管理员使用的。

    如何关闭:

    like-unix: ps 找到进程 kill 掉
    
    windows:
    netstat -ano | findstr "65001"
    taskkill /f /t /im  19036
    

    远程端口转发

    远程端口转发和本地端口转发很像,只不过调换了 ssh server 和 ssh client 的位置。

    考虑下面的场景,还是 Client A 无法访问 Server B,但是 Server A 可以访问 Server B, 与之前不同的是,Client A 也不能访问 Server A 了,但 Server A 可以访问 Client.

    这时我们可以在 Server A 进行配置,把 Client A 作为 SSH Server 而自己作为 SSH Client 建立隧道。和之前本地一样,在 Client A 上访问配置的端口,就会把流量转发给 SSH Client 也就是 SSH Server A,这时 Sever A 再将流量转发至 Server B.

      $ ssh -R <ssh client port>:<destnation host>:<destnation port> <ssh client host>
      
      # Server B 进行配置
      ssh -NfR 65001:10.124.207.152:8000 root@10.124.207.154
    

    这时我们就可以达到和本地端口转发相同的效果,在 Client A 上访问 Server B.

    如果分不清本地还是远程端口转发,可以通过 SSH Client 和 SSH server 来在加上访问应用的顺序加以区分

    比如这里 Client A 想要访问 Server B 的 HTTP。

    那么 Client A 上的浏览器作为 HTTP 的客户端,Server B 作为 HTTP 的服务端。也就是在 HTTP 应用视角,是从 Client A 给 Server B 发送请求。这个无论是本地还是远程,方向都一样。

    接着再看 SSH 的客户端和服务端。

    如果 SSH 的客户端在 Client A,则说明是本地端口转发。和 HTTP client 和 server 同向。由于建立的转发端口在本地,所以叫本地转发。

    否则如果是 SSH 的客户端在 Server A,则说明是远程端口转发。和 HTTP client 和 server 反向。由于建立的转发端口在远端,所以叫远程端口转发。

    其实无论是同向和反向,都是建立了一条隧道,只不过发起者不一样,实现的目的都是一样的。

    本地和远程端口转发的共享

    有时我们会希望共享 SSH Client 和 SSH Server 建立的隧道,提供给其他主机同时使用。这时我们可以通过 -g 参数来实现。

    比如对本地端口转发进行共享:

    ssh -g -NfL 65001:10.124.207.152:8000 root@10.124.207.155
    

    原来仅对 localhost 和 127.0.0.1 生效,现在对当前主机的所有地址都会生效,也就是 0.0.0.0 的范围。在其他主机上可以通过访问 SSH Client IP:65001 来进行服务的访问。

    远程端口转发同理:

     ssh -g -NfR 65001:10.124.207.152:8000 root@10.124.207.154
    

    动态端口转发

    动态端口转发的原理和本地及远程没有任何的区别,唯一的不同是,对于本地和远程来说我们需要固定访问应用的端口号,比如 80,443 等等。

    但假设应用的端口不固定或者需要很多的端口号怎么办?这时就需要动态端口转发。

    ssh -D <local port> <SSH Server>
    # local port - ssh client 开启的代理转发端口
    # ssh server - ssh server 的ip及端口
    
    ssh -g -Nf -D 65001 root@10.124.207.155
    

    可以用 curl 进行测试:

    curl  --socks5 127.0.0.1:6500  http://10.124.207.152:8000/api-token-auth/
    

    总结

    最后我们完成了本地,远程,共享,动态的端口转发配置。

    从整体来看,其实实现的都是相同的功能。在 SSH Client 和 SSH Server 中建立隧道。只不过有时隧道连接的方向是不同的。

  • 相关阅读:
    跨浏览器 JavaScript判断窗口是否最小化
    .net 5 获取用户真实IP(nginx)
    C# EF 字符串模糊查询完整实例 lambda
    (zt)过程生成
    (zt)IOS开发常用的开源类库和一些示例
    wp7 生命周期及多任务 详解
    Js中concat()与push()的区别
    Ruby中p、print和puts的区别
    jquery Bug:当表单中包含name为nodeType的input时jquery选择器失效的bug 与您分享我的快乐
    Openlaszlo学习(一)Demo "Applying Constraints"的修改 与您分享我的快乐
  • 原文地址:https://www.cnblogs.com/michael9/p/13496090.html
Copyright © 2011-2022 走看看