ssh端口转发

SSH Tunneling

ssh端口转发,用来实现翻墙的操作。

它有几种不同的称呼:ssh端口映射,端口转发,ssh隧道,英文(SSH port forward, SSH tunneling )实际上是指同样的意思。

动态转发

动态转发指的是,本机与 SSH 服务器之间创建了一个加密连接,然后本机内部针对某个端口的通信,都通过这个加密连接转发。它的一个使用场景就是,访问所有外部网站,都通过 SSH 转发。

动态转发需要把本地端口绑定到 SSH 服务器。至于 SSH 服务器要去访问哪一个网站,完全是动态的,取决于原始通信,所以叫做动态转发。

$ ssh -D local-port tunnel-host -N

上面命令中,-D表示动态转发,local-port是本地端口,tunnel-host是 SSH 服务器,-N表示这个 SSH 连接只进行端口转发,不登录远程 Shell,不能执行远程命令,只能充当隧道。

举例来说,如果本地端口是2121,那么动态转发的命令就是下面这样。

$ ssh -D 2121 tunnel-host -N

注意,这种转发采用了 SOCKS5 协议。访问外部网站时,需要把 HTTP 请求转成 SOCKS5 协议,才能把本地端口的请求转发出去。

下面是 SSH 隧道建立后的一个使用实例。

$ curl -x socks5://localhost:2121 http://www.example.com

上面命令中,curl 的-x参数指定代理服务器,即通过 SOCKS5 协议的本地2121端口,访问http://www.example.com

Test tunnel

curl --socks5-hostname "socks5://localhost:2121" ifconfig.me

如果经常使用动态转发,可以将设置写入 SSH 客户端的用户个人配置文件(~/.ssh/config)。

DynamicForward tunnel-host:local-port

建立本地ssh隧道

典型场景

TunnelStruc.png

我想要从自己的机器直接访问远程服务的8080端口,可以建立本机的隧道监听端口,实现方法:

MyPC操作(192.168.0.111)

前提:通过ssh 可以直接从MyPC连接Jump Server

ssh -N -f -L 1111:10.0.1.4:8080 redhat@40.74.67.218

检查本地新出现的监听端口

$ netstat -an | grep LISTEN | grep 1111
tcp4       0      0  127.0.0.1.1111         *.*                    LISTEN
tcp6       0      0  ::1.1111               *.*                    LISTEN

本机打开浏览器,地址栏输入 http://localhost:1111 ,把本地 1111端口通过一台机器做跳板映射到了远程8080端口,可以直接访问。

连续跳转

当访问内部服务器需要跳过两个jump server,可以在jump机器上建立跳转,然后本机再做一次。

image-20201105134053882.png

第一次在靠近自己的跳板机(Jump1)上做。

ssh -i mykey jump2 -N -f -L 8443:real-server:8443

第二次在本机做映射

ssh -N -f -L 1111:localhost:8443 jump1

于是,在本机就可以访问端口1111了。

建立远程ssh隧道

假设由于网络或防火墙的原因我们不能用 SSH 直接从 本机 连接到 跳板 服务器(40.74.67.218),但是反向连接却是被允许的。那此时我们的选择自然就是远程端口转发了。
(场景:MyPC -> ssh -> Jump 被禁止;MyPC <- ssh <- Jump 允许)

因为本机使用内网IP, 不能直接反向直连,我找了另外一台服务器做例子,如下图:

TunnelSRemote.png

Jump 机操作(40.74.67.218)

ssh -N -f -R 2222:10.0.1.4:8080 redhat@40.83.72.19

Work 机验证(40.83.72.19)

$ netstat -an | grep 2222
tcp        0      0 127.0.0.1:2222          0.0.0.0:*               LISTEN
tcp6       0      0 ::1:2222                :::*                    LISTEN
$ wget http://localhost:2222

本地转发与远程转发的对比

SSH 端口转发自然需要 SSH 连接,而 SSH 连接是有方向的,从 SSH Client 到 SSH Server 。而我们的应用也是有方向的,比如需要连接 Web Server 时,Web Server 自然就是 Server 端,我们应用连接的方向也是从应用的 Client 端连接到应用的 Server 端。如果这两个连接的方向一致,那我们就说它是本地转发。而如果两个方向不一致,我们就说它是远程转发。

本地转发时:

MyPC 同时是应用的客户端,也是 SSH Client,这两个连接都从它指向 Jump所在网络。

远程转发时:

Work 是应用的客户端,但却是 SSH Server ;而 Jump 所在网络是 Web 的服务端,但却是 SSH Client 。这样两个连接的方向刚好相反。

另一种简单粗暴的区分:所有操作在同一台机器完成,这就是本地转发;否则就是远程转发。

过程中使用参数的解释

-f Fork into background after authentication.

-N Do not execute a shell or command.

-L port:host:hostport

-R port:host:hostport

中文再解释一遍,这里我们用到了SSH客户端的三个参数:

  • -N 告诉SSH客户端,这个连接不需要执行任何命令。仅仅做端口转发

  • -f 告诉SSH客户端在后台运行

  • -L 做本地映射端口,被冒号分割的三个部分含义分别是

    • 需要使用的本地端口号 (端口:1111)

    • 需要访问的目标机器IP地址(IP: 10.0.1.4)

    • 需要访问的目标机器端口(端口: 8080)

  • 最后一个参数是我们用来建立隧道的中间机器的IP地址(IP: 40.74.67.218)

我们再重复一下-L参数的行为。-L X:Y:Z的含义是,将IP为Y的机器的Z端口通过中间服务器映射到本地机器的X端口。

命令使用格式:

ssh -f -N -L listen_port:DST_Host:DST_port user@Tunnel_Host (本地转发)

ssh -f -N -R listen_port:DST_Host:DST_port user@Tunnel_Host (远程转发)

Windows SSH App 端口转发的方法

以Xshell 为例

xshellTunnel.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第一部分 概述当你在咖啡馆享受免费 WiFi 的时候,有没有想到可能有人正在窃取你的密码及隐私信息?当你发现实验室...
    fastjrun阅读 1,180评论 0 8
  • 实战 SSH 端口转发 通过本文的介绍,读者可以从中了解到如何应用 SSH 端口转发机制来解决日常工作 / 生活中...
    hopevow阅读 1,066评论 0 9
  • 我的应用场景是:在vps(root@159.89.206.20)上面跑了个只能在服务器本地访问的网页:127.0....
    ThomasYoungK阅读 1,233评论 0 0
  • 这个应该不陌生吧, 当你看到自己账单上那个显赫的数字时,有没有被吓到呢? 对比一下自己的收入,看看我的账单,似乎还...
    山雨林夕阅读 202评论 0 1
  • 文 丨雪花如糖 这不是一本名家之作。没有宏大的主题,沒有引人入胜的故事,也没有所谓华美的文笔,有的只是平静从容的讲...
    雪花如糖阅读 3,137评论 35 69