Allison is coding...

Vultr, Hysteria 2, and Clash Setup Guide

A minimalist walkthrough on setting up Vultr + Hysteria 2 + Clash Verge. You won’t even need to touch the command line. If all goes smoothly, it takes under 20 minutes from start to finish, leaving you with a private proxy node ready to use in Clash Verge.

I won’t be diving into what each of these tools does—if you’re curious, a quick search will fill in the blanks.

1. Vultr Configuration

Sign up for a Vultr account and add some funds.

1.1 Preliminary Setup

Firewall

Head to Network → Firewall Groups in the sidebar or go directly to Firewall Groups to create a new group.

Add the following rule:

Protocol: UDP
Port: 443
Source: 0.0.0.0/0

Startup Scripts

Navigate to Orchestration → Startup Scripts or visit Startup Scripts to create a new boot script.

Startup scripts run automatically when the VPS boots for the first time, handling all software installation and provisioning hands-free.

Inside the script, locate the PASSWORD="password1234" line. It is strongly recommended to replace it with a strong, randomized password mixing uppercase, lowercase, numbers, and symbols—e.g., PASSWORD="X7!kP9@v2Lm".

The full script is below:

#!/bin/bash
set -e

sleep 10

# ==================== config ====================
PASSWORD="password1234"
LISTEN_PORT="443"
MASQUERADE_URL="https://www.bing.com"
CERT_DAYS="365"
HY_VERSION="v2.12.3"
# ============================================================

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}   Hysteria ${HY_VERSION} VPN Server Installation   ${NC}"
echo -e "${GREEN}                    ${NC}"
echo -e "${GREEN}========================================${NC}"

if [[ $EUID -ne 0 ]]; then
    echo -e "${RED}Error: Please run this script as root user (sudo ./script.sh)${NC}"
    exit 1
fi

echo -e "${YELLOW}[1/7] Updating system and installing dependencies...${NC}"
apt update -qq
apt install -y -qq wget curl openssl ufw

echo -e "${YELLOW}[2/7] Creating directory structure...${NC}"
mkdir -p /etc/hysteria /etc/ssl/hysteria

echo -e "${YELLOW}[3/7] Generating SSL certificate (valid for ${CERT_DAYS} days)...${NC}"
openssl req -x509 -newkey rsa:4096 -nodes \
    -keyout /etc/ssl/hysteria/key.pem \
    -out /etc/ssl/hysteria/cert.pem \
    -days ${CERT_DAYS} \
    -subj "/CN=www.bing.com"

chmod 644 /etc/ssl/hysteria/key.pem
chmod 644 /etc/ssl/hysteria/cert.pem
echo -e "${GREEN} Certificate permissions set to 644${NC}"

echo -e "${YELLOW}[4/7] Creating configuration file /etc/hysteria/config.yaml ...${NC}"
cat > /etc/hysteria/config.yaml << YAML
listen: :${LISTEN_PORT}

tls:
  cert: /etc/ssl/hysteria/cert.pem
  key: /etc/ssl/hysteria/key.pem

auth:
  type: password
  password: ${PASSWORD}

masquerade:
  type: proxy
  proxy:
    url: ${MASQUERADE_URL}
    rewriteHost: true

quic:
  initStreamReceiveWindow: 8388608
  maxStreamReceiveWindow: 8388608
  initConnReceiveWindow: 20971520
  maxConnReceiveWindow: 20971520
YAML

echo -e "${YELLOW}[5/7] Installing Hysteria ${HY_VERSION} using official script...${NC}"
bash <(curl -fsSL https://get.hy2.sh/) --version ${HY_VERSION}

echo -e "${YELLOW}[6/7] Configuring firewall (ufw)...${NC}"
ufw allow ${LISTEN_PORT}/udp
echo -e "${GREEN}UDP ${LISTEN_PORT} port has been allowed${NC}"

echo -e "${YELLOW}[7/7] Restarting Hysteria service and applying configuration...${NC}"
systemctl stop hysteria-server || true
systemctl start hysteria-server
systemctl enable hysteria-server
sleep 3

if systemctl is-active --quiet hysteria-server; then
    SERVER_IP=$(curl -s ifconfig.me)
    echo -e "\n${GREEN}========================================${NC}"
    echo -e "${GREEN} Hysteria deployment completed successfully!${NC}"
    echo -e "${GREEN}========================================${NC}"
    echo -e "${YELLOW}Service status:${NC}$(systemctl status hysteria-server --no-pager | grep "Active:")"
    echo -e "${YELLOW}Port listening status:${NC}"
    ss -tulnp | grep ":${LISTEN_PORT}" | grep -v grep || echo "  Waiting for port to listen..."

    echo ""
    echo -e "${GREEN}Client connection information:${NC}"
    echo -e "  Server address: ${SERVER_IP}:${LISTEN_PORT}"
    echo -e "  Protocol: Hysteria ${HY_VERSION}"

    echo ""
    echo -e "${YELLOW}Common management commands:${NC}"
    echo -e "  Check status: systemctl status hysteria-server"
    echo -e "  View logs: journalctl -u hysteria-server -f"
    echo -e "  Restart service: systemctl restart hysteria-server"
    echo -e "  Stop service: systemctl stop hysteria-server"
else
    echo -e "${RED}Service failed to start! Check error logs:${NC}"
    journalctl -u hysteria-server -n 20 --no-pager
    exit 1
fi

SSH (Optional)

This makes remote connections from your machine both safer and more convenient. It’s not strictly required, but it’s good practice.

Go to Orchestration → SSH Keys or SSH Keys to add your public key.

1.2 Deploying the Instance

Head over to Vultr’s Deploy page to spin up a new instance.

I went with the cheapest viable plan available: Shared CPU, vc2-1c-0.5gb, New York, US (AMER).

A few quick notes:

  • The cheapest $2.50/month plan does not include an IPv4 address, making it unusable for this setup. The lowest working tier starts at $3.50/month in the New York region.
  • You can uncheck Automatic Backups to shave a bit off the monthly cost.
  • If lower latency matters to you, pick a location geographically closer to you (though European and Asian data centers tend to cost noticeably more than US East).

Stick with the default Debian for the OS image. Under Server Settings, select the Firewall Group, Startup Script, and SSH Key (if configured) that you created earlier. Then click Deploy.

Wait a few minutes for the automated installation to wrap up. Once the dashboard shows the instance status as Running, the server is ready.

2. Clash Verge Configuration

Grab the latest release from the Clash Verge Rev repository on GitHub.

2.1 Creating the Clash Config File

Create a new file named config.yaml on your local machine with the following content:

proxies:
  - name: "VPS-Hysteria2"
    type: hysteria2
    server: Your-VPS-IPv4-Address
    port: 443
    password: "password1234"
    sni: www.bing.com
    skip-cert-verify: true
    up: "20 Mbps"
    down: "50 Mbps"

Note on Routing: If you want split-tunneling (e.g., direct connections for domestic sites and proxies for overseas traffic), check online for standard rule-provider setups. I run in Global mode by default, so I omitted routing rules entirely here.

Update server with your VPS IPv4 address (found in your Vultr dashboard), and set password to whatever you defined in your Startup Script.

2.2 Importing into Clash Verge

In Clash Verge, navigate to Profiles → New → Local → CHOOSE FILE, and select the config.yaml file you just created. Once loaded, activate the profile. You should now see the VPS-Hysteria2 node appear and connect.

3. Creating a Subscription URL via Cloudflare Workers (Optional)

If you use multiple devices and don’t want to manually copy config.yaml every time, you can host it behind a Cloudflare Worker subscription URL (e.g., [https://xxxxx.workers.dev/token](https://xxxxx.workers.dev/token)). Both Clash Verge on desktop and Clash Meta on mobile can subscribe and pull updates directly from this link.

Create a new Worker and paste in this script:

export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    if (url.pathname !== "/" + env.SUB_TOKEN) {
      return new Response("Not Found", {
        status: 404
      });
    }

    const config = `
proxies:
  - name: NewYork-Vultr
    type: hysteria2
    server: ${env.SERVER}
    port: 443
    password: ${env.HY_PASSWORD}
    sni: www.bing.com
    skip-cert-verify: true
    up: "20 Mbps"
    down: "50 Mbps"
`;

    return new Response(config, {
      headers: {
        "Content-Type": "text/yaml; charset=utf-8"
      }
    });
  }
};

(As with the local file, this template skips routing rules—add your own if needed.)

Next, add your environment variables in the Worker’s settings:

KeyValue
SERVERYour VPS IPv4
HY_PASSWORDYour Hysteria password
SUB_TOKENAny secret token of your choice

Once deployed, you can subscribe to it just like any commercial proxy feed. For instance, if your token is dg867dsgjklSH, your subscription URL will be: < https://xxxxx.username.workers.dev/dg867dsgjklSH>.

If you ever migrate to a new region or rebuild the server (changing the IP or password), you only need to update SERVER and HY_PASSWORD inside the Cloudflare Worker settings—no need to rewrite or re-import configuration files across all your devices.

Pros & Limitations

The Pros: Running your own VPS grants you a dedicated, static public IP. Unlike commercial VPNs or shared proxy providers where thousands of people reuse the same pool, you won’t constantly run into bot challenges or rate-limits when accessing AI platforms like ChatGPT, Claude, and Gemini.

The Limitations: You are relying on a single personal server rather than a resilient multi-node network. Speeds may throttle or drop intermittently during peak hours. Network reachability also hinges entirely on the health of your specific IP; if it gets blocked or throttled, you’ll need to redeploy or allocate a new IP in Vultr.

One peculiar quirk with Vultr IPs: self-uploaded books in Google Play Books fail to load properly. The web interface displays the text while completely dropping images, and the mobile app refuses to download user-uploaded books altogether. Inspecting the network requests revealed that user uploads route through a distinct CDN endpoint compared to official store titles. If you rely heavily on Google Play Books for personal uploads, you’ll likely still need a backup proxy on hand.