1 Why run Mihomo inside Crostini
A Chromebook is excellent for classrooms and travel, yet power users still want the same rule-based routing they rely on on macOS or Windows. Native Chrome extensions can proxy the browser, but they rarely match the flexibility of a full Clash-compatible core with DNS helpers, provider-driven rule sets, and a single mixed port for both HTTP and SOCKS clients. Google’s Linux container feature—commonly called Crostini—closes that gap without unlocking developer-only firmware: you get a Debian-based environment that behaves like a small cloud VM living beside Chrome OS.
Mihomo (the community continuation of Clash.Meta) is a natural fit here. It consumes the same YAML vocabulary as mainstream Clash clients, supports modern transports your provider may offer, and runs happily as a single static binary with no desktop environment requirement. You can keep the daemon inside the container, then use Chrome OS port forwarding to publish the listener toward the host and the rest of your LAN. That pattern mirrors what administrators do on a headless Linux server, except the “server” is your laptop and the hypervisor is Chrome OS instead of KVM on a datacenter host.
This article complements our generic Linux systemd guide by focusing on Crostini-specific networking, permission, and lifecycle quirks. Where that tutorial assumes a standard systemd system service as root, here we emphasize per-user units, linger settings, and the extra hop through Chrome OS when you want phones or consoles to reuse the tunnel. Nothing here endorses bypassing school or workplace policy; treat outbound access as a personal responsibility and verify compliance before you deploy.
2 Enable Linux (Beta) and prepare Debian
Open Settings, search for Linux development environment, and follow the wizard to install the default penguin container. First boot can take several minutes while Chrome OS downloads the Termina VM image. When the terminal app opens successfully, update package indexes and install baseline tools you will need for downloads and editing. The stock image is usually Debian bookworm or newer; commands below use apt accordingly.
sudo apt update
sudo apt install -y curl ca-certificates gzip
Confirm architecture with uname -m. Most classroom and consumer Chromebooks ship x86_64, which maps to Mihomo’s amd64 artifacts. ARM models report aarch64 and need the arm64 build instead. Storage inside the container counts against your overall disk quota; keeping logs and cached provider files under your home directory avoids permission friction later.
3 Install the Mihomo binary in your container
Create a layout under your home directory so you never need root to edit everyday policy. A practical choice is ~/.local/bin for the executable and ~/.config/mihomo for configuration, mimicking XDG conventions. Add the bin directory to your PATH inside ~/.bashrc if it is not already present.
mkdir -p ~/.local/bin ~/.config/mihomo
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Download the latest stable release from the Mihomo GitHub project, picking the asset that matches your architecture. The snippet below illustrates amd64; swap the URL when a newer tag appears or when you need arm64. After decompressing, move the binary into ~/.local/bin/mihomo, mark it executable, and print the version banner to verify integrity.
# Replace URL with the latest amd64 release asset
curl -LO https://github.com/MetaCubeX/Mihomo/releases/download/v1.18.0/mihomo-linux-amd64-v1.18.0.gz
gunzip mihomo-linux-amd64-v1.18.0.gz
mv mihomo-linux-amd64-v1.18.0 ~/.local/bin/mihomo
chmod +x ~/.local/bin/mihomo
mihomo -v
Sticking to user-writable paths means you can iterate on YAML without sudo, which matters on a locked-down school device. If you prefer a system-wide install under /usr/local/bin, you certainly can, but you will need elevated rights for every upgrade and your systemd unit must reference the matching paths.
4 Subscription import with proxy-providers
Hard-coding dozens of nodes inside proxies: grows stale quickly. Mihomo supports remote subscription import through proxy-providers: you supply the HTTPS URL your vendor gives you, a local cache path, refresh interval, and optional health checks. At runtime the core downloads the provider, normalizes proxies, and exposes them to proxy-groups through the use: field. This is the same mental model as desktop Clash clients, so you can reuse community snippets after a quick sanity review.
Replace the placeholder subscription URL with your own. If the provider emits a format Mihomo cannot consume directly, run it through a trusted converter in a separate step, then point url: at the converted endpoint or paste static proxies instead. Never commit real tokens into public repositories; keep the file inside the container with permissions chmod 600 if others share the machine.
mixed-port: 7890
allow-lan: true
mode: rule
log-level: info
ipv6: false
external-controller: 127.0.0.1:9090
secret: "replace_with_a_long_random_secret"
dns:
enable: true
listen: 127.0.0.1:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- 223.5.5.5
- 119.29.29.29
fallback:
- https://1.1.1.1/dns-query
- https://8.8.8.8/dns-query
proxy-providers:
airport:
type: http
url: "https://example.com/sub?token=YOUR_TOKEN"
path: ./providers/airport.yaml
interval: 3600
health-check:
enable: true
interval: 600
url: https://www.gstatic.com/generate_204
proxy-groups:
- name: Proxy
type: select
use:
- airport
proxies:
- DIRECT
rules:
- GEOIP,CN,DIRECT
- MATCH,Proxy
The sample binds the REST API to loopback on port 9090 so random devices on the café Wi-Fi cannot toggle your routing until you deliberately forward that port. The DNS listener stays on 1053 inside the container to avoid fighting Chrome OS services that may assume port 53 is special. Tune nameserver and fallback to match your region; the values above are only illustrations.
mkdir -p ~/.config/mihomo/providers
chmod 600 ~/.config/mihomo/config.yaml
5 Run Mihomo under a user systemd unit
Crostini ships systemd user sessions, which is ideal for background daemons you do not want tied to an interactive terminal. Create ~/.config/systemd/user/mihomo.service with Type=simple, point ExecStart at your binary and config directory, and request automatic restarts. Enable lingering with loginctl enable-linger $USER so the service can start without an open Terminal window after reboot—this single command is easy to forget yet critical for “appliance-like” behavior on a Chromebook.
[Unit]
Description=Mihomo (Clash-compatible) for Chromebook Crostini
After=network-online.target
[Service]
Type=simple
ExecStart=%h/.local/bin/mihomo -d %h/.config/mihomo
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
loginctl enable-linger "$USER"
systemctl --user daemon-reload
systemctl --user enable --now mihomo.service
systemctl --user status mihomo.service --no-pager
While debugging YAML mistakes, you can foreground the process with mihomo -d ~/.config/mihomo in a terminal to read errors immediately, then stop the user service temporarily via systemctl --user stop mihomo.service. Logs go to the journal; follow them with journalctl --user -u mihomo.service -f. Once the configuration parses cleanly, return to the supervised service so closing the Terminal tab does not kill your uplink.
6 Forward ports from Crostini to Chrome OS
By default, listeners inside the Linux container are not reachable from the Chrome browser or from other machines on your Wi-Fi. Chrome OS exposes an explicit port forwarding UI: navigate to Settings → Developers → Linux development environment → Port forwarding, add TCP port 7890, and map it to the same port inside the container. After saving, 127.0.0.1:7890 on the Chrome OS side should reach Mihomo’s mixed port. If you plan to operate the dashboard from the browser, repeat the process for 9090 only after you understand the security trade-off of exposing the API.
Forwarding is also the bridge for LAN proxy scenarios. Once Chrome OS publishes the port on the laptop’s Wi-Fi address, a phone or tablet can aim at http://CHROMEBOOK_LAN_IP:7890 as its HTTP proxy, assuming your firewall allows it. Document the IP with a sticky note in your password manager; DHCP may change it unless you reserve an address on the router. IPv6-only networks may need additional thought—most home setups remain IPv4-centric, but campus Wi-Fi sometimes differs.
allow-lan: true combined with port forwarding exposes your proxy to anyone who can reach the Chromebook’s interface. Use strong secret values, keep the controller on localhost until you need otherwise, and disable forwarding on public networks.
7 Point Chrome OS apps and shells at the mixed port
Linux applications inside Crostini can export the usual environment variables. After port forwarding, many users set http_proxy and https_proxy to http://127.0.0.1:7890 inside ~/.bashrc, mirroring the pattern from our broader Linux tutorial. Android apps and the Chrome browser do not automatically inherit those variables; for Chrome you typically rely on a proxy-switching extension or the system network settings if your Chrome OS version exposes them. Test with curl -I https://www.example.com from the Linux terminal once variables are active.
export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"
export no_proxy="localhost,127.0.0.1,::1"
Android subsystem traffic is a separate world: if you need parity there, consider a dedicated VPN or per-app proxy that your vendor supports. The Crostini-focused workflow in this guide keeps expectations honest—your Debian tools and many command-line workflows are covered first; extending to every Chrome OS surface is a product-specific exercise.
8 Share the proxy with other LAN devices
After you confirm port 7890 is reachable from another device’s browser or curl, configure that device to use an explicit HTTP proxy pointing at your Chromebook. Game consoles often support HTTP proxies in network settings; phones allow per-Wi-Fi proxy configuration on many Android builds. Remember Mihomo is not a full VPN: applications that ignore system proxy settings will still bypass unless you adopt TUN-style routing, which is substantially more complex inside Crostini and outside the scope of a first install.
If friends or family share the network, treat the forwarded port like an open SOCKS relay. Toggle forwarding off when idle, especially on hotel or conference Wi-Fi. Pairing this setup with router-level DNS overrides is possible but error-prone; start with explicit proxy configuration until you fully understand path MTU issues and split-DNS behavior on your hardware.
9 Optional: external controller and dashboards
Once external-controller listens on 127.0.0.1:9090, you can attach a web UI such as YACD or metacubexd by tunneling through port forwarding. Our Mihomo external controller and dashboard primer explains REST paths, secrets, and TLS expectations in depth. On a Chromebook, prefer localhost binding plus forwarding instead of 0.0.0.0 until you have packet-level controls equivalent to ufw on a traditional Linux desktop.
10 Troubleshooting checklist
- Service exits immediately: Run
journalctl --user -u mihomo.service -n 50 --no-pager. Typos insideproxy-providersor invalid indentation are common; validate YAML with a relaxed eye toward tabs versus spaces. - Subscriptions never populate: Confirm the container can reach the provider URL with
curl -I. Clock skew on a freshly resumed Chromebook can break TLS; set time automatically in Settings. - Chrome OS cannot reach
127.0.0.1:7890: Revisit port forwarding rules and ensure Mihomo still listens on0.0.0.0:7890viaallow-lanplus default bind behavior; check for another process occupying the port withss -lntpinside Linux. - LAN clients time out: Verify both devices share the same subnet, disable guest isolation on the router if enabled, and confirm Chrome OS firewall prompts are not blocking incoming Wi-Fi peers.
- DNS leaks or odd resolutions: Align Chrome OS DNS with your intent; mixing ISP resolvers with FakeIP can confuse captive portals. Temporarily set
mode: directto log in at a hotel, then return torulemode.
11 Wrap-up
You now have an end-to-end path for running a Clash-compatible Mihomo stack on a Chromebook: enable the Linux container, install a user-scoped binary, describe subscription import with proxy-providers, supervise the daemon through systemd, and surface port 7890 with Chrome OS forwarding so both local tools and LAN peers can share one policy file. Compared with juggling multiple single-app VPN clients, centralizing logic in Mihomo keeps routing consistent for terminals, developer tools, and explicit-proxy devices—while still respecting the boundary between Chrome OS, Android, and Debian.
When you move back to a traditional desktop, the same YAML usually drops straight into a graphical client with richer editors and optional TUN mode. Polished apps often shorten the feedback loop for rule tweaks, even though the Crostini deployment remains unbeatable for always-on, low-UI operation on lightweight hardware. If that desktop path sounds appealing, grab a maintained build for your platform from our hub rather than hunting release artifacts while you are in a hurry.