fix(sockopt): honor trustedXForwardedFor on gRPC inbounds (xray v26.6.22) (#5503)

* fix(sockopt): honor trustedXForwardedFor on gRPC inbounds

xray-core v26.6.22 (commit 711aea4) switched the gRPC server from reading
the x-real-ip gRPC metadata to resolving the client IP from X-Forwarded-For
via sockopt.trustedXForwardedFor, matching ws/httpupgrade/xhttp.

The panel already exposed the trustedXForwardedFor field and wire output, but
the per-transport gate (TRUSTED_HEADER_NETWORKS) still omitted grpc. On a gRPC
inbound this raised a false "transport does not honor this header" warning and
mis-flagged the Cloudflare real-client-IP preset. Add grpc to the gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(i18n): note gRPC in trustedXForwardedFor hint (all locales)

Follow-up to the gRPC gate fix: the trustedXForwardedForHint tooltip across
all 13 locales said the header is honored "only on WebSocket, HTTPUpgrade and
XHTTP". xray-core v26.6.22 added gRPC, so list it too.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rouzbeh†
2026-06-23 14:55:12 +02:00
committed by GitHub
parent 1c0b76c27a
commit a0f4c13dc5
14 changed files with 19 additions and 17 deletions
@@ -11,8 +11,10 @@ const TRANSPORT_PROXY_FIELD: Record<string, string> = {
ws: 'wsSettings',
httpupgrade: 'httpupgradeSettings',
};
// Transports on which xray-core honors sockopt.trustedXForwardedFor.
const TRUSTED_HEADER_NETWORKS = ['ws', 'httpupgrade', 'xhttp'];
// Transports on which xray-core honors sockopt.trustedXForwardedFor. gRPC joined
// in v26.6.22 (xray-core 711aea4): it now reads X-Forwarded-For via this option
// instead of the old x-real-ip gRPC metadata.
const TRUSTED_HEADER_NETWORKS = ['ws', 'httpupgrade', 'xhttp', 'grpc'];
type RealClientIpPreset = 'off' | 'cloudflare' | 'proxy';
@@ -27,7 +29,7 @@ export default function SockoptForm({
// Presets write the same sockopt fields the user could set by hand below,
// picking the mechanism xray-core actually honors for the chosen transport:
// CF-Connecting-IP via trustedXForwardedFor (ws/httpupgrade/xhttp) or the
// CF-Connecting-IP via trustedXForwardedFor (ws/httpupgrade/xhttp/grpc) or the
// PROXY-protocol header via acceptProxyProtocol (every transport but mKCP).
const applyRealClientIpPreset = (
preset: RealClientIpPreset,
@@ -60,7 +62,7 @@ export default function SockoptForm({
}
// proxy — clear trustedXForwardedFor so a lingering header can't override the
// PROXY-recovered IP (xray reads the header last on ws/httpupgrade/xhttp).
// PROXY-recovered IP (xray reads the header last on ws/httpupgrade/xhttp/grpc).
setFieldValue(['streamSettings', 'sockopt', 'trustedXForwardedFor'], []);
setFieldValue(['streamSettings', 'sockopt', 'acceptProxyProtocol'], true);
if (transportField) setFieldValue(['streamSettings', transportField, 'acceptProxyProtocol'], true);