Last active
March 26, 2026 05:23
-
-
Save ryan4yin/443aa25d3c79b8de02f5296ef72d7128 to your computer and use it in GitHub Desktop.
transparent proxy (mihomo tproxy + nftables)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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