SSH进行端口转发

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSH进行端口转发相关的知识,希望对你有一定的参考价值。

参考技术A

大前提,windows可以使用freesshd做ssh服务器当一级代理,但是它的端口转发功能有bug,所以还是用linux的ssh吧。
ps:Earthworm虽然简单好用,但是传输的流量是不加密的,已经碰到过好几次反弹回来仍然被安全设备拦截的情况,所以还是老老实实用ssh代理了

安装sshpass,需要gcc编译安装。

ssh会话会在空闲一段时间后自动僵死,但是要注意 进程 连接 仍在。虽然客户端也可以设置心跳检测,但在服务端设置更方便。
修改/etc/ssh/sshd_config

p参数表示ssh的端口
ssh命令
ssh -fCN -L 127.0.0.1:1234:192.168.99.125:3389 root@192.168.99.199 -p 53
plink.exe命令
plink.exe -v -C -N -L 127.0.0.1:8888:127.0.0.1:3389 test@117.28.112.73 -P 9398 -pw password
直接访问 本机 开启监听的1234端口,其实等于通过 远程主机 192.168.99.199来访问 远程主机 192.168.99.125上的3389端口

-n 将 stdio 重定向到 /dev/null,与 -f 配合使用
-T 不分配 TTY 只做代理用
-q 安静模式,不输出 错误/警告 信息
-f 后台连接
-N 连接后不取得shell
-C 启动压缩,加快速度
(如不理解参数可以去掉他们看效果)
-L 1234为建立隧道后本地监听的端口,192.168.99.125是隧道出口转发到的目标地址(即xp靶机),3389是目标端口,root@192.168.99.199是建立隧道的另一方,即rolling版登录的账号和ip,-p 53是rolling版的监听端口。

ssh -fCN -R 0.0.0.0:9999:192.168.1.1:80 root@test.com

0.0.0.0表示vps上监听所有地址。
直接访问 远程主机 上开启监听的9999端口就相当于通过 本机 来访问192.168.1.1上的80端口。

其中有个 大坑
bind_address 参数默认值为空,等价于

并不意味着任何机器,都可以通过 VPS 来访问 内网 机器。建立连接后,只能在 VPS ( sshd server ) 本地 访问 「内网」 机器。要在办公网的笔记本上通过 VPS 映射的端口来访问 内网 机器,需要修改vps上的/etc/ssh/sshd_config文件,启用 VPS sshd 的 GatewayPorts 参数,set to yes or clientspecified ,允许任意请求地址,通过转发的端口访问内网机器。

-D socks代理,不多解释了。
-g 监听所有地址,允许其他主机连接。

使用 sshtunnel 包进行两步 SSH 本地端口转发

【中文标题】使用 sshtunnel 包进行两步 SSH 本地端口转发【英文标题】:Two step SSH local port forwarding using sshtunnel package 【发布时间】:2021-01-28 07:45:35 【问题描述】:

我正在尝试在 host1 和 host3 之间打开一条双向隧道,其中 host2 位于中间。

host1 <--> host2 <--> host3

这是我在 host1 上运行的(阻塞)bash 命令转发端口 51672。

ssh -g -L 51672:host2:51672 host2_username@host2 \'/tmp/sshpass -p host3_pass ssh -g -L 51672:host3:51672 host3_username@host3 \'\'"while true; do : ; sleep 5; done"\'\'\'

我有一个在host3 上运行的脚本,监听端口51672。当我在host1 上创建一个TCP 套接字并连接到host2:51672 时,我可以通过该套接字与host3 上的脚本进行通信。

在下一步中,我尝试将其移植到 python 中并使用 sshtunnel 包。我有点困惑here 中的哪个选项相当于我的场景。

这是我的第一次尝试:

import paramiko
import sshtunnel

with sshtunnel.open_tunnel(
        ssh_address_or_host=(host2, 22),
        ssh_username=host2_username,
        ssh_password=host2_pass,
        local_bind_address=('0.0.0.0', 51672),
        remote_bind_address=(host3, 22),
        block_on_close=False
) as tunnel1:
    log.info('Tunnel to host2 is established.')
    with sshtunnel.open_tunnel(
            ssh_address_or_host=('localhost', tunnel1.local_bind_port),
            ssh_username=host3_username,
            ssh_password=host3_password,
            remote_bind_address=(host3, 51672),
            block_on_close=False
    ) as tunnel2:
        log.info('Tunnel to host3 is established.')
        while True:
            time.sleep(1)

我可以确认从 host1 到 host2 的隧道是打开的,因为下面的命令在 host1 上返回 0。

nc -z localhost 51672

但是,host2 和 host3 之间的隧道似乎无法正常工作。

【问题讨论】:

【参考方案1】:

第一步是建立 SSH 隧道。然后你隧道你的自定义端口。

更容易掌握的方法(尽管不是最佳的)是:

打开到host2的直接SSH连接。 通过host2 连接将本地host1:A 端口转发到host3:22 使用转发端口host1:A 打开与host3 的SSH 连接。 通过host3 将另一个本地host1:B 端口转发到host3:51672。 连接到host1:B 以访问host3:51672

但您实际上不需要进行第一个物理端口转发,您可以使用sock 方法,例如Nested SSH using Python Paramiko。

(我相信即使是您最初的 ssh 方法也过于复杂,有两个转发)

【讨论】:

以上是关于SSH进行端口转发的主要内容,如果未能解决你的问题,请参考以下文章

SSH端口转发

SSH端口转发

SSH端口转发

使用 sshtunnel 包进行两步 SSH 本地端口转发

SSH的端口转发

SSH 端口转发