写了一个 proxy 用途你懂的

标签: Go 语言 我爱折腾 | 发表时间:2011-05-05 13:57 | 作者:云风 jqian
出处:http://blog.codingnow.com/

用 linode 有一年多了 ,除了架设 blog ,我也折腾点小程序放在上面跑。在互联网上有一台自己的主机,对于一个程序员来说,还是很有必要的。当然这 vps 绝对不能选国内的,原因你懂的。这样,附带的一个好处就是可以用 ssh -D ,相信许多同学都喜欢用。

没来由的,我想自己写一个小程序,完成 ssh -D 一样的功能,不过,不走 SSL 加密。当然也不能走明文,由于众所周知的原因,明文通讯很容易引起奇异的连接断开或长期超时的 bug ,此 bug 绝对不在于你的程序。网络连接永远不是 100% 可靠的嘛。

我花了两天实现我的构想,本来第一天已经完成了,但实现的过于复杂,且 bug 重重。花了一个通宵都没完全解决。在补了个好觉后,我在梦中意识到,应该简化方案,然后在第二天重写了一遍,终于可以跑起来了。代码是用 Go 实现的,比较玩具,quick & dirty 。不过我还是把它们放在后面。有兴趣的同学可以拿去改进。目前这个雏形已经够我用了,所以即使有改进或许也懒得再贴出来了。

主体想法是由两个部分的程序构成,一边放在本机上,对 localhost 开启一个兼容 socks5 的本地端口。当然只这一部分是不够用的,我们需要在墙外再设置一个程序,它才是真正的 proxy server 。这两个程序之间保持一个 TCP 连接。由本地的程序负责把本地的 proxy 请求都转发到墙外。

最初的想法,我阅读了 socks5 的 RFC1928 ,觉得实现一个 socks5 server 没什么大不了的。我要做的只是把所有的 socks5 请求编码成私有协议,通过唯一的 TCP 连接转发到墙外,由墙外的程序正确的 proxy 。事实证明,想在一天时间内正确的实现 socks5 协议还是有点难度的。即使用 Go 语言,对于我这个新手来说也不现实。ps , 通宵不睡觉调 bug 的效率也太低,不推荐在 30 岁以后还经常干。

睡了一觉后,我修正了我的方案。整个系统由三部分构成:

本地 n:1 连接转发服务 ----(传说中的墙)---- 墙外 1:n 连接转发服务 ---- socks5 服务器

简单的说,本地可以向本地服务提起若干个 TCP 连接,请求 socks5 服务。然后,我的程序把他们合成一个,通过一个长连接,通通转发到墙外。这中间可以做简单的加密或数据压缩。

在墙外的 vps 上,我放置一个私有程序,接收这些合并起来的连接。然后分解为一个个独立的请求。然后去连接 vps 本地的一个 socks5 服务器。

因为是个人使用,墙的两边的自写程序,只保持一个连接,一旦连接建立起来后,墙外的服务不在监听接受新的连接。只做 1:1 的服务。这样比较安全。不过想扩展成多个服务的,对于 Go 语言来说也相当容易,只是我懒的做罢了。

私有程序没有做身份认证。这是因为我只提供 1:1 服务,所以即使不认证也不会被人盗用。我只需要在需要使用时,手动开启即可。当然加上认证机制也不难,没加的理由还是我比较懒 :)

真正的 socks5 服务器就不用自己写啦。我用的 ssocks 比较轻量,也很单纯,就是一个 socks5 server 而已。不过这个东东目前的版本(0.0.10)有个小问题,它默认的监听绑定地址是 0.0.0.0 且不能配置(写死在代码里了)。在 README 中,我们看到 TODO 里作者有让它可配置的计划。在我这个应用中,我希望 socks5 server 只给本地用。所以需要自己做点小修改了。

只需要把 src/libsocks/net-util.c 中 new_listen_socket 函数里

      addrS->sin_addr.s_addr = htonl(INADDR_ANY);  /* All Local addresses */

这一行中的 INADDR_ANY 改成 INADDR_LOOPBACK 即可。

我的程序的源代码看这里。如有 bug 欢迎指出,若有问题概不解答 :) 。写的很乱,估计自己都不想再看一遍了。


ps. 最近买了一套新桌游,七大奇迹,很是不错,推荐一下。

相关 [proxy 你懂的] 推荐:

写了一个 proxy 用途你懂的

- jqian - 云风的 BLOG
用 linode 有一年多了 ,除了架设 blog ,我也折腾点小程序放在上面跑. 在互联网上有一台自己的主机,对于一个程序员来说,还是很有必要的. 当然这 vps 绝对不能选国内的,原因你懂的. 这样,附带的一个好处就是可以用 ssh -D ,相信许多同学都喜欢用. 没来由的,我想自己写一个小程序,完成 ssh -D 一样的功能,不过,不走 SSL 加密.

MySQL Proxy 0.8.4 发布

- - 开源中国社区最新新闻
MySQL Proxy 0.8.4 发布. 2014-01-10 这是MySQL官方读写分离以及负载均衡工具,上一个版本还是2012-08-20的0.8.3.过了一年半. 国内360基于这个发布了Atlas. MySQL-Proxy是处在你的MySQL数据库客户和服务端之间的程序,它还支持嵌入性脚本语言 Lua.

为MetroTwit设置Http Proxy

- stranger - iGFW
MetroTwit无疑是Windows平台上让人赏心悦目的Twitter Client. 但没有为用户提供Http Proxy或API Proxy,这给很多人带来了使用上的不便. 下面我尝试了两种为MetroTwit设置Http Proxy的方法,效果都还不错. 为Windows系统设置全局的Proxy,也就是在IE中设置Proxy.

java 动态代理(Proxy)

- - BlogJava_首页
动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实,代理对象对客户隐藏了实际对象. 动态代理可以对请求进行其他的一些处理,在不允许直接访问某些类,. 或需要对访问做一些特殊处理等,这时候可以考虑使用代理. 目前 Java 开发包中提供了对动态代理的支持,但现在只支持对接口的实现. 主要是通过 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口.

Dynamic Proxy (动态代理)

- - CSDN博客推荐文章
动态代理主要有一个 Proxy类 和一个 InvocationHandler接口. 真实主题角色(实现了抽象主题接口). 动态代理主题角色(实现了 InvocationHandler接口,并实现了 invoke()方法). Proxy 要调用 newProxyInstance方法. 1.抽象主题角色 SubjectDemo.java.

Twemproxy – Twitter 开源的 Redis proxy

- - NoSQLFan
在去年的QCon London2012 大会上,Twitter 发表了题为 《 Timelines @ Twitter》的演讲,里面提到以 Redis作为其timeline的主要存储,目前目测全球范围内,Twitter可能是Redis的最大用户了(或者是新浪微博. 而今天我们要说的这个 Twemproxy,是 Twitter 开源出来的 Redis 和 Memcached 代理.

设计模式之代理模式(Proxy)

- - 博客园_首页
这段时间一直忙于期末考试,好久没来博客园了,现在好了,终于考完了,也该过上正常的日子了. 开学就是大四的学生了,时间过的可是真快啊,转眼间大学四年已经接近尾声了. 回想大学这三年,成绩还可以吧(年级前10%),参加过各种竞赛(acm,数学建模等等),学生会也呆过(打了一年的酱油),好哥们也有那么五六个(希望以后能在一个城市发展,大学期间的宝贵财富啊),另外所谓的大学生创新实践项目也搞了一个(就算开阔一下视野吧,大学能生有什么创新呢.

使用nginx作为websocket的proxy server

- - CSDN博客推荐文章
WebSocket协议为创建客户端和服务器端需要实时双向通讯的webapp提供了一个选择. 其为HTML5的一部分,WebSocket相较于原来开发这类app的方法来说,其能使开发更加地简单. 大部分现在的浏览器都支持WebSocket,比如Firefox,IE,Chrome,Safari,Opera,并且越来越多的服务器框架现在也同样支持WebSocket.

Chrome和Proxy Switchy支持远程DNS解析

- 洋白菜 - 月光微博客
  以前的Chrome因为没有远程域名解析功能,所以一般都开着一个Firefox作为代理备用. 但是Firefox占用资源太大,总是想换.   现在发现,原来Chrome不知道什么时候已经添加了远程域名解析功能,使用 Proxy Switchy 设置 Socks5 代理之后,访问自动会启用远程DNS解析,不用设置就行,经过测试访问Facebook、Twitter、Youtube等网站均无问题.

GAppProxy、wallproxy和hyk-proxy挂了之后的解决办法

- 阿德 - iGFW
GAppProxy、wallproxy和hyk-proxy都是使用GAE做代理服务器的优秀软件,不过由于GFW封锁加剧它们都悲剧了. 最先的封锁是封锁.appspot.com网址,不过我们可以用Google提供的代理(www.google.com:80 、 www.google.com.hk:80 、 www.google.cn:80)来连接,不过最近这几个代理也挂了,想想其他办法吧.