Skip to content

rqzbeh/netlify-cdn-worker

Repository files navigation

netlify-cdn-worker

Use Netlify's global edge network as a CDN-fronting / reverse-proxy layer in front of your VPS — similar to how Cloudflare Workers or gCore are used to hide an Xray / 3x-ui server from Deep Packet Inspection (DPI).

[Xray Client]  ──TLS──►  [Netlify Edge Function]  ──►  [Your VPS / 3x-ui]
                              (this repo)

Netlify Edge Functions run on Deno at the edge. This worker accepts every incoming request and forwards it to your backend, preserving the full request path, headers, and body. It therefore acts as a transparent reverse proxy that supports all the transports Xray Core uses.


Supported transports

Transport Works? Notes
WebSocket (ws / wss) Full bidirectional proxying with message queuing
xHTTP / SplitHTTP Chunked-streaming POST + GET forwarded as-is
gRPC-web application/grpc-web* content-type proxied over HTTP/1.1
HTTP Upgrade Upgrade: websocket is handled natively; other Upgrade values are forwarded as regular HTTP headers
Native gRPC (HTTP/2) ⚠️ Netlify's edge may downgrade to HTTP/1.1; use gRPC-web in the Xray config instead
QUIC / UDP Not available on edge functions

Quick start

1 — Fork & deploy to Netlify

Deploy to Netlify

Or manually:

  1. Fork this repository.
  2. Go to https://app.netlify.comAdd new site → Import an existing project.
  3. Connect your fork. No build command is required.
  4. Netlify auto-deploys the edge function on every push.

2 — Set environment variables

In the Netlify dashboard go to Site settings → Environment variables and add:

Variable Required Description
TARGET_HOST Yes VPS hostname or IP, e.g. 1.2.3.4
TARGET_PORT No Backend port (default 443)
TARGET_HTTPS No true (default) or false — whether to use TLS when connecting to the backend

Tip: set TARGET_HTTPS=false and TARGET_PORT=<port> when Xray listens on a plain HTTP/WS port and Netlify terminates TLS for the client.

After saving the variables, trigger a new deploy (or use Deploys → Trigger deploy).

3 — Configure your Xray inbound (3x-ui)

The Netlify site URL becomes the CDN front for your server. The proxy forwards the full path unchanged, so the Xray inbound path must match what the client connects to.

WebSocket example

{
  "inbounds": [{
    "protocol": "vmess",
    "settings": { "clients": [{ "id": "YOUR-UUID" }] },
    "streamSettings": {
      "network": "ws",
      "wsSettings": { "path": "/ws" },
      "security": "none"
    }
  }]
}

Client-side Xray config:

{
  "outbounds": [{
    "protocol": "vmess",
    "settings": {
      "vnext": [{
        "address": "YOUR-APP.netlify.app",
        "port": 443,
        "users": [{ "id": "YOUR-UUID", "alterId": 0 }]
      }]
    },
    "streamSettings": {
      "network": "ws",
      "security": "tls",
      "tlsSettings": { "serverName": "YOUR-APP.netlify.app" },
      "wsSettings": { "path": "/ws" }
    }
  }]
}

xHTTP / SplitHTTP example

"streamSettings": {
  "network": "xhttp",
  "xhttpSettings": { "path": "/xhttp", "mode": "auto" },
  "security": "none"
}

Client points to YOUR-APP.netlify.app:443 with TLS + path /xhttp.

gRPC-web example

Set grpcSettings.serviceName to any string and enable multiMode: false. Point the client at YOUR-APP.netlify.app:443.


How it works

The edge function (netlify/edge-functions/proxy.ts) runs at every Netlify PoP worldwide. It:

  1. Reads TARGET_HOST, TARGET_PORT, and TARGET_HTTPS from environment variables.
  2. For requests with Upgrade: websocket — performs a Deno native WebSocket upgrade, opens a WebSocket to the backend, and bridges both sockets bidirectionally (with a message queue so no data is lost during connection setup).
  3. For all other requests (HTTP, gRPC-web, xHTTP chunked streams, …) — uses fetch() with a streaming body/response so data flows without buffering.
  4. Strips hop-by-hop headers (per RFC 7230) in both directions.

Local development

npm install -g netlify-cli   # if not already installed
cp .env.example .env         # fill in TARGET_HOST etc.
netlify dev                  # starts a local edge-function dev server

Security notes

  • TARGET_HOST is the only backend this proxy will connect to. It is not an open proxy.
  • Always keep TARGET_HOST private; do not commit it to version control.
  • The VPS should enforce its own authentication (UUID / password in the Xray config).
  • For extra obfuscation, set a non-obvious path (e.g. /a1b2c3d4) in both the Xray server and client configs.

About

use netlify as cdn

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors