SSH Tunnel 技巧

66 views
Skip to first unread message

Zoom.Quiet

unread,
May 14, 2015, 10:48:25 AM5/14/15
to shlug
折腾了半天未果,特此咨询一下髙人们:

- 背景:
+ localhost 在中国
+ hostUS 在米国
+ hostJP 当然在日本
+ hostBR 国内的跳板机
+ 限制:
* hostUS 是生产机
* 只允许从 hostBR 接入
* 每次必须用口令+google 的二次口令
* 慢到飞溅
- 条件:
+ hostJP 是俺私人主机
+ 通过 hostBR 进入 hostUS 后经过配置
+ 可以从 hostUS SSH 到 hostJP
+ 但是,反向不行,有 host 限制
+ 从 localhost 可直接 ssh hostJP, 速度很不错
- 问题:
俺如何可以利用 hostJP 作为隧道,直接连接 hostUS 进行快速测试开发?
- 分析:
+ 一般思路
+ 将 hostUS 的 22 端口,用 hostJP 的 9022 端口代理
+ 然后就能从 localhost 访问 hostJP:9022 等于进入 hostUS
+ hostUS 上尝试:
ssh -C -f -N -g -R 9022:localhost:22 hostJP

在 hostJP 上用 netstat -nltp 观察到了 9022 端口发布

但是,在 hostJP 上测试 ssh -p 9022 localhost 时
要 password ?!
即使在 hostUS 上配置了对应用户帐号的 password 一样无法登录回 hostUS

- 测试:
+ 为了明确思路可行
+ 俺在 hostUS 上运行
+ python27 -m SimpleHTTPServer 10080
+ 然后
ssh -C -f -N -g -R 8080:localhost:10080 hostJP
+ 在 hostUS 上 curl localhost:10080
+ 和 hostJP 上 curl localhost:8080
+ 获得了相同的返回

所以,哪儿出问题了!?


--
Life's Pathetic, Let's Pythonic! 人生苦短, Python是岸!
俺: http://zoomquiet.io
授: http://creativecommons.org/licenses/by-sa/2.5/cn/
怒: 冗余不做,日子甭过!备份不做,十恶不赦!
KM keep growing environment culture which promoting organization be learnning!

雷钦

unread,
May 14, 2015, 5:42:29 PM5/14/15
to shlug
该隧道只是将 hostJP 的 9022 端口 转发到 hostUS 的 22 端口,
这和直接在 hostJP 上 ssh hostUS 应该没什么区别(除了绕过了墙),
需要登陆是正常情况

> 即使在 hostUS 上配置了对应用户帐号的 password 一样无法登录回 hostUS

在 hostUS 上限制了 除 hostBR 之外 其他的 host 登陆,
这一步 是在 哪里做的? iptables 、 hosts.allow 还是 sshd_config

如果是在 iptables 里,那这个隧道应该可以绕开这个限制。

如果是在 hosts.allow 或者 sshd_config 里, 无法登陆 就是正常情况。

>
> - 测试:
> + 为了明确思路可行
> + 俺在 hostUS 上运行
> + python27 -m SimpleHTTPServer 10080
> + 然后
> ssh -C -f -N -g -R 8080:localhost:10080 hostJP
> + 在 hostUS 上 curl localhost:10080
> + 和 hostJP 上 curl localhost:8080
> + 获得了相同的返回
>
> 所以,哪儿出问题了!?


我能想到的办法是用 nc

首先 在 hostJP 上用 tmux 分屏, 就叫作 A 屏 和 B 屏

在 A 屏运行

nc -l -p 9002

用于显示 输出

然后 在 hostUS 上

1. 将 hostUS 的 9002 转发到 hostJP 的 9002

ssh -C -f -N -g -L 9002:localhost:9002 hostJP

2. 将 hostJP 的 9001 转发到 hostUS 的 9001 , 该端口 用于 接受 输入

ssh -C -f -N -g -R 9001:localhost:9001 hostJP

3. 运行

nc -l -p 9001 | bash | nc localhost 9002

最后, 回到 hostJP, 在 B 屏 运行

nc localhost 9001

然后 就是 B 屏 输入, A 屏 输出。

这个样子,虽然别有一番风味,但是也挺蛋疼的, 大妈可以试试。
而且这个样子无法编辑文件。

希望其他人有更好的办法...

Felix Yan

unread,
May 14, 2015, 10:51:08 PM5/14/15
to sh...@googlegroups.com
正好前几天因为另一个原因开过反弹 shell……分享一下:

可以用 socat 换掉 nc 和管道,为了用到它的 raw 模式;然后用 script 提供的
pty 给 bash 加上 job control 等支持,得到相对更好的效果:

在 hostUS 上:

$ ssh -C -f -N -g -R 9002:localhost:9002 hostJP
$ socat tcp-listen:9002,fork,bind=127.0.0.1 SYSTEM:"script
/dev/null",pty,stderr

在 hostJP 上:

$ socat tcp:127.0.0.1:9002 stdio,raw,echo=0

在 hostJP 上每次执行上面命令的时候会得到一个新的 (script 开出来的)
bash,里面所有控制指令都可以用,vim 等工具也正常,唯一的问题是终端字符界
面大小(宽、高)是一个固定值,不能跟随你的终端窗口变化。

条件允许的话,这个方法还可以进一步简化到使用 socat 的 openssl 连接模式直
接反弹到 hostJP 的公开端口,完全避开 ssh 隧道。

--
Regards,
Felix Yan

signature.asc

Chaos Eternal

unread,
May 15, 2015, 12:06:43 AM5/15/15
to sh...@googlegroups.com
hostUS可以ssh localhost吗?如果可以,那你只要用remote 方式把127.0.0.1:22定向到hostjs上的一个端口就好。

否则你得开后门:
比如用socat tcp-listen:someport exec:/bin/bash
然后把这个someport用remote的方式给hostjp, 然后hostjp telnet 到这个port
> --
> -- You received this message because you are subscribed to the Google Groups Shanghai Linux User Group group. To post to this group, send email to sh...@googlegroups.com. To unsubscribe from this group, send email to shlug+un...@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/shlug?hl=zh-CN
> ---
> 您收到此邮件是因为您订阅了 Google 网上论坛的“Shanghai Linux User Group”群组。
> 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到shlug+un...@googlegroups.com
> 要查看更多选项,请访问 https://groups.google.com/d/optout

依云

unread,
May 15, 2015, 12:20:45 AM5/15/15
to sh...@googlegroups.com
On Fri, May 15, 2015 at 10:50:51AM +0800, Felix Yan wrote:
> 正好前几天因为另一个原因开过反弹 shell……分享一下:
>
> 可以用 socat 换掉 nc 和管道,为了用到它的 raw 模式;然后用 script 提供的
> pty 给 bash 加上 job control 等支持,得到相对更好的效果:
>
> 在 hostUS 上:
>
> $ ssh -C -f -N -g -R 9002:localhost:9002 hostJP
> $ socat tcp-listen:9002,fork,bind=127.0.0.1 SYSTEM:"script
> /dev/null",pty,stderr
>
> 在 hostJP 上:
>
> $ socat tcp:127.0.0.1:9002 stdio,raw,echo=0
>
> 在 hostJP 上每次执行上面命令的时候会得到一个新的 (script 开出来的)
> bash,里面所有控制指令都可以用,vim 等工具也正常,唯一的问题是终端字符界
> 面大小(宽、高)是一个固定值,不能跟随你的终端窗口变化。
>
> 条件允许的话,这个方法还可以进一步简化到使用 socat 的 openssl 连接模式直
> 接反弹到 hostJP 的公开端口,完全避开 ssh 隧道。

既然用 socat 了就不要用 script 了。服务端:

socat tcp-l:8889,reuseaddr,bind=127.1 exec:'zsh -i',pty,setsid,stderr,sane

客户端可以用 nc:

stty raw -echo; nc 0 8889; stty cooked echo

当然也可以还用 socat:

socat tcp:127.0.0.1:8889 stdio,raw,echo=0


--
Best regards,
lilydjwg

Linux Vim Python 我的博客:
http://lilydjwg.is-programmer.com/
--
A: Because it obfuscates the reading.
Q: Why is top posting so bad?

Felix Yan

unread,
May 15, 2015, 12:32:18 AM5/15/15
to sh...@googlegroups.com
On 05/15/2015 12:19 PM, 依云 wrote:
> 既然用 socat 了就不要用 script 了。服务端:
>
> socat tcp-l:8889,reuseaddr,bind=127.1 exec:'zsh -i',pty,setsid,stderr,sane

exec: 在我的测试中是不能带参数的,所以我猜测你指的是 system:'zsh -i'。

我没有试过 zsh,不过把 zsh 换成 bash 的话,这样依然不能打开 job
control,会得到这样的错误信息:

bash: cannot set terminal process group (11135): Inappropriate ioctl for
device
bash: no job control in this shell

这是我把 'bash -i' 换成 'script /dev/null' 的原因。我得承认这一块我不是
很懂,会想到用 script 是因为以前遇到 sudo 成其他用户用 screen 提示没有
pty 时,可以用 script /dev/null 来 workaround,于是在这里试了一下,发现
居然也可以用。

--
Regards,
Felix Yan

signature.asc

Zoom.Quiet

unread,
May 15, 2015, 2:30:21 AM5/15/15
to shlug
多了很多可能性,
容俺逐一尝试一下,,,,
不过,目测可能没那么简单.
> --
> -- You received this message because you are subscribed to the Google Groups Shanghai Linux User Group group. To post to this group, send email to sh...@googlegroups.com. To unsubscribe from this group, send email to shlug+un...@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/shlug?hl=zh-CN
> ---
> 您收到此邮件是因为您订阅了 Google 网上论坛的“Shanghai Linux User Group”群组。
> 要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到shlug+un...@googlegroups.com
> 要查看更多选项,请访问 https://groups.google.com/d/optout



依云

unread,
May 15, 2015, 4:41:38 AM5/15/15
to sh...@googlegroups.com
咦为什么你的 socat 不支持 exec 带参数?这是我的 socat 版本信息:

>>> socat -V
socat by Gerhard Rieger - see www.dest-unreach.org
socat version 1.7.3.0 on Jan 24 2015 07:40:41
running on Linux version #10 SMP PREEMPT Sun May 3 19:45:16 CST 2015, release 4.0.1-1-lily, machine x86_64
features:
#define WITH_STDIO 1
#define WITH_FDNUM 1
#define WITH_FILE 1
#define WITH_CREAT 1
#define WITH_GOPEN 1
#define WITH_TERMIOS 1
#define WITH_PIPE 1
#define WITH_UNIX 1
#define WITH_ABSTRACT_UNIXSOCKET 1
#define WITH_IP4 1
#define WITH_IP6 1
#define WITH_RAWIP 1
#define WITH_GENERICSOCKET 1
#define WITH_INTERFACE 1
#define WITH_TCP 1
#define WITH_UDP 1
#define WITH_SCTP 1
#define WITH_LISTEN 1
#define WITH_SOCKS4 1
#define WITH_SOCKS4A 1
#define WITH_PROXY 1
#define WITH_SYSTEM 1
#define WITH_EXEC 1
#define WITH_READLINE 1
#define WITH_TUN 1
#define WITH_PTY 1
#define WITH_OPENSSL 1
#undef WITH_FIPS
#undef WITH_LIBWRAP
#define WITH_SYCLS 1
#define WITH_FILAN 1
#define WITH_RETRY 1
#define WITH_MSGLEVEL 0 /*debug*/

你的是不是没有 WITH_PTY 之类的?

Felix Yan

unread,
May 15, 2015, 4:57:18 AM5/15/15
to sh...@googlegroups.com
On 05/15/2015 04:40 PM, 依云 wrote:
> 咦为什么你的 socat 不支持 exec 带参数?

PTY 应当是有的:
#define WITH_PTY 1

使用 exec:'bash -i' 得到的错误提示是这样的:
2015/05/15 16:52:11 socat[51] E execvp("bash", "bash", "-i"): No such
file or directory

但是直接 exec:bash 却是可以的。

--
Regards,
Felix Yan

signature.asc

依云

unread,
May 16, 2015, 1:34:06 AM5/16/15
to sh...@googlegroups.com
好奇怪,我这里是正常的。大概你的 socat 是某个有 bug 的版本?

Felix Yan

unread,
May 16, 2015, 2:44:16 AM5/16/15
to sh...@googlegroups.com
On 05/16/2015 01:33 PM, 依云 wrote:
> 好奇怪,我这里是正常的。大概你的 socat 是某个有 bug 的版本?

我的运行环境是 socat on wine + msys2,可能在其中某个地方触发了 bug……

刚才在 Linux 上测试了 exec:'bash -i',可以正常工作。解决 no job control
问题的参数是 pty,setsid 这对 flag。我之前只给了 pty 是不行的。

多谢!

--
Regards,
Felix Yan

signature.asc

Ray Song

unread,
May 28, 2015, 3:24:04 AM5/28/15
to Felix Yan, sh...@googlegroups.com
看上去不带 setsid 选项的话 exec 的命令的控制终端仍然是之前 socat 的,但 fd 0,1,2 是新 pty
没有权限进行前台进程组操作(tcsetpgrp等),失去了 job control
Reply all
Reply to author
Forward
0 new messages