← Back to DevBytes

Shadowsocks Proxy: Complete Setup and Configuration Guide

Introduction to Shadowsocks Proxy

Shadowsocks is a free, open-source encrypted proxy protocol designed to bypass internet censorship and protect network traffic. Originally developed by a Chinese developer known as "clowwindy" in 2012, Shadowsocks has become one of the most popular tools for secure, unrestricted internet access. Unlike traditional VPN protocols that operate at the network layer, Shadowsocks works at the application layer, making it lightweight, fast, and difficult to detect.

At its core, Shadowsocks uses SOCKS5 proxy with strong encryption to tunnel traffic between a client and a remote server. The traffic is encrypted and appears as random HTTPS traffic, making it challenging for firewalls and deep packet inspection (DPI) systems to identify and block.

Why Shadowsocks Matters

Understanding the value proposition of Shadowsocks requires looking at several key areas where it excels compared to alternatives:

Performance Advantages

Shadowsocks is significantly faster than traditional VPN protocols like OpenVPN or IPSec. Because it operates at the application layer and uses lightweight encryption, the overhead is minimal. This makes it ideal for streaming, gaming, and other bandwidth-intensive activities.

Stealth and Anti-Censorship

The protocol is designed to be difficult to detect. Traffic patterns resemble normal HTTPS connections, and modern implementations include features like traffic obfuscation plugins that further disguise the proxy traffic. This is particularly valuable in regions with strict internet censorship.

Cross-Platform Support

Shadowsocks has clients available for virtually every operating system, including Windows, macOS, Linux, Android, iOS, and even routers running OpenWrt. This ubiquity makes it a versatile choice for developers and users alike.

Open Source and Auditable

Being open source means the code can be audited by security researchers, reducing the risk of backdoors or vulnerabilities. The community actively maintains several implementations, ensuring ongoing security updates.

Understanding the Architecture

Before diving into setup, it is important to understand how Shadowsocks works. The architecture consists of three main components:

When you browse a website through Shadowsocks, your traffic flows like this: your application sends data to the local Shadowsocks client, which encrypts it and sends it to the remote server. The server decrypts the data, fetches the requested content from the internet, encrypts the response, and sends it back to your client, which decrypts it and passes it to your application.

Server Setup and Installation

The first step in setting up Shadowsocks is deploying a server. You will need a VPS (Virtual Private Server) with a public IP address. Popular providers include DigitalOcean, Linode, Vultr, and AWS. For this tutorial, we will assume you are using a Linux server running Ubuntu 22.04 or later.

Installing Shadowsocks-libev

Shadowsocks-libev is the most widely used and actively maintained C implementation of Shadowsocks. It is lightweight and performant. Install it using the following commands:

# Update package lists
sudo apt update

# Install shadowsocks-libev
sudo apt install shadowsocks-libev -y

# Verify installation
ss-server --help

Configuring the Server

After installation, you need to create a configuration file. The default location is /etc/shadowsocks-libev/config.json. Create or edit this file with your preferred text editor:

sudo nano /etc/shadowsocks-libev/config.json

Here is a complete example configuration:

{
    "server": "0.0.0.0",
    "server_port": 8388,
    "password": "YourStrongPasswordHere123!",
    "timeout": 300,
    "method": "aes-256-gcm",
    "fast_open": true,
    "mode": "tcp_and_udp",
    "plugin": "",
    "plugin_opts": "",
    "nameserver": "8.8.8.8",
    "reuse_port": true
}

Let us break down each configuration option:

Generating a Strong Password

Never use a simple or guessable password. Generate a strong random password using the following command:

# Generate a 32-character random password
openssl rand -base64 24

# Or use /dev/urandom
head -c 32 /dev/urandom | base64

Starting and Enabling the Service

Once configured, start the Shadowsocks service and enable it to start automatically on boot:

# Start the service
sudo systemctl start shadowsocks-libev

# Enable auto-start on boot
sudo systemctl enable shadowsocks-libev

# Check service status
sudo systemctl status shadowsocks-libev

# View logs for troubleshooting
sudo journalctl -u shadowsocks-libev -f

Configuring the Firewall

You must open the port specified in your configuration. If you are using UFW (Uncomplicated Firewall), run:

# Allow the Shadowsocks port (replace 8388 with your port)
sudo ufw allow 8388/tcp
sudo ufw allow 8388/udp

# Verify firewall rules
sudo ufw status

If you are using iptables directly, the commands would be:

# Allow TCP traffic on port 8388
sudo iptables -A INPUT -p tcp --dport 8388 -j ACCEPT

# Allow UDP traffic on port 8388
sudo iptables -A INPUT -p udp --dport 8388 -j ACCEPT

# Save iptables rules
sudo iptables-save | sudo tee /etc/iptables/rules.v4

Optimizing System Parameters

For better performance, especially under high load, tune the kernel network parameters. Create or edit /etc/sysctl.d/shadowsocks.conf:

# Increase maximum file descriptors
fs.file-max = 51200

# Increase TCP max buffer size
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864

# Increase TCP buffer size
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864

# Enable TCP Fast Open
net.ipv4.tcp_fastopen = 3

# Increase connection tracking
net.netfilter.nf_conntrack_max = 1048576

# Enable BBR congestion control
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

Apply the changes with:

sudo sysctl -p /etc/sysctl.d/shadowsocks.conf

Client Configuration

With the server running, you now need to configure a client on your local machine. Shadowsocks clients are available for all major platforms.

Linux Client Setup

On Linux, you can use the same shadowsocks-libev package as a client. Install it the same way as on the server, then create a client configuration file:

sudo nano /etc/shadowsocks-libev/client.json

Add the following configuration:

{
    "server": "your_server_ip",
    "server_port": 8388,
    "local_address": "127.0.0.1",
    "local_port": 1080,
    "password": "YourStrongPasswordHere123!",
    "timeout": 300,
    "method": "aes-256-gcm",
    "fast_open": true,
    "mode": "tcp_and_udp"
}

Start the client using the local mode:

# Start the local SOCKS5 proxy
ss-local -c /etc/shadowsocks-libev/client.json -d

# Verify it is running
ss -tlnp | grep 1080

Your local SOCKS5 proxy is now available at 127.0.0.1:1080. You can configure applications to use this proxy.

Testing the Proxy Connection

Verify that your proxy is working by making a request through it:

# Test with curl through SOCKS5 proxy
curl --socks5 127.0.0.1:1080 https://ifconfig.me

# Test with curl through SOCKS5h (DNS resolution through proxy)
curl --socks5-hostname 127.0.0.1:1080 https://ifconfig.me

If the proxy is working correctly, the returned IP address should be your server's IP address, not your local IP.

Configuring Applications to Use the Proxy

Most applications support SOCKS5 proxies. Here are common configuration methods:

# Set proxy environment variables for command-line tools
export ALL_PROXY=socks5://127.0.0.1:1080
export HTTP_PROXY=socks5://127.0.0.1:1080
export HTTPS_PROXY=socks5://127.0.0.1:1080

# Test with wget
wget -qO- https://ifconfig.me

# Use with git
git config --global http.proxy socks5://127.0.0.1:1080

# Remove git proxy when done
git config --global --unset http.proxy

macOS Client Setup

On macOS, the most popular client is ShadowsocksX-NG. You can install it via Homebrew or download the GUI application:

# Install via Homebrew Cask
brew install --cask shadowsocksx-ng

# Or download manually from GitHub releases
# https://github.com/shadowsocks/ShadowsocksX-NG/releases

After installation, open the app, add a new server profile with your server details, and enable the proxy. ShadowsocksX-NG can also configure system-wide proxy settings automatically.

Windows Client Setup

For Windows, Shadowsocks-Windows is the standard client. Download it from the official GitHub repository and configure it with your server details. The client provides a system tray icon for easy management and can set the system proxy automatically.

Mobile Client Setup

For Android, download Shadowsocks from the Google Play Store or F-Droid. For iOS, several clients are available, including Shadowrocket and Potatso. Configure them with the same server details as your desktop client.

Advanced Configuration

Using Obfuscation Plugins

To make Shadowsocks traffic even harder to detect, you can use obfuscation plugins. The most popular is obfs4 or v2ray-plugin. Here is how to set up the simple-obfs plugin:

First, install the plugin on the server:

# Install build dependencies
sudo apt install --no-install-recommends build-essential autoconf libtool \
    libssl-dev libpcre3-dev libev-dev libudns-dev \
    asciidoc xmlto -y

# Clone and build simple-obfs
git clone https://github.com/shadowsocks/simple-obfs.git
cd simple-obfs
git submodule update --init --recursive
./autogen.sh
./configure && make
sudo make install

Update your server configuration to use the plugin:

{
    "server": "0.0.0.0",
    "server_port": 8388,
    "password": "YourStrongPasswordHere123!",
    "timeout": 300,
    "method": "aes-256-gcm",
    "fast_open": true,
    "mode": "tcp_and_udp",
    "plugin": "obfs-server",
    "plugin_opts": "obfs=http"
}

Restart the service:

sudo systemctl restart shadowsocks-libev

On the client side, update your configuration to match:

{
    "server": "your_server_ip",
    "server_port": 8388,
    "local_address": "127.0.0.1",
    "local_port": 1080,
    "password": "YourStrongPasswordHere123!",
    "timeout": 300,
    "method": "aes-256-gcm",
    "fast_open": true,
    "plugin": "obfs-local",
    "plugin_opts": "obfs=http;http-host=www.bing.com"
}

Using v2ray-plugin for WebSocket Transport

The v2ray-plugin is a more modern alternative that supports WebSocket transport, allowing you to front Shadowsocks with a web server like Nginx. This makes the traffic indistinguishable from normal HTTPS traffic.

Download the plugin from the official releases page and place it in your PATH:

# Download v2ray-plugin (check for latest version)
wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.2/v2ray-plugin-linux-amd64-v1.3.2.tar.gz

# Extract
tar -xzf v2ray-plugin-linux-amd64-v1.3.2.tar.gz

# Move to a directory in PATH
sudo mv v2ray-plugin_linux_amd64 /usr/local/bin/v2ray-plugin
sudo chmod +x /usr/local/bin/v2ray-plugin

Server configuration with v2ray-plugin:

{
    "server": "0.0.0.0",
    "server_port": 8388,
    "password": "YourStrongPasswordHere123!",
    "timeout": 300,
    "method": "aes-256-gcm",
    "plugin": "v2ray-plugin",
    "plugin_opts": "server"
}

Setting Up Multiple Users

If you want to share your server with multiple users, each with their own password, use the manager API. Create a manager configuration:

{
    "server": "0.0.0.0",
    "local_port": 1080,
    "port_password": {
        "8381": "password_for_user1",
        "8382": "password_for_user2",
        "8383": "password_for_user3"
    },
    "timeout": 300,
    "method": "aes-256-gcm",
    "fast_open": true,
    "mode": "tcp_and_udp"
}

Start the manager:

ss-manager -c /etc/shadowsocks-libev/manager.json -d

Fronting with Nginx for WebSocket Mode

For maximum stealth, front your Shadowsocks server with Nginx using WebSocket mode. Install Nginx and obtain an SSL certificate:

# Install Nginx
sudo apt install nginx -y

# Install Certbot for SSL
sudo apt install certbot python3-certbot-nginx -y

# Obtain SSL certificate
sudo certbot --nginx -d yourdomain.com

Create an Nginx configuration:

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8388;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Update your Shadowsocks server config to use WebSocket mode:

{
    "server": "127.0.0.1",
    "server_port": 8388,
    "password": "YourStrongPasswordHere123!",
    "timeout": 300,
    "method": "aes-256-gcm",
    "plugin": "v2ray-plugin",
    "plugin_opts": "server;path=/;host=yourdomain.com"
}

Client configuration for WebSocket mode with TLS:

{
    "server": "yourdomain.com",
    "server_port": 443,
    "local_address": "127.0.0.1",
    "local_port": 1080,
    "password": "YourStrongPasswordHere123!",
    "timeout": 300,
    "method": "aes-256-gcm",
    "plugin": "v2ray-plugin",
    "plugin_opts": "tls;mode=websocket;path=/;host=yourdomain.com"
}

Monitoring and Logging

Setting Up Log Rotation

Shadowsocks-libev logs to the systemd journal by default. To set up proper log files with rotation, create a custom systemd override:

sudo systemctl edit shadowsocks-libev

Add the following configuration:

[Service]
ExecStart=
ExecStart=/usr/bin/ss-server -c /etc/shadowsocks-libev/config.json --log-file /var/log/shadowsocks/server.log -v

Create the log directory and set up logrotate:

# Create log directory
sudo mkdir -p /var/log/shadowsocks
sudo chown nobody:nogroup /var/log/shadowsocks

# Create logrotate configuration
sudo tee /etc/logrotate.d/shadowsocks << 'EOF'
/var/log/shadowsocks/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 644 nobody nogroup
    postrotate
        systemctl restart shadowsocks-libev >/dev/null 2>&1 || true
    endscript
}
EOF

Monitoring Connections

Monitor active connections to your Shadowsocks server:

# View active connections to port 8388
sudo ss -tnp | grep 8388

# Count active connections
sudo ss -tn | grep 8388 | wc -l

# Monitor bandwidth usage with iftop
sudo apt install iftop -y
sudo iftop -i eth0 -P

Using vnStat for Bandwidth Monitoring

Install vnStat to track long-term bandwidth usage:

# Install vnStat
sudo apt install vnstat -y

# Enable and start the service
sudo systemctl enable vnstat
sudo systemctl start vnstat

# View bandwidth statistics
vnstat -h  # hourly
vnstat -d  # daily
vnstat -m  # monthly

Best Practices

Security Best Practices

Performance Best Practices

Reliability Best Practices

Setting Up Automatic Restarts

To ensure the service always restarts on failure, create a systemd override:

sudo systemctl edit shadowsocks-libev

Add the following:

[Service]
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Reload systemd and restart the service:

sudo systemctl daemon-reload
sudo systemctl restart shadowsocks-libev

Troubleshooting Common Issues

Connection Refused

If you cannot connect, check the following:

# Check if the service is running
sudo systemctl status shadowsocks-libev

# Check if the port is listening
sudo ss -tlnp | grep 8388

# Check firewall rules
sudo ufw status

# Check server logs
sudo journalctl -u shadowsocks-libev --no-pager -n 50

Slow Speeds

If your connection is slow, try these steps:

# Verify BBR is enabled
sysctl net.ipv4.tcp_congestion_control

# Check server load
uptime

# Check network interface errors
ip -s link show eth0

# Test raw server speed (without proxy)
iperf3 -c your_server_ip -p 5201

DNS Leaks

DNS leaks can expose your browsing activity even when using a proxy. To prevent DNS leaks, use SOCKS5h (which resolves DNS through the proxy) instead of plain SOCKS5. In your client configuration, ensure DNS queries go through the proxy:

# Test for DNS leaks
curl --socks5-hostname 127.0.0.1:1080 https://dnsleaktest.com

# Or use a dedicated DNS leak test
curl --socks5-hostname 127.0.0.1:1080 https://ipleak.net/json/

Verifying Encryption

Confirm that your traffic is properly encrypted by capturing packets on the server:

# Install tcpdump
sudo apt install tcpdump -y

# Capture traffic on port 8388
sudo tcpdump -i eth0 port 8388 -c 20 -X

# You should see encrypted data, not plaintext HTTP requests

Automating Deployment with a Script

For convenience, here is a complete deployment script that installs and configures Shadowsocks on a fresh Ubuntu server:

#!/bin/bash

# Shadowsocks-libev Auto-Install Script
# Usage: sudo bash install_shadowsocks.sh

set -e

# Configuration
SERVER_PORT=8388
PASSWORD=$(openssl rand -base64 24)
METHOD="aes-256-gcm"

echo "=== Shadowsocks-libev Installation Script ==="

# Update system
echo "Updating system packages..."
apt update && apt upgrade -y

# Install shadowsocks-libev
echo "Installing shadowsocks-libev..."
apt install shadowsocks-libev -y

# Generate configuration
echo "Creating configuration..."
cat > /etc/shadowsocks-libev/config.json << EOF
{
    "server": "0.0.0.0",
    "server_port": ${SERVER_PORT},
    "password": "${PASSWORD}",
    "timeout": 300,
    "method": "${METHOD}",
    "fast_open": true,
    "mode": "tcp_and_udp",
    "nameserver": "8.8.8.8",
    "reuse_port": true
}
EOF

# Configure firewall
echo "Configuring firewall..."
if command -v ufw >/dev/null 2>&1; then
    ufw allow ${SERVER_PORT}/tcp
    ufw allow ${SERVER_PORT}/udp
fi

# Optimize kernel parameters
echo "Optimizing kernel parameters..."
cat > /etc/sysctl.d/shadowsocks.conf << 'EOF'
fs.file-max = 51200
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.ipv4.tcp_fastopen = 3
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF

sysctl -p /etc/sysctl.d/shadowsocks.conf

# Enable and start service
echo "Starting service..."
systemctl enable shadowsocks-libev
systemctl restart shadowsocks-libev

# Display connection info
SERVER_IP=$(curl -s ifconfig.me)
echo ""
echo "=== Installation Complete ==="
echo "Server IP: ${SERVER_IP}"
echo "Port: ${SERVER_PORT}"
echo "Password: ${PASSWORD}"
echo "Method: ${METHOD}"
echo ""
echo "Client configuration:"
cat << EOF
{
    "server": "${SERVER_IP}",
    "server_port": ${SERVER_PORT},
    "local_address": "127.0.0.1",
    "local_port": 1080,
    "password": "${PASSWORD}",
    "timeout": 300,
    "method": "${METHOD}",
    "fast_open": true,
    "mode": "tcp_and_udp"
}
EOF
echo ""
echo "Save this information securely!"

Save this script and run it with sudo privileges:

# Save the script
nano install_shadowsocks.sh

# Make it executable
chmod +x install_shadowsocks.sh

# Run it
sudo ./install_shadowsocks.sh

Conclusion

Shadowsocks remains one of the most effective, performant, and flexible proxy solutions available today. By following this guide, you have learned how to deploy a Shadowsocks server from scratch, configure clients across different platforms, implement advanced features like obfuscation plugins and WebSocket transport with Nginx, optimize performance through kernel tuning, and follow security best practices to keep your proxy safe and reliable. Whether you are using Shadowsocks for privacy, bypassing censorship, or secure remote access, the combination of strong encryption, lightweight architecture, and extensive community support makes it an excellent choice for developers and power users. Remember to keep your software updated, monitor your server's health, and maintain strong operational security practices to ensure your proxy remains fast, secure, and available when you need it.

— Ad —

Google AdSense will appear here after approval

← Back to all articles