Quick chapter this time. Two maintenance fixes and the mobile client setup I've been putting off.

Fix 1: The "nobody" Warning

The Xray service was running as the nobody user, which systemd flagged on every startup:

Special user nobody configured, this is not safe!

Running services as nobody is a bad practice: if multiple services all run as nobody, they can potentially access each other's resources. The fix is giving Xray its own dedicated user, same principle as the deploy user from Chapter 6.

sudo useradd -r -s /usr/sbin/nologin -d /nonexistent xray

Updated the service file to use User=xray instead of User=nobody. Warning gone. Each service runs in its own sandbox.

Fix 2: WebSocket → XHTTP Migration

Xray was also throwing a deprecation warning:

The feature WebSocket transport (with ALPN http/1.1, etc.) is deprecated, 
not recommended for using and might be removed. 
Please migrate to XHTTP H2 & H3 as soon as possible.

WebSocket was the original transport for V2Ray, it works, but it's old. XHTTP is the modern replacement: same concept (tunnel traffic over HTTP), better performance, and actively maintained. The migration was straightforward.

On the server, in /usr/local/etc/xray/config.json:

// Before
"streamSettings": {
    "network": "ws",
    "wsSettings": {
        "path": "/v2ray"
    }
}

// After
"streamSettings": {
    "network": "xhttp",
    "xhttpSettings": {
        "path": "/v2ray"
    }
}

Same change on every client. The Nginx proxy config stays the same, XHTTP is backwards compatible through HTTP upgrade, so the same location /v2ray block handles it.

One gotcha: I initially changed network to xhttp on the client but forgot to rename wsSettings to xhttpSettings. Xray started fine but silently ignored the settings, the SOCKS proxy never bound to its port. No error, no warning, just... nothing listening. Took a few minutes of confused ss -tlnp to figure out.

"The most dangerous bugs are the ones that don't produce errors."

Mobile Client: v2rayNG

With the server properly configured, setting up mobile access was actually the easiest thing I've done in this entire series.

The Share Link

Xray uses a standardized URL format for sharing configs. Generated one on the server:

vless://[UUID]@mosearc.eu:443?type=xhttp&security=tls&sni=mosearc.eu&path=%2Fv2ray&encryption=none#HomeServer

Then turned it into a QR code:

sudo apt install qrencode
echo -n "vless://[UUID]@..." | qrencode -o /tmp/v2ray-qr.png

Pulled the image to my computer, opened it, and scanned it with my phone. Deleted the QR code from the server afterward don't want the UUID sitting in /tmp as an image.

Android Setup

Downloaded v2rayNG from GitHub (not Play Store, the GitHub release is more up to date). Installed the APK, opened the app, scanned the QR code. One tap to connect.

That's it. No manual config entry, no certificate files, no debugging. Scan, tap, connected. My phone now routes all traffic through my home server, same DPI bypass as the desktop, but from my pocket.

For iOS, V2Box (free) or Streisand (free) do the same thing import via QR code or paste the share link.

What This Enables

With v2rayNG on my phone, I can now:

  • Browse through my home connection from anywhere: privacy on public Wi-Fi
  • Bypass restrictive networks (university, hotels, airports) from my phone
  • Access my home network services (SSH via Termux, local devices)
  • Appear to be in Italy when abroad, useful for Italian-only streaming services

And because it goes through Cloudflare → my website → Xray, the traffic looks like someone visiting a portfolio website. Even on mobile.


What's Next

  • Replace the disk with an SSD (URGENT)
  • UPS
  • Containerization with Docker
  • Self-hosted drive with NAS
  • VPS reverse proxy
  • Mail server
  • Local LLM