python版shadowsocks流量及用户管理开发

上周五回青岛了,让我不爽的是航班因为天气问题被取消了,然后回北京的时候,特么飞机起飞的时间又拖延了2个小时,特么真倒霉… …

在北京T3机场的时候,碰到几个屌丝,长那样就是个IT屌丝的样子… 本来没眯一会的,但是他们的声音有些大,各种python专业术语。搞得我有些心痒痒,就跟他们聊了会,原来这几个孩子是打算回青岛做一个类似浏览器代理的东西。 

因为青岛的外企很多,里面的员工是需要经常翻墙浏览一些资料的,最少是gmail和google搜索…  没办法,咱们就这样… 

关于shadowsocks相关开发的文章,http://xiaorui.cc/?p=1812

http://xiaorui.cc/2015/08/03/python%E7%89%88%E7%9A%84shadowsocks%E5%85%B3%E4%BA%8E%E6%B5%81%E9%87%8F%E5%8F%8A%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86%E5%BC%80%E5%8F%91/



话说shadowsocks这个bt的代理,我自己也经常用,我相信在看这篇文章的人,一定是或用过,或听过的… shadowsocks是个socketv5协议的代理,为了避开GFW针对纯ssh代理的封杀。 

开源的shadowsocks使用很简单,但默认不能很好的支持多用户管理和流量统计,及各种自动化管理的。 shadowsocks的作者在项目里面,没有描述过接口的使用,在readme里面也只是教你怎么用罢了。   有不少人开始用shadowsocks做个产品,也卖了不少钱。  看来要实现流量管理和多用户需要看他的源码了….    注:我曾经给作者发过一个邮件让他写点 shadowsocks api接口的文档。。。。

 现在有一好人贡献了shadowsock的扩展代码  https://github.com/mengskysama/shadowsocks/tree/manyuser ,让我舒心的是,这个python写得,能看懂。。。。呵呵   貌似现在shadowsocks各个语言版本都有,python和golang的用的普遍要多。     manyuser是支持多用户,多端口,流量,针对流量超出进行判断,至于性能方面我还没有测试,介于他支持增加了功能模块,性能应该不受影响。 

他这边对于用户的管理和流量统计及阈值判断都在mysql做的,如果有兴趣的人,可以把她改成redis的模式,其实用mysql只做最基本的用户验证及统计结果存储,一些临时累加计算的就用redis来做就用了。  

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(32) NOT NULL,
  `pass` varchar(16) NOT NULL,
  `passwd` varchar(16) NOT NULL,
  `t` int(11) NOT NULL DEFAULT '0',
  `u` bigint(20) NOT NULL,
  `d` bigint(20) NOT NULL,
  `transfer_enable` bigint(20) NOT NULL,
  `port` int(11) NOT NULL,
  `switch` tinyint(4) NOT NULL DEFAULT '1',
  `enable` tinyint(4) NOT NULL DEFAULT '1',
  `type` tinyint(4) NOT NULL DEFAULT '1',
  `last_get_gift_time` int(11) NOT NULL DEFAULT '0',
  `last_rest_pass_time` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`,`port`)
) ENGINE=InnoDB AUTO_INCREMENT=415 DEFAULT CHARSET=utf8;

这边的代码是python写得。   filename shadowsocks/db_transfer.py   ,db_transfer.py里面的逻辑大多数是用户管理相关的。 

@staticmethod
def thread_db():
    import socket
    import time
    timeout = 60
    socket.setdefaulttimeout(timeout)
    while True:
        #logging.warn(‘db loop’)
        try:
            #更新每个用户的流量到mysql里面。
            DbTransfer.get_instance().push_db_all_user() 
            #对于流量超出的用户,进行下一步操作。
            rows = DbTransfer.get_instance().pull_db_all_user()  
            DbTransfer.del_server_out_of_bound_safe(rows)
        except Exception as e:
            logging.warn(‘db thread except:%s’ % e)
        finally:
            time.sleep(15)

我们可以在mysql里面,获取该用户在数据库中记录的上次流量信息。 

last_transfer = self.last_get_transfer
通过调用server_pool里的 get_servers_transfer()信息,比如当前的使用流量。 
curr_transfer = ServerPool.get_instance().get_servers_transfer()

在 shadowsocks/server_pool.py文件有个new_server函数,这是用来增加新用户的链接 , 也是多用户的相关逻辑。 

def new_server(self, port, password):
    ret = True
    port = int(port)

    if ‘server’ in self.config:
        if port in self.tcp_servers_pool:
            logging.info(“server already at %s:%d” % (self.config[‘server’], port))
            return ‘this port server is already running’
        else:
            a_config = self.config.copy()
            a_config[‘server_port’] = port
            a_config[‘password’] = password
            try:
                logging.info(“starting server at %s:%d” % (a_config[‘server’], port))
                tcp_server = tcprelay.TCPRelay(a_config, self.dns_resolver, False)
                tcp_server.add_to_loop(self.loop)
                self.tcp_servers_pool.update({port: tcp_server})
                #udp_server = udprelay.UDPRelay(a_config, self.dns_resolver, False)
                #udp_server.add_to_loop(self.loop)
                #self.udp_servers_pool.update({port: udp_server})
            except Exception, e:
                logging.warn(e)

先这样吧,还有几个模块没有来得及看,有时间再把那几个模块分享下。 


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

5 Responses

  1. 云开发 2015年9月8日 / 上午8:04

    写的不错,赞一个

  2. 歪妖内涵网 2015年9月1日 / 上午8:01

    我不是来抢沙发的,也不是来打酱油的。

  3. 米运维 2015年8月10日 / 上午7:39

    峰云兄咋又对这感兴趣了?

  4. 求子 2015年8月9日 / 下午2:35

    最新版已经有api接口 但怎么使用?

    • 峰云就她了 2015年8月9日 / 下午9:24

      已经有了么? 貌似在doc上没有说明吧?

发表评论

邮箱地址不会被公开。 必填项已用*标注