If you watch YouTube or listen to podcasts, you’ve heard the pitch a thousand times: “Protect your privacy, hide your IP, and unlock content with [Insert Big-Name VPN Here].”

Commercial VPNs are marketed as the ultimate digital Swiss Army Knife. But for the truly privacy-conscious—or those living under digital authoritarianism—renting a VPN connection from a massive corporation often creates as many problems as it solves.

It is time to stop sharing a server with thousands of strangers and start hosting your own. Here is why commercial VPNs are falling short and how you can take total control using Shadowsocks or VLESS.


The Problem with Commercial Providers

When you sign up for a commercial VPN, you aren’t buying a private tunnel; you are buying a ticket on a crowded bus.

1. The Bandwidth Bottleneck

Commercial providers operate on an overselling model. They crowd thousands of users onto a single server, banking on the fact that not everyone will be downloading at full speed simultaneously. During peak times, your connection can slow to a crawl. When you host your own server on a VPS (Virtual Private Server), the bandwidth is yours alone.

2. The “No-Logs” Myth

You pay for a VPN to prevent your ISP from tracking you. However, with a commercial provider, you are simply shifting your trust from your ISP to the VPN company. While they claim “Zero Logs,” you have no way to verify this. If you don’t control the server, you don’t control the logs.

3. The Censorship Target

For countries with strict internet censorship (you know who), blocking commercial VPNs is easy. Governments simply identify the IP ranges of major data centers and blacklist them. Blocking one commercial server can silence thousands of users instantly.


Step 1: Choosing Your Infrastructure

By renting a cheap VPS for roughly $5/month, you get a dedicated IP address that isn’t flagged by streaming services or government firewalls.

Server Specifications

For personal usage, you only need:

  • CPU: 1 Core
  • RAM: 1 GB
  • Storage: 20 GB SSD or NVMe

Recommended Providers

  • Google Cloud: Offers an always “Free Tier” VPS if you use us-central1, us-east1, or us-west1 regions with 1 CPU, 1GB RAM and up to 30GB standard storage.
  • UltaHost: A good choice if you want to maintain anonymity by paying with cryptocurrency. I get a small referral fees when you sign up with UltaHost from this link https://ultahost.com/#best-hosting, so help a brother out.
  • Location Tip: Choose a server close to your physical location to minimize latency. If you are in Asia, Singapore is an ideal hub due to its high-speed connectivity.

Step 2: Server Provisioning

Ideally, run Debian Linux for its low memory footprint. Once your VPS is live, follow these steps to prepare the environment.

1. Enable a Swap File

Adding a swap file prevents crashes if memory runs low.

# Check if swap is already enabled, skip if already enabled
sudo swapon --show

# Create a 2GB swap file
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Make swap persistent across reboots
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Lower swappiness to 10
# IMPORTANT: for Google standard drive/spinning drives only
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

2. Install Docker

Follow the official Docker guide to install the Docker engine on your server.

3. Enable TCP BBR (The Speed Booster)

“BBR” is a congestion control algorithm by Google. It significantly improves network speed and reduces latency on weak signals (like 4G/5G). This helps battery life by finishing data transfers faster.

Run these commands on your VPS host (not inside the Docker container):

echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Check if it’s running:

lsmod | grep bbr

(If you see tcp_bbr, you are good to go).


Step 3: Choose Your Protocol

Depending on your location and threat model, you have two primary paths:

Feature Shadowsocks Xray with VLESS (REALITY)
Best For Speed & Battery Life Bypassing Strict Censorship
Setup Extremely Easy (Docker) Complex (Manual Config)
Visibility Looks like “Encrypted Data” Looks like “Normal HTTPS”
Usage US, Europe, Australia China, Iran, Russia

Note: Do not host both Shadowsocks and VLESS on the same server. If a censor detects Shadowsocks, they may block the entire IP, rendering your VLESS connection useless.


Step 4: Implementation

Option A: Shadowsocks (The Speed Demon)

Generate a new 32 bytes key

openssl rand -base64 32

Create a docker-compose.yml file:

name: shadowsocks
services:
  method-aes:
    image: ghcr.io/shadowsocks/ssserver-rust:latest
    restart: unless-stopped
    ports:
      - "80:8388/tcp"
      - "80:8388/udp"
    command: ssserver -s 0.0.0.0:8388 -k "YOUR-TOP-SECRET-PASSWORD" -m aes-256-gcm -U

  method-chacha:
    image: ghcr.io/shadowsocks/ssserver-rust:latest
    restart: unless-stopped
    ports:
      - "443:8388/tcp"
      - "443:8388/udp"
    command: ssserver -s 0.0.0.0:8388 -k "KEY-GENERATED-PREVIOUSLY" -m 2022-blake3-aes-256-gcm -U
  • Tip: Use 2022-blake3-aes-256-gcm if your VPS hardware supports encryption (faster). Use 2022-blake3-chacha20-poly1305 for older hardware.

Start the server: sudo docker compose up -d


Option B: VLESS with Xray (The Stealth Bomber)

VLESS mimics standard web traffic. If a censor visits your IP, they will simply see a legitimate website (like Microsoft or Amazon).

1. Generate your credentials

Run these commands to generate your unique IDs:

  • UUID: docker run --rm ghcr.io/xtls/xray-core:latest uuid
  • Keys: docker run --rm ghcr.io/xtls/xray-core:latest x25519 (Save both PrivateKey and Password, password is the public key)
  • Short ID: openssl rand -hex 8

2. Create config.json

Use your generated IDs to fill in the placeholders in the inbounds section of the Xray configuration.

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {
    "servers": [
      "45.90.28.0",
      "45.90.30.0",
      "localhost"
    ]
  },
  "inbounds": [
    {
      "port": 443,
      "listen": "0.0.0.0",
      "protocol": "vless",
      "settings": {
        "clients": [ { "id": "<GENERATED-UUID>", "flow": "xtls-rprx-vision" } ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "show": false,
          "dest": "www.microsoft.com:443",
          "serverNames": [ "www.microsoft.com", "microsoft.com" ],
          "privateKey": "<GENERATED-PRIVATE-KEY>",
          "shortIds": [ "<GENERATED-SHORT-ID>" ] 
    }
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [ "http", "tls", "quic" ],
        "routeOnly": true
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom", 
      "tag": "direct",
      "settings": {
        "domainStrategy": "UseIP"
      } 
    },
    { "protocol": "blackhole", "tag": "block" }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "ip": [ "geoip:private", "geoip:cn" ],
        "outboundTag": "block"
      }
    ]
  }
}

3. Deploy with Docker

name: vless
services:
  xray:
    image: ghcr.io/xtls/xray-core:latest
    restart: unless-stopped
    volumes:
      - ./config.json:/etc/xray/config.json:ro
    command: run -c /etc/xray/config.json

Step 5: Connecting Your Devices

To use your new VPN, download a client that supports these protocols:

  • Hiddify (Windows, macOS, Android, iOS)
  • v2rayTun (macOS, Android, iOS)

Connection String for VLESS

Your connection string will look like this:

vless://GENERATED-UUID@IP:443?security=reality&encryption=none&pbk=GENERATED-PUBLIC-KEY&headerType=none&fp=chrome&type=tcp&flow=xtls-rprx-vision&sni=SNI_DOMAIN&sid=GENERATED-SHORT-ID#PROFILE-NAME

Replace these values:

  • GENERATED-UUID: Your GENERATED-UUID in previous step.
  • IP: Your VPS Public IP.
  • PUBLIC_KEY: The Public Key generated in previous step.
  • SNI_DOMAIN: The domain you used in config.json (e.g., www.microsoft.com).
  • GENERATED-SHORT-ID: generated previously.
  • PROFILE-NAME: Any name for your profile (e.g., MyVPN).

Conclusion

If you want convenience and don’t mind sharing a connection with thousands of others, keep your commercial subscription.

But if you want consistent speeds, verifiable privacy, and a connection that can “disappear” in plain sight, host it yourself. Take back your internet—one VPS at a time.