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, orus-west1regions 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-gcmif your VPS hardware supports encryption (faster). Use2022-blake3-chacha20-poly1305for 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.