Quantcast
Viewing all articles
Browse latest Browse all 767

shadowsocks实现原理

shadowsocks实现原理

shadowsocks是目前最好的科学上网方式,它的流量经过加密,所以没有流量特征不会被GFW阻断;关键是,它的实现原理也通俗易懂。

笔者是ss的重度用户,电脑和手机都在使用。本文不会介绍怎么安装使用shadowsocks,因为很多文章都有详细介绍。在文中简称shadowsocks为ss。

前言

shadowsocks已经出现很多年了,作者是clowwindy,大家可以去github查看他的主页。github上ss仓库https://github.com/shadowsocks/shadowsocks/tree/master的代码已经比较难维护了,状态机和epoll很好,提高了程序的性能效率,但是很多东西也影响了我们去看核心的东西是什么。所以本文解析的是一个轻量级的ss,clowwindy写的比较早的版本,那个时候使用select而不是epoll,网络通信的逻辑也很清晰,容易了解ss的原理,代码的仓库为https://github.com/YvesChan/shadowsocks

概述

Image may be NSFW.
Clik here to view.

ss要求本机运行local.py,海外服务器运行server.py。local.py默认监听localhost的1080端口,该端口代理浏览器的请求。browser要访问google时,会和localhost:1080进行一次基于sock5协议的通信,如上图的红色虚线框,sock5协议可以去了解下,维基百科有不错的介绍。

代理的流程如下:

  1. localhost:1080经过sock5协议后,就知道要访问google了
  2. local程序会把流量加密,然后把普通的TCP流量发往海外服务器;
  3. 海外服务器收到请求后,解密得到要访问google
  4. 海外服务器请求google后把得到的数据加密返回给local
  5. local解密返回给browser。

ss的解密和加密基于用户设置的密码,所以local和server之间可以做到加密和解密的一致。

网络编程

python网络编程相比C语言要少很多代码,由于有很多封装得很好的类可以使用,网络编程更加符合思维走向。作者clowwindy使用了SocketServer.TCPServer和SocketServer.StreamRequestHandler两个类完成TCP的处理。在python的官方文档可以查看到两者的详细介绍。从名字中也可以知道两者的作用:TCPServer负责处理连接accept或close等,此类的构造函数要求传入Handler类;Handler类负责连接的数据处理,包括recv和send,此类要求实现handle方法。StreamRequestHandler更进一步把recv和send封装为rfile读端的read和wfile.write,把socket操作转化为了文件的读写,更加便捷。

local程序的handle方法:

Image may be NSFW.
Clik here to view.

图截自github,本人已经标注handle函数每个部分的作用,最后的handle_tcp等待sock和remote的事件,sock可读则读取然后发往remote,remote可读就读取然后发往sock,代码如下图:

Image may be NSFW.
Clik here to view.

注意encrypt和decrypt,加密和解密的算法感兴趣可以去看看代码,使用到了python自带的加密解密方法。

server端的handle方法就不再截图了,因为和local.py很类似,只是一些细节流程不一致而已。大家感兴趣可以下载代码阅读。

运行效果
服务端先运行server.py后,本地运行loca.py,并且设置浏览器代理为本地1080就OK了

Image may be NSFW.
Clik here to view.

总结

ss除了python版本之外还有c和go的版本,后两者的口碑比python版本的好一点。

感谢clowwindy大牛,正是有能力的人的辛勤且无悔的付出,开源领域才越来越繁荣。

最后,我们应该为生活在有github的时代而感到幸福。


Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.

Viewing all articles
Browse latest Browse all 767

Trending Articles