• Create a sing-box configuration with tproxy inbound listening on port 12345. Run sing-box using the systemd service below.

  • /usr/lib/systemd/system/[email protected]

    [Unit]
    Description=sing-box service
    Documentation=https://sing-box.sagernet.org
    After=network.target nss-lookup.target network-online.target
    
    [Service]
    CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
    AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
    
    ExecStart=/usr/bin/sing-box -D /var/lib/sing-box-%i -c /etc/sing-box/%i.json run
    ExecStartPost=/usr/sbin/ip rule add fwmark 1 table 1
    ExecStartPost=/usr/sbin/ip route add local default dev lo table 1
    ExecStartPost=/usr/sbin/nft -f /etc/nftables/transparent_proxy.nft
    
    ExecStop=/usr/sbin/nft delete table transparent_proxy
    ExecStop=/usr/sbin/ip route flush table 1
    ExecStop=/usr/sbin/ip rule delete fwmark 1 table 1
    
    ExecReload=/bin/kill -HUP $MAINPID
    Restart=on-failure
    RestartSec=10s
    LimitNOFILE=infinity
    
    [Install]
    WantedBy=multi-user.target
    
  • /etc/nftables/transparent_proxy.nft

    table ip transparent_proxy {
    	chain prerouting_mangle {
    		type filter hook prerouting priority mangle; policy accept;
    		meta l4proto { tcp, udp } mark 0x00000001 tproxy ip to 127.0.0.1:12345
    	}
    
    	chain output_mangle {
    		type route hook output priority mangle; policy accept;
    		meta mark 0x00000002 return
    		oifname != "lo" meta l4proto { tcp, udp } meta mark set 0x00000001
    	}
    }