Mobile Proxies US logo
Guide

VLESS Config for Headless Automation: xray on a Server

Published

A Mobile Proxies US line on a VLESS-enabled server can be reached over VLESS as well as plain HTTP(S) and SOCKS5; vless_link in GET /proxies/my holds the share line and is null when the server does not offer it. For a server running scripts, the useful arrangement is xray-core as a local gateway: it holds the VLESS credentials, keeps one encrypted tunnel to the line, and exposes 127.0.0.1:1080 (SOCKS5) and 127.0.0.1:1081 (HTTP) with no authentication. Scripts, Playwright and curl then point at localhost and never see a password. This page gives the install, the config, a systemd unit and the checks.

Why a local gateway instead of direct proxy auth

Three reasons. Chromium does not support authenticated SOCKS5, so a local unauthenticated port is the only way to give a headless browser SOCKS semantics. Credentials live in one file with one owner instead of in every script's environment. And the tunnel is encrypted and looks like ordinary TLS to anything between your server and the line, which matters on shared hosting and some corporate networks.

The cost is one more process to run. xray is a single static binary with a JSON config, so the cost is small. One xray instance can carry several lines on separate local ports, which is covered at the end.

Install xray-core

Use the official install script or your package manager. The script places the binary in /usr/local/bin and a systemd unit that reads /usr/local/etc/xray/config.json. Verify the version prints, then replace the config.

# Debian/Ubuntu, official installer
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
xray version
# config lives here
ls /usr/local/etc/xray/config.json

Get the VLESS parameters

Read vless_link from GET /proxies/my, or copy the vless:// link from the line's page in the dashboard at cp.mobileproxiesus.com. It encodes the host, port, your UUID, the transport, the security mode and the SNI. You can import the link into a client to test on a laptop, but for xray on a server you will place the same values into the outbound block by hand. The fields map one to one: address, port, id, network, security, serverName, flow, and for REALITY the publicKey (pbk) and shortId (sid).

The link is per line and it is the credential itself, so treat the config file like a secret: owned by root, mode 600.

The config: two local inbounds, one VLESS outbound

Inbounds listen only on 127.0.0.1. The SOCKS inbound enables UDP so QUIC and DNS over the tunnel work. The outbound is the line. Routing sends everything from both inbounds to that outbound; DNS is resolved on the far side by default because the SOCKS inbound passes hostnames through.

Placeholders in capitals come from the vless:// link. If the link says security=tls instead of reality, drop the realitySettings block and use tlsSettings with the serverName.

{
  "log": {"loglevel": "warning"},
  "inbounds": [
    {"tag": "socks-in", "listen": "127.0.0.1", "port": 1080, "protocol": "socks",
     "settings": {"auth": "noauth", "udp": true}},
    {"tag": "http-in", "listen": "127.0.0.1", "port": 1081, "protocol": "http"}
  ],
  "outbounds": [
    {"tag": "line", "protocol": "vless",
     "settings": {"vnext": [{"address": "HOST", "port": PORT,
       "users": [{"id": "UUID", "encryption": "none", "flow": "xtls-rprx-vision"}]}]},
     "streamSettings": {"network": "tcp", "security": "reality",
       "realitySettings": {"serverName": "SNI", "fingerprint": "chrome",
                            "publicKey": "PBK", "shortId": "SID"}}}
  ],
  "routing": {"rules": [
    {"type": "field", "inboundTag": ["socks-in", "http-in"], "outboundTag": "line"}
  ]}
}

Run it as a service and verify

Enable the unit so the gateway comes up at boot before your schedulers do. Then check from the box: an echo through the SOCKS port and one through the HTTP port should both print a carrier address, and a lookup of that address should show AT&T, T-Mobile or Verizon. Compare with ip from GET /proxy/status for the line; they should match.

If the echo prints your server's own address, the inbound is reachable but routing is not sending to the outbound; check the tags. If the connection fails outright, the SNI, publicKey or shortId is wrong; re-copy from the link.

sudo chmod 600 /usr/local/etc/xray/config.json
sudo systemctl enable --now xray
sudo systemctl status xray --no-pager
curl -s -x socks5h://127.0.0.1:1080 https://api.ipify.org
curl -s -x http://127.0.0.1:1081 https://api.ipify.org
# compare with the API
curl -s "https://cp.mobileproxiesus.com/backend/api_v1/proxy/status?license=$UUID" | jq -r .ip

Using it from scripts and browsers

Scripts: requests with proxies set to socks5h://127.0.0.1:1080, or curl -x. Playwright: proxy server socks5://127.0.0.1:1080 with no username or password, which Chromium accepts because there is no auth. Scrapy: the HTTP port on 1081 through the standard HttpProxyMiddleware. Nothing in the application layer knows the line's credentials.

Rotation is unchanged: GET the line's rotation_link. The tunnel survives the rotation; connections inside it are reset while the modem re-attaches, then traffic resumes on the new address. Confirm the new exit through the local port before continuing, exactly as with direct proxy auth.

from playwright.sync_api import sync_playwright
with sync_playwright() as p:
    b = p.chromium.launch(proxy={"server": "socks5://127.0.0.1:1080"})
    page = b.new_page(); page.goto("https://api.ipify.org"); print(page.inner_text("body"))

Several lines in one xray

Add an inbound pair per line on different ports (1080/1081, 1090/1091, and so on), an outbound per line with its own VLESS parameters, and a routing rule mapping each inbound tag to its outbound tag. Scripts pick a line by picking a local port. Keep the mapping in the same place you keep licence uuids from the API; after a free move to another metro, read the line's vless_link again, update that line's outbound and restart xray.

On a server this is the arrangement that scales cleanly: one gateway process, one config file under version control with secrets templated in at deploy time, and every consumer talking to localhost.

Frequently asked

Does VLESS cost extra?

No. VLESS is included wherever the line's server offers it. The vless:// link is on the line's page in the dashboard and in vless_link, which is null when the server does not offer it.

Do I still need the proxy username and password?

Not for the tunnel. The VLESS UUID authenticates it. The username and password remain valid for direct HTTP and SOCKS5 use.

Does rotation work through the tunnel?

Yes. Rotate with the rotation link as usual; connections inside the tunnel reset during re-attach and resume on the new address.

Can one xray carry lines in different metros?

Yes. One outbound per line, one local port pair per line, one routing rule each. Scripts choose the metro by choosing the port.

USA mobile proxies on hardware we own

Real 4G and 5G carrier exit IPs, eight US metros; unlimited rotation, sticky sessions, HTTP(S) or SOCKS5. An endpoint costs $2 for the first two hours or $5 per day; paid hours are credited against the day.

View plans See all locations