A lightweight shadowsocks client written in Go that provides local HTTP/HTTPS and SOCKS5 proxy servers. Forward all your traffic through a shadowsocks server with ease.
- Shadowsocks Client: Connect to any shadowsocks server with AEAD cipher support
- Server Testing: Test SS servers without starting the daemon - measure latency and speed (latency-only mode available for bandwidth savings)
- Unified Proxy Mode: Single port for HTTP/HTTPS and SOCKS5 (like Clash)
- Separate Proxy Mode: Dedicated ports for HTTP and SOCKS5
- Simple-obfs Plugin: HTTP and TLS obfuscation support
- Command-line Parameters: Run without config files - perfect for automation
- Config Converters: Import from ss-local and Clash configurations
- Statistics Monitoring: Track connections and bandwidth usage
- Management API: REST API for monitoring, speed testing (with latency-only mode), and hot-reload
- Graceful Shutdown: Proper cleanup on exit signals
- Flexible Configuration: YAML/JSON config files, environment variables, or CLI params
git clone https://github.com/xrdavies/light-ss.git
cd light-ss
make buildThe binary will be available at ./bin/light-ss.
go build -o light-ss ./cmd/light-ss- Create a configuration file:
cp config.yaml.example config.yaml- Edit
config.yamlwith your shadowsocks server details:
shadowsocks:
server: "example.com:8388"
password: "your-strong-password"
cipher: "AEAD_CHACHA20_POLY1305"
timeout: 300
# Unified mode - single port for both HTTP and SOCKS5
proxies: "127.0.0.1:1080"Or use JSON format (config.json):
{
"shadowsocks": {
"server": "example.com",
"port": 8388,
"method": "aes-128-gcm",
"password": "your-password",
"timeout": 300
},
"proxies": "127.0.0.1:1080"
}- Start the client:
./light-ss start -c config.yaml- Configure your applications to use the proxy at
127.0.0.1:1080
./light-ss start \
--server example.com \
--port 8388 \
--password your-strong-password \
--method aes-128-gcm \
--proxies 127.0.0.1:1080./light-ss start \
--server example.com \
--port 8388 \
--password your-strong-password \
--method aes-128-gcm \
--plugin simple-obfs \
--plugin-obfs http \
--plugin-host www.bing.com \
--proxies 127.0.0.1:1080# With config file
./light-ss start -c config.yaml
# With CLI parameters only
./light-ss start -s server.com -p 8388 --password pass -m aes-128-gcm
# Override config file values
./light-ss start -c config.yaml --log-level debug --proxies 0.0.0.0:1080
# View all available flags
./light-ss start --help# Convert from ss-local format
./light-ss convert --from ss-local --input ss-local.json --output config.json
# Convert from Clash format
./light-ss convert --from clash --input clash.yaml --output config.yaml
# Print to stdout (JSON format)
./light-ss convert --from ss-local --input ss-local.jsonTest a shadowsocks server without starting the full daemon. This is useful for:
- Validating server credentials before use
- Testing server availability and performance
- Benchmarking multiple servers
- Integration with automation tools
Basic Test:
# Test with command-line parameters
./light-ss test \
-s server.com:8388 \
--password your-password \
-m aes-128-gcm
# Output:
# ✅ Test successful
# Server: server.com:8388
# Cipher: aes-128-gcm
# Latency: 45ms
# Speed: 127.78 MbpsTest from Config File:
./light-ss test -c config.yamlQuick Latency Check (Skip Speed Test):
./light-ss test \
-s server.com:8388 \
--password your-password \
-m aes-128-gcm \
--latency-onlyJSON Output (For Automation):
./light-ss test \
-s server.com:8388 \
--password your-password \
-m aes-128-gcm \
--json
# Output:
# {
# "server": "server.com:8388",
# "cipher": "aes-128-gcm",
# "success": true,
# "latency_ms": 45,
# "download_speed_bps": 16777216,
# "download_speed_mbps": 127.78,
# "timestamp": "2025-12-02T10:30:00Z"
# }With Plugin:
./light-ss test \
-s server.com:8388 \
--password your-password \
-m aes-128-gcm \
--plugin simple-obfs \
--plugin-obfs http \
--plugin-host www.bing.comTest Flags:
-s, --server- Server address (with or without port)-p, --port- Server port (if not in server address)--password- Server password-m, --method- Encryption method-c, --config- Load from config file--timeout- Connection timeout in seconds (default: 10)--duration- Speed test duration in seconds (default: 10)--latency-only- Only test connection latency, skip download speed test. Saves bandwidth (~10MB per test). Useswww.google.com:80for faster testing.--json- Output result as JSON--plugin- Plugin name (e.g., simple-obfs)--plugin-obfs- Obfuscation mode (http or tls)--plugin-host- Obfuscation host header
Use Cases:
# Test multiple servers and compare
for server in server1.com:8388 server2.com:8388; do
./light-ss test -s $server --password pass -m aes-128-gcm --json
done
# Validate subscription servers
cat servers.txt | while read server; do
./light-ss test -s $server --password pass -m aes-128-gcm --latency-only
done
# CI/CD health check
./light-ss test -c config.yaml --json | jq -e '.success == true'# Unified mode (single port for both protocols)
curl -x socks5://127.0.0.1:1080 https://www.google.com
curl -x http://127.0.0.1:1080 https://www.google.com
# Separate mode
curl -x socks5://127.0.0.1:1080 https://www.google.com
curl -x http://127.0.0.1:8080 https://www.google.com- Settings → Network Settings → Manual proxy configuration
- SOCKS Host:
127.0.0.1, Port:1080 - Check "SOCKS v5" and "Proxy DNS when using SOCKS v5"
Note: With unified mode, both HTTP and SOCKS5 work on the same port!
# Unified mode - use either SOCKS5 or HTTP on same port
chromium --proxy-server="socks5://127.0.0.1:1080"
chromium --proxy-server="http://127.0.0.1:1080"
# Separate mode
chromium --proxy-server="socks5://127.0.0.1:1080"
chromium --proxy-server="http://127.0.0.1:8080"The configuration file supports both YAML and JSON formats. See config.yaml.example or config.json.example for complete examples.
# Optional: Instance name for identification
name: "my-hk-proxy"The instance name helps identify your light-ss instance in:
- Log messages (stats output)
- API responses (health, version, stats, config endpoints)
- Monitoring and debugging across multiple instances
This is especially useful when running multiple light-ss instances and need to distinguish between them.
shadowsocks:
server: "example.com:8388" # Server address and port
password: "your-strong-password" # Server password
cipher: "AEAD_CHACHA20_POLY1305" # Encryption cipher
timeout: 300 # Connection timeout (seconds)
# Optional: Simple-obfs plugin
plugin: "simple-obfs"
plugin_opts:
obfs: "http" # or "tls"
obfs-host: "www.bing.com"Supported Ciphers:
AEAD_CHACHA20_POLY1305(recommended)AEAD_AES_256_GCMAEAD_AES_192_GCMAEAD_AES_128_GCMAEAD_XCHACHA20_POLY1305
Alternative formats (auto-normalized):
aes-128-gcm,aes-192-gcm,aes-256-gcmchacha20-poly1305,chacha20-ietf-poly1305xchacha20-poly1305
Unified Mode (Recommended): Single port for both HTTP/HTTPS and SOCKS5
# YAML format
proxies: "127.0.0.1:1080"// JSON format
{
"proxies": "127.0.0.1:1080"
}Separate Mode: Dedicated ports for each protocol
# YAML format
proxies:
http: "127.0.0.1:8080"
socks5: "127.0.0.1:1080"// JSON format
{
"proxies": {
"http": "127.0.0.1:8080",
"socks5": "127.0.0.1:1080"
}
}SOCKS5 with Authentication:
proxies:
socks5: "user:pass@127.0.0.1:1080"stats:
enabled: true # Enable stats collection
interval: 60 # Report interval in secondsWhen enabled, statistics will be logged periodically showing:
- Total and active connections
- HTTP and SOCKS5 connection counts
- Bytes sent and received
- Uptime
logging:
level: "info" # debug, info, warn, error
format: "text" # json, textAll configuration can be specified via command-line flags:
./light-ss start [flags]Shadowsocks Flags:
-s, --server string- Shadowsocks server address-p, --port int- Shadowsocks server port--password string- Shadowsocks password-m, --method string- Encryption method (aes-128-gcm, aes-256-gcm, chacha20-poly1305)--timeout int- Connection timeout in seconds
Plugin Flags:
--plugin string- Plugin name (e.g., simple-obfs)--plugin-obfs string- Obfuscation mode: http or tls--plugin-host string- Obfuscation host header
Proxy Flags:
--proxies string- Unified proxy listen address (e.g., 127.0.0.1:1080)--http-proxy string- HTTP/HTTPS proxy listen address--socks5-proxy string- SOCKS5 proxy listen address (supports user:pass@host:port)
Other Flags:
-c, --config string- Path to configuration file (optional)--log-level string- Log level (debug, info, warn, error)
Examples:
# Minimal setup
./light-ss start -s server.com -p 8388 --password pass -m aes-128-gcm
# With plugin
./light-ss start \
-s server.com -p 8388 --password pass -m aes-128-gcm \
--plugin simple-obfs --plugin-obfs http --plugin-host www.bing.com
# Separate proxy ports
./light-ss start -s server.com -p 8388 --password pass -m aes-128-gcm \
--http-proxy 127.0.0.1:8080 --socks5-proxy 127.0.0.1:1080
# Override config file
./light-ss start -c config.yaml --log-level debug --proxies 0.0.0.0:1080You can override configuration values using environment variables:
export LIGHT_SS_SERVER="example.com:8388"
export LIGHT_SS_PASSWORD="your-strong-password"
export LIGHT_SS_CIPHER="AEAD_CHACHA20_POLY1305"
export LIGHT_SS_HTTP_LISTEN="127.0.0.1:8080"
export LIGHT_SS_SOCKS5_LISTEN="127.0.0.1:1080"
export LIGHT_SS_LOG_LEVEL="debug"Priority: CLI flags > Environment variables > Config file > Defaults
Single port handles both HTTP/HTTPS and SOCKS5 through protocol detection:
Client Apps → Unified Proxy:1080 → Stats → Shadowsocks+Plugin → Server → Internet
(HTTP or SOCKS5)
Dedicated ports for each protocol:
Client Apps → HTTP:8080 ────┐
SOCKS5:1080 ───┴→ Stats → Shadowsocks → Server → Internet
Light-ss provides a REST API for monitoring, configuration management, and control operations.
Via Config File:
api:
enabled: true
listen: "127.0.0.1:8090"
token: "your-secret-token" # Optional bearer token for authenticationVia CLI Flags:
./light-ss start -c config.yaml \
--api-enabled \
--api-listen 127.0.0.1:8090 \
--api-token secret123Health check endpoint - always returns 200 OK when running
curl http://127.0.0.1:8090/health
# Response: {"name": "my-hk-proxy", "status": "ok", "uptime": "2h30m15s"}
# Note: "name" field only included if instance name is configuredGet version and build information
curl http://127.0.0.1:8090/version
# Response: {"name": "my-hk-proxy", "version": "1.0.0", "commit": "abc123", "build_time": "2024-01-01"}
# Note: "name" field only included if instance name is configuredGet current statistics (connections, bandwidth, real-time speed)
curl http://127.0.0.1:8090/stats
# With authentication:
curl -H "Authorization: Bearer secret123" http://127.0.0.1:8090/statsResponse includes:
- Instance name (if configured)
- Connection counts (total, active, HTTP, SOCKS5)
- Bandwidth (bytes sent/received)
- Current speed (download/upload in bytes/sec)
- Uptime
Run active speed test through SS connection
# Default 10-second test
curl http://127.0.0.1:8090/speedtest
# Custom duration
curl "http://127.0.0.1:8090/speedtest?duration=30"
# Latency-only test (saves bandwidth, no download test)
curl "http://127.0.0.1:8090/speedtest?latency_only=true"
# Combined parameters
curl "http://127.0.0.1:8090/speedtest?duration=5&latency_only=true"
# Response: {"download_speed": 1234567, "latency_ms": 45, "test_duration_sec": 30}
# Note: download_speed will be 0 when latency_only=trueQuery Parameters:
duration- Test duration in seconds (1-300, default: 10). Only used for download speed test.latency_only- Iftrueor1, only measures connection latency without downloading test data. Useswww.google.com:80for faster testing. Iffalseor omitted, performs full speed test usingspeed.cloudflare.com.
Get current configuration (passwords sanitized)
curl http://127.0.0.1:8090/config
# Response includes instance name (if configured), server, cipher, plugin settings, and proxy configuration
# Passwords replaced with "***"Hot-reload shadowsocks configuration without restart
# Reload server configuration
curl -X POST http://127.0.0.1:8090/reload \
-H "Content-Type: application/json" \
-H "Authorization: Bearer secret123" \
-d '{"server": "new-server.com:8388", "password": "newpass", "cipher": "aes-256-gcm"}'
# Reload with plugin
curl -X POST http://127.0.0.1:8090/reload \
-H "Content-Type: application/json" \
-H "Authorization: Bearer secret123" \
-d '{
"server": "new-server.com:8388",
"password": "newpass",
"cipher": "aes-256-gcm",
"plugin": "simple-obfs",
"plugin_opts": {
"obfs": "http",
"obfs-host": "www.bing.com"
}
}'Behavior: Graceful reload - new connections use new config immediately, existing connections continue with old config until they close naturally.
Graceful shutdown of all servers
curl -X POST http://127.0.0.1:8090/stop \
-H "Authorization: Bearer secret123"- Bearer Token: Optional authentication (disabled by default)
- Localhost Binding: Binds to 127.0.0.1 by default for security
- Password Sanitization: Passwords never exposed in API responses
- HTTPS: Use a reverse proxy (nginx/caddy) for HTTPS if needed
Light-ss can import configurations from other shadowsocks clients:
# Convert and save
./light-ss convert --from ss-local --input ss-local.json --output config.json
# Print to stdout
./light-ss convert --from ss-local --input ss-local.jsonss-local format (JSON):
{
"server": "example.com",
"server_port": 8388,
"password": "password",
"method": "aes-128-gcm",
"plugin": "obfs-local",
"plugin_opts": "obfs=http;obfs-host=www.bing.com"
}# Convert to YAML
./light-ss convert --from clash --input clash.yaml --output config.yaml
# Convert to JSON
./light-ss convert --from clash --input clash.yaml --output config.jsonClash format (YAML):
proxies:
- name: "ss-server"
type: ss
server: example.com
port: 8388
cipher: aes-128-gcm
password: "password"
plugin: obfs
plugin-opts:
mode: http
host: www.bing.com- Cipher Selection: Always use AEAD ciphers (ChaCha20-Poly1305 or AES-GCM)
- Plugin Obfuscation: Use simple-obfs to disguise traffic as HTTP/TLS
- Local Only: Proxies bind to
127.0.0.1by default - don't expose them publicly - Config File: Protect your config file permissions:
chmod 600 config.yaml - No Logging: Sensitive data like passwords are never logged
- HTTPS: The client doesn't inspect HTTPS traffic - it only tunnels it
./light-ss start -c config.yaml --log-level debug- Verify shadowsocks server is running and accessible
- Check cipher matches server configuration
- Ensure password is correct
- Test server connectivity:
telnet example.com 8388
- Verify the proxy server started (check logs)
- Test local connectivity:
curl http://127.0.0.1:8080 - Check firewall rules
- Ensure no other service is using the same port
- Enable stats in config:
stats.enabled: true - Check stats interval setting
- View logs for statistics output
make buildmake build-allThis creates binaries for:
- Linux (amd64)
- macOS (amd64, arm64)
- Windows (amd64)
- go-shadowsocks2 - Shadowsocks client
- go-socks5 - SOCKS5 server
- goproxy - HTTP/HTTPS proxy
- cobra - CLI framework
- yaml.v3 - YAML parser
MIT License
Contributions are welcome! Please feel free to submit issues or pull requests.
xrdavies