Python bindings for LinkSocks - SOCKS proxy over WebSocket
Project description
LinkSocks Python Bindings
Python bindings for LinkSocks - a SOCKS5 over WebSocket proxy tool.
Overview
LinkSocks is a SOCKS proxy implementation over WebSocket protocol that allows you to securely expose SOCKS proxy services under Web Application Firewall (WAF) protection. This package provides Python bindings for the Go implementation.
Key Features
- 🔄 Forward & Reverse Proxy: Support both forward and reverse SOCKS5 proxy modes
- 🌐 WebSocket Transport: Works under WAF protection using standard WebSocket connections
- ⚖️ Load Balancing: Round-robin load balancing for reverse proxy with multiple clients
- 🔐 Authentication: SOCKS5 proxy authentication and secure token-based WebSocket authentication
- 🌍 Protocol Support: Full IPv6 over SOCKS5 and UDP over SOCKS5 support
- 🐍 Pythonic API: Both synchronous and asynchronous APIs with context manager support
Installation
Using pip (Recommended)
pip install linksocks
Development Installation
git clone https://github.com/linksocks/linksocks.git
cd linksocks/_bindings/python
pip install -e .
Requirements
- Python 3.8 or later
- Go 1.19 or later (for building from source)
Quick Start
Forward Proxy Example
import asyncio
from linksocks import Server, Client
async def main():
# Create server and client with async context managers
async with Server(ws_port=8765) as server:
# Add forward token asynchronously
token = await server.async_add_forward_token()
async with Client(token, ws_url="ws://localhost:8765", socks_port=9870, no_env_proxy=True) as client:
print("✅ Forward proxy ready!")
print("🌐 SOCKS5 proxy: 127.0.0.1:9870")
print("🔧 Test: curl --socks5 127.0.0.1:9870 http://httpbin.org/ip")
# Keep running
await asyncio.sleep(3600)
if __name__ == "__main__":
asyncio.run(main())
Reverse Proxy Example
import asyncio
from linksocks import Server, Client
async def main():
# Create server and client with async context managers
async with Server(ws_port=8765) as server:
# Add reverse token (port is auto-allocated)
result = server.add_reverse_token()
print(f"🔑 Reverse token: {result.token}")
print(f"🌐 SOCKS5 proxy will be available on: 127.0.0.1:{result.port}")
# Create client in reverse mode
async with Client(result.token, ws_url="ws://localhost:8765", reverse=True, no_env_proxy=True) as client:
print("✅ Reverse proxy ready!")
print(f"🔧 Test: curl --socks5 127.0.0.1:{result.port} http://httpbin.org/ip")
# Keep running
await asyncio.sleep(3600)
if __name__ == "__main__":
asyncio.run(main())
API Reference
Server Class
The Server class manages WebSocket connections and provides SOCKS5 proxy functionality.
from linksocks import Server
# Create server with options
server = Server(
ws_host="0.0.0.0", # WebSocket listen address
ws_port=8765, # WebSocket listen port
socks_host="127.0.0.1", # SOCKS5 listen address (reverse mode)
buffer_size=32768, # Buffer size for data transfer
api_key="your_api_key", # Enable HTTP API
channel_timeout=30.0, # WebSocket channel timeout (seconds)
connect_timeout=10.0, # Connection timeout (seconds)
fast_open=False, # Enable fast open optimization
upstream_proxy="socks5://proxy:1080", # Upstream proxy
upstream_username="user", # Upstream proxy username
upstream_password="pass" # Upstream proxy password
)
Token Management
# Add forward proxy token (synchronous)
token = server.add_forward_token("custom_token") # or auto-generate with None
# Add forward proxy token (asynchronous - recommended)
token = await server.async_add_forward_token("custom_token")
# Add reverse proxy token
result = server.add_reverse_token(
token="custom_token", # optional, auto-generated if None
port=9870, # optional, auto-allocated if None
username="socks_user", # optional, SOCKS5 auth username
password="socks_pass", # optional, SOCKS5 auth password
allow_manage_connector=True # optional, allow client connector management
)
print(f"Token: {result.token}, Port: {result.port}")
# Add connector token
connector_token = server.add_connector_token("connector_token", "reverse_token")
# Remove any token
success = server.remove_token("token_to_remove")
Running the Server
# Asynchronous (recommended) - automatically waits for ready
async with server:
print("Server is ready!") # No need for async_wait_ready()
# Server runs while in context
# Synchronous - requires manual wait
server.wait_ready() # Blocks until ready
# Server runs in background
server.close() # Clean shutdown
# Manual wait with timeout (only needed for synchronous usage)
server.wait_ready(timeout=30.0) # 30 second timeout
await server.async_wait_ready(timeout="30s") # Go duration string (rarely needed)
Client Class
The Client class connects to WebSocket servers and provides SOCKS5 functionality.
from linksocks import Client
# Create client with options
client = Client(
token="your_token", # Authentication token (required)
ws_url="ws://localhost:8765", # WebSocket server URL
reverse=False, # Enable reverse proxy mode
socks_host="127.0.0.1", # SOCKS5 listen address (forward mode)
socks_port=9870, # SOCKS5 listen port (forward mode)
socks_username="user", # SOCKS5 auth username
socks_password="pass", # SOCKS5 auth password
socks_wait_server=True, # Wait for server before starting SOCKS5
reconnect=True, # Auto-reconnect on disconnect
reconnect_delay=5.0, # Reconnect delay (seconds)
buffer_size=32768, # Buffer size for data transfer
channel_timeout=30.0, # WebSocket channel timeout
connect_timeout=10.0, # Connection timeout
threads=4, # Number of processing threads
fast_open=False, # Enable fast open optimization
upstream_proxy="socks5://proxy:1080", # Upstream proxy
upstream_username="proxy_user", # Upstream proxy username
upstream_password="proxy_pass", # Upstream proxy password
no_env_proxy=False # Ignore proxy environment variables
)
Running the Client
# Asynchronous (recommended) - automatically waits for ready
async with client:
print(f"Client ready! SOCKS5 port: {client.socks_port}")
print(f"Connected: {client.is_connected}")
# Client runs while in context
# Synchronous - requires manual wait
client.wait_ready()
print(f"Connected: {client.is_connected}")
client.close() # Clean shutdown
Connector Management (Reverse Mode)
# Add connector token (reverse mode only)
connector_token = client.add_connector("my_connector") # or auto-generate
connector_token = await client.async_add_connector(None) # async version
Logging
import logging
from linksocks import set_log_level
# Set global log level
set_log_level(logging.DEBUG)
set_log_level("INFO") # String format
# Use custom logger
logger = logging.getLogger("my_app")
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger.addHandler(handler)
server = Server(logger=logger)
client = Client("token", logger=logger)
Advanced Examples
Agent Proxy with Connector Management
import asyncio
from linksocks import Server, Client
async def agent_proxy():
# Server with connector autonomy enabled
async with Server(ws_port=8765) as server:
result = server.add_reverse_token(allow_manage_connector=True)
print(f"🔑 Provider token: {result.token}")
print(f"🌐 SOCKS5 proxy will be available on: 127.0.0.1:{result.port}")
# Provider client (provides network access)
async with Client(result.token, ws_url="ws://localhost:8765", reverse=True, no_env_proxy=True) as provider:
print("✅ Agent proxy server and provider ready!")
# Provider can manage its own connectors
connector_token = await provider.async_add_connector("my_connector")
print(f"🔑 Connector token: {connector_token}")
# Now external connectors can use this token
print(f"🔧 Start connector: linksocks connector -t {connector_token} -u ws://localhost:8765 -p 1180")
await asyncio.sleep(3600)
asyncio.run(agent_proxy())
Error Handling and Monitoring
import asyncio
import logging
from linksocks import Client
async def robust_client():
logger = logging.getLogger("robust_client")
client = Client(
"your_token",
ws_url="ws://server:8765",
reconnect=True,
reconnect_delay=5.0,
no_env_proxy=True,
logger=logger
)
try:
async with client:
logger.info("✅ Client connected successfully")
# Monitor connection status
while True:
if not client.is_connected:
logger.warning("⚠️ Connection lost, reconnecting...")
await asyncio.sleep(5)
except asyncio.TimeoutError:
logger.error("❌ Connection timeout after 30 seconds")
except Exception as e:
logger.error(f"❌ Client error: {e}")
finally:
logger.info("🔄 Client shutting down")
asyncio.run(robust_client())
HTTP API Integration
import asyncio
import aiohttp
from linksocks import Server
async def api_server_example():
# Start server with API enabled
server = Server(ws_port=8765, api_key="secret_api_key")
async with server:
print("✅ Server with API ready!")
# Use HTTP API to manage tokens
async with aiohttp.ClientSession() as session:
headers = {"X-API-Key": "secret_api_key"}
# Add forward token via API
async with session.post(
"http://localhost:8765/api/token",
headers=headers,
json={"type": "forward", "token": "api_token"}
) as resp:
result = await resp.json()
print(f"📝 Added token via API: {result}")
# Get server status
async with session.get(
"http://localhost:8765/api/status",
headers=headers
) as resp:
status = await resp.json()
print(f"📊 Server status: {status}")
await asyncio.sleep(3600)
asyncio.run(api_server_example())
Type Hints
The package includes comprehensive type hints for better IDE support:
from typing import Optional
from linksocks import Server, Client, ReverseTokenResult
def create_proxy_pair(token: str, port: Optional[int] = None) -> tuple[Server, Client]:
server = Server(ws_port=8765)
server.add_forward_token(token)
client = Client(token, ws_url="ws://localhost:8765", socks_port=port or 9870, no_env_proxy=True)
return server, client
# ReverseTokenResult is a dataclass
server = Server(ws_port=8765)
result: ReverseTokenResult = server.add_reverse_token()
print(f"Token: {result.token}, Port: {result.port}")
Comparison with CLI Tool
| Feature | Python Bindings | Go CLI Tool |
|---|---|---|
| Integration | Library for Python apps | Standalone binary |
| API Style | Object-oriented, async/sync | Command-line flags |
| Use Cases | Embedded in applications | Quick setup, scripting |
| Performance | Same (uses Go backend) | Same |
| Features | Full feature parity | Full feature parity |
Troubleshooting
Common Issues
- Import Error: Make sure Go 1.19+ is installed when building from source
- Connection Refused: Check that server is running and ports are correct
- Authentication Failed: Verify tokens match between server and client
- Port Already in Use: Choose different ports or check for existing processes
Debug Logging
import logging
from linksocks import set_log_level
# Enable debug logging
set_log_level(logging.DEBUG)
# Or use environment variable
import os
os.environ["LINKSOCKS_LOG_LEVEL"] = "DEBUG"
Performance Tuning
# Increase buffer size for high-throughput scenarios
server = Server(buffer_size=65536)
client = Client("token", buffer_size=65536, threads=8)
# Enable fast open for lower latency
server = Server(fast_open=True)
client = Client("token", fast_open=True)
Contributing
We welcome contributions! Please see the main LinkSocks repository for contribution guidelines.
License
This project is licensed under the MIT License.
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file linksocks-1.7.15.tar.gz.
File metadata
- Download URL: linksocks-1.7.15.tar.gz
- Upload date:
- Size: 99.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
064014d89f0ad8b55555c9e4d007bb6145c96e4d6f71de910e352045cb1d2a16
|
|
| MD5 |
a083960a488199d8908379ca8314a89b
|
|
| BLAKE2b-256 |
7efaaa3da878d8aa2be1bff18715cdeb638aa2650700783dd0e7c0a3a03961cc
|
Provenance
The following attestation bundles were made for linksocks-1.7.15.tar.gz:
Publisher:
publish-pypi.yml on linksocks/linksocks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linksocks-1.7.15.tar.gz -
Subject digest:
064014d89f0ad8b55555c9e4d007bb6145c96e4d6f71de910e352045cb1d2a16 - Sigstore transparency entry: 908781300
- Sigstore integration time:
-
Permalink:
linksocks/linksocks@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Branch / Tag:
refs/tags/v1.7.15 - Owner: https://github.com/linksocks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file linksocks-1.7.15-py3-none-win_amd64.whl.
File metadata
- Download URL: linksocks-1.7.15-py3-none-win_amd64.whl
- Upload date:
- Size: 5.4 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
146fedb3b9da7c209fc6dedc1b8bf75d6648eb842ed9faa113f8474dac2bd191
|
|
| MD5 |
9f55fca130b6c822aead47ad85b1c38f
|
|
| BLAKE2b-256 |
1cc2d95102cc8e73c25e77b719697f9444a32c81151b4add07c8e96c15bdee91
|
Provenance
The following attestation bundles were made for linksocks-1.7.15-py3-none-win_amd64.whl:
Publisher:
publish-pypi.yml on linksocks/linksocks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linksocks-1.7.15-py3-none-win_amd64.whl -
Subject digest:
146fedb3b9da7c209fc6dedc1b8bf75d6648eb842ed9faa113f8474dac2bd191 - Sigstore transparency entry: 908781311
- Sigstore integration time:
-
Permalink:
linksocks/linksocks@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Branch / Tag:
refs/tags/v1.7.15 - Owner: https://github.com/linksocks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file linksocks-1.7.15-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl.
File metadata
- Download URL: linksocks-1.7.15-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
- Upload date:
- Size: 4.5 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
145aa2ea0d9d5c4130a89b7a76a08d00af264655bb1d66dab29cf5c8ab83f3c0
|
|
| MD5 |
5313e407a451b5da5262f8ac5eba8e28
|
|
| BLAKE2b-256 |
610f1c49b994190424ef1c1192ce72d89677e23649a6f14ea253a2896910d3c3
|
Provenance
The following attestation bundles were made for linksocks-1.7.15-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl:
Publisher:
publish-pypi.yml on linksocks/linksocks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linksocks-1.7.15-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl -
Subject digest:
145aa2ea0d9d5c4130a89b7a76a08d00af264655bb1d66dab29cf5c8ab83f3c0 - Sigstore transparency entry: 908781302
- Sigstore integration time:
-
Permalink:
linksocks/linksocks@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Branch / Tag:
refs/tags/v1.7.15 - Owner: https://github.com/linksocks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file linksocks-1.7.15-py3-none-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl.
File metadata
- Download URL: linksocks-1.7.15-py3-none-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl
- Upload date:
- Size: 4.8 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c051aa13c6932a9fcb5a56bb996db75f56cacdf55090aa407e9ee06f583a3c1
|
|
| MD5 |
a86c2afebcc64c63cf95af91f06b1238
|
|
| BLAKE2b-256 |
7eb28def0fe1568050a443c32389ba43206543e83a1b746af02b36797564f56e
|
Provenance
The following attestation bundles were made for linksocks-1.7.15-py3-none-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl:
Publisher:
publish-pypi.yml on linksocks/linksocks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linksocks-1.7.15-py3-none-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl -
Subject digest:
5c051aa13c6932a9fcb5a56bb996db75f56cacdf55090aa407e9ee06f583a3c1 - Sigstore transparency entry: 908781316
- Sigstore integration time:
-
Permalink:
linksocks/linksocks@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Branch / Tag:
refs/tags/v1.7.15 - Owner: https://github.com/linksocks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file linksocks-1.7.15-py3-none-macosx_15_0_universal2.whl.
File metadata
- Download URL: linksocks-1.7.15-py3-none-macosx_15_0_universal2.whl
- Upload date:
- Size: 2.6 MB
- Tags: Python 3, macOS 15.0+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47946890bb6e54c5b2d2970b45b646ae612009f1aa95019a5dd972928b685833
|
|
| MD5 |
63ea5ae6ed1b2fe8592112f7024d8fbf
|
|
| BLAKE2b-256 |
c9e448e80d7b0b89b383f15b9da1ae770b9108351067c1fddf3f53e35fa22bc2
|
Provenance
The following attestation bundles were made for linksocks-1.7.15-py3-none-macosx_15_0_universal2.whl:
Publisher:
publish-pypi.yml on linksocks/linksocks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linksocks-1.7.15-py3-none-macosx_15_0_universal2.whl -
Subject digest:
47946890bb6e54c5b2d2970b45b646ae612009f1aa95019a5dd972928b685833 - Sigstore transparency entry: 908781305
- Sigstore integration time:
-
Permalink:
linksocks/linksocks@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Branch / Tag:
refs/tags/v1.7.15 - Owner: https://github.com/linksocks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file linksocks-1.7.15-py3-none-macosx_14_0_universal2.whl.
File metadata
- Download URL: linksocks-1.7.15-py3-none-macosx_14_0_universal2.whl
- Upload date:
- Size: 2.5 MB
- Tags: Python 3, macOS 14.0+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ac7744170d56ef6f88187c51c104726f4629146ad529a9b6754212cb56b7151
|
|
| MD5 |
4c71e6cecf0ffd354bc1854fefca554c
|
|
| BLAKE2b-256 |
bc8d55aed37a6c6b12bf5fc800934f83e8692f9fe4a38c0493ffffe99cde60a7
|
Provenance
The following attestation bundles were made for linksocks-1.7.15-py3-none-macosx_14_0_universal2.whl:
Publisher:
publish-pypi.yml on linksocks/linksocks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linksocks-1.7.15-py3-none-macosx_14_0_universal2.whl -
Subject digest:
9ac7744170d56ef6f88187c51c104726f4629146ad529a9b6754212cb56b7151 - Sigstore transparency entry: 908781306
- Sigstore integration time:
-
Permalink:
linksocks/linksocks@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Branch / Tag:
refs/tags/v1.7.15 - Owner: https://github.com/linksocks
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@5a259a5ddf276875fa884345a0e5cbd16eb18ce8 -
Trigger Event:
release
-
Statement type: