ssh tunnel , ssh reverse proxy, ssh over ssh , ssh tunnel proxy 特殊网络打洞大法,突破变态网管审核

修改备注:

config文件中的ProxyCommand中不需要=

大致起源是公司的网络审核超级严格,本地access美国server只能先使用link到审核服务器,然后vnc到中间服务器,然后再bbb。。。。总不能这边修改一行代码再去vnc上重新敲一遍吧。。。于是萌生了打洞的想法(操作完全违规,请参考员工离职手册,做好被fire的准备)

Note: 追加BB一句,该限制仅限制大中华地区,可见国人把自己名声搞得多坏。。

sequenceDiagram
    participant HA as My Host A
    participant FW as Fire Wall
    participant RHB as Remote Server B
    Note over HA,RHB: My host initiates a connection to remote server
    HA ->> FW: Hi, I want B
    FW -->> HA: No, You do not

    Note over HA,RHB: Remote Server initiates a connection to my host
    RHB ->> FW: I want A
    FW  ->> HA: Go,Go,Go
    loop Normal traffic
            HA-> RHB: Lol, Yeah
        end

先描述几个概念:

  1. ssh tunnel ,简单来说就是利用ssh通讯协议做一个隧道,或者是洞让你进行数据通讯
  2. ssh tunnel proxy 在ssh打开的洞里进行socks 5代理
  3. ssh reverse proxy ,和第一个差不多,是从a–>b 开洞,然后使用者从b->a 发起应用。
  4. ssh over ssh , ssh 通讯是建立在另外一条ssh tunnel基础

网络环境嘛。。。很常见,我从A发起对B只能绕道C,还是VNC,可以想象跨洋访问的恐怖,画面刷新感人。

sequenceDiagram
    participant HA as My Host A
    participant AM as Audit Machine
    participant RHB as Remote Server B
    HA ->>+ AM: VCN Access
    AM ->>+ RHB: SSH Access
    RHB ->>- AM : SSH Access
    AM ->>- HA: VCN Access

(因为我们这里B能发起对A的连接(其实也有限制,22端口屏蔽。但是80和443开放,我就把A的ssh server端口改443了), 我不再使用公网的C作为跳转,其实也就是多了一步而已)

sequenceDiagram
    participant HA as My Host A
    participant FW as Fire Wall
    participant AM as Audit Machine
    participant RHB as Remote Server B
    Note over HA,RHB: My host initiates a connection to remote server
    HA ->> FW: Hi, I want B
    FW -->> HA: No, You do not
    Note over HA,RHB:Access through Audit Machine

    HA ->>+ AM: VCN Access
    AM ->>+ RHB: SSH Access

    Note over HA,RHB: Remote Server initiates a ssh tunnel to my host
    RHB ->> FW: I want A ssh tunnel
    FW  ->> HA: Go,Go,Go
    
    loop Tunnel is ready
            HA  --> HA : Open local 2222 to listen and forward data to Host B 22(或者443)

            RHB  --> RHB : Open local 22 and receive data to Host A 2222
            HA -> RHB: Host A pen 2222  ---- Host B 22
        end

下边开始干活:

第一步: 打通B->A的隧道(注意A的ssh server 端口是443,有意绕过监控为之),通过在B上执行如下命令:

1
ssh -p 443  -NR 0.0.0.0:2222:127.0.0.1:22 user_A@A

成功打通了B->A的连接,同时在A上监听端口2222,所有连接A:2222的连接都会转发到B:22 ,这时核心步骤已经完成。

为了避免连接挂掉,结合autossh自动重连:

1
autossh -p 443 -M 2223 -NR 0.0.0.0:2222:127.0.0.1:22 user_A@A

第二步:A ssh 到 B, 注意此时地址是A的本机地址。

1
ssh -P  2222 user_B@127.0.0.1

此刻你就可以用B做跳板access C,D,E ,然后在反复不断敲ssh命令中,手指开始生疼,在A的~/.ssh/config中添加一行:

1
2
3
4
host B
hostname 127.0.0.1
port 2222
user user_B

每次只要ssh B,就可以登录B了。(什么密钥登录或者sshpass登录自己的百度。懒人一个)

另外数据复制蛋疼。。。于是需要扩大战果,实现更多好处

战果1: 利用B做代理给A上网(因为B是国外服务器,然后youtube什么的404有很多红利了)

1
ssh  -NfD 0.0.0.0:1080     -P 2222   user_B@127.0.0.1

然后本地打开了1080端口时能socks 5代理,浏览器配置代理什么的,自己百度

这里说明一下,如果不写0.0.0.0 ,1080端口只接受本机发起的连接,如果需要支持局域网其他client访问,可能需要增加一步,在A的/etc/ssh/sshd_config 中添加一句(懒得验证是否需要,大家可以留言告知我):

1
GatewayPorts yes

此刻其实我们的浏览器数据的http/https —> ssh –> ssh –>404 , 简单的就是说socks over ssh

战果2 : A直接ssh访问C,D, E(好处就是可以使用sftp,scp等命令直接复制数据。。。。我不会告诉你可以使用用mobaxterm和filezilla管理这些东西)

这里有三种思路,

1: ssh1 over ssh2 (此时ssh2已经是ssh over ssh) ,利用第一步打通的ssh隧道过日子,

核心命令 :

1
ProxyCommand="ssh -W %h:%p -P 2222 user_B@127.0.0.1"

完整的命令是,同样支持sftp,scp:

1
ssh  -o ProxyCommand="ssh -W %h:%p -P 2222 user_B@127.0.0.1"  user_C@C

简化的用法就是A的~/.ssh/config中添加:

1
2
3
4
5
6
host C
hostname server_C
user user_C
ProxyCommand ssh -W %h:%p -P 2222 user_B@127.0.0.1

#这里修了一个坑。。。就是PorxyCommand后边不需要=

然后直接ssh C即可

2:ssh over socks ((此时socks已经是sock over ssh)),利用战果1开通的socks过日子,好处是很多第三方软件都支持socks,此时协议就不限于ssh了。

核心命令 :

1
ProxyCommand="nc -X 5 -x localhost:1080 %h %p"
1
完整的命令是,同样支持sftp,scp:
1
ssh  -o ProxyCommand="nc -X 5 -x localhost:1080 %h %p"  user_C@C

简化的用法就是A的~/.ssh/config中添加:

1
2
3
4
host C
hostname server_C
user user_C
ProxyCommand nc -X 5 -x localhost:1080 %h %p

然后直接ssh C即可

3:监听A的特殊端口,直接转发数据到目标机(麻烦,但是也好用),实现的效果是当连接到A的20567端口,自动转发到C的22端口。

1
ssh -NfL  20567:C:22   -P 2222  user_B@127.0.0.1

此时执行如下命令就可以直接连接到C:

1
ssh -P 20567 user_C@127.0.01

简化的用法就是A的~/.ssh/config中添加:

1
2
3
4
host C
hostname 127.0.0.1
port 20567
user user_C

然后直接ssh C即可

至于上边提及的public C, 就是多中转一下,隧道套隧道,,俄罗斯套娃娃

今天看到一个居然CSDN乞讨的,也来凑一下热闹。。。看看能不能买包烟。。