Skip to content

Instantly share code, notes, and snippets.

@boypt
Last active December 25, 2023 07:28
Show Gist options
  • Save boypt/cf8e79c943e2217785115d0201c0f9e3 to your computer and use it in GitHub Desktop.
Save boypt/cf8e79c943e2217785115d0201c0f9e3 to your computer and use it in GitHub Desktop.
TPROXY use case with v2ray
#!/bin/bash
apply_mangle() {
ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100
iptables -t mangle -N V2RAY_MASK
iptables -t mangle -A V2RAY_MASK -m set --match-set white_list dst -j RETURN
iptables -t mangle -A V2RAY_MASK -p udp -m multiport --ports 53,67:68,135:139 -j RETURN
iptables -t mangle -A V2RAY_MASK -p udp -j TPROXY --on-port $PORT --on-ip 127.0.0.1 --tproxy-mark 1
iptables -t mangle -A V2RAY_MASK -p tcp -j TPROXY --on-port $PORT --on-ip 127.0.0.1 --tproxy-mark 1
local MATCH=""
if [[ $SRCIP ]]; then MATCH="-s $SRCIP $MATCH"; fi
if [[ $INTERFACE ]]; then MATCH="-i $INTERFACE $MATCH"; fi
iptables -t mangle -A PREROUTING ${MATCH} -j V2RAY_MASK
}
flush_rules(){
iptables -t mangle -F PREROUTING
iptables -t mangle -F V2RAY_MASK
iptables -t mangle -X V2RAY_MASK
ip route flush table 100
ip rule del fwmark 1 table 100
ipset flush white_list
ipset destroy white_list
}
# creat ipset rules
create_ipset(){
ipset -! create white_list nethash && ipset flush white_list
WHLIST="10.0.0.0/8 \
100.64.0.0/10 \
127.0.0.0/8 \
169.254.0.0/16 \
172.16.0.0/12 \
192.0.0.0/24 \
192.0.2.0/24 \
192.168.0.0/16 \
224.0.0.0/4 \
240.0.0.0/4"
for ENTRY in $WHLIST; do
ipset add white_list "$ENTRY"
done
# ipset list
}
usage () {
echo "usage: $0 [-f|--flush] [-s|--src SRC] [-i|--interface INTERFACE] [-h|--help]"
echo " ";
echo " -f | --flush : flush rules created by this script."
echo " -s | --src : source ip to match.";
echo " -i | --interface : interface to match. Note: between -s and -i, one should at least be specified, both is fine.";
echo " -p | --port : dokodemo-door port of v2ray. Default: 1080"
echo " -h | --help : This message";
}
parse_args() {
# positional args
declare -a args
# named args
while [ "$1" != "" ]; do
case "$1" in
-f | --flush ) flush_rules; exit;;
-s | --src ) SRCIP="$2"; shift;;
-i | --interface ) INTERFACE="$2"; shift;;
-p | --port ) PORT="$2"; shift;;
-h | --help ) usage; exit;; # quit and show usage
* ) args+=("$1") # if no match, add it to the positional args
esac
shift # move to next kv pair
done
# restore positional args
set -- "${args[@]}"
# set positionals to vars
# positional_1="${args[0]}"
# positional_2="${args[1]}"
# validate required args
# if [[ -z "${an_arg}" || -z "${some_more_args}" ]]; then
# echo "Invalid arguments"
# usage
# exit;
# fi
# set defaults
# if [[ -z "$yet_more_args" ]]; then
# yet_more_args="a default value";
# fi
if [[ -z $INTERFACE && -z $SRCIP ]]; then
echo "Missing args: -s and -i, one should at least be specified, both is fine."
exit 1
fi
if [[ -z $PORT ]]; then
PORT=1080
fi
}
parse_args $@
flush_rules
create_ipset
apply_mangle
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment