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():
async with Server(ws_port=8765) as server:
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")
await asyncio.sleep(3600)
if __name__ == "__main__":
asyncio.run(main())
Reverse Proxy Example
import asyncio
from linksocks import Server, Client
async def main():
async with Server(ws_port=8765) as server:
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}")
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")
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
server = Server(
ws_host="0.0.0.0",
ws_port=8765,
socks_host="127.0.0.1",
buffer_size=32768,
api_key="your_api_key",
channel_timeout=30.0,
connect_timeout=10.0,
fast_open=False,
upstream_proxy="socks5://proxy:1080",
upstream_username="user",
upstream_password="pass"
)
Token Management
token = server.add_forward_token("custom_token")
token = await server.async_add_forward_token("custom_token")
result = server.add_reverse_token(
token="custom_token",
port=9870,
username="socks_user",
password="socks_pass",
allow_manage_connector=True
)
print(f"Token: {result.token}, Port: {result.port}")
connector_token = server.add_connector_token("connector_token", "reverse_token")
success = server.remove_token("token_to_remove")
Running the Server
async with server:
print("Server is ready!")
server.wait_ready()
server.close()
server.wait_ready(timeout=30.0)
await server.async_wait_ready(timeout="30s")
Client Class
The Client
class connects to WebSocket servers and provides SOCKS5 functionality.
from linksocks import Client
client = Client(
token="your_token",
ws_url="ws://localhost:8765",
reverse=False,
socks_host="127.0.0.1",
socks_port=9870,
socks_username="user",
socks_password="pass",
socks_wait_server=True,
reconnect=True,
reconnect_delay=5.0,
buffer_size=32768,
channel_timeout=30.0,
connect_timeout=10.0,
threads=4,
fast_open=False,
upstream_proxy="socks5://proxy:1080",
upstream_username="proxy_user",
upstream_password="proxy_pass",
no_env_proxy=False
)
Running the Client
async with client:
print(f"Client ready! SOCKS5 port: {client.socks_port}")
print(f"Connected: {client.is_connected}")
client.wait_ready()
print(f"Connected: {client.is_connected}")
client.close()
Connector Management (Reverse Mode)
connector_token = client.add_connector("my_connector")
connector_token = await client.async_add_connector(None)
Logging
import logging
from linksocks import set_log_level
set_log_level(logging.DEBUG)
set_log_level("INFO")
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():
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}")
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!")
connector_token = await provider.async_add_connector("my_connector")
print(f"🔑 Connector token: {connector_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")
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():
server = Server(ws_port=8765, api_key="secret_api_key")
async with server:
print("✅ Server with API ready!")
async with aiohttp.ClientSession() as session:
headers = {"X-API-Key": "secret_api_key"}
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}")
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
server = Server(ws_port=8765)
result: ReverseTokenResult = server.add_reverse_token()
print(f"Token: {result.token}, Port: {result.port}")
Comparison with 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
set_log_level(logging.DEBUG)
import os
os.environ["LINKSOCKS_LOG_LEVEL"] = "DEBUG"
Performance Tuning
server = Server(buffer_size=65536)
client = Client("token", buffer_size=65536, threads=8)
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