跳转到主要内容

可以通过正则表达式规则在远程服务器之间建立隧道的服务器。

项目描述

made-with-python PyPI-version Hit-Count Downloads Downloads-month Downloads-week

使用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://

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隧道

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

      回显服务

      直接

      直接连接

  • http://”接受作为服务器GET/POST/CONNECT,作为客户端发送CONNECT。“httponly://”作为客户端发送“GET/POST”,仅在http流量上工作。

  • 有效方案:http://、http+socks4+socks5://、http+ssl://、ss+secure://、http+socks5+ss://

  • 无效方案:ssl://、secure://

  • 加密

    • 加密格式:“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 (50.4 kB 查看哈希值)

上传时间

构建分布

pproxy_ext-2.7.9-py3-none-any.whl (42.9 kB 查看哈希值)

上传时间 Python 3

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面