Skip to content

EasyTier — mihomo ​

mihomo embeds an EasyTier node and routes traffic into its decentralized mesh overlay. The node runs in userspace with no TUN device (mihomo always forces no_tun and turns off device binding), and all of its underlay connections go through mihomo's own dialer, so dialer-proxy, interface-name and routing-mark apply to them. The overlay is IPv4-only.

Outbound ​

Entry under proxies: with type: easytier. Embeds BasicOption (common outbound fields such as dialer-proxy, interface-name, routing-mark and ip-version).

FieldTypeDefaultAllowed valuesDescription
namestring(required)<string>Unique proxy name. Also the default instance-name and part of the default state-dir, and the name et:// DNS servers refer to.
network-namestring(required)<string>EasyTier network name. Nodes join the same overlay only when name and secret match.
network-secretstring(empty)<string>Shared network secret. secure-mode requires a non-empty secret.
hostnamestring(core default)<string>Hostname this node announces on the overlay; other nodes can reach it as <hostname> or <hostname>.<tld-dns-zone>.
ipv4string(DHCP)<IPv4 CIDR>Static overlay IPv4 with prefix, e.g. 10.144.0.1/24. When empty, DHCP is switched on automatically.
dhcpbooltrue when ipv4 is emptytrue | falseObtain the overlay IPv4 address automatically.
peers[]string[]<peer URI> | …Peers or relays to connect to, e.g. tcp://192.0.2.10:11010 or udp://…. Append ?peer-public-key=<base64 X25519 key> to pin a peer's key. Required when the node has no listeners; public.easytier.top is never used implicitly.
listeners[]string[]<listener URI> | …Local listener URIs such as tcp://0.0.0.0:11010, so other nodes can connect to this one. Cannot be combined with no-listener: true.
no-listener*bool(no listeners)true | falsetrue (or unset with empty listeners) opens no listener. An explicit false with empty listeners opens the default tcp://0.0.0.0:11010.
mapped-listeners[]string[]<listener URI> | …Externally reachable listener addresses to advertise to other nodes, e.g. when a port is forwarded on a NAT gateway.
exit-nodes[]string[]<overlay IPv4> | …Overlay IPv4 addresses of nodes that act as exit nodes for destinations outside the overlay.
proxy-networks[]string[]<CIDR> | …Subnets this node exposes to the rest of the overlay through EasyTier's subnet proxy.
instance-namestring(proxy name)<string>Name of the embedded EasyTier instance.
state-dirstringeasytier/<name><directory path>Directory where the instance ID is persisted, so the node keeps the same instance across restarts. Resolved against the mihomo working directory.
udpboolfalsetrue | falseAllow UDP traffic through this outbound.
accept-dns*bool(core default)true | falsePassed to the EasyTier core as its Magic DNS switch. mihomo's own overlay-name lookup (see Notes) works either way.
enable-exit-node*bool(core default)true | falseLet other nodes use this node as an exit node.
enable-encryption*bool(core default)true | falseEncrypt overlay traffic between peers.
encryption-algorithmstring(core default)aes-gcm | <EasyTier algorithm name>Cipher used when encryption is enabled. The upstream example config uses aes-gcm.
private-mode*bool(core default)true | falseOnly allow nodes of the same network to handshake with or relay through this node.
latency-first*bool(core default)true | falsePrefer the lowest-latency path over the path with the fewest hops.
disable-p2p*bool(core default)true | falseDo not form direct peer-to-peer connections; traffic goes through relaying peers only.
enable-kcp-proxy*bool(core default)true | falseCarry proxied TCP over KCP between peers (can help on lossy links).
disable-kcp-input*bool(core default)true | falseRefuse KCP-proxied connections from other peers.
enable-quic-proxy*bool(core default)true | falseCarry proxied TCP over QUIC between peers.
disable-quic-input*bool(core default)true | falseRefuse QUIC-proxied connections from other peers.
mtuint(core default)<bytes>Overlay MTU. Only passed on when greater than 0.
tld-dns-zonestringet.net.<DNS zone>Magic DNS zone for overlay hostnames.
secure-mode*bool(auto)true | falseNoise-based end-to-end encryption between nodes. Switched on automatically when local keys or a peer-public-key are configured; an explicit false together with such keys is an error.
local-private-keystring(generated)<base64 X25519 private key>Fixes this node's secure-mode identity so its public key does not change between starts.
local-public-keystring(derived)<base64 X25519 public key>Matching public key. Usually derived from local-private-key; setting it alone is an error.

Source: adapter/outbound/easytier.go:51-84 · pinned at v1.19.31 (ab405ba)

Examples ​

Minimal outbound that joins a network through two peers:

yaml
proxies:
  - name: et
    type: easytier
    network-name: example
    network-secret: secret
    peers:
      - tcp://192.0.2.10:11010
      - udp://192.0.2.11:11010
    udp: true

Static address, pinned relay key (turns on secure mode), and overlay names resolved by mihomo:

yaml
proxies:
  - name: et-office
    type: easytier
    network-name: office
    network-secret: secret
    hostname: mihomo
    ipv4: 10.144.0.5/24
    peers:
      - "tcp://relay.example.com:11010?peer-public-key=<base64-x25519-public-key>"
    local-private-key: "<base64-x25519-private-key>"
    exit-nodes: ["10.144.0.1"]

dns:
  nameserver-policy:
    "+.et.net": et://et-office

Notes ​

  • network-name is required. A node with no peers must have listeners, otherwise the config is rejected — mihomo never falls back to the public public.easytier.top node.
  • Listener logic: listeners are closed by default. Set listeners to open specific ones, or no-listener: false with empty listeners to open the default tcp://0.0.0.0:11010. no-listener: true together with listeners is an error.
  • Dials stay on the overlay and never fall back to the host network. Destinations must be overlay IPv4 addresses, subnets other nodes expose with proxy-networks, or — with exit-nodes — addresses reachable through an exit node. IPv6 destinations are rejected; ip-version only affects the underlay peer connections.
  • Hostname lookup: names matching an overlay node (<hostname> or <hostname>.<tld-dns-zone>) resolve from the overlay route table. Other names under the zone fail as "not found"; everything else resolves with the resolver mihomo uses for proxy server names.
  • DNS: a nameserver written as et://<proxy-name> (or easytier://<proxy-name>) answers overlay A and PTR queries from that outbound (TTL 60 s; unknown names get NXDOMAIN). It is meant for nameserver-policy entries covering the Magic DNS zone rather than as a general resolver — see DNS.
  • Secure mode switches on by itself when you set local-private-key / local-public-key or add peer-public-key to a peer URI. It needs a non-empty network-secret. Pin local-private-key to keep the node's public key stable across restarts.
  • state-dir (default easytier/<name>) stores the instance ID only; the overlay address comes from ipv4 or DHCP.
  • Optional flags left unset keep the embedded EasyTier core's defaults.
  • EasyTier support is compiled in by default. A build with the no_easytier tag keeps the config shape but fails at startup with "EasyTier support is disabled".

Cross-core notes ​

  • Xray-core and sing-box have no EasyTier support. The closest analogues on this site are the mesh-VPN endpoints: Tailscale — sing-box and WireGuard — sing-box.
  • Within mihomo, Tailscale and ZeroTier are the other userspace overlay-network outbounds. Tailscale's ts://<proxy-name> nameserver is the counterpart of et://.

Source: adapter/outbound/easytier.go:51-84 · v1.19.31 (ab405ba)

Core Tutorial by Argsment