Post-quantum REALITY, faster XHTTP through CDNs, and a protocol cleanup
Everything below is merged into the dev branch but is not in a release or prerelease yet. dev is no longer packaged as Prerelease-dev, so for now the only way to try it is to build the core from source on the dev branch.
Post-quantum REALITY (#8, #10)
Since Xray 26.9.8, a REALITY server silently drops any ClientHello without an X25519MLKEM768 key share placed before X25519, so earlier Citrus could not connect to current Xray servers.
Client (reality-opts)
- X25519MLKEM768 is on by default.
support-x25519mlkem768: falsesends the classical hello for old servers. Fingerprints without ML-KEM (ios, edge, randomized and others) get the key share added. client-version: the Xray version the client reports to the server. Defaults to26.10.10, instead of the hard-coded1.8.2, so servers withminClientVeraccept it.mldsa65-verify: checks the ML-DSA-65 signature in the temporary certificate, like Xray’smldsa65Verify(pqvin share links).client-fingerprint: firefoxandsafarinow send the real Firefox 148 and Safari 26.3 hellos from our getmikan/utls fork. Xray names such ashellofirefox_148,hellosafari_26_3andhellochrome_131are accepted too.
proxies: - name: vless-reality-vision type: vless server: server port: 443 uuid: uuid network: tcp tls: true flow: xtls-rprx-vision servername: www.microsoft.com client-fingerprint: chrome reality-opts: public-key: xxx short-id: xxx # support-x25519mlkem768: true # default; false only for old servers # client-version: 26.10.10 # default # mldsa65-verify: xxx # ML-DSA-65 public key (pqv)Server (reality-config on inbounds)
mldsa65-seed: signs the temporary certificate with ML-DSA-65, like Xray’smldsa65Seed. Thedestcertificate chain must be at least about 3.5 KB, or the signature does not fit and the handshake fails. Xray has the same limit.require-x25519mlkem768: only accept clients with X25519MLKEM768; the rest fall back todest.min-client-verandmax-client-ver: the accepted range of client versions.
listeners: - name: vless-in type: vless port: 443 users: - username: 1 uuid: uuid flow: xtls-rprx-vision reality-config: dest: test.com:443 private-key: xxx # citrus generate reality-keypair short-id: - 0123456789abcdef server-names: - test.com # max-time-difference: 60000 # milliseconds # mldsa65-seed: xxx # xray mldsa65 # require-x25519mlkem768: true # min-client-ver: 26.9.8 # max-client-ver: 26.10.10Live-tested against Xray 26.10.10 (VLESS + Vision + REALITY) in both directions, a Citrus client to an Xray server and an Xray client to a Citrus server, with and without ML-DSA-65. A wrong key is rejected.
Behaviour change. max-time-difference is now in milliseconds, like Xray’s maxTimeDiff. It used to be read as microseconds, so a value copied from an Xray config allowed 1000 times less clock skew. If you tuned the value for the old unit, divide it by 1000.
Every key is described in the config reference.
XHTTP through CDNs (#9)
- In
packet-upmode the next POST no longer waits for the previous response, as in Xray. Through a CDN each POST used to cost a full client → CDN → origin round trip, so upload was bound by latency. In a live test against Xray 26.10.10 a packet-up request took 0.4 s instead of 5.4 s. Over HTTP/1.1 responses are still awaited. x-padding-bytes: "0-0"now means Xray’s default padding (100–1000 bytes) instead of none.- A
pathwith a query, such as/xh?ed=2048, is sent as a path and a query, as in Xray, instead of an escaped%3Finside the path.
Legacy protocols removed (#7)
ShadowsocksR, Hysteria v1, TUIC v4, Shadowsocks stream ciphers (rc4-md5, aes-ctr/cfb, chacha20 and others) and v2ray-plugin are gone. Shadowsocks accepts only none, AEAD and 2022-blake3-*. VMess stays for now.
- In a proxy provider such a node is skipped with a warning, and the rest of the subscription loads.
- In the main config it is an error with a clear message, for example “TUIC v4 is no longer supported, use uuid/password (v5)”.
Rejected-auth journal (#5)
The component/authevent package reports failed logins on TrustTunnel, REALITY, AnyTLS, VLESS, Trojan, TUIC v5, Hysteria2 and Sudoku inbounds: protocol, addresses and reason, never credentials. It is the core side of a journal of rejected requests in the panel. Events go through a queue and never slow down the handshake.
Data races in Vision and AnyTLS (#11)
Fixed the data races go test -race found in the XTLS Vision filter and reader and in the AnyTLS stream. After the first packets, the Vision hot path costs one atomic load.
