GL.iNet Flint 3 + Slate 7 Pro: Self-Hosted VLESS REALITY with OpenClash
Overview
Affiliate disclosure: This post may contain affiliate links. If you purchase through those links, Tech Relay may earn a commission at no additional cost to you.
Overview
This guide walks through a complete end-to-end setup:
- Install OpenClash on a GL.iNet Slate 7 Pro.
- Install and configure Xray on a GL.iNet Flint 3.
- Build a VLESS REALITY tunnel using XTLS Vision.
- Configure OpenClash/Mihomo on the Slate 7 Pro.
- Route all Slate-connected client devices through the Flint 3 at home.
The goal is to turn the Slate 7 Pro or Slate 7 into a travel router that tunnels connected devices back through the Flint 3 without using a traditional WireGuard/OpenVPN-style tunnel.
The finished path looks like this:
1Phone / Laptop / Tablet
2 ↓
3GL.iNet Slate 7 Pro or Slate 7
4 ↓
5OpenClash / Mihomo Meta
6 ↓
7VLESS + REALITY + XTLS Vision
8 ↓
9GL.iNet Flint 3
10 ↓
11Home Internet Connection
Hardware Used
GL.iNet Flint 3 / GL-BE9300
The Flint 3 is the home-side endpoint. It runs the Xray server and accepts inbound VLESS REALITY connections.
Affiliate link:
https://amzn.to/4fhCJaf
GL.iNet Slate 7 Pro / GL-BE10000
The Slate 7 Pro is the travel-side router. It runs OpenClash and transparently tunnels connected client devices back through the Flint 3.
(Not available in the US yet so no Affiliate link, if you want to buy it in the US you must order direct from GL and use a forwarding service)
Non-Affiliate link:
https://store.gl-inet.com/products/slate-7-pro-gl-be10000-tri-band-wi-fi-7-travel-router
OR
GL.iNet Slate 7 / GL-BE3600
The Slate 7 can also be the travel-side router. It runs OpenClash and transparently tunnels connected client devices back through the Flint 3.
Affiliate link:
https://amzn.to/4o55c5w
Optional Accessories
- Anker USB-C PD battery: Affiliate Link
https://amzn.to/4vlc1Cg - Portable 4G/5G modem/hotspot (will update with Simpoyo uFi 5G when it is available): Non-Affiliate link:
https://store.gl-inet.com/products/simpoyo-ufi-4g-usb-dongle-with-hotspot
VLESS REALITY vs WireGuard vs Tailscale
| Feature | VLESS REALITY | WireGuard | Tailscale |
|---|---|---|---|
| Self-hostable | Yes | Yes | Partially |
| Requires TLS certs | No | No | No |
| Looks like HTTPS | Yes | No | No |
| Easy client config | Medium | Easy | Easy |
| Router-level travel setup | Yes | Yes | Yes |
| Built-in mesh | No | No | Yes |
Use WireGuard when you want simple and fast VPN tunneling.
Use Tailscale when you want easy mesh networking.
Use VLESS REALITY when you want a self-hosted transport that more closely resembles normal HTTPS traffic and does not require TLS certificate management.
Requirements
You need:
- Flint 3 with SSH access
- Slate 7 Pro with SSH access
- DDNS hostname pointing to your home connection
- TCP port forward to the Flint 3
- Xray Core for ARM64
- OpenClash installed on the Slate 7 Pro
- Mihomo Meta core for OpenClash
This guide uses sanitized placeholders:
1YOUR_DDNS_HOSTNAME
2YOUR_UUID
3YOUR_PRIVATE_KEY
4YOUR_PUBLIC_KEY
5YOUR_SHORT_ID
6YOUR_PROXY_PASSWORD
7YOUR_OPENCLASH_SECRET
Do not publish real keys, UUIDs, short IDs, hostnames, IPs, or passwords.
Part 1: Install OpenClash on the Slate 7 Pro
The Slate 7 Pro does not ship with OpenClash installed by default. Install it first.
Check the Slate 7 Pro Architecture
SSH into the Slate 7 Pro:
1ssh root@192.168.8.1
Check the platform:
1cat /etc/openwrt_release
A Slate 7 Pro may report something like:
1DISTRIB_TARGET='mediatek/mt7987'
2DISTRIB_ARCH='aarch64_cortex-a53'
That means you want the IPK OpenClash package and the ARM64/AArch64 Mihomo core.
Update Package Lists
1opkg update
Install OpenClash Dependencies
For the Slate 7 Pro firmware used in this setup, the working OpenClash dependency path was the iptables/IPK install path, not the nftables one.
Use:
1opkg install bash iptables dnsmasq-full curl ca-bundle ipset ip-full \
2iptables-mod-tproxy iptables-mod-extra ruby ruby-yaml kmod-tun \
3kmod-inet-diag unzip luci-compat luci luci-base
Why not kmod-nft-tproxy?
On this GL.iNet OpenWrt 21.02-based firmware, kmod-nft-tproxy was not available in the GL.iNet feeds. The router already had iptables TProxy support:
1opkg list-installed | grep tproxy
Expected:
1iptables-mod-tproxy
2kmod-ipt-tproxy
So the iptables OpenClash install path is the safer path on this firmware.
Download the Latest OpenClash IPK
1cd /tmp
2
3curl -L --retry 2 https://api.github.com/repos/vernesong/OpenClash/releases/latest \
4 -o /tmp/openclash_version
5
6download_url=$(cat /tmp/openclash_version | jsonfilter -e '@.assets[*].browser_download_url' | grep '\.ipk$')
7
8curl -L --retry 2 "$download_url" -o /tmp/openclash.ipk
Verify it is not a tiny failed download:
1ls -lh /tmp/openclash.ipk
If the file is only a few bytes, the URL failed.
Install it:
1opkg install /tmp/openclash.ipk
Verify OpenClash Files
1ls -lah /etc/openclash/
Check the core directory:
1ls -lah /etc/openclash/core/
You should eventually have:
1clash_meta
If the Meta core is missing, install or download it through the OpenClash LuCI interface:
1Services → OpenClash → Version Update
Select or update the Mihomo Meta core.
Verify the Mihomo Meta Core
1/etc/openclash/core/clash_meta -v
Expected output should identify Mihomo Meta for Linux ARM64.
Example:
1Mihomo Meta ... linux arm64
Basic OpenClash Settings
In LuCI:
1Services → OpenClash
Recommended initial settings:
1Mode: Rule
2DNS Mode: redir-host
3Core: Meta / Mihomo
Avoid Fake-IP while first testing. Fake-IP may return 198.18.x.x addresses, which is normal for that mode but makes troubleshooting harder.
From CLI, force redir-host:
1uci set openclash.config.en_mode='redir-host'
2uci set openclash.config.operation_mode='redir-host'
3uci commit openclash
Part 2: Install Xray on the Flint 3
SSH into the Flint 3.
1mkdir -p /opt/xray
2cd /opt/xray
Download Xray:
1wget -O xray.zip https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-arm64-v8a.zip
2unzip -o xray.zip
3chmod +x xray
Generate REALITY keys:
1./xray x25519
Example placeholder output:
1PrivateKey: YOUR_PRIVATE_KEY
2PublicKey: YOUR_PUBLIC_KEY
Generate a UUID:
1./xray uuid
Example:
1YOUR_UUID
Generate a short ID:
1head -c 8 /dev/urandom | xxd -p
Example:
1YOUR_SHORT_ID
Part 3: Create the Xray Server Config on the Flint 3
Create /opt/xray/config.json:
1cat >/opt/xray/config.json <<'EOF'
2{
3 "log": {
4 "loglevel": "warning"
5 },
6 "inbounds": [
7 {
8 "listen": "0.0.0.0",
9 "port": 9443,
10 "protocol": "vless",
11 "settings": {
12 "clients": [
13 {
14 "id": "YOUR_UUID",
15 "flow": "xtls-rprx-vision"
16 }
17 ],
18 "decryption": "none"
19 },
20 "streamSettings": {
21 "network": "tcp",
22 "security": "reality",
23 "realitySettings": {
24 "show": false,
25 "dest": "www.cloudflare.com:443",
26 "serverNames": [
27 "www.cloudflare.com"
28 ],
29 "privateKey": "YOUR_PRIVATE_KEY",
30 "shortIds": [
31 "YOUR_SHORT_ID"
32 ]
33 }
34 }
35 }
36 ],
37 "outbounds": [
38 {
39 "protocol": "freedom"
40 }
41 ]
42}
43EOF
Test the config:
1/opt/xray/xray run -test -config /opt/xray/config.json
Expected:
1Configuration OK.
Part 4: Open the Flint 3 Firewall
1uci -q delete firewall.xray
2
3uci set firewall.xray='rule'
4uci set firewall.xray.name='Xray-9443'
5uci set firewall.xray.src='wan'
6uci set firewall.xray.proto='tcp'
7uci set firewall.xray.dest_port='9443'
8uci set firewall.xray.target='ACCEPT'
9
10uci commit firewall
11/etc/init.d/firewall restart
If the Flint is behind an ISP gateway, forward:
1TCP 9443 → Flint 3 LAN IP → TCP 9443
Part 5: Create an Xray Startup Service
Create /etc/init.d/xray:
1cat >/etc/init.d/xray <<'EOF'
2#!/bin/sh /etc/rc.common
3
4START=99
5USE_PROCD=1
6
7start_service() {
8 procd_open_instance
9 procd_set_param command /opt/xray/xray run -config /opt/xray/config.json
10 procd_set_param env XRAY_LOCATION_ASSET=/opt/xray
11 procd_set_param respawn
12 procd_set_param stdout 1
13 procd_set_param stderr 1
14 procd_close_instance
15}
16EOF
Enable and start:
1chmod +x /etc/init.d/xray
2/etc/init.d/xray enable
3/etc/init.d/xray start
Verify:
1netstat -lntp | grep 9443
Expected:
1:::9443 LISTEN
Part 6: Create the OpenClash Config on the Slate 7 Pro
On the Slate 7 Pro, create:
1/etc/openclash/config/flint3-reality.yaml
Use:
1mixed-port: 7890
2allow-lan: true
3mode: rule
4log-level: info
5ipv6: false
6tcp-concurrent: true
7
8dns:
9 enable: true
10 listen: 0.0.0.0:7874
11 ipv6: false
12 enhanced-mode: redir-host
13 nameserver:
14 - https://1.1.1.1/dns-query
15 - https://dns.google/dns-query
16 fallback:
17 - https://dns.cloudflare.com/dns-query
18 - https://dns.google/dns-query
19
20proxies:
21 - name: Flint3-Reality
22 type: vless
23 server: YOUR_DDNS_HOSTNAME
24 port: 9443
25 uuid: YOUR_UUID
26 network: tcp
27 tls: true
28 udp: true
29 flow: xtls-rprx-vision
30 servername: www.cloudflare.com
31 client-fingerprint: chrome
32 reality-opts:
33 public-key: YOUR_PUBLIC_KEY
34 short-id: YOUR_SHORT_ID
35
36proxy-groups:
37 - name: Proxy
38 type: select
39 proxies:
40 - Flint3-Reality
41
42rules:
43 - MATCH,Proxy
In OpenClash LuCI:
1Config Manage → Select flint3-reality.yaml
Start OpenClash.
Part 7: Fix the OpenClash SAFE_PATHS Issue
On this Slate 7 Pro setup, OpenClash generated a runtime config at:
1/etc/openclash/flint3-reality.yaml
It included:
1external-ui: "/usr/share/openclash/ui"
2external-ui-name: metacubexd
3external-ui-url: https://codeload.github.com/MetaCubeX/metacubexd/zip/refs/heads/gh-pages
Mihomo refused to start with:
1Parse config error: path is not subpath of home directory or SAFE_PATHS: /usr/share/openclash/ui
2allowed paths: [/etc/openclash]
Remove the bad UI lines:
1sed -i '/external-ui:/d' /etc/openclash/flint3-reality.yaml
2sed -i '/external-ui-name:/d' /etc/openclash/flint3-reality.yaml
3sed -i '/external-ui-url:/d' /etc/openclash/flint3-reality.yaml
Restart OpenClash:
1/etc/init.d/openclash restart
Verify Mihomo is running:
1ps w | grep clash
Expected:
1/etc/openclash/clash -d /etc/openclash -f /etc/openclash/flint3-reality.yaml
Part 8: Verify OpenClash Ports
1netstat -lnt | grep 789
Expected listeners include:
17890
27891
37892
47893
57895
Check DNS:
1netstat -lnt | grep 7874
Part 9: Test the Tunnel
If HTTP proxy authentication is enabled, test with:
1curl -x http://Clash:YOUR_PROXY_PASSWORD@127.0.0.1:7890 https://ipv4.icanhazip.com
Expected:
1YOUR_FLINT_PUBLIC_IP
This should be the Flint 3 public IP, not the Slate 7 Pro WAN IP.
Check the OpenClash API:
1curl -s http://127.0.0.1:9090/proxies \
2 -H "Authorization: Bearer YOUR_OPENCLASH_SECRET"
Confirm:
1"Proxy": {
2 "now": "Flint3-Reality"
3}
Check active connections:
1curl -s http://127.0.0.1:9090/connections \
2 -H "Authorization: Bearer YOUR_OPENCLASH_SECRET"
Expected:
1"chains": ["Flint3-Reality", "Proxy"]
Part 10: Verify Phone Clients
Connect a phone or laptop to the Slate 7 Pro Wi-Fi.
Visit:
1https://ipv4.icanhazip.com
Expected:
1YOUR_FLINT_PUBLIC_IP
If it shows the Slate 7 Pro WAN IP instead, OpenClash is running but client traffic is not being transparently redirected.
Check:
1tail -100 /tmp/openclash.log
2curl -s http://127.0.0.1:9090/connections \
3 -H "Authorization: Bearer YOUR_OPENCLASH_SECRET"
Troubleshooting
OpenClash IPK Download Is Only a Few Bytes
If the IPK is only a few bytes, the GitHub URL was wrong or truncated.
Use the GitHub API method from this guide instead of manually copying a release URL.
kmod-nft-tproxy Cannot Be Installed
Use the iptables OpenClash dependency path instead.
Check:
1opkg list-installed | grep tproxy
If iptables-mod-tproxy and kmod-ipt-tproxy exist, the iptables path is appropriate.
DNS Returns 198.18.x.x
That means Fake-IP mode is active.
Use redir-host:
1uci set openclash.config.en_mode='redir-host'
2uci set openclash.config.operation_mode='redir-host'
3uci commit openclash
4/etc/init.d/openclash restart
OpenClash Says Already Start but Nothing Works
Check if Mihomo is actually running:
1pidof clash
2pidof clash_meta
3ps w | grep clash
Check logs:
1tail -100 /tmp/openclash.log
SAFE_PATHS Error
Remove:
1external-ui:
2external-ui-name:
3external-ui-url:
from:
1/etc/openclash/flint3-reality.yaml
407 Proxy Error
If this fails:
1curl -x http://127.0.0.1:7890 https://ipv4.icanhazip.com
with:
1CONNECT tunnel failed, response 407
use credentials:
1curl -x http://Clash:YOUR_PROXY_PASSWORD@127.0.0.1:7890 https://ipv4.icanhazip.com
Xray Works in Foreground but Not as a Service
Make sure /etc/init.d/xray includes:
1procd_set_param env XRAY_LOCATION_ASSET=/opt/xray
Port Already in Use
Check:
1netstat -lntp | grep 9443
If another service owns the port, change both the Xray server and OpenClash client to a different port.
Final Validation Checklist
A complete working deployment should show:
- OpenClash installed on the Slate 7 Pro
- Mihomo Meta core present and executable
- Xray running on the Flint 3
- TCP
9443listening on the Flint 3 - TCP
9443reachable from the Slate 7 Pro - OpenClash proxy group set to
Flint3-Reality curlthrough the local proxy returning the Flint public IP- Phone clients connected to the Slate 7 Pro showing the Flint public IP
- Xray logs showing accepted TCP sessions
Conclusion
This setup turns a GL.iNet Flint 3 into a self-hosted VLESS REALITY endpoint and a GL.iNet Slate 7 Pro into a travel router that tunnels connected clients back through home.
The complete working chain is:
1Client Device → Slate 7 Pro → OpenClash/Mihomo → VLESS REALITY → Flint 3/Xray → Internet
The most important troubleshooting lesson was that the tunnel itself may be working even when OpenClash is not. In this case, the key failure was OpenClash generating a Mihomo config with an invalid external-ui path that violated Mihomo's SAFE_PATHS restriction.