- Python 100%
| common | add .gitignore | |
| peer_main | project structure change | |
| server_main | project structure change | |
| tests | cleanup | |
| LICENSE | Initial commit | |
| README.md | fix README.md | |
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
- System Components
- Protocol Specification
- Installation
- Configuration
- Running the Application
- Database Schema
- Testing
- API Reference
- Development
Architecture Overview
High-Level Design
mproxy implements a three-tier architecture:
- Peer Clients (
peer_main/) - Distributed proxy clients that register with the server and provide tunneling services - Central Server (
server_main/) - Orchestrates connections between peers and SOCKS5 clients - 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 varintdecode_bytes(buf: bytes) -> int- Decodes varint from bytesdecode_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 errorsLEVEL_ERROR(1) - Red, recoverable errorsLEVEL_WARNING(2) - Yellow, warningsLEVEL_INFO(3) - Blue, informational messagesLEVEL_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
- Clone the repository:
git clone <repository-url>
cd mproxy
- Install dependencies:
pip install -r server_main/requirements.txt
pip install -r peer_main/requirements.txt
- 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 passwordip: Source IP address of registrationtimestamp: 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.