ichuan.net

自信打不死的心态活到老

python小工具:tcp proxy和tcp hub

刚才看书,忽然想用 pythonsocket 模块写个 tcp proxy 工具,于是立马动手。写完后运行,改了几个手误,竟再无严重 bug。这点让我很欣慰。

完成的脚本是:tcp_proxy.py。这个脚本作用就是让一台机器变成 tcp 跳板。例如 A 机器想连 B 机器,但不能直接连上;而 C 机器可以直接连 B 机器,也可以与 A 机器连接。则在 C 机器上执行此脚本,A 机器连 C 机器的一个端口,就相当于连到 B 机器的某个端口,间接实现 AB 的通信。这和 HTTP 代理类似。

这个脚本支持多客户端同时连接。

以下是一个在代理机上执行此脚本后,我连接代理机 1234 端口的输出:

$ python tcp_proxy.py -l 1234 -r baidu.com:80 -v
Listening at 0.0.0.0:1234 ...
New clients from 10.2.3.5:56344
10.2.3.5:56344 => 220.181.111.85:80 (481 bytes)
220.181.111.85:80 => 10.2.3.5:56344 (381 bytes)
10.2.3.5:56344 => 220.181.111.85:80 (406 bytes)
New clients from 10.2.3.5:56348
220.181.111.85:80 => 10.2.3.5:56344 (551 bytes)
10.2.3.5:56348 => 123.125.114.144:80 (593 bytes)
123.125.114.144:80 => 10.2.3.5:56348 (197 bytes)
New clients from 10.2.3.5:56352
10.2.3.5:56352 => 220.181.111.86:80 (136 bytes)
220.181.111.86:80 => 10.2.3.5:56352 (381 bytes)
Socket closed by 10.2.3.5:56352
Socket closed by 220.181.111.85:80
Socket closed by 123.125.114.144:80
^CClosing...

上例中 10.2.3.5 相当于 A 机器,而 baidu.com 相当于 B 机器。

测试了代理 ssh 连接,无问题。

还有一种情况是:C 也无法连接 B,但 B 能连接 C。比如 AB 都是处在不同内网的机器,C 是公网上的一台机器。这样就需要 AB 分别连接 CC 然后把两个 socket 中转。

针对这种情况,我改了下原先的脚本,得到一个新的脚本:tcp_hub.py

以下是在公网机器上执行此脚本后的输出。我另外在两个内网机器上分别用 nc 去连公网机器的 1234512346 端口,连接后两个内网机器可以相互 echo 信息:

$ python tcp_hub.py -a 12345 -b 12346 -v
Listening at 0.0.0.0:12345 ...
Listening at 0.0.0.0:12346 ...
New clients from 128.224.233.142:35595 ...
New clients from 128.224.233.142:33668 ...
128.224.233.142:33668 => 128.224.233.142:35595 (2 bytes)
128.224.233.142:35595 => 128.224.233.142:33668 (5 bytes)
Socket closed by 128.224.233.142:33668
Socket closed by 128.224.233.142:35595

Comments