|
#!/bin/sh |
|
|
|
REMOTE_SERVER="x.x.x.x" |
|
INBOUND_PORT="10808" |
|
HANDLE_IPV6="1" |
|
|
|
TPROXY_CHAIN="XRAY_TPROXY" |
|
GATEWAY_CHAIN="XRAY_GATEWAY" |
|
|
|
EXCLUDE_MARK="5" |
|
TPROXY_MARK="1" |
|
TPROXY_TABLE="99" |
|
|
|
CLIENTS_FILE="$(dirname $0)/clients.txt" |
|
CLIENTS_V6_FILE="$(dirname $0)/clients_v6.txt" |
|
|
|
excludeV4() { |
|
local CHAIN="$1" |
|
# Loopback address |
|
iptables -t mangle -A $CHAIN -d 127.0.0.1/8 -j RETURN |
|
# Broadcast address |
|
iptables -t mangle -A $CHAIN -d 255.255.255.255 -j RETURN |
|
# Remote address |
|
iptables -t mangle -A $CHAIN -d $REMOTE_SERVER -j RETURN |
|
# All except DNS |
|
iptables -t mangle -A $CHAIN -d 192.168.0.0/16 -p tcp -j RETURN |
|
iptables -t mangle -A $CHAIN -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN |
|
} |
|
|
|
excludeV6() { |
|
local CHAIN="$1" |
|
# Loopback address |
|
ip6tables -t mangle -A $CHAIN -d ::1/128 -j RETURN |
|
# Multicast addresses |
|
ip6tables -t mangle -A $CHAIN -d ff00::/8 -j RETURN |
|
# ULA addresses |
|
ip6tables -t mangle -A $CHAIN -d fc00::/7 -j RETURN |
|
# Link-local addresses |
|
ip6tables -t mangle -A $CHAIN -d fe80::/10 -j RETURN |
|
# All except DNS |
|
ip6tables -t mangle -A $CHAIN -d fd12:3456:789a::/64 -p tcp -j RETURN |
|
ip6tables -t mangle -A $CHAIN -d fd12:3456:789a::/64 -p udp ! --dport 53 -j RETURN |
|
} |
|
|
|
apply() { |
|
local VERSION="$1" |
|
local MAIN="$2" |
|
local CHAIN="$3" |
|
|
|
if [[ "$VERSION" == "6" ]]; then |
|
local IPTABLES="ip6tables" |
|
local INBOUND_ADDR="::1" |
|
local CLIENTS=$(cat $CLIENTS_V6_FILE) |
|
else |
|
local IPTABLES="iptables" |
|
local INBOUND_ADDR="127.0.0.1" |
|
local CLIENTS=$(cat $CLIENTS_FILE) |
|
fi |
|
|
|
local CHECK=$($IPTABLES -t mangle --list $MAIN | grep $CHAIN) |
|
|
|
if [ -n "$CHECK" ]; then |
|
echo "($IPTABLES) $CHAIN exits in $MAIN !!" |
|
exit 0 |
|
fi |
|
|
|
$IPTABLES -t mangle -N $CHAIN |
|
|
|
if [[ "$VERSION" == "6" ]]; then |
|
excludeV6 "$CHAIN" |
|
else |
|
excludeV4 "$CHAIN" |
|
fi |
|
|
|
$IPTABLES -t mangle -A $CHAIN -p udp --dport 123 -j RETURN |
|
$IPTABLES -t mangle -A $CHAIN -p udp --dport 323 -j RETURN |
|
$IPTABLES -t mangle -A $CHAIN -j RETURN -m mark --mark $EXCLUDE_MARK |
|
|
|
if [[ "$CHAIN" == "$TPROXY_CHAIN" ]]; then |
|
$IPTABLES -t mangle -A $CHAIN -p tcp -j TPROXY --on-ip $INBOUND_ADDR --on-port $INBOUND_PORT --tproxy-mark $TPROXY_MARK |
|
$IPTABLES -t mangle -A $CHAIN -p udp -j TPROXY --on-ip $INBOUND_ADDR --on-port $INBOUND_PORT --tproxy-mark $TPROXY_MARK |
|
fi |
|
|
|
if [[ "$CHAIN" == "$GATEWAY_CHAIN" ]]; then |
|
$IPTABLES -t mangle -A $CHAIN -p tcp -j MARK --set-mark $TPROXY_MARK |
|
$IPTABLES -t mangle -A $CHAIN -p udp -j MARK --set-mark $TPROXY_MARK |
|
fi |
|
|
|
echo "++ ($IPTABLES) $CHAIN => $MAIN" |
|
|
|
for CLIENT in $CLIENTS; do |
|
$IPTABLES -t mangle -A $MAIN -s $CLIENT -j $CHAIN |
|
done |
|
} |
|
|
|
flush() { |
|
local VERSION="$1" |
|
local MAIN="$2" |
|
local CHAIN="$3" |
|
|
|
if [[ "$VERSION" == "6" ]]; then |
|
local IPTABLES="ip6tables" |
|
local CLIENTS=$(cat $CLIENTS_V6_FILE) |
|
else |
|
local IPTABLES="iptables" |
|
local CLIENTS=$(cat $CLIENTS_FILE) |
|
fi |
|
|
|
echo "-- ($IPTABLES) $CHAIN => $MAIN" |
|
|
|
for CLIENT in $CLIENTS; do |
|
$IPTABLES -t mangle -D $MAIN -s $CLIENT -j $CHAIN |
|
done |
|
|
|
$IPTABLES -t mangle -F $CHAIN |
|
$IPTABLES -t mangle -X $CHAIN |
|
} |
|
|
|
if [[ "$1" == "start" ]]; then |
|
echo "Starting ..." |
|
|
|
apply "4" "PREROUTING" "$TPROXY_CHAIN" |
|
apply "4" "OUTPUT" "$GATEWAY_CHAIN" |
|
|
|
ip -4 rule add fwmark $TPROXY_MARK table $TPROXY_TABLE |
|
ip -4 route add local default dev lo table $TPROXY_TABLE |
|
|
|
if [[ "$HANDLE_IPV6" == "1" ]]; then |
|
apply "6" "PREROUTING" "$TPROXY_CHAIN" |
|
apply "6" "OUTPUT" "$GATEWAY_CHAIN" |
|
|
|
ip -6 rule add fwmark $TPROXY_MARK table $TPROXY_TABLE |
|
ip -6 route add local default dev lo table $TPROXY_TABLE |
|
fi |
|
elif [[ "$1" == "stop" ]]; then |
|
echo "Stoping ..." |
|
|
|
flush "4" "PREROUTING" "$TPROXY_CHAIN" |
|
flush "4" "OUTPUT" "$GATEWAY_CHAIN" |
|
|
|
ip -4 route del default table $TPROXY_TABLE |
|
ip -4 rule del fwmark $TPROXY_MARK |
|
|
|
if [[ "$HANDLE_IPV6" == "1" ]]; then |
|
flush "6" "PREROUTING" "$TPROXY_CHAIN" |
|
flush "6" "OUTPUT" "$GATEWAY_CHAIN" |
|
|
|
ip -6 route del default table $TPROXY_TABLE |
|
ip -6 rule del fwmark $TPROXY_MARK |
|
fi |
|
elif [[ "$1" == "status" ]]; then |
|
echo "iptables" |
|
iptables -v -t mangle --list PREROUTING |
|
iptables -v -t mangle --list OUTPUT |
|
|
|
if [[ "$HANDLE_IPV6" == "1" ]]; then |
|
echo "ip6tables" |
|
ip6tables -v -t mangle --list PREROUTING |
|
ip6tables -v -t mangle --list OUTPUT |
|
fi |
|
elif [[ "$1" == "chains" ]]; then |
|
echo "iptables" |
|
iptables -v -t mangle --list $TPROXY_CHAIN |
|
iptables -v -t mangle --list $GATEWAY_CHAIN |
|
|
|
if [[ "$HANDLE_IPV6" == "1" ]]; then |
|
echo "ip6tables" |
|
ip6tables -v -t mangle --list $TPROXY_CHAIN |
|
ip6tables -v -t mangle --list $GATEWAY_CHAIN |
|
fi |
|
else |
|
echo "You should run it with \"start\", \"stop\", \"status\" or \"chains\" argument" |
|
fi |
|
|
|
echo "Done!" |