Sign inSign up

killdns/xray-socks5-router

By killdns

โ€ขUpdated about 2 months ago

Multi-platform L3 Xray gateway with routed TCP/UDP/DNS transit and a SOCKS5 frontend.

Image
0

1.3K

killdns/xray-socks5-router repository overview

โ Xray SOCKS5 Router

GitHub source and full documentationโ  ยท Russian documentationโ 

A multi-platform Docker image that provides an L3 gateway for routed IPv4 traffic through Xray and a HevSocks5Server frontend with TCP CONNECT and UDP ASSOCIATE.

Platforms: linux/amd64 (x86_64), linux/arm64 (AArch64), and linux/arm/v7 (32-bit ARMv7, including compatible MikroTik devices).

โ Routing modes

ModeTypical hostRequirement
tproxyStandard Linux Dockerworking iptables/nftables TPROXY
tunRouterOS containers or Linux/dev/net/tun, NET_ADMIN, policy routing

tproxy is the default. tun avoids netfilter interception and is intended for RouterOS kernels that do not expose the TPROXY target to containers.

This is an L3 next hop, not an L2 bridge. Route selected networks or a policy table to the container IP. It does not bridge VLANs, Ethernet frames, broadcast domains, or Docker networks.

routed client/network
        |
        | iif policy rule -> table 100
        v
xray0 (Xray TUN inbound) -> Xray outbound

container-local process except Xray
        |
        | inverted Xray-UID rule -> table 100
        v
xray0 -> Xray outbound

SOCKS5 client -> HevSocks5Server :1080
        |
        | process-UID policy rule -> table 200
        v
xray0 -> Xray outbound

Xray runs under a dedicated UID with only ambient CAP_NET_ADMIN. All other container-local traffic enters TUN, while Xray's own upstream sockets keep using the main table to avoid a loop.

In tproxy mode, SOCKS traffic instead re-enters Xray through an internal VRF/veth loop and the TPROXY inbound. That loop is not a VLAN or Docker network, and TUN mode does not create it.

โ Quick start

docker pull killdns/xray-socks5-router:0.3.0

TUN example:

services:
  gateway:
    image: killdns/xray-socks5-router:0.3.0
    cap_add: [NET_ADMIN, NET_RAW]
    devices:
      - /dev/net/tun:/dev/net/tun
    sysctls:
      net.ipv4.ip_forward: "1"
      net.ipv4.conf.all.rp_filter: "0"
      net.ipv4.conf.default.rp_filter: "0"
    environment:
      VLESS_URI: ${VLESS_URI}
      ROUTING_MODE: tun
      SOCKS_ALLOW_NO_AUTH: "1"

On RouterOS, set ROUTING_MODE=tun in the envlist and confirm that the container sees /dev/net/tun.

โ Connection configuration

Set VLESS_URI to generate an ephemeral Xray configuration automatically at container startup. The selected routing-mode and TUN/TPROXY environment values are applied to the generated config. VLESS_URI takes precedence when a mounted XRAY_CONFIG is also present.

The URI is passed to the embedded generator through stdin, is not logged, and is removed from Xray's child-process environment. It is still visible to Docker administrators through container inspection and remains stored in a RouterOS envlist. Use a read-only mounted config.json instead when that exposure is not acceptable.

RouterOS example:

/container/envs/add list=xray-router key=VLESS_URI value="vless://..."
/container/envs/add list=xray-router key=ROUTING_MODE value=tun

The host-side generator remains available when a file is preferred.

The GitHub repository includes a Python 3.10+ generator for one vless:// URI:

python3 tools/vless_to_config.py \
  --uri-file ./vless-link.txt \
  --routing-mode tun \
  --tun-interface xray0 \
  --tun-mtu 1400 \
  --output ./config/config.json

Use --routing-mode tproxy for TPROXY. With ROUTING_MODE=tun, the entrypoint can also convert an existing TPROXY dokodemo-door inbound to an ephemeral TUN config under /run; the mounted file remains unchanged.

Never commit the URI or generated configuration.

โ Environment reference

VariableDefaultPurpose
XRAY_CONFIG/etc/xray/config.jsonMounted Xray configuration
VLESS_URIemptyGenerate an ephemeral config from one VLESS share URI; takes precedence over XRAY_CONFIG
ROUTING_MODEtproxytproxy or tun
INBOUND_INTERFACEautoInterface receiving routed traffic
INBOUND_GATEWAYemptyNext hop for RETURN_CIDRS
OUTBOUND_INTERFACEdefault routeUnderlay/uplink interface
OUTBOUND_GATEWAYdefault gatewayUnderlay gateway
RETURN_CIDRSemptyClient networks returned through the inbound gateway
LOCAL_BYPASS_CIDRSprivate/reserved IPv4Destinations routed directly
TUN_INTERFACExray0Xray TUN interface name
TUN_GATEWAY198.18.0.1/30Address used during automatic conversion
TUN_MTU1400MTU used during automatic conversion
TUN_TABLE100Policy table for routed traffic
TUN_PRIORITY1000Inbound-interface rule priority; above 200 on RouterOS
TUN_SOCKS_PRIORITY900Hev UID rule priority; above 200 on RouterOS
TUN_LOCAL_PRIORITY950Route container-local traffic except Xray through TUN
TPROXY_PORT12345TPROXY inbound port
TPROXY_MARK0x1/0x1TPROXY packet mark
ENABLE_SOCKS1Start HevSocks5Server
SOCKS_BIND0.0.0.0TCP and UDP listen address
SOCKS_PORT1080SOCKS5 TCP port
SOCKS_USER / SOCKS_PASSWORDemptyCredentials; set both together
SOCKS_ALLOW_NO_AUTH0Must be 1 to run without credentials
SOCKS_DNS_SERVER1.1.1.1Container resolver
SOCKS_LOG_LEVELwarndebug, info, warn, or error
SOCKS_UDP_PORT_MIN / MAX20000 / 20999UDP relay range
SOCKS_UDP_ADVERTISE_IPemptyClient-reachable UDP relay IPv4

Without credentials, startup fails unless SOCKS_ALLOW_NO_AUTH=1 is explicitly set. Never expose unauthenticated SOCKS to an untrusted network.

The image requires NET_ADMIN and NET_RAW, not privileged mode. Mount the Xray config read-only. TUN is fail-closed for traffic selected by its policy table. This release configures IPv4 transit routing; IPv6 transit is out of scope.

See the GitHub READMEโ  for full examples, tests, source code, and upstream links.

Tag summary

Content type

Image

Digest

sha256:790b1ef4fโ€ฆ

Size

34.8 MB

Last updated

about 2 months ago

docker pull killdns/xray-socks5-router