Skip to content

Instantly share code, notes, and snippets.

@ryan4yin
Last active March 26, 2026 05:23
Show Gist options
  • Select an option

  • Save ryan4yin/443aa25d3c79b8de02f5296ef72d7128 to your computer and use it in GitHub Desktop.

Select an option

Save ryan4yin/443aa25d3c79b8de02f5296ef72d7128 to your computer and use it in GitHub Desktop.
transparent proxy (mihomo tproxy + nftables)
# https://wiki.metacubex.one/en/example/conf/
######### 锚点 start #######
# 策略组相关
pr: &pr
type: select
proxies: [默认, 香港, 香港自动选择, 台湾, 台湾自动选择, 日本, 日本自动选择, 新加坡, 新加坡自动选择, 美国, 美国自动选择, 其它地区, 全部节点, 自动选择, 直连]
#这里是订阅更新和延迟测试相关的
p: &p
type: http
interval: 3600
health-check: {enable: true, url: "https://www.gstatic.com/generate_204", interval: 3600}
######### 锚点 end #######
# ======================= 订阅 ======================= #
proxy-providers:
provider1:
<<: *p
url: 'https://your-subscription-1.com/'
provider2:
<<: *p
url: 'https://your-subscription-2.com/'
# ===================== 核心配置 ====================== #
# http/socks5 prot
mixed-port: 7897
# Transparent proxy server port for Linux (TProxy TCP and TProxy UDP)
tproxy-port: 7893
secret: NOTE-PLEASE-CHNAGE-ME-32I4rGs-8F
external-controller: 0.0.0.0:9090
external-ui: ui
external-ui-url: "https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip"
log-level: warning
mode: rule
allow-lan: true
ipv6: true
unified-delay: true
# =================== TUN 代理本机流量 ================== #
#
tun:
enable: true
stack: mixed
auto-route: true
strict-route: false
auto-detect-interface: true
dns-hijack:
- any:53
route-address:
- 0.0.0.0/1
- 128.0.0.0/1
- "::/1"
- "8000::/1"
route-exclude-address:
- 192.168.0.0/16
- fc00::/7
# ======================== DNS ========================= #
dns:
enable: true
ipv6: true
listen: :1053
enhanced-mode: fake-ip
respect-rules: false
use-hosts: false
use-system-hosts: false
default-nameserver:
- system
- 223.6.6.6
- 8.8.8.8
- 2400:3200::1
- 2001:4860:4860::8888
direct-nameserver: []
direct-nameserver-follow-policy: false
fake-ip-filter:
- '*.lan'
- '*.local'
- '*.arpa'
- time.*.com
- ntp.*.com
- time.*.com
- +.market.xiaomi.com
- localhost.ptlogin2.qq.com
- '*.msftncsi.com'
fake-ip-filter-mode: blacklist
fake-ip-range: 198.18.0.1/16
fallback: []
fallback-filter:
domain:
- +.google.com
- +.facebook.com
- +.youtube.com
geoip: true
geoip-code: CN
ipcidr:
- 240.0.0.0/4
- 0.0.0.0/32
nameserver:
- 8.8.8.8
- https://doh.pub/dns-query
- https://dns.alidns.com/dns-query
prefer-h3: false
proxy-server-nameserver:
- https://doh.pub/dns-query
- https://dns.alidns.com/dns-query
- tls://223.5.5.5
# ================== 分流配置 ============================ #
geox-url:
geoip: "https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat"
geosite: "https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat"
mmdb: "https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/country.mmdb"
asn: "https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/GeoLite2-ASN.mmdb"
proxies:
- name: "直连"
type: direct
udp: true
proxy-groups:
- {name: 默认, type: select, proxies: [自动选择, 直连, 香港, 香港自动选择, 台湾, 台湾自动选择, 日本, 日本自动选择, 新加坡, 新加坡自动选择, 美国, 美国自动选择, 其它地区, 全部节点], icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Proxy.png"}
- {name: Google, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Google_Search.png"}
- {name: Apple, <<: *pr, icon: https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Apple.png}
- {name: Telegram, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Telegram.png"}
- {name: Twitter, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Twitter.png"}
- {name: ehentai, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Panda.png"}
- {name: 哔哩哔哩, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/bilibili.png"}
- {name: 哔哩东南亚, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/bilibili.png"}
- {name: 巴哈姆特, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Bahamut.png"}
- {name: YouTube, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/YouTube.png"}
- {name: NETFLIX, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Netflix.png"}
- {name: Spotify, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Spotify.png"}
- {name: 国内, type: select, proxies: [直连, 默认, 香港, 香港自动选择, 台湾, 台湾自动选择, 日本, 日本自动选择, 新加坡, 新加坡自动选择, 美国, 美国自动选择, 其它地区, 全部节点, 自动选择], icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/China_Map.png"}
- {name: 其他, <<: *pr, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Final.png"}
#分隔,下面是地区分组
- {name: 香港, type: select, include-all: true, filter: "(?i)(?!直连)(港|hk|hongkong|hong kong)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/HK.png"}
- {name: 台湾, type: select, include-all: true, filter: "(?i)(?!直连)(台|tw|taiwan)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/TW.png"}
- {name: 日本, type: select, include-all: true, filter: "(?i)(?!直连)(日本|jp|japan)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/JP.png"}
- {name: 美国, type: select, include-all: true, filter: "(?i)(?!直连)(美|us|unitedstates|united states)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/US.png"}
- {name: 新加坡, type: select, include-all: true, filter: "(?i)(?!直连)(新|狮城|sg|singapore)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/SG.png"}
- {name: 其它地区, type: select, include-all: true, filter: "(?i)^(?!.*(?:🇭🇰|🇯🇵|🇺🇸|🇸🇬|🇨🇳|港|hk|hongkong|台|tw|taiwan|日|jp|japan|新|sg|singapore|美|us|unitedstates|直连)).*", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Available.png"}
- {name: 自动选择, type: url-test, include-all: true, tolerance: 10, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Auto.png"}
- {name: 全部节点, type: select, include-all: true, icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/Global.png"}
- {name: 香港自动选择,type: url-test, include-all: true, filter: "(?i)(?!直连)(港|hk|hongkong|hong kong)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/HK.png"}
- {name: 台湾自动选择,type: url-test, include-all: true, filter: "(?i)(?!直连)(台|tw|taiwan)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/TW.png"}
- {name: 日本自动选择,type: url-test, include-all: true, filter: "(?i)(?!直连)(日本|jp|japan)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/JP.png"}
- {name: 美国自动选择,type: url-test, include-all: true, filter: "(?i)(?!直连)(美|us|unitedstates|united states)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/US.png"}
- {name: 新加坡自动选择,type: url-test, include-all: true, filter: "(?i)(新|狮城|sg|singapore)", icon: "https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/mini/SG.png"}
rules:
- GEOIP,lan,直连,no-resolve
- RULE-SET,biliintl_domain,哔哩东南亚
- RULE-SET,ehentai_domain,ehentai
- RULE-SET,github_domain,其他
- RULE-SET,twitter_domain,Twitter
- RULE-SET,youtube_domain,YouTube
- RULE-SET,google_domain,Google
- RULE-SET,telegram_domain,Telegram
- RULE-SET,netflix_domain,NETFLIX
- RULE-SET,bilibili_domain,哔哩哔哩
- RULE-SET,bahamut_domain,巴哈姆特
- RULE-SET,spotify_domain,Spotify
- RULE-SET,pixiv_domain,其他
- RULE-SET,geolocation-!cn,其他
- RULE-SET,google_ip,Google
- RULE-SET,netflix_ip,NETFLIX
- RULE-SET,telegram_ip,Telegram
- RULE-SET,twitter_ip,Twitter
- RULE-SET,cn_domain,国内
- RULE-SET,cn_ip,国内
- MATCH,其他
rule-anchor:
ip: &ip {type: http, interval: 86400, behavior: ipcidr, format: text}
domain: &domain {type: http, interval: 86400, behavior: domain, format: text}
rule-providers:
private:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/private.list"
cn_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/cn.list"
biliintl_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/biliintl.list"
ehentai_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/ehentai.list"
github_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/github.list"
twitter_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/twitter.list"
youtube_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/youtube.list"
google_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/google.list"
telegram_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/telegram.list"
netflix_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/netflix.list"
bilibili_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/bilibili.list"
bahamut_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/bahamut.list"
spotify_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/spotify.list"
pixiv_domain:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/pixiv.list"
geolocation-!cn:
<<: *domain
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geosite/geolocation-!cn.list"
cn_ip:
<<: *ip
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/cn.list"
google_ip:
<<: *ip
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/google.list"
netflix_ip:
<<: *ip
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/netflix.list"
twitter_ip:
<<: *ip
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/twitter.list"
telegram_ip:
<<: *ip
url: "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/meta/geo/geoip/telegram.list"
#!/bin/bash
# Mihomo nftables TProxy installation script for Debian
# Run with: sudo bash this-script.sh
mkdir -p /etc/mihomo
mv config.yaml /etc/mihomo
# Step 1: Install nftables (TProxy firewall dependency)
apt update -qq && apt install -y nftables
# Step 2: Create mihomo system user (for anti-loop rules)
useradd -r -s /usr/sbin/nologin mihomo || true
MIHOMO_UID=$(id -u mihomo)
# Step 3: Enable kernel params for TProxy(IPv4 + IPv6)
tee /etc/sysctl.d/99-mihomo.conf <<EOF
net.ipv4.ip_forward = 1
net.ipv4.conf.all.route_localnet = 1
net.ipv6.conf.all.forwarding = 1
EOF
sysctl --system >/dev/null
# Step 4: Create custom route table 666(used by both IPv4 and IPv6)
# Routes marked traffic to loopback interface (lo)
grep -q "^666 mihomo" /etc/iproute2/rt_tables 2>/dev/null || echo "666 mihomo" >> /etc/iproute2/rt_tables
# Step 5: nftables rules with 2 core chains
tee /etc/mihomo/tproxy.nft <<EOF
#!/usr/sbin/nft -f
# Clean old rules
flush ruleset
table inet mihomo {
# Private IPv4 ranges (bypass proxy)
set private4 {
type ipv4_addr
flags interval
elements = {
0.0.0.0/8, 10.0.0.0/8, 127.0.0.0/8,
169.254.0.0/16, 172.16.0.0/12, 192.168.0.0/16,
224.0.0.0/4, 240.0.0.0/4
}
}
# Private IPv6 ranges (bypass proxy)
# Includes link-local, ULA, multicast, etc. Fake-IP IPv6 will still go through proxy
set private6 {
type ipv6_addr
flags interval
elements = {
::/128, ::1/128, ::ffff:0:0:0/96,
fe80::/10, fc00::/7, ff00::/8, 2001:db8::/32
}
}
# prerouting chain: handles incoming traffic from LAN devices
# (transparent proxy for phones, laptops, etc.)
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
ip daddr @private4 return
ip6 daddr @private6 return
# IPv4 TProxy
meta l4proto { tcp, udp } tproxy ip to 127.0.0.1:7893 meta mark set 666 accept
# IPv6 TProxy
meta l4proto { tcp, udp } tproxy ip6 to [::1]:7893 meta mark set 666 accept
}
# output chain: handles traffic generated by this machine itself
# (so curl, browser, apt, ssh on the gateway also use the proxy)
chain output {
type route hook output priority mangle; policy accept;
ip daddr @private4 return
ip6 daddr @private6 return
# Skip mihomo's own traffic (prevents infinite loop)
meta skuid ${MIHOMO_UID} return
# Mark all other traffic (IPv4 + IPv6)
meta l4proto { tcp, udp } meta mark set 666
}
}
# NAT for IPv4 (DNS redirect + fake-ip ICMP fix)
table ip mihomo_nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
udp dport 53 redirect to 1053;
ip protocol icmp ip daddr 198.18.0.0/15 dnat to 127.0.0.1;
}
}
# NAT for IPv6 (DNS redirect)
table ip6 mihomo_nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
udp dport 53 redirect to 1053
}
}
EOF
chmod +x /etc/mihomo/tproxy.nft
# Step 6: Set config permissions
mkdir -p /etc/mihomo
chown -R mihomo:mihomo /etc/mihomo
# Step 7: Systemd service - Link nft marks → route table 666 → lo interface
# https://wiki.metacubex.one/en/startup/service/
tee /etc/systemd/system/mihomo.service <<EOF
[Unit]
Description=mihomo Daemon, Another Clash Kernel.
After=network.target NetworkManager.service systemd-networkd.service iwd.service
[Service]
Type=simple
LimitNPROC=500
LimitNOFILE=1000000
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE
Restart=always
User=mihomo
ExecStartPre=/usr/bin/sleep 1s
# TProxy Routing Core:
# 1. Bind mark 666 to custom route table 666
# 2. Force marked traffic to lo (for Mihomo TProxy)
# 3. Load nft rules to mark traffic
ExecStartPre=-/usr/sbin/ip rule add fwmark 666 lookup 666 priority 100
ExecStartPre=-/usr/sbin/ip route add local 0.0.0.0/0 dev lo table 666
ExecStartPre=-/usr/sbin/ip -6 rule add fwmark 666 lookup 666 priority 100
ExecStartPre=-/usr/sbin/ip -6 route add local ::/0 dev lo table 666
ExecStartPre=/usr/sbin/nft -f /etc/mihomo/tproxy.nft
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
ExecReload=/bin/kill -HUP \$MAINPID
ExecStop=/usr/sbin/nft flush ruleset
[Install]
WantedBy=multi-user.target
EOF
# Step 8: Activate service
systemctl daemon-reload
systemctl enable --now mihomo.service
echo "Installation completed successfully!"
echo "Web UI: http://<your-ip>:9090/ui/#/"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment