1
0
Fork
You've already forked mproxy
0
A server-mediated peer-to-peer proxy
  • Python 100%
2026年02月01日 21:07:20 -05:00
common add .gitignore 2026年01月30日 08:41:42 -05:00
peer_main project structure change 2026年02月01日 20:59:01 -05:00
server_main project structure change 2026年02月01日 20:59:01 -05:00
tests cleanup 2026年02月01日 21:00:04 -05:00
LICENSE Initial commit 2026年01月30日 14:05:45 +01:00
README.md fix README.md 2026年02月01日 21:07:20 -05:00

mproxy - Server-Mediated Peer-to-Peer Proxy

A Python-based proxy system that enables peer-to-peer connections mediated through a central server. mproxy allows distributed clients to establish tunneled connections to remote services while maintaining centralized control and monitoring.

Table of Contents


Architecture Overview

High-Level Design

mproxy implements a three-tier architecture:

  1. Peer Clients (peer_main/) - Distributed proxy clients that register with the server and provide tunneling services
  2. Central Server (server_main/) - Orchestrates connections between peers and SOCKS5 clients
  3. Common Library (common/) - Shared utilities including protocol handling and logging

Network Flow

┌─────────────────┐
│ SOCKS5 Client │
└────────┬────────┘
 │ SOCKS5 Request
 ▼
┌──────────────────────┐
│ Central Server │
│ - SOCKS5 Listener │
│ - Peer Listener │
│ - Peer Finder │
│ - Protocol Handler │
└─────────┬──────────┬─┘
 │ │
 Peer Lookup Relay Data
 │ │
 ┌─────▼──┐ ┌────▼──────┐
 │ Peer A │ │ Peer B │
 │ Client │ │ Client │
 └────────┘ └────────────┘

Key Features

  • Varint Encoding: Efficient variable-length integer encoding for protocol messages
  • Thread-Safe Operations: Uses locks for concurrent socket operations
  • Async Database: Queue-based asynchronous SQLite operations
  • Device Authentication: Bcrypt-based password hashing for peer authentication
  • Session Management: Stateful session tracking with event synchronization
  • SOCKS5 Protocol: Full SOCKS5 proxy protocol implementation
  • Extensible Logging: Color-coded, level-based logging system

System Components

Server Components (server_main/)

main.py - Server Entry Point

  • Initializes database and creates schema
  • Starts peer listener on configured port
  • Starts SOCKS5 listener for client connections
  • Handles graceful shutdown

listener.py - Peer Connection Listener

  • Accepts incoming peer connections
  • Manages connection lifecycle
  • Maintains list of active peer connections
  • Provides connection ID management

peerfinder.py - Device Discovery

  • Locates connected peers by device ID
  • Searches through active connections
  • Returns connection objects for relay operations

socks5.py - SOCKS5 Protocol Handler

  • Implements SOCKS5 authentication and negotiation
  • Handles client connection requests
  • Manages tunnel setup between SOCKS5 clients and peer proxies
  • Uses username/password authentication with device ID as username

protocol.py - Custom Peer Protocol Handler

  • Defines packet structure and handlers
  • Routes incoming packets to appropriate handlers (0x00-0x04, 0xFF)
  • Manages session lifecycle
  • Handles proxy data relay

connection.py - Peer Connection Management

  • Represents active peer connection
  • Manages socket communication with peer
  • Handles packet reception and parsing

session.py - Session State

  • Represents individual tunneled session
  • Tracks upstream/downstream bytes
  • Manages connection state with Event synchronization

sql.py - Database Operations

  • Queue-based async database executor
  • Device registration and verification
  • Password hash storage and retrieval
  • Thread-safe database access

config.py - Server Configuration

LOG_LVL = 4 # Debug logging level
PEER_LHOST = "0.0.0.0" # Peer listener bind address
PEER_LPORT = 38877 # Peer listener port
SOCKS_LHOST = "0.0.0.0" # SOCKS5 listener bind address
SOCKS_LPORT = 38878 # SOCKS5 listener port
DB_PATH = "mproxy.db" # SQLite database file
SRV_NAME = "mproxy" # Server identifier
SRV_VER = "1" # Server version
PROTO_VER = 1 # Protocol version

Peer Components (peer_main/)

main.py - Peer Entry Point

  • Parses command-line arguments
  • Loads saved server settings and credentials
  • Initializes device ID and password
  • Launches GUI or CLI mode

connection.py - Server Connection Manager

  • Maintains connection to central server
  • Implements reconnection logic with exponential backoff
  • Manages outgoing packet queue
  • Handles protocol initialization

protocol.py - Peer Protocol Implementation

  • Receives and parses packets from server
  • Routes packets to appropriate handlers
  • Manages session lifecycle on peer side
  • Handles proxy data relay to local services

session.py - Local Session Management

  • Manages connections to local remote services
  • Implements socket communication with target services
  • Tracks bytes transferred
  • Handles session lifecycle

config.py - Peer Configuration

LOG_LVL = 4 # Debug logging level
SRV_ADDR = "127.0.0.1" # Central server address
SRV_PORT = 38877 # Central server peer port
VER = "1.0.0" # Client version
PROTO_VER = 1 # Protocol version

Common Library (common/)

varint.py - Variable-Length Integer Encoding

Implements efficient LEB128 (Little Endian Base 128) encoding:

  • encode(number: int) -> bytes - Encodes integer to varint
  • decode_bytes(buf: bytes) -> int - Decodes varint from bytes
  • decode_stream(stream: socket | BytesIO) -> int - Decodes from stream
  • Minimal overhead for small values, efficient for large values

logger.py - Logging System

Color-coded console logging with levels:

  • LEVEL_CRITICAL (0) - Red, critical errors
  • LEVEL_ERROR (1) - Red, recoverable errors
  • LEVEL_WARNING (2) - Yellow, warnings
  • LEVEL_INFO (3) - Blue, informational messages
  • LEVEL_DEBUG (4) - Green, debug information

Protocol Specification

Packet Structure

All packets use a length-prefixed format:

[Varint Length] [Packet ID] [Payload]
  • Length: Varint-encoded packet body length (excludes length field itself)
  • Packet ID: Single byte identifying packet type
  • Payload: Variable-length packet-specific data

Packet Types

0x00 - Initialize Connection (Bidirectional)

Client to Server (C2S):

[Device ID: 16 bytes]
[Password Hash Length: Varint]
[Password Hash: N bytes (bcrypt)]

Server to Client (S2C):

[Protocol Version: Varint]
[Server Name Length: Varint]
[Server Name: UTF-8 string]
[Server Version Length: Varint]
[Server Version: UTF-8 string]
[Connection ID: Varint]
[Boolean Data: 1 byte]
 - Bit 0: Is new registration

0x02 - Open Session Request (Bidirectional)

Server to Client (S2C - Open Request):

[Session ID: Varint]
[Address Type: 1 byte]
 - 0x00: IPv4 (4 bytes)
 - 0x01: Domain (Varint length + UTF-8 string)
 - 0x02: IPv6 (16 bytes)
[Address: Variable]
[Port: 2 bytes, big-endian]

Client to Server (C2S - Open Response):

[Session ID: Varint]
[Connection Status: 1 byte]
 - 0x00: Success
 - 0x01: General failure
 - 0x04: Address resolution failed
 - 0x05: Connection refused
 - 0x06: Connection timeout

0x03 - Proxy Data (Bidirectional)

[Session ID: Varint]
[Data Length: Varint]
[Data: N bytes]

Relays arbitrary data between client and remote service.

0x04 - Close Session (Bidirectional)

[Session ID: Varint]

Terminates tunnel session and closes connection.

0xFF - Error Message (Server to Client)

[Error Message Length: Varint]
[Error Message: UTF-8 string]

Installation

Prerequisites

  • Python 3.10+
  • pip package manager

Required Dependencies

pip install bcrypt
pip install colorama

Setup Steps

  1. Clone the repository:
git clone <repository-url>
cd mproxy
  1. Install dependencies:
pip install -r server_main/requirements.txt
pip install -r peer_main/requirements.txt
  1. Verify installation:
python3 -m unittest tests.test_mproxy -v

Configuration

Server Configuration (server_main/config.py)

Key settings:

Setting Default Purpose
LOG_LVL 4 Logging level (0=critical, 4=debug)
PEER_LHOST "0.0.0.0" Peer listener bind address
PEER_LPORT 38877 Peer listener port
SOCKS_LHOST "0.0.0.0" SOCKS5 listener bind address
SOCKS_LPORT 38878 SOCKS5 listener port
DB_PATH "mproxy.db" SQLite database file
PROTO_VER 1 Protocol version

Peer Configuration (peer_main/config.py)

Setting Default Purpose
LOG_LVL 4 Logging level
SRV_ADDR "127.0.0.1" Central server IP
SRV_PORT 38877 Central server peer port
VER "1.0.0" Peer client version
PROTO_VER 1 Protocol version

Running the Application

Starting the Server

cd server_main
python3 main.py

Expected output:

2026年02月01日 10:00:00: [main] [INFO] 🚀 Starting server...
2026年02月01日 10:00:00: [main] [INFO] 📁 Using database mproxy.db
2026年02月01日 10:00:00: [main] [INFO] 👂 Listening for peers on 0.0.0.0:38877
2026年02月01日 10:00:00: [main] [INFO] 👂 SOCKS5 server listening on 0.0.0.0:38878

Starting a Peer Client

With GUI (default):

cd peer_main
python3 main.py

CLI Mode:

cd peer_main
python3 main.py --no-gui

Custom Server:

python3 main.py --server-ip 192.168.1.100 --server-port 38877

Using the SOCKS5 Proxy

Configure your application to use SOCKS5:

  • Host: localhost or server IP
  • Port: 38878 (or configured SOCKS_LPORT)
  • Username: Device ID (hex)
  • Password: Device password

Example with curl:

curl -x socks5://user:pass@localhost:38878 http://example.com

Database Schema

SQLite Schema

devices Table

CREATETABLEIFNOTEXISTSdevices(idTEXTNOTNULL,-- Device ID (hex string, 32 chars)
passwordBLOBNOTNULL,-- Bcrypt password hash (60 bytes)
ipTEXT,-- Last known IP address
timestampDATETIMEDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(id))

Columns:

  • id: Unique device identifier (UUID v4 as hex string)
  • password: Bcrypt hash of device authentication password
  • ip: Source IP address of registration
  • timestamp: Registration or last update timestamp

Database Operations (sql.py)

db_conn = sql.DBConn(db_path)
# Create schema
db_conn.create_schema()
# Register device
db_conn.add_device(ip, device_id_bytes, password_hash_bytes)
# Check device existence
exists = db_conn.does_device_exist(device_id_bytes)
# Retrieve password
password = db_conn.get_device_password(device_id_bytes)
# Shutdown (flush async operations)
db_conn.exit_flag = True

Testing

Running Tests

# Run all tests
python3 -m unittest tests.test_mproxy -v
# Run specific test class
python3 -m unittest tests.test_mproxy.TestVarint -v
# Run specific test
python3 -m unittest tests.test_mproxy.TestVarint.test_encode_single_byte -v

Test Coverage

The test suite includes 25+ tests covering:

  • Varint Encoding/Decoding: Single-byte, multi-byte, roundtrip tests
  • Logger: Creation, levels, filtering
  • Session Management: State, bytes tracking, event synchronization
  • Database Operations: Device registration, password retrieval, async operations
  • Edge Cases: Large numbers, EOF handling, boundary conditions

Creating New Tests

Tests are located in tests/test_mproxy.py:

import unittest
class TestMyFeature(unittest.TestCase):
 def test_my_functionality(self):
 # Arrange
 expected = "value"
 # Act
 result = some_function()
 # Assert
 self.assertEqual(result, expected)

API Reference

Varint Module (common/varint.py)

from common import varint
# Encoding
encoded = varint.encode(300) # Returns: b'\xac\x02'
# Decoding
decoded = varint.decode_bytes(b'\xac\x02') # Returns: 300
# Stream decoding
from io import BytesIO
stream = BytesIO(b'\xac\x02')
decoded = varint.decode_stream(stream) # Returns: 300

Logger Module (common/logger.py)

from common.logger import Logger, LEVEL_DEBUG, LEVEL_ERROR
logger = Logger("component_name", LEVEL_DEBUG)
logger.debug("Debug message")
logger.info("Info message")
logger.warning("Warning message")
logger.error("Error message")
logger.critical("Critical message")

Session Management

Server-Side Session (server_main/session.py)

sess = session.Session(addr, port, sess_id, client_sock, dev_id, client_id)
sess.addr # Target address
sess.port # Target port
sess.sess_id # Session identifier
sess.up_bytes # Uploaded bytes (client → peer)
sess.down_bytes # Downloaded bytes (peer → client)
sess.is_open.set() # Mark session as open
sess.is_open.wait() # Wait for session to open

Peer-Side Session (peer_main/session.py)

sess = session.Session(sess_id, addr, port, proto)
sess.start() # Initiate connection
sess.destroy() # Close connection
sess.bytes_up # Bytes sent upstream
sess.bytes_down # Bytes received downstream
sess.recv_thread() # Receive data from remote

Development

Project Structure

mproxy/
├── common/
│ ├── logger.py # Logging system
│ ├── varint.py # Variable-length integer encoding
│ └── __pycache__/
├── server_main/
│ ├── config.py # Server configuration
│ ├── connection.py # Peer connection handling
│ ├── listener.py # Peer listener
│ ├── main.py # Server entry point
│ ├── peerfinder.py # Device discovery
│ ├── protocol.py # Custom protocol
│ ├── session.py # Session state
│ ├── socks5.py # SOCKS5 implementation
│ ├── sql.py # Database operations
│ └── requirements.txt
├── peer_main/
│ ├── config.py # Peer configuration
│ ├── connection.py # Server connection
│ ├── gui.py # GUI interface
│ ├── main.py # Peer entry point
│ ├── protocol.py # Peer protocol
│ ├── save.py # Settings persistence
│ ├── session.py # Remote session
│ └── requirements.txt
├── tests/
│ └── test_mproxy.py # Unit tests
├── LICENSE
└── README.md

License

See LICENSE file for details.