Setting up TPROXY
TPROXY is a transparent proxy framework available only on Linux, supporting both TCP and UDP protocols.
Avoiding Loops
Skip this section if you don't need to proxy traffic from the device itself that is running the Hysteria client.
In scenarios where the device's own traffic needs to be proxied, to avoid traffic loops with Hysteria, it's essential to separate the Hysteria client's own traffic from the traffic that's being proxied. The best way to achieve this is to run the Hysteria client as a dedicated user and then perform user-based matching in iptables.
We also recommend running Hysteria as a dedicated user when using one-click installation scripts and Linux distribution packages, and to configure it according to this section.
-
Create a dedicated user specifically for running the Hysteria client.
-
Grant the necessary
capabilities(7)
for the Hysteria client to operate normally.- Replace with the actual installation path of Hysteria.
You'll need to perform this step each time you manually update the Hysteria client.
-
Configure the Hysteria client to start as this dedicated user.
If running the Hysteria client manually:
Alternatively, if you're using systemd to manage the Hysteria service, you can add
User=hysteria
under the[Service]
section in the systemd configuration for the service.
Configuring the Client
In the examples that follow, we will use
2500
as the listening port for TProxy. Feel free to use a different port if you wish.
Add the following lines to your client configuration:
Configuring Routing Rules
This step is not optional. Do not skip this step; otherwise TProxy will not work.
You will need to run these commands every time the system boots unless you make them persistent.
In the following examples, we will use
0x1
as the fwmark for TProxy policy routing rules and100
as the Table ID for the TProxy routing table. Feel free to use different values if you wish.
Configuring iptables
You will need to run these commands every time the system boots, unless you make them persistent.
iptables -t mangle -N HYSTERIA
# Skip traffic already handled by TProxy (1)
iptables -t mangle -A HYSTERIA -p tcp -m socket --transparent -j MARK --set-mark 0x1
iptables -t mangle -A HYSTERIA -p udp -m socket --transparent -j MARK --set-mark 0x1
iptables -t mangle -A HYSTERIA -m socket -j RETURN
# Skip private and special IPv4 addresses (3)
iptables -t mangle -A HYSTERIA -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A HYSTERIA -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A HYSTERIA -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A HYSTERIA -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A HYSTERIA -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A HYSTERIA -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A HYSTERIA -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A HYSTERIA -d 240.0.0.0/4 -j RETURN
# Redirect traffic to the TProxy port
iptables -t mangle -A HYSTERIA -p tcp -j TPROXY --on-port 2500 --on-ip 127.0.0.1 --tproxy-mark 0x1
iptables -t mangle -A HYSTERIA -p udp -j TPROXY --on-port 2500 --on-ip 127.0.0.1 --tproxy-mark 0x1 # (4)!
# Enable the above rules
iptables -t mangle -A PREROUTING -j HYSTERIA
# === Proxy Local Traffic - Start === (2)
iptables -t mangle -N HYSTERIA_MARK
# Match user to prevent loops
iptables -t mangle -A HYSTERIA_MARK -m owner --uid-owner hysteria -j RETURN
# Skip LAN and special IPv4 addresses
iptables -t mangle -A HYSTERIA_MARK -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A HYSTERIA_MARK -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A HYSTERIA_MARK -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A HYSTERIA_MARK -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A HYSTERIA_MARK -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A HYSTERIA_MARK -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A HYSTERIA_MARK -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A HYSTERIA_MARK -d 240.0.0.0/4 -j RETURN
# Mark traffic to re-route it to PREROUTING
iptables -t mangle -A HYSTERIA_MARK -p tcp -j MARK --set-mark 0x1
iptables -t mangle -A HYSTERIA_MARK -p udp -j MARK --set-mark 0x1
# Enable the above rules
iptables -t mangle -A OUTPUT -j HYSTERIA_MARK
# === Proxy Local Traffic - End ===
-
If the interface for the default route has a public IPv4 address assigned by your ISP, omitting these rules will result in abnormal proxy behavior for local traffic.
-
The following rules are additional rules for configuring proxy for local traffic. The rules before this line are still mandatory even if you only need to proxy local traffic. If you only need to proxy traffic within the local network, you can skip the rules after this line.
-
When proxying local traffic (enabling OUTPUT chain rules), additional rules are needed if you require access to this router via a public IPv4 address assigned by your ISP.
-
If you do not need to proxy UDP traffic, you can remove all rules that include
-p udp
.
ip6tables -t mangle -N HYSTERIA
# Skip traffic already handled by TProxy (1)
ip6tables -t mangle -A HYSTERIA -p tcp -m socket --transparent -j MARK --set-mark 0x1
ip6tables -t mangle -A HYSTERIA -p udp -m socket --transparent -j MARK --set-mark 0x1
ip6tables -t mangle -A HYSTERIA -m socket -j RETURN
# Only proxy public IPv6 addresses (3)
ip6tables -t mangle -A HYSTERIA ! -d 2000::/3 -j RETURN
# Redirect traffic to the TProxy port
ip6tables -t mangle -A HYSTERIA -p tcp -j TPROXY --on-port 2500 --on-ip ::1 --tproxy-mark 0x1
ip6tables -t mangle -A HYSTERIA -p udp -j TPROXY --on-port 2500 --on-ip ::1 --tproxy-mark 0x1 # (4)!
# Enable the above rules
ip6tables -t mangle -A PREROUTING -j HYSTERIA
# === Proxy Local Traffic - Start === (2)
ip6tables -t mangle -N HYSTERIA_MARK
# Match user to prevent loops
ip6tables -t mangle -A HYSTERIA_MARK -m owner --uid-owner hysteria -j RETURN
# Only proxy public IPv6 addresses
ip6tables -t mangle -A HYSTERIA_MARK ! -d 2000::/3 -j RETURN
# Mark traffic to re-route it to PREROUTING
ip6tables -t mangle -A HYSTERIA_MARK -p tcp -j MARK --set-mark 0x1
ip6tables -t mangle -A HYSTERIA_MARK -p udp -j MARK --set-mark 0x1
# Enable the above rules
ip6tables -t mangle -A OUTPUT -j HYSTERIA_MARK
# === Proxy Local Traffic - End ===
-
If the interface for the default route has a public IPv6 address assigned by your ISP, omitting these rules will result in abnormal proxy behavior for local traffic.
-
The following rules are additional rules for configuring proxy for local traffic. The rules before this line are still mandatory even if you only need to proxy local traffic. If you only need to proxy traffic within the local network, you can skip the rules after this line.
-
When proxying local traffic (enabling OUTPUT chain rules), additional rules are needed if you require access to this router via a public IPv6 address assigned by your ISP.
-
If you do not need to proxy UDP traffic, you can remove all rules that include
-p udp
.