可以通过正则表达式规则在远程服务器之间建立隧道的服务器。
项目描述
使用Python3 asyncio实现的Python3异步隧道代理,支持HTTP/HTTP2/HTTP3/Socks4/Socks5/Shadowsocks/SSH/Redirect/Pf/QUIC TCP/UDP。
快速开始
$ pip3 install pproxy
Successfully installed pproxy-1.9.5
$ pproxy
Serving on :8080 by http,socks4,socks5
^C
$ pproxy -l ss://chacha20:abc@:8080
Serving on :8080 by ss (chacha20-py)
可选:(使用C加密可以提高性能)
$ pip3 install pproxy[accelerated]
Successfully installed pycryptodome-3.6.4
全局系统代理设置:(MacOS, Windows)
$ pproxy -r ss://chacha20:abc@server_ip:8080 --sys -vv
Serving on :8080 by http,socks4,socks5
System proxy setting -> socks5 localhost:8080
socks5 ::1:57345 -> ss server_ip:8080 -> slack.com:443
socks5 ::1:57345 -> ss server_ip:8080 -> www.google.com:443
..... (all local traffic log) ......
CLI代理设置:(MacOS, Linux)
$ export http_proxy=http://localhost:8080
$ export https_proxy=http://localhost:8080
使用Docker运行
pproxy Docker容器提供python3(包含Cryptodome以优化性能)和pypy版本。
Python3
docker run -it -p 8080:8080 mosajjal/pproxy:latest -l http://:8080 -vv
Pypy3
docker run -it -p 8080:8080 mosajjal/pproxy:latest-pypy -l http://:8080 -vv
功能
轻量级单线程异步IO。
纯Python编写,无需额外库。
TCP/UDP的代理客户端/服务器。
在远程服务器之间进行负载均衡。
自动检测入站流量。
支持隧道/跳转/反向跳转。
支持Unix域套接字。
HTTP v2, HTTP v3 (QUIC)
支持用户名/密码认证。
支持正则表达式模式过滤/屏蔽主机名。
支持SSL/TLS客户端/服务器。
支持Shadowsocks OTA (一次性认证),SSR插件。
按带宽和流量进行统计。
支持JavaScript配置的PAC。
Iptables/Pf NAT重定向数据包隧道。
支持系统代理自动设置。
提供客户端/服务器API。
协议
名称 |
TCP服务器 |
TCP客户端 |
UDP服务器 |
UDP客户端 |
方案 |
---|---|---|---|---|---|
http (连接) |
✔ |
✔ |
|||
http (get,post等) |
✔ |
httponly:// (作为客户端) |
|||
http v2 (连接) |
✔ |
✔ |
h2:// |
||
http v3 (连接) |
✔ 通过UDP |
✔ 通过UDP |
h3:// |
||
https |
✔ |
✔ |
http+ssl:// |
||
socks4 |
✔ |
✔ |
socks4:// |
||
socks5 |
✔ |
✔ |
✔ udp-only |
✔ udp-only |
socks5:// |
socks5 over TLS |
✔ |
✔ |
socks5+ssl:// |
||
shadowsocks |
✔ |
✔ |
✔ |
✔ |
ss:// |
shadowsocks aead |
✔ |
✔ |
ss:// |
||
shadowsocksR |
✔ |
✔ |
ssr:// |
||
trojan |
✔ |
✔ |
trojan:// |
||
ssh隧道 |
✔ |
||||
quic |
✔ 通过UDP |
✔ 通过UDP |
✔ |
✔ |
http+quic:// |
iptables nat |
✔ |
redir:// |
|||
pfctl nat (macos) |
✔ |
pf:// |
|||
echo |
✔ |
✔ |
echo:// |
||
tunnel (原始套接字) |
✔ |
✔ |
✔ |
✔ |
tunnel:// tunnel{ip}:// |
websocket (简单隧道) |
✔ |
✔ |
ws:// ws{dst_ip}:// |
||
xxx over TLS |
✔ |
✔ |
xxx+ssl:// |
||
AUTO DETECT |
✔ |
✔ |
a+b+c+d:// |
调度算法
名称 |
TCP |
UDP |
参数 |
默认 |
---|---|---|---|---|
first_available |
✔ |
✔ |
-s fa |
✔ |
round_robin |
✔ |
✔ |
-s rr |
|
random_choice |
✔ |
✔ |
-s rc |
|
least_connection |
✔ |
-s lc |
需求
pycryptodome是一个可选库,用于启用更快的(C版本)加密。 pproxy包含许多内置的纯Python加密。它们轻量级且稳定,但比C加密慢。通过PyPy加速后,纯Python加密可以获得与C版本相似的性能。如果性能很重要且没有PyPy,则安装pycryptodome。
asyncssh是一个可选库,用于启用SSH隧道客户端支持。
以下是在Python和C加密之间的一些性能基准测试(数据集:8M)
chacha20-c |
0.64秒 |
chacha20-py (pypy3) |
1.32秒 |
chacha20-py |
48.86秒 |
Pypy3 快速开始
$ pypy3 -m ensurepip
$ pypy3 -m pip install asyncio pproxy
用法
$ pproxy -h
usage: pproxy [-h] [-l LISTEN] [-r RSERVER] [-ul ULISTEN] [-ur URSERVER]
[-b BLOCK] [-a ALIVED] [-v] [--ssl SSLFILE] [--pac PAC]
[--get GETS] [--sys] [--test TESTURL] [--version]
Proxy server that can tunnel among remote servers by regex rules. Supported
protocols: http,socks4,socks5,shadowsocks,shadowsocksr,redirect,pf,tunnel
optional arguments:
-h, --help show this help message and exit
-l LISTEN tcp server uri (default: http+socks4+socks5://:8080/)
-r RSERVER tcp remote server uri (default: direct)
-ul ULISTEN udp server setting uri (default: none)
-ur URSERVER udp remote server uri (default: direct)
-b BLOCK block regex rules
-a ALIVED interval to check remote alive (default: no check)
-s {fa,rr,rc,lc} scheduling algorithm (default: first_available)
-v print verbose output
--ssl SSLFILE certfile[,keyfile] if server listen in ssl mode
--pac PAC http PAC path
--get GETS http custom {path,file}
--sys change system proxy setting (mac, windows)
--test TEST test this url for all remote proxies and exit
--version show program's version number and exit
Online help: <https://github.com/qwj/python-proxy>
URI语法
{scheme}://[{cipher}@]{netloc}/[@{localbind}][,{plugins}][?{rules}][#{auth}]
方案
目前支持的方案:http, socks, ss, ssl, secure。您可以使用+将多个协议链接在一起。
http
http协议(CONNECT)
httponly
HTTP协议(GET/POST)
socks4
socks4协议
socks5
socks5协议
ss
shadowsocks协议
ssr
shadowsocksr(SSR)协议
trojan
trojan协议
ssh
ssh客户端隧道
redir
重定向(iptables nat)
pf
pfctl(macos pf nat)
ssl
未加密ssl/tls(无证书)
安全
安全ssl/tls(证书)
隧道
原始连接
ws
websocket连接
echo
回显服务
直接
直接连接
加密
加密格式:“cipher_name:cipher_key”。加密可以是base64编码的。因此,具有“YWVzLTEyOC1nY206dGVzdA==”的加密字符串等于“aes-128-gcm:test”。
完整加密支持列表
加密
密钥长度
IV长度
评分(0-5)
table-py
任意
0
0(最低)
rc4
16
0
0(最低)
rc4-md5
16
16
0.5
chacha20
32
8
5(最高)
chacha20-ietf
32
12
5
chacha20-ietf- poly1305-py
32
32
AEAD
salsa20
32
8
4.5
aes-128-cfb
aes-128-cfb8
aes-128-cfb1-py
16
16
3
慢
aes-192-cfb
aes-192-cfb8
aes-192-cfb1-py
24
16
3.5
慢
aes-256-cfb
aes-256-ctr
aes-256-ofb
aes-256-cfb8
aes-256-cfb1-py
32
16
4.5
慢
aes-256-gcm
aes-192-gcm
aes-128-gcm
32
24
16
32
24
16
AEAD
AEAD
AEAD
camellia-256-cfb
camellia-192-cfb
camellia-128-cfb
32
24
16
16
16
16
4
4
4
bf-cfb
16
8
1
cast5-cfb
16
8
2.5
des-cfb
8
8
1.5
rc2-cfb-py
16
8
2
idea-cfb-py
16
8
2.5
seed-cfb-py
16
16
2
pproxy加密具有纯Python实现。如果pycryptodome中有C实现,程序将切换到C加密。否则,使用纯Python加密。
AEAD加密在每包之后使用额外的有效载荷。底层协议不同。规范:AEAD。
一些纯Python加密(aes-256-cfb1-py)相当慢,不建议在不使用PyPy加速的情况下使用。尝试安装pycryptodome并使用C版本加密。
要启用shadowsocks的OTA加密,在加密名称后立即添加“!”。
netloc
可以是“hostname:port”或“/unix_domain_socket”。如果主机名为空,服务器将监听所有接口。
有效的netloc:localhost:8080、0.0.0.0:8123、/tmp/domain_socket、:8123
localbind
可以是“@in”或@ipv4_address或@ipv6_address
有效的localbind:@in、@192.168.1.15、@::1
plugins
可以是多个通过“,”连接的插件。支持的插件:plain、origin、http_simple、tls1.2_ticket_auth、verify_simple、verify_deflate
有效的插件:/、tls1.2_ticket_auth、verify_simple
rules
包含正则表达式规则的文件名
auth
用户名,冒号“:”,和密码
URI可以通过“__”连接,以表示通过跳转进行隧道。例如,ss://1.2.3.4:1324__http://4.5.6.7:4321将对第一个shadowsocks代理服务器进行远程连接,然后跳转到第二个http代理服务器。
客户端API
TCP客户端API
import asyncio, pproxy async def test_tcp(proxy_uri): conn = pproxy.Connection(proxy_uri) reader, writer = await conn.tcp_connect('google.com', 80) writer.write(b'GET / HTTP/1.1\r\n\r\n') data = await reader.read(1024*16) print(data.decode()) asyncio.run(test_tcp('ss://aes-256-cfb:password@remote_host:remote_port'))
UDP客户端API
import asyncio, pproxy async def test_udp(proxy_uri): conn = pproxy.Connection(proxy_uri) answer = asyncio.Future() await conn.udp_sendto('8.8.8.8', 53, b'hello the world', answer.set_result) await answer print(answer.result()) asyncio.run(test_udp('ss://chacha20:password@remote_host:remote_port'))
服务器API
服务器API示例
import asyncio import pproxy server = pproxy.Server('ss://0.0.0.0:1234') remote = pproxy.Connection('ss://1.2.3.4:5678') args = dict( rserver = [remote], verbose = print ) loop = asyncio.get_event_loop() handler = loop.run_until_complete(server.start_server(args)) try: loop.run_forever() except KeyboardInterrupt: print('exit!') handler.close() loop.run_until_complete(handler.wait_closed()) loop.run_until_complete(loop.shutdown_asyncgens()) loop.close()
示例
正则表达式规则
将正则表达式文件“rules”定义为以下内容
#google domains (?:.+\.)?google.*\.com (?:.+\.)?gstatic\.com (?:.+\.)?gmail\.com (?:.+\.)?ntp\.org (?:.+\.)?glpals\.com (?:.+\.)?akamai.*\.net (?:.+\.)?ggpht\.com (?:.+\.)?android\.com (?:.+\.)?gvt1\.com (?:.+\.)?youtube.*\.com (?:.+\.)?ytimg\.com (?:.+\.)?goo\.gl (?:.+\.)?youtu\.be (?:.+\.)?google\..+
然后启动pproxy
$ pproxy -r http://aa.bb.cc.dd:8080?rules -vv Serving on :8080 by http,socks4,socks5 http ::1:57768 -> http aa.bb.cc.dd:8080 -> www.googleapis.com:443 http ::1:57772 -> www.yahoo.com:80 socks4 ::1:57770 -> http aa.bb.cc.dd:8080 -> www.youtube.com:443
pproxy将通过http/socks4/socks5自动检测协议提供入站流量服务,将所有谷歌流量重定向到http代理aa.bb.cc.dd:8080,并直接从本地访问所有其他流量。
使用加密
添加加密以确保数据不会被拦截。在本地运行pproxy
$ pproxy -l ss://:8888 -r ss://chacha20:cipher_key@aa.bb.cc.dd:12345 -vv
接下来,在服务器“aa.bb.cc.dd”上远程运行pproxy.py。也支持“chacha20:cipher_key”的base64编码字符串
$ pproxy -l ss://chacha20:cipher_key@:12345
相同于
$ pproxy -l ss://Y2hhY2hhMjA6Y2lwaGVyX2tleQ==@:12345
本地和aa.bb.cc.dd之间的流量通过流加密Chacha20和密钥“cipher_key”加密。
Unix域套接字
一个更复杂的示例
$ pproxy -l ss://salsa20!:complex_cipher_key@/tmp/pproxy_socket -r http+ssl://domain1.com:443#username:password
pproxy 在Unix域套接字“/tmp/pproxy_socket”上监听,使用加密算法“salsa20”和密钥“complex_cipher_key”。通过在加密算法名称后添加“!”来启用OTA数据包协议。流量通过简单HTTP身份验证被隧道传输到远程https代理。
SSL/TLS服务器
如果您想使用SSL/TLS监听,必须通过参数“–ssl”指定SSL证书和私钥文件。
$ pproxy -l http+ssl://0.0.0.0:443 -l http://0.0.0.0:80 --ssl server.crt,server.key --pac /autopac
pproxy 监听80 HTTP和443 HTTPS端口,使用指定的SSL/TLS证书和私钥文件。“–pac”启用PAC功能,因此可以将“https://yourdomain.com/autopac”路径放在您的设备自动配置的URL中。
生成自签名ssl证书的简单指南
$ openssl genrsa -des3 -out server.key 1024 $ openssl req -new -key server.key -out server.csr $ cp server.key server.key.org $ openssl rsa -in server.key.org -out server.key $ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
SSR插件
使用插件“tls1.2_ticket_auth”的ShadowsocksR示例,以模拟常见的TLS流量
$ pproxy -l ssr://chacha20:mypass@0.0.0.0:443/,tls1.2_ticket_auth,verify_simple
本地绑定IP
如果您想通过不同的本地绑定路由流量,请使用@localbind URI语法。例如,服务器有三个IP接口:192.168.1.15,111.0.0.1,112.0.0.1。您想将匹配“rule1”的流量路由到111.0.0.2,将匹配“rule2”的流量路由到222.0.0.2,其余流量直接传输
$ pproxy -l ss://:8000/@in -r ss://111.0.0.2:8000/@111.0.0.1?rule1 -r ss://222.0.0.2:8000/@222.0.0.1?rule2
重定向/Pf协议
IPTable NAT重定向示例(Ubuntu)
$ sudo iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 5555 $ pproxy -l redir://:5555 -r http://remote_http_server:3128 -vv
上述示例说明了如何将所有目标端口为80的本地输出TCP流量重定向到由pproxy监听的本地主机端口5555,然后隧道传输到远程http代理。
Pf重定向示例(MacOS)
$ sudo pfctl -ef /dev/stdin rdr pass on lo0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080 pass out on en0 route-to lo0 inet proto tcp from any to any port 80 keep state ^D $ sudo pproxy -l pf://:8080 -r socks5://remote_socks5_server:1324 -vv
请确保pproxy以root模式(sudo)运行,否则它无法重定向pf数据包。
多次跳转示例
$ pproxy -r http://server1__ss://server2__socks://server3
pproxy首先连接到server1,告诉server1连接到server2,然后告诉server2连接到server3,并由server3进行实际流量。
原始连接隧道
TCP原始连接隧道示例
$ pproxy -l tunnel{google.com}://:80 $ curl -H "Host: google.com" http://localhost
UDP DNS隧道示例
$ pproxy -ul tunnel{8.8.8.8}://:53 $ nslookup google.com localhost
UDP更复杂的示例
在远程机器上运行shadowsocks udp代理
$ pproxy -ul ss://remote_server:13245
在本地机器上运行命令
$ pproxy -ul tunnel{8.8.8.8}://:53 -ur ss://remote_server:13245 -vv UDP tunnel 127.0.0.1:60573 -> ss remote_server:13245 -> 8.8.8.8:53 UDP tunnel 127.0.0.1:60574 -> ss remote_server:13245 -> 8.8.8.8:53 ... $ nslookup google.com localhost
负载均衡示例
指定多个-r服务器,并指定一个调度算法(rr = 轮询,rc = 随机选择,lc = 最少连接)
$ pproxy -r http://server1 -r ss://server2 -r socks5://server3 -s rr -vv http ::1:42356 -> http server1 -> google.com:443 http ::1:42357 -> ss server2 -> google.com:443 http ::1:42358 -> socks5 server3 -> google.com:443 http ::1:42359 -> http server1 -> google.com:443 ... $ pproxy -ul tunnel://:53 -ur tunnel://8.8.8.8:53 -ur tunnel://8.8.4.4:53 -s rc -vv UDP tunnel ::1:35378 -> tunnel 8.8.8.8:53 UDP tunnel ::1:35378 -> tunnel 8.8.4.4:53 ...
WebSocket示例
WebSocket协议类似于隧道协议。它是原始的,不支持任何代理功能。它可以连接到其他类似于隧道协议的代理。
首先在远程机器上运行pproxy
$ pproxy -l ws://:80 -r tunnel:///tmp/myproxy -v $ pproxy -l ss://chacha20:abc@/tmp/myproxy -v
在本地机器上运行pproxy
$ pproxy -l tunnel://:1234 -r ws://remote_ip:80 -vv
然后本地机器的端口:1234通过WebSocket隧道连接到远程机器上的/tmp/myproxy。您可以在/tmp/myproxy上指定任何代理协议细节。
在本地/远程机器之间使用一些CDN是一个好习惯。支持WebSocket的CDN可以隐藏远程机器的真实IP。
反向代理
有时,代理服务器隐藏在NAT路由器后面,没有公网IP。客户端具有公网IP“client_ip”。反向代理功能使服务器能够连接回客户端并等待代理请求。
如下运行pproxy客户端
$ pproxy -l http://:8080 -r http+in://:8081 -v
如下运行pproxy服务器
$ pproxy -l http+in://client_ip:8081
服务器连接到client_ip:8081并等待客户端代理请求。指定的http协议只是一个示例。它可以是任何pproxy支持的协议和加密。URI中的方案“in”应存在,以通知pproxy它是一个反向代理。
$ pproxy -l http+in://jumpserver__http://client_ip:8081
这是一个复杂的示例。服务器通过跳转http://jumpserver连接到client_ip:8081。反向代理通过跳转工作。
SSH客户端隧道
通过安装额外的库asyncssh启用SSH客户端隧道支持。在“pip3 install asyncssh”之后,您可以指定“ssh”作为通过SSH客户端隧道代理的方案。
$ pproxy -l http://:8080 -r ssh://remote_server.com/#login:password
如果使用客户端私钥进行身份验证,请在登录和私钥路径之间放置双冒号“::”。
$ pproxy -l http://:8080 -r ssh://remote_server.com/#login::private_key_path
默认禁用SSH连接known_hosts功能。
SSH跳转
通过使用“__”连接支持SSH跳转。
$ pproxy -r ssh://server1__ssh://server2__ssh://server3
与服务器1建立首次连接。其次,从服务器1到服务器2建立SSH连接。最后,连接到服务器3,并使用服务器3进行流量代理。
SSH远程转发
$ pproxy -l ssh://server__tunnel://0.0.0.0:1234 -r tunnel://127.0.0.1:1234
远程服务器上的TCP:1234被转发到本地服务器的127.0.0.1:1234
$ pproxy -l ssh://server1__ssh://server2__ss://0.0.0.0:1234 -r ss://server3:1234
这是一个复杂示例。从SSH服务器1跳转到SSH服务器2,服务器2上监听ss://0.0.0.0:1234。流量被转发到ss://server3:1234。
特洛伊木马协议示例
通常应与ssl://一起使用trojan://。您应指定ssl使用的SSL crt/key文件。一个典型的特洛伊木马服务器可以是
$ pproxy --ssl ssl.crt,ssl.key -l trojan+tunnel{localhost:80}+ssl://:443#yourpassword -vv
如果特洛伊木马密码不匹配,tunnel{localhost:80}将被切换。它看起来与一个普通的HTTPS网站完全一样。
QUIC协议示例
QUIC是HTTP/3中使用的UDP流协议。如果您想通过QUIC代理,则需要库aioquic。QUIC在UDP端口上监听,但可以处理TCP或UDP流量。如果您想处理TCP流量,应使用“-l quic+http”而不是“-ul quic+http”。
$ pip3 install aioquic $ pproxy --ssl ssl.crt,ssl.key -l quic+http://:1234
在客户端
$ pproxy -r quic+http://server:1234
QUIC协议可以在单个UDP流上传输大量的TCP流。如果连接数很大,QUIC可以通过减少TCP握手时间来受益。
VPN服务器示例
您可以通过安装ppvpn(Python VPN),一个具有pproxy隧道功能的轻量级VPN服务器,来简单地运行VPN服务器。
$ pip3 install pvpn Successfully installed pvpn-0.2.1 $ pvpn -wg 9999 -r http://remote_server:remote_port Serving on UDP :500 :4500... Serving on UDP :9000 (WIREGUARD)... TCP xx.xx.xx.xx:xx -> HTTP xx.xx.xx.xx:xx -> xx.xx.xx.xx:xx
项目
python-vpn - 纯Python编写的VPN服务器(IPSec、IKE、IKEv2、L2TP、WireGuard)
shadowproxy - guyingbo的出色的Python代理实现
项目详情
下载文件
下载您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分布
构建分布
pproxy-ext-2.7.9.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 67316762d4d034f362da3cbddea3e587cd470a0fc68c241d354077c89e9e1fea |
|
MD5 | 5850d66de513f436d76c9424d9a0b1d1 |
|
BLAKE2b-256 | 262e0e6cd63988776f48dfb640849dc0b58d184b90bd08ff65c2b5f5c48b079a |
pproxy_ext-2.7.9-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 841c47fe19b9976b67c50c1614480442a53ac0545f000702777b9a31e5bba710 |
|
MD5 | 4e0fca77ee86f3a168b5f8f6ee914aa5 |
|
BLAKE2b-256 | bb6e760e2e7affc41d7417d63189ed5de206f638e6b0eb1b5d7140c5320b82e9 |