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:

  1. Install OpenClash on a GL.iNet Slate 7 Pro.
  2. Install and configure Xray on a GL.iNet Flint 3.
  3. Build a VLESS REALITY tunnel using XTLS Vision.
  4. Configure OpenClash/Mihomo on the Slate 7 Pro.
  5. 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
1011Home 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 9443 listening on the Flint 3
  • TCP 9443 reachable from the Slate 7 Pro
  • OpenClash proxy group set to Flint3-Reality
  • curl through 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.