Skip to content

Preventing traffic theft

VPS traffic is billed or capped, so traffic someone else uses costs you real money. There are two usual ways it gets stolen:

  1. Your server becomes a free relay. REALITY and ShadowTLS forward connections that fail authentication to the camouflage target unchanged. If that target sits behind a CDN such as Cloudflare, anyone can reach the whole CDN through your server, on your bandwidth. A public SOCKS5 without a password is the same story.
  2. A link or subscription leaks. Once a share link or subscription URL is in someone else's hands, they can use your node directly.

Not becoming a free relay

The target is checked before the node is created. When you create a REALITY node (the XHTTP REALITY layer included), PSM performs handshakes against the camouflage target's IP using Cloudflare, Fastly and Akamai names: if it gets a valid certificate for them, the target is a CDN front end shared by many sites, and PSM warns you clearly. The handshake target of mihomo's ShadowTLS gets the same check.

Fallback rate limiting turns on when it matters. When the target is a shared CDN front end, Xray and mihomo REALITY nodes switch on fallback rate limiting: each fallback connection is throttled to 256 KiB/s after its first 1 MiB. This is only a backstop: the limit is per connection, and someone reconnecting in a loop gets around it. The real fix is a camouflage target that is not behind a CDN; how to choose one: Choosing a protocol. sing-box REALITY has no fallback rate limit, so in that case PSM advises putting the node on shared port 443.

On shared port 443, unknown names are dropped. For nodes on shared port 443, Nginx forwards only the names you configured and drops everything else. Nobody can use your server as a springboard to arbitrary names; the only name that can fall back is the one camouflage name you set.

SOCKS5 is never left open. SOCKS5 listens on loopback by default; to open it to the network, PSM requires a username and password. The protocol is plaintext, so a password only stops casual scanners: keep the loopback default where you can.

  • Credentials are random. UUIDs, passwords and keys are generated by PSM; there are no weak passwords.

  • Online subscriptions cannot be guessed. The URL is a path with a 48-character random token, served only over HTTPS, in a directory that cannot be listed, valid for 30 days by default. If you suspect a leak, reset the token in main menu 22 (Subscriptions) and the old link stops working at once. See Subscriptions.

  • Several people? Give each an account. Everyone gets their own credentials and subscription URL, so when something goes wrong you deal with that one person instead of changing everyone's nodes:

    bash
    psm user token NAME              # a new subscription URL; the old one stops working at once
    psm user update NAME --disable   # suspend this person

    See Per-user accounts.

  • A node's credentials leaked? Replace them. Give it a new UUID or password with psm node update, then export the link again:

    bash
    psm node update xray reality my-reality --uuid "$(cat /proc/sys/kernel/random/uuid)"

Spotting unusual traffic

  • Quotas and warnings: give nodes or users a monthly limit, get a Telegram warning at 90%, and a pause when it is used up. A sudden surge in traffic reaches you right away. See Traffic quotas and expiry.
  • Expiry dates on nodes you lend: they stop by themselves.
  • The Telegram daily health report: a daily look at traffic and service status; see Telegram bot.

Checklist

  1. The REALITY camouflage target is not behind a CDN, and no shared-CDN warning appeared when you created the node.
  2. Every node that can go on shared port 443 is on it.
  3. No public SOCKS5 without a password.
  4. Subscriptions go only to people you trust; several people get per-user accounts, one subscription each.
  5. Nodes or users have traffic quotas, with Telegram warnings on.

Released under the AGPL-3.0 license · For lawful use only; follow the laws where you live