#!/usr/sbin/nft -f table inet mihomo { set dns_hijack_nfproto { type nf_proto flags interval } set proxy_nfproto { type nf_proto flags interval } set china_ip { type ipv4_addr flags interval } set china_ip6 { type ipv6_addr flags interval } set reserved_ip { type ipv4_addr flags interval auto-merge } set reserved_ip6 { type ipv6_addr flags interval auto-merge } set fake_ip { type ipv4_addr flags interval } set acl_dport { type inet_proto . inet_service flags interval auto-merge } set acl_ip { type ipv4_addr flags interval auto-merge } set acl_ip6 { type ipv6_addr flags interval auto-merge } set acl_mac { type ether_addr flags interval auto-merge } chain router_dns_hijack { meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 oifname lo meta skuid != $MIHOMO_USER counter redirect to :$DNS_PORT } chain all_dns_hijack { meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter redirect to :$DNS_PORT } chain allow_dns_hijack { meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip saddr @acl_ip counter redirect to :$DNS_PORT meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip6 saddr @acl_ip6 counter redirect to :$DNS_PORT meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ether saddr @acl_mac counter redirect to :$DNS_PORT } chain block_dns_hijack { meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip saddr @acl_ip counter return meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip6 saddr @acl_ip6 counter return meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ether saddr @acl_mac counter return meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter redirect to :$DNS_PORT } chain all_redirect { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } counter redirect to :$REDIR_PORT } chain allow_redirect { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter redirect to :$REDIR_PORT meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter redirect to :$REDIR_PORT meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter redirect to :$REDIR_PORT } chain block_redirect { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter return meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter return meta nfproto @proxy_nfproto meta l4proto { tcp, udp } counter redirect to :$REDIR_PORT } chain all_tproxy { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept } chain allow_tproxy { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip meta mark set mark ^ $FW_MARK tproxy ip to :$TPROXY_PORT counter accept meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 meta mark set mark ^ $FW_MARK tproxy ip6 to :$TPROXY_PORT counter accept meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept } chain block_tproxy { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter return meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter return meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept } chain all_tun { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter } chain allow_tun { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip meta mark set mark ^ $FW_MARK counter meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 meta mark set mark ^ $FW_MARK counter meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac meta mark set mark ^ $FW_MARK counter } chain block_tun { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter return meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter return meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter } chain router_redirect { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } counter redirect to :$REDIR_PORT } chain router_reroute { meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter accept } chain dstnat { type nat hook prerouting priority dstnat + 1; policy accept; fib daddr type local counter return ct direction reply counter return ip daddr @reserved_ip counter return ip6 daddr @reserved_ip6 counter return ip daddr @china_ip counter return ip6 daddr @china_ip6 counter return meta l4proto . th dport != @acl_dport ip daddr != @fake_ip counter return meta nfproto ipv6 meta l4proto . th dport != @acl_dport counter return } chain nat_output { type nat hook output priority filter; policy accept; meta skuid $MIHOMO_USER counter return fib daddr type local counter return ct direction reply counter return ip daddr @reserved_ip counter return ip6 daddr @reserved_ip6 counter return ip daddr @china_ip counter return ip6 daddr @china_ip6 counter return meta l4proto . th dport != @acl_dport ip daddr != @fake_ip counter return meta nfproto ipv6 meta l4proto . th dport != @acl_dport counter return } chain mangle_prerouting { type filter hook prerouting priority mangle; policy accept; meta l4proto { tcp, udp } iifname lo meta mark & $FW_MARK_MASK == $FW_MARK tproxy to :$TPROXY_PORT counter accept meta l4proto { tcp, udp } iifname $TUN_DEVICE counter return fib daddr type local counter return ct direction reply counter return ip daddr @reserved_ip counter return ip6 daddr @reserved_ip6 counter return ip daddr @china_ip counter return ip6 daddr @china_ip6 counter return meta l4proto . th dport != @acl_dport ip daddr != @fake_ip counter return meta nfproto ipv6 meta l4proto . th dport != @acl_dport counter return meta l4proto { tcp, udp } th dport 53 counter return } chain mangle_output { type route hook output priority mangle; policy accept; meta skuid $MIHOMO_USER counter return fib daddr type local counter return ct direction reply counter return ip daddr @reserved_ip counter return ip6 daddr @reserved_ip6 counter return ip daddr @china_ip counter return ip6 daddr @china_ip6 counter return meta l4proto . th dport != @acl_dport ip daddr != @fake_ip counter return meta nfproto ipv6 meta l4proto . th dport != @acl_dport counter return meta l4proto { tcp, udp } th dport 53 counter return } }