vercel-xhttp-relay
Deploy an XHTTP relay on Vercel Edge Functions to proxy Xray/V2Ray traffic and hide your origin server IP behind *.vercel.app
How do I install this agent skill?
npx skills add https://github.com/reason-machines/trending-skills --skill vercel-xhttp-relayIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill provides instructions and code for deploying a Vercel-based relay to proxy Xray/V2Ray traffic. It involves installing official tools and scripts from well-known sources for server setup and TLS certificate management. No malicious behavior or hidden threats were identified.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
Vercel XHTTP Relay
Skill by ara.so — Daily 2026 Skills collection.
A minimal Vercel Edge Function relay that forwards XHTTP traffic from Xray/V2Ray clients to a backend Xray server. Vercel's *.vercel.app domain acts as a CDN front, hiding your origin VPS IP from censors.
Architecture
Client (v2rayN/Hiddify)
→ TLS (SNI=vercel.com) to *.vercel.app
→ Vercel Edge Function (relay, no buffer)
→ HTTP/2 to backend Xray XHTTP inbound
Supported transports: XHTTP only
Not supported on Vercel Edge: WebSocket, gRPC, TCP, mKCP, QUIC, Reality
Prerequisites
- Linux VPS outside Iran (Ubuntu 22.04/24.04 recommended), min 1 vCPU / 1 GB RAM
- A domain with an A record pointing to your VPS (DNS only, not proxied)
- Vercel account (free Hobby tier works for light personal use)
- Node.js + npm installed locally (for Vercel CLI)
- Xray v1.8.16+ installed on VPS
Step 1 — Install Xray on VPS
# Update system
apt update && apt upgrade -y
apt install -y curl socat cron ufw
# Install Xray via official script
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
# Verify version (must be >= 1.8.16)
xray version
# Generate a UUID for your inbound
xray uuid
# Save this UUID — you'll need it in client and server configs
Step 2 — Obtain a TLS Certificate
# Install acme.sh
curl https://get.acme.sh | sh
source ~/.bashrc # or re-login
# Issue certificate (replace with your domain)
~/.acme.sh/acme.sh --issue --standalone -d xray.yourdomain.com
# Install certificate to Xray paths
~/.acme.sh/acme.sh --install-cert -d xray.yourdomain.com \
--key-file /etc/xray/private.key \
--fullchain-file /etc/xray/cert.crt \
--reloadcmd "systemctl restart xray"
Step 3 — Xray Server Config (XHTTP Inbound)
/etc/xray/config.json:
{
"log": { "loglevel": "warning" },
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "$YOUR_UUID",
"flow": ""
}
],
"decryption": "none"
},
"streamSettings": {
"network": "xhttp",
"security": "tls",
"tlsSettings": {
"certificates": [
{
"certificateFile": "/etc/xray/cert.crt",
"keyFile": "/etc/xray/private.key"
}
]
},
"xhttpSettings": {
"path": "/your-secret-path",
"mode": "auto"
}
}
}
],
"outbounds": [
{ "protocol": "freedom", "tag": "direct" }
]
}
# Apply and start
systemctl restart xray
systemctl enable xray
systemctl status xray
Step 4 — The Vercel Edge Relay (api/proxy.js)
The relay function streams request bodies and responses without buffering:
// api/proxy.js — Vercel Edge Function
export const config = { runtime: 'edge' };
const BACKEND = process.env.XRAY_BACKEND_URL;
// e.g. https://xray.yourdomain.com:443/your-secret-path
export default async function handler(req) {
if (!BACKEND) {
return new Response('Backend not configured', { status: 500 });
}
const url = new URL(req.url);
const targetUrl = BACKEND + url.pathname.replace(/^\/proxy/, '') + url.search;
// Forward all headers except host
const headers = new Headers();
for (const [key, value] of req.headers.entries()) {
if (key.toLowerCase() !== 'host') {
headers.set(key, value);
}
}
try {
const response = await fetch(targetUrl, {
method: req.method,
headers,
body: req.method !== 'GET' && req.method !== 'HEAD' ? req.body : undefined,
// @ts-ignore — duplex required for streaming body
duplex: 'half',
});
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: response.headers,
});
} catch (err) {
return new Response(`Relay error: ${err.message}`, { status: 502 });
}
}
Step 5 — vercel.json
{
"rewrites": [
{ "source": "/(.*)", "destination": "/api/proxy" }
]
}
Step 6 — package.json (minimal)
{
"name": "vercel-xhttp-relay",
"version": "1.0.0",
"private": true
}
Step 7 — Deploy to Vercel
Via CLI
# Install Vercel CLI
npm i -g vercel
# Login
vercel login
# Deploy (from project root)
vercel
# Set the backend environment variable
vercel env add XRAY_BACKEND_URL
# Enter: https://xray.yourdomain.com:443/your-secret-path
# Redeploy with env var active
vercel --prod
Via Dashboard (no CLI needed)
- Push repo to GitHub
- Go to vercel.com/new → Import repo
- Settings → Environment Variables → add
XRAY_BACKEND_URL - Deploy
Your relay URL will be: https://your-project.vercel.app
Step 8 — Client Configuration (v2rayN / Hiddify)
| Field | Value |
|---|---|
| Protocol | VLESS |
| Address | your-project.vercel.app |
| Port | 443 |
| UUID | $YOUR_UUID (from xray uuid) |
| Transport | XHTTP |
| Path | /your-secret-path |
| TLS | TLS |
| SNI | vercel.com |
| Fingerprint | chrome |
| Flow | (empty) |
VLESS link format:
vless://$YOUR_UUID@your-project.vercel.app:443?encryption=none&security=tls&sni=vercel.com&fp=chrome&type=xhttp&path=%2Fyour-secret-path#MyVercelRelay
Project File Structure
vercel-xhttp-relay/
├── api/
│ └── proxy.js # Edge Function relay
├── vercel.json # Rewrite rules
└── package.json
Environment Variables
| Variable | Description | Example |
|---|---|---|
XRAY_BACKEND_URL | Full URL to your Xray XHTTP inbound | https://xray.yourdomain.com:443/secret-path |
Set via CLI:
vercel env add XRAY_BACKEND_URL production
vercel env add XRAY_BACKEND_URL preview
Or in vercel.json for non-secret config (not recommended for backend URLs):
{
"env": {
"XRAY_BACKEND_URL": "@xray-backend-url"
}
}
Firewall Setup on VPS
# Allow SSH, XHTTP port
ufw allow 22/tcp
ufw allow 443/tcp
ufw enable
ufw status
Common Patterns
Multiple Vercel Projects for Failover
Deploy the same relay to multiple Vercel accounts and configure load balance in v2rayN:
// v2rayN outbound balancer (simplified concept)
{
"tag": "balancer",
"selector": ["relay1", "relay2", "relay3"]
}
Check Vercel Usage
vercel billing
# Or monitor at: https://vercel.com/dashboard → Usage tab
Redeploy After Config Change
vercel --prod
View Logs
vercel logs your-project.vercel.app --follow
Troubleshooting
502 Bad Gateway from Vercel
# Check Xray is running
systemctl status xray
# Check Xray logs
journalctl -u xray -f
# Verify port 443 is open
ufw status
ss -tlnp | grep 443
# Test backend directly (from your local machine, not Iran)
curl -v https://xray.yourdomain.com:443/your-secret-path
DNS Not Resolving
# Mac/Linux
dig @8.8.8.8 xray.yourdomain.com +short
# Windows PowerShell
Resolve-DnsName xray.yourdomain.com -Server 8.8.8.8 -Type A
DNS record must be DNS only (grey cloud in Cloudflare), not proxied.
TLS Certificate Issues
# Check cert expiry
~/.acme.sh/acme.sh --list
# Renew manually
~/.acme.sh/acme.sh --renew -d xray.yourdomain.com --force
# Verify cert is valid
openssl x509 -in /etc/xray/cert.crt -noout -dates
Xray Config Validation
xray run -test -c /etc/xray/config.json
# Should output: Configuration OK
Client Can't Connect
- Confirm SNI is set to
vercel.com, not your project domain - Confirm transport is
xhttp(notws,grpc, etc.) - Confirm path matches exactly between server config and client
- Check UUID matches exactly
Vercel Account Paused (Hobby Bandwidth Exceeded)
Hobby plan counts bandwidth twice (client↔Vercel + Vercel↔origin). To avoid:
- Exclude 4K video and large downloads from the proxy
- Use multiple Hobby accounts with failover
- Upgrade to Pro ($20/month) and set Spend Management limits
Vercel Hobby Plan Limits (Reference)
| Resource | Limit |
|---|---|
| Edge Function invocations | 500,000 / month |
| Fast Origin Transfer | 10 GB / month (counts both directions) |
| Bandwidth (to client) | 100 GB / month |
| Edge Function duration | 30 seconds max per request |
Monitor at Vercel Dashboard → Usage. Vercel sends email alerts at 80% and 100%.
Key Commands Cheatsheet
# VPS: install/manage Xray
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
xray uuid
xray version
xray run -test -c /etc/xray/config.json
systemctl restart xray && systemctl status xray
journalctl -u xray -f
# Local: Vercel CLI
npm i -g vercel
vercel login
vercel # deploy preview
vercel --prod # deploy production
vercel env add XRAY_BACKEND_URL
vercel logs your-project.vercel.app --follow
vercel billing
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/reason-machines/trending-skills/vercel-xhttp-relay">View vercel-xhttp-relay on skillZs</a>