trt-json.sh (12767B)
1#!/bin/bash 2 3# trt (transparent proxy for Trojan) 4 5INFO=~/.local/share/data/trojan/srvinfo.json 6CONFIG="/etc/trojan/config.json" 7SUBURL="" 8# the value of IPV4_SERVERS_LIST and IPV6_SERVERS_LIST should be generated by the script itself 9IPV4_SERVERS_LIST="" 10IPV6_SERVERS_LIST="" 11: "${progname:="${0##*/}"}" 12 13## Part 1: iptables 14 15query_ipv4() { 16 all_servers=$1 17 while true; do 18 servers=$(printf "$all_servers" | grep '[[:alpha:]]') 19 if [[ -z "$servers" ]]; then 20 all_servers=$(echo "$all_servers" | sort | uniq | paste -s -d' ') 21 break 22 fi 23 servers_ip=$(dig +short -t A $servers) 24 all_servers=$(echo "$all_servers" | sed "/[[:alpha:]]/d") 25 all_servers+=$(echo -e "\n$servers_ip") 26 done 27 echo $all_servers 28} 29query_ipv6() { 30 all_servers=$1 31 while true; do 32 servers=$(printf "$all_servers" | grep -v ':' | grep '[[:alpha:]]') 33 if [[ -z "$servers" ]]; then 34 all_servers=$(echo "$all_servers" | sort | uniq | paste -s -d' ') 35 break 36 fi 37 servers_ip=$(dig +short -t AAAA $servers) 38 all_servers=$(echo "$all_servers" | sed "/\./d") 39 all_servers+=$(echo -e "\n$servers_ip") 40 done 41 echo $all_servers 42} 43clear_iptables_rules() { 44 [ "$EUID" -ne 0 ] && { echo "Please run as root" && exit 1; } 45 ## https://gist.github.com/jarek-przygodzki/29830f868e0c29e1dccb09beafbc4f72 46 iptables -P INPUT ACCEPT 47 iptables -P FORWARD ACCEPT 48 iptables -P OUTPUT ACCEPT 49 iptables -F INPUT 50 iptables -F OUTPUT 51 iptables -F FORWARD 52 iptables -F 53 iptables -t nat -F 54 iptables -t mangle -F 55 iptables -X 56 iptables -t nat -X 57 iptables -t mangle -X 58 echo "Cleared iptables rules" 59} 60add_iptables_rules() { 61 clear_iptables_rules 62 ## https://github.com/shadowsocks/shadowsocks-libev#transparent-proxy 63 iptables -t nat -N TROJAN 64 for ip in $IPV4_SERVERS_LIST; do 65 iptables -t nat -A TROJAN -d $ip -j RETURN 66 done 67 iptables -t nat -A TROJAN -d 0.0.0.0/8 -j RETURN 68 iptables -t nat -A TROJAN -d 10.0.0.0/8 -j RETURN 69 iptables -t nat -A TROJAN -d 127.0.0.0/8 -j RETURN 70 iptables -t nat -A TROJAN -d 169.254.0.0/16 -j RETURN 71 iptables -t nat -A TROJAN -d 172.16.0.0/12 -j RETURN 72 iptables -t nat -A TROJAN -d 192.168.0.0/16 -j RETURN 73 iptables -t nat -A TROJAN -d 224.0.0.0/4 -j RETURN 74 iptables -t nat -A TROJAN -d 240.0.0.0/4 -j RETURN 75 iptables -t nat -A TROJAN -p tcp -j REDIRECT --to-ports 16280 76 iptables -t nat -A OUTPUT -j TROJAN 77 echo "Added iptables rules" 78} 79 80## Part 2: Update servers 81 82update_srv() { 83 read -p "Type $(tput bold)Yes$(tput sgr0) to continue... " && [ $REPLY == "Yes" ] || { echo "$(tput bold; tput setaf 1)Canceled$(tput sgr0)"; exit 1; } 84 TROJAN_URLS=$(curl -s "${SUBURL}" | base64 -d) 85 ## IPv4 list 86 SERVERS_LIST=$(echo "$TROJAN_URLS" | cut -d'@' -f2 | cut -d':' -f1 | sort | uniq) 87 ipv4_list=$(query_ipv4 "$SERVERS_LIST") 88 sed -i "s/^IPV4_SERVERS_LIST=.*$/IPV4_SERVERS_LIST=\"$ipv4_list\"/" $(realpath $0) && echo "Successfully updated $(tput bold)$(echo "$ipv4_list" | wc -w)$(tput sgr0) IPv4 addresses" 89 ## IPv6 list 90 ipv6_list=$(query_ipv6 "$SERVERS_LIST") 91 sed -i "s/^IPV6_SERVERS_LIST=.*$/IPV6_SERVERS_LIST=\"$ipv6_list\"/" $(realpath $0) && echo "Successfully updated $(tput bold)$(echo "$ipv6_list" | wc -w)$(tput sgr0) IPv6 addresses" 92 ## JSON 93 : >"$INFO" 94 while read -r node; do 95 ## mark 96 mark=$(urldecode ${node#*\#}) 97 mark=$(echo $mark | edit_mark) 98 mark_lower=$(echo $mark | tr '[:upper:]' '[:lower:]' | tr ' ' '_') 99 country=$(echo $mark | cut -d' ' -f1) 100 flag=$(echo $country | name2flag) 101 provider=$(echo $mark | cut -d' ' -f2) 102 order=$(echo $mark | cut -d' ' -f3) 103 ## info 104 node=${node#trojan://} && node=${node%\#*} 105 password=${node%\@*} && node=${node#*@} 106 remote_addr=${node%\:*} 107 remote_port=${node#*:} 108 case $provider in GIA|RT|AWS|Azure|CHT|TFN|TTNet|KDDI|GTT|Cogent|ETPI|KT|NTT|PCCW|WTT) level=global ratio="1";; esac 109 case $provider in BGP) level=bgp ratio="1";; esac 110 case $provider in IPLC) level=iplc ratio="2";; esac 111 case $provider in IEPL) level=iepl ratio="2";; esac 112 case $provider in Gamer) level=advanced ratio="10";; esac 113 ## json 114 jo remote_addr=$remote_addr remote_port=$remote_port password="[\"$password\"]" mark="$(jo -- level=$level ratio=$ratio name="$mark" id="$mark_lower" flag="$flag" country="$country" provider="$provider" -s order="$order")" 115 unset level ratio 116 done < <(echo "$TROJAN_URLS" | sed 's/?allowInsecure=1&tfo=1//') | jo -p -a >"$INFO" && echo "Successfully updated $(tput bold)$(jq -r '.[].remote_addr' "$INFO"| wc -l)$(tput sgr0) servers" 117} 118 119gen_hosts() { 120 DOMAINS=$(jq -r '.[].remote_addr' srvinfo.json | grep '[[:alpha:]]') 121 while IFS= read -r domain; do 122 query_ipv4 $domain | tr ' ' '\n' | sed "s/$/ $domain/" 123 done <<< "$DOMAINS" | column -t 124} 125 126## Part 2: JSON 127 128urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; } 129name2flag() { 130 sed -e ' 131 s/AE/๐ฆ๐ช/ 132 s/AU/๐ฆ๐บ/ 133 s/BR/๐ง๐ท/ 134 s/DE/๐ฉ๐ช/ 135 s/FR/๐ซ๐ท/ 136 s/GB/๐ฌ๐ง/ 137 s/HK/๐ญ๐ฐ/ 138 s/IN/๐ฎ๐ณ/ 139 s/JP/๐ฏ๐ต/ 140 s/KR/๐ฐ๐ท/ 141 s/PH/๐ต๐ญ/ 142 s/RU/๐ท๐บ/ 143 s/SG/๐ธ๐ฌ/ 144 s/TR/๐น๐ท/ 145 s/TW/๐น๐ผ/ 146 s/US/๐บ๐ธ/ 147 ' 148} 149edit_mark() { 150 sed -e ' 151 s/^ไฟ็พ ๆฏ/RU/ 152 s/^ๅฐๅบฆ/IN/ 153 s/^ๅ่ณๅ ถ/TR/ 154 s/^ๅทด่ฅฟ/BR/ 155 s/^ๅพทๅ/DE/ 156 s/^ๆฐๅ ๅก/SG/ 157 s/^ๆฅๆฌ/JP/ 158 s/^ๆณๅ/FR/ 159 s/^ๆพณๅคงๅฉไบ/AU/ 160 s/^็พๅ/US/ 161 s/^่บ็ฃ/TW/ 162 s/^่ฑๅ/GB/ 163 s/^่ฒๅพ่ณ/PH/ 164 s/^้ๅ/KR/ 165 s/^้ฆๆธฏ/HK/ 166 s/^้ฟ่ฏ้ /AE/ 167 ' 168} 169query_nodes() { 170 case "$LEVEL" in 171 global|bgp|iplc|iepl|advanced) 172 # summary 173 ratio=$(jq -r --arg v "$LEVEL" '[.[].mark | select(.level==$v)][0].ratio' "$INFO") 174 countries=$(jq -r --arg v "$LEVEL" '.[].mark | select(.level==$v) | .country' "$INFO" | sort | uniq | tr '[:upper:]' '[:lower:]' | tr '\n' ' ') 175 providers=$(jq -r --arg v "$LEVEL" '.[].mark | select(.level==$v) | .provider' "$INFO" | sort | uniq | tr '\n' ' ') 176 # list of servers 177 #srvlist=$(jq -r --arg v "$LEVEL" '.[].mark | select(.level==$v) | .id + "\t" + .time_appconnect' "$INFO" | sed 's/^/ /' | sort) 178 #num_srv=$(echo "$srvlist" | wc -l) 179 # print 180 srvlist=$(jq -r --arg v "$LEVEL" '.[].mark | select(.level==$v) | .time_appconnect + "|" + .speed_download + "|" + .id' "$INFO" | sed 's/^/ /' | sort -hr | column -s'|' -t) 181 echo -e "\n$srvlist\n" 182 echo -e "Level:|${LEVEL^}\nRatio:|$ratio\nCountries:|$countries\nNodes:|${num_srv}\nProviders:|$providers" | column -s'|' -t | sed 's/^/ /' && echo 183 ;; 184 time) jq -r '.[].mark | .time_appconnect + "|" + .speed_download + "|" + .id' $INFO | sed 's/^/ /' | column -s'|' -t | sort -hr | sed '/^ /d' | grep 'MiB/s\|0B/s' | GREP_COLORS='ms=01;32' egrep --color 'hk_|kr_|jp_|tw_|$';; 185 speed) jq -r '.[].mark | .speed_download + "|" + .time_appconnect + "|" + .id' $INFO | sed 's/^/ /' | column -s'|' -t | sort -h | sed '/^ /d' | grep 'MiB/s\|0B/s' | GREP_COLORS='ms=01;32' egrep --color 'hk_|kr_|jp_|tw_|$';; 186 country) jq -r '.[].mark | .id + "|" + .time_appconnect + "|" + .speed_download' $INFO | sed 's/^/ /' | column -s'|' -t | sort -h | GREP_COLORS='ms=01;32' egrep --color 'hk_|kr_|jp_|tw_|$';; 187 188 *) usage ;; 189 esac 190} 191switch_node() { 192 # info 193 if [[ ! -z "$NODE" ]] && [[ $(jq -r --arg v "$NODE" '.[].mark | select(.id==$v) | .id' $INFO) == "$NODE" ]]; then 194 id="$NODE" 195 else 196 echo "No such node" && exit 1 197 fi 198 # variables 199 remote_addr=$(jq -r --arg v "$id" '.[] | select(.mark.id==$v) | .remote_addr' "$INFO") 200 remote_port=$(jq -r --arg v "$id" '.[] | select(.mark.id==$v) | .remote_port' "$INFO") 201 password=$(jq -r --arg v "$id" '.[] | select(.mark.id==$v) | .password | .[0]' "$INFO") 202 level=$(jq -r --arg v "$id" '.[].mark | select(.id==$v) | .level' "$INFO") 203 ratio=$(jq -r --arg v "$id" '.[].mark | select(.id==$v) | .ratio' "$INFO") 204 flag=$(jq -r --arg v "$id" '.[].mark | select(.id==$v) | .flag' "$INFO") 205 id=$(jq -r --arg v "$id" '.[].mark | select(.id==$v) | .id' "$INFO") 206 name=$(jq -r --arg v "$id" '.[].mark | select(.id==$v) | .name' "$INFO") 207 provider=$(jq -r --arg v "$id" '.[].mark | select(.id==$v) | .provider' "$INFO") 208 # edit config 209 jj -v "$remote_addr" -p -i $CONFIG -o $CONFIG 'remote_addr' 210 jj -v "$remote_port" -p -i $CONFIG -o $CONFIG 'remote_port' 211 jj -v "$password" -p -i $CONFIG -o $CONFIG 'password.0' 212 jj -v "$level" -p -i $CONFIG -o $CONFIG 'info.level' 213 jj -v "$ratio" -p -i $CONFIG -o $CONFIG 'info.ratio' 214 jj -v "$flag" -p -i $CONFIG -o $CONFIG 'info.flag' 215 jj -v "$id" -p -i $CONFIG -o $CONFIG 'info.id' 216 jj -v "$name" -p -i $CONFIG -o $CONFIG 'info.name' 217 jj -v "$provider" -p -i $CONFIG -o $CONFIG 'info.provider' 218 #echo -e "Level:|$level\nRatio:|$ratio\nNode:|$NODE\nServer:|$remote_addr\nPort:|$remote_port\nPassword:|$password" | column -s'|' -t 219 echo -e "$id\t${remote_addr}:${remote_port}" 220} 221 222get_info() { 223 echo "Servers: $(tput bold)$(jq -r '.[].remote_addr' $INFO | wc -l)$(tput sgr0)" 224 echo "IPv4: $(tput bold)$(echo $IPV4_SERVERS_LIST | wc -w)$(tput sgr0)" 225 echo "IPv6: $(tput bold)$(echo $IPV6_SERVERS_LIST | wc -w)$(tput sgr0)" 226 echo 227 [ -s /var/service/trojan/supervise/pid ] && jq -r '.info | "NAT: " + .name + " (" + .level + " *" + (.ratio|tostring) + ")"' /etc/trojan/config.json 228 [ -s $HOME/.local/service/trojan-client/supervise/pid ] && jq -r '.info | "Client: " + .name + " (" + .level + " *" + (.ratio|tostring) + ")"' $HOME/.local/service/trojan-client/client.json 229 230} 231 232speedtest() { 233 case "$LEVEL" in 234 global|bgp|iplc|iepl|advanced) 235 read -p "Type $(tput bold)Yes$(tput sgr0) to continue... " && [ $REPLY == "Yes" ] || { echo "$(tput bold; tput setaf 1)Canceled$(tput sgr0)"; exit 1; } 236 #echo "$INFO $CONFIG" 237 SERVERS=$(jq -r --arg v "$LEVEL" '.[].mark | select(.level==$v) | .id' $INFO) 238 #echo "$SERVERS" 239 for id in $SERVERS; do 240 #id=$(jq -r --arg v "$sid" '.[] | select(.id==$v) | .mark | .id' $INFO) 241 index=$(jq -r --arg v "$id" 'map(.mark.id==$v) | index(true)' $INFO) 242 NODE=$id switch_node 243 if sv reload ~/.local/service/trojan-client{,/log} >/dev/null; then 244 sleep 1 245 else 246 echo "Failed to reload trojan-client service config, exiting..." && exit 1 247 fi 248 time_appconnect=$(curl --connect-timeout 2 -x socks5h://127.0.0.1:51837 -o/dev/null -sw '%{time_appconnect}' 'https://connectivitycheck.gstatic.com/generate_204') 249 time_appconnect=$(printf "%.0f ms" "$(bc<<<${time_appconnect}*1000)") 250 if [[ $time_appconnect == "0 ms" ]]; then 251 time_appconnect="" 252 speed_download="" 253 else 254 speed_download=$(curl -x socks5h://127.0.0.1:51837 http://speedtest-sgp1.digitalocean.com/10mb.test -s -o/dev/null --write-out '%{speed_download}' | numfmt --to=iec-i --suffix=B/s) 255 fi 256 echo -e "$time_appconnect\t$speed_download\n" 257 jj -v "$time_appconnect" -p -i $INFO -o $INFO "$index.mark.time_appconnect" 258 jj -v "$speed_download" -p -i $INFO -o $INFO "$index.mark.speed_download" 259 done;; 260 *) usage ;; 261 esac 262} 263 264usage() { 265 cat <<_EOF | GREP_COLORS='ms=1' egrep --color "$progname|$" 266Usage: $progname <node_level> query nodes by levels 267 $progname <time|speed|country> query nodes by types 268 $progname sn <node_id> switch node (nat) 269 $progname sc <node_id> switch node (client) 270 $progname i show info 271 272 $progname -u update IP list and json 273 $progname -t <node_level> speed test 274 275 sudo $progname -a add iptables rules 276 sudo $progname -c clear iptables rules 277 278 +------------+-------+-------------+ 279 | node_level | ratio | provider | 280 +------------+-------+-------------+ 281 | global | 1 | *various* | 282 | bgp | 1.2 | BGP | 283 | iplc | 2 | IPLC | 284 | iepl | 2 | IEPL | 285 | advanced | 10 | *gamer* | 286 +------------+-------+-------------+ 287 288_EOF 289 exit 1 290} 291 292case "$1" in 293 global|bgp|iplc|iepl|advanced|time|speed|country) LEVEL=$1 query_nodes | GREP_COLORS='ms=01;32' egrep --color 'hk_|kr_|jp_|tw_|$';; 294 sn) 295 NODE=$2 switch_node 296 sv reload trojan{,/log} 297 ;; 298 sc) 299 NODE=$2 CONFIG=~/.local/service/trojan-client/client.json switch_node 300 sv reload ~/.local/service/trojan-client 301 ;; 302 i) get_info ;; 303 #-h) gen_hosts ;; 304 -u) update_srv ;; 305 -t) CONFIG=~/.local/service/trojan-client/client.json LEVEL=$2 speedtest ;; 306 -a) add_iptables_rules ;; 307 -c) clear_iptables_rules ;; 308 *) usage ;; 309esac 310exit 0 311 312 313## extra comands 314# jq -r --arg v global '.[].mark | select(.level==$v) | .speed_download + "|" + .time_appconnect + "|" + .id' ~/.local/share/data/trojan/srvinfo.json | sed 's/^/ /' | column -s'|' -t | sort -h 315# jq -r '.[].mark | .speed_download + "|" + .time_appconnect + "|" + .id' ~/.local/share/data/trojan/srvinfo.json | sed 's/^/ /' | column -s'|' -t | sort -h | GREP_COLORS='ms=01;32' egrep --color 'hk_|kr_|jp_|tw_|$' 316# jq -r '.[].mark | .time_appconnect + "|" + .speed_download + "|" + .id' ~/.local/share/data/trojan/srvinfo.json | sed 's/^/ /' | column -s'|' -t | sort -h | GREP_COLORS='ms=01;32' egrep --color 'hk_|kr_|jp_|tw_|$'