server.py文件的内容:
#!/usr/bin/env python |
| |
| # Copyright (c) 2012 clowwindy |
| # |
| # Permission is hereby granted, free of charge, to any person obtaining a copy |
| # of this software and associated documentation files (the "Software"), to deal |
| # in the Software without restriction, including without limitation the rights |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| # copies of the Software, and to permit persons to whom the Software is |
| # furnished to do so, subject to the following conditions: |
| # |
| # The above copyright notice and this permission notice shall be included in |
| # all copies or substantial portions of the Software. |
| # |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| # SOFTWARE. |
| |
| PORT = 8499 |
| KEY = "foobar!" |
| |
| import sys |
| import socket |
| import select |
| import SocketServer |
| import struct |
| import string |
| import hashlib |
| |
| def get_table(key): |
| m = hashlib.md5() |
| m.update(key) |
| s = m.digest() |
| (a, b) = struct.unpack('<QQ', s) |
| table = [c for c in string.maketrans('', '')] |
| for i in xrange(1, 1024): |
| table.sort(lambda x, y: int(a % (ord(x) + i) - a % (ord(y) + i))) |
| return table |
| |
| |
| class ThreadingTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): |
| pass |
| |
| |
| class Socks5Server(SocketServer.StreamRequestHandler): |
| def handle_tcp(self, sock, remote): |
| try: |
| fdset = [sock, remote] |
| while True: |
| r, w, e = select.select(fdset, [], []) |
| if sock in r: |
| if remote.send(self.decrypt(sock.recv(4096))) <= 0: |
| break |
| if remote in r: |
| if sock.send(self.encrypt(remote.recv(4096))) <= 0: |
| break |
| finally: |
| remote.close() |
| |
| def encrypt(self, data): |
| return data.translate(encrypt_table) |
| |
| def decrypt(self, data): |
| return data.translate(decrypt_table) |
| |
| def send_encrpyt(self, sock, data): |
| sock.send(self.encrypt(data)) |
| |
| def handle(self): |
| try: |
| print 'socks connection from ', self.client_address |
| sock = self.connection |
| sock.recv(262) |
| self.send_encrpyt(sock, "\x05\x00") |
| data = self.decrypt(self.rfile.read(4)) |
| mode = ord(data[1]) |
| addrtype = ord(data[3]) |
| if addrtype == 1: |
| addr = socket.inet_ntoa(self.decrypt(self.rfile.read(4))) |
| elif addrtype == 3: |
| addr = self.decrypt( |
| self.rfile.read(ord(self.decrypt(sock.recv(1))))) |
| else: |
| # not support |
| return |
| port = struct.unpack('>H', self.decrypt(self.rfile.read(2))) |
| reply = "\x05\x00\x00\x01" |
| try: |
| if mode == 1: |
| remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| remote.connect((addr, port[0])) |
| local = remote.getsockname() |
| reply += socket.inet_aton(local[0]) + struct.pack(">H", |
| local[1]) |
| print 'Tcp connect to', addr, port[0] |
| else: |
| reply = "\x05\x07\x00\x01" # Command not supported |
| print 'command not supported' |
| except socket.error: |
| # Connection refused |
| reply = '\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00' |
| self.send_encrpyt(sock, reply) |
| if reply[1] == '\x00': |
| if mode == 1: |
| self.handle_tcp(sock, remote) |
| except socket.error: |
| print 'socket error' |
| |
| |
| def main(host=''): |
| server = ThreadingTCPServer((host, PORT), Socks5Server) |
| server.allow_reuse_address = True |
| print "starting server at port %d ..." % PORT |
| server.serve_forever() |
| |
| if __name__ == '__main__': |
| encrypt_table = ''.join(get_table(KEY)) |
| decrypt_table = string.maketrans(encrypt_table, string.maketrans('', '')) |
| arg = sys.argv |
| if len(arg) == 1: |
| host = '' |
| print "Use default host" |
| else: |
| host = arg[1] |
| print "Use host %s" % host |
| main(host) |
---------------------------------------------------------------------
balan-proxy程序fork自shadowsocks。
balan-proxy项目地址:https://github.com/lerry/balan-proxy
增加自定义服务器列表支持,请将服务器地址列表放在同文件夹下,文件名: list.txt 格式:
8.8.8.8:8499
4.4.4.4:8499
#1.1.1.1:8849
暂时不使用的服务器地址可使用#注释
用法和shadowsocks一样( 装gevent,然后在启动server.py,能省下一些内存)。
不过上面代理加密简单,如果要高强度的加密可以考虑换成两边用ssl来通信,
这就有了sockstunnel,sockstunnel是一个使用ssl加密隧道的简单 socks5服务器
(shadowsocks也在测试更强的加密方式)。
sockstunnel项目地址:https://github.com/wynemo/sockstunnel
在服务器上,使用 openssl 生成您的密钥和证书文件的方法
openssl genrsa -out privkey.pem 2048
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
作者说其在server:ubuntu 11.10 x64 python2.7 /client:windows7 python 2.7.3,ubuntu 11.10 python 2.7.2下测试成功,有兴趣的可以试试。
除了加密问题,还有人提出了IPv6支持问题,于是shadowsocks作者加了一个实验性的 IPv6 branch,Server 是 IPv6 地址,因为和 IPv4 不兼容,所以暂时没合并。
IPv6 branch项目地址:https://github.com/clowwindy/shadowsocks/tree/ipv6
shadowsocks作者折腾完Python版后又把目光瞄向了node.js,这就有了加密代理 shadowsocks node.js
版。作者说加密代理 shadowsocks node.js 版经过一个多月的改进现在可以在 1000 并发,500 QPS
下稳定工作。现在用在一个项目中,每天通过上百 GB 流量。
shadowsocks-nodejs项目地址:https://github.com/clowwindy/shadowsocks-nodejs
和原 Python 版相比优势:
1. 不会大量创建线程,VSZ 使用很少,适合 OpenVZ。
2. 支持更大并发。因为 Python 版用的是 select(),fd > 1024 的时候就挂了。
缺点:
下载大文件时内存占用峰值会达到几十 MB,怀疑与 V8 的 GC 策略有关。(
参考)
当然 Python 版也可以改用非阻塞模型,不过写起来比 nodejs 麻烦就是了。欢迎有兴趣的童鞋做这样的尝试 :)
说明:
如果都升到最新版,Python 版与 node.js 版的协议是互相兼容的。即可以用 python client + node.js server。
另外感叹 V8 的性能确实很好,基本相同的计算密码表过程,纯 js 实现比纯 Python 实现快了几十倍。
使用方法:
Edit config.json
, change the following values:
server your-server-ip
server_port server port
local_port local port
password a password used to encrypt transfer
timeout in seconds
Put all the files on your server. Run
node server.js
on your server.
To run it in the background, run
setsid node server.js
.
Put all the files on your client machine. Run
node local.js
on your client machine.
Change proxy settings of your browser into
SOCKS5 127.0.0.1:local_port
另外作者还将多 server 功能加到一个新分支里了。
multi-server branc项目地址:https://github.com/clowwindy/shadowsocks-nodejs/tree/multi-server
50多行代码引起了这许多故事,终究使用起来还是要比ssh代理速度快,有VPS的同学可以试试啦。
另外以前说过goagent在
1.9.1a2测试版本中加入使用ssl加密独立主机上的wsgi.py(使用方法:python wsgi.py 443 -ssl ),这个和上面介绍的也是殊途同归
---------------------
用polipo把socks代理转换为http代理也很好用.把socks代理转换为http代理的最大好处就是
可以避免dns污染,比如你使用IE并且设置ie的socks代理的话,你依然是打不开
dongtaiwang.com的;但是如果你使用IE并且设置ie的http代理的话,
这样你就可顺利打开dongtaiwang.com (建议使用polipo,privoxy有时会出错。
polipo的使用方法:
http://web.archive.org/web/20130524201431/http://www.iusesoft.info/using-polipo-to-make-opera-works-with-socks5,)
不建议把此shadowsocks(它是一个socks proxy)搭配sockscap使用,因为通过ie还是打不开dongtaiwang.com
related post:
http://briteming.blogspot.com/2012/07/sockstunnel.html(利用sockstunnel翻墙)
http://briteming.blogspot.co.uk/2012/07/proxifierssh.html
http://briteming.blogspot.co.uk/2012/06/blog-post_20.html
------------------------
shadowsocks(SERVER.PY版)的改进版
usage
First, make sure you have Python 2.6 or 2.7.
$ python --version
Python 2.6.8
Then edit config.json as follows
:
{
"server":"your_vps_ip",
"server_port":8086,
"local_port":1030,
"password":"你自设的密码",
"timeout":600
}
(注意:在该版本中,不要在上面的配置文件里加上"method":"aes-256-cfb",否则翻墙速度会变慢)
Put all the files on your server. Run python server.py
on your server. To run it in the background, run nohup python server.py > log &
.
Put all the files on your client machine. Run python local.py
on your client machine.
Change proxy settings of your browser into
SOCKS5 127.0.0.1:local_port
advanced
You can use args to override settings from config.json
.
python local.py -s server_name -p server_port -l local_port -k password
python server.py -p server_port -k password
You may want to install gevent for better performance:
$ apt-get install python-gevent
Or:
$ sudo easy_install gevent
troubleshooting
- I can only load some websites
Check the logs of local.py. If you see only IPs, not hostnames, your may got DNS poisoned, but your browser hasn't been configured to let the proxy resolve DNS.
To set proper DNS config, you can simply install FoxyProxy / Autoproxy for Firefox, or ProxySwitchy / SwitchySharp for Chrome. They will set the config in your browser automatically.
Or you can change network.proxy.socks_remote_dns into true in about:config page if you use Firefox.
- I can't load any websites and the log prints mode != 1
Make sure proxy protocol is set to Socks5, not Socks4 or HTTP.
- I use IE and I can't get my proxy to work
Since you can't specify Socks4 or Socks5 in IE settings,
- you may want to use a PAC(Proxy auto-config) script, or just use Firefox instead.
-
from https://github.com/YvesChan/shadowsocks
shadowsocks 原理是借助国外的 VPS 翻墙。国外的 VPS 上运行服务端,在本地运行本地端,就可以建立加密连接。
用文本编辑器编辑 config.json,请注意一定要修改密码。
server 你的 VPS 的地址
server_port 使用的服务端口
local_port 本地 socks5 端口
password 请设置一个你的密码
用winscp 上传 server.py 和 config.json 到 VPS 上的某个目录。如果是 root 用户,放到 /root/ 下;如果是其他用户,放到 /home/用户名 目录下。
用putty 登录到 VPS。
安装 python:
Debian, Ubuntu:
sudo apt-get install python
CentOS:
yum install python
(其实大部分LINUX VPS已默认安装了PYTHON)
cd 进入到上传的目录,运行(注意后面的 &):
nohup python server.py > /dev/null &
退出 putty。接下来只要 VPS 没有重启,服务端会一直运行下去。
在本地的windows机器运行 local.exe
修改浏览器的代理设置。使用 SOCKS5 代理,地址为
127.0.0.1:刚才设置的本地socks5端口。
最简单的方法是:建一个 Chrome 的快捷方式,右键,属性,在目标的最后加上:
--proxy-server=socks5://127.0.0.1:所设置的本地端口。
推荐 Firefox 配合 Autoproxy 使用,Chrome 配合 SwitchySharp 使用,
可以根据网址自动选择是否翻墙。注意使用的时候,代理协议要选择 SOCKS5
(而不是 SOCKS4 或者 HTTP)。 IE浏览器使用 SOCKS5代理,需要配合 PAC 文件,
不推荐使用。
如果哪天你翻墙失败, 那么可能是
nohup python server.py > /dev/null &所对应的python进程退出了。你可运行命令:
lsof -i:所使用的服务端口号 或
netstat -anp|grep 所使用的服务端口号
查看一下有无进程在使用该端口。如果没有进程在使用该端口,说明
nohup python server.py > /dev/null &所对应的python进程退出了,需要在VPS中,
重新运行一次该命令:nohup python server.py > /dev/null &
如果你想创建账号给某人使用,可这样做:
登录VPS, nano config.json
在这一步修改server_port和password的值.
下载地址:
https://cloud.github.com/downloads/clowwindy/shadowsocks-win32pack/shadowsocks.7z
以上内容适用于WINDOWS桌面系统。
-------------------------
https://github.com/mengskysama/shadowsocks-rm/tree/master/shadowsocks
--------------------------
因为BALAN-PROXY没有加密,有时翻墙速度较慢。它不如sockstunnel的翻墙速度快。
sockstunnel: http://briteming.blogspot.com/2012/07/sockstunnel.html
-----------------------------
https://github.com/li-plus/secure-socks,这个翻墙项目也是没有加密的。