Skip to content

v3.0.0

Latest

Choose a tag to compare

@dalirnet dalirnet released this 16 Aug 06:00
· 1 commit to main since this release

Client protocols are now VLESS + REALITY and Shadowsocks. HTTP and SOCKS5 are gone.

Upgrading from v2.x

update does not migrate an existing install. It replaces the script and stamps the version; it does not regenerate the config. An existing server keeps its old ports and its HTTP/SOCKS5 inbounds until you run setup again.

./xcp.sh update
./xcp.sh setup gateway    # or: setup edge

Clients on HTTP or SOCKS5 move to VLESS or Shadowsocks — run user ls for the new share URIs. Ports changed, so update your provider firewall:

22, 80, 443, 8443/tcp
8443/udp

VLESS + REALITY

REALITY holds 443 and proxies handshakes from unknown clients to a real site, so an active prober gets a genuine TLS 1.3 answer with that site's own valid certificate chain.

It works from a bare IP — clients reach the server by address, and the SNI carries a domain someone else owns.

One account covers both protocols: Shadowsocks derives its key from the password, and VLESS sends its UUID inside the encrypted handshake. user add prints both URIs and a QR code.

The dest is verified with a real handshake

A dest can answer TLS 1.3 with HTTP/2 and still return a server hello REALITY cannot reuse. When that happens the handshake never completes, every client is dropped before its uuid is read, and the client sees an EOF that reads like bad credentials — while the server log looks clean and an openssl probe of port 443 still shows a valid certificate, because that exercises the fallback path.

Setup and test now run a real VLESS client against the running inbound, which is the only check that catches it:

./xcp.sh test          # reports whether a client completes the handshake
./xcp.sh config dest   # change it without a full re-setup

Default dest is www.bing.com. Also known good: dl.google.com, cdn.jsdelivr.net, www.cloudflare.com.

Ports

Port Purpose
443 VLESS + REALITY
8443 Shadowsocks
80 Answers with the caller's IP
53, 10080, 10085, 11080 Loopback only

Shadowsocks sits on 8443, which reads as alternate HTTPS and stays open on networks that close uncommon ports. HTTP and SOCKS5 were removed because both put credentials on the wire in the clear — on the gateway that meant sending them across a border.

DNS answers on loopback, keeping both servers off the open-resolver abuse lists. Devices where DNS is the only setting available can query it once allowed by address with dns add; ufw enforces the list.

Link stability

  • xray-tunnel sets StartLimitIntervalSec=0, so systemd retries forever. The default limit of 5 starts in 10 seconds would strand the unit whenever the gateway is briefly unreachable at boot.
  • xray-tunnel-health.timer fetches through the tunnel every 60s and restarts after two failures, catching a link that answers keepalives while its throughput has collapsed.
  • BBR, fq and 16 MB socket buffers applied at setup.
  • status reports RTT, jitter and retransmits read from the tunnel socket.

Correctness

Several paths aborted under set -e/pipefail before their own error handlers could report a reason, turning bad input into a silent exit. The port 80 responder is a standalone file run under DynamicUser, and drains the full request so the kernel sends FIN rather than RST. Config rewrites are validated as JSON before replacing the original. A preflight check names the process holding a required port. Client uuids come from the kernel, so adding a user no longer depends on the xray binary being healthy.

Tests grew from 59 to 149.