├── LICENSE ├── README.md └── install.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Peyman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wstunnel 2 | 3 | Tunnel all your traffic over websocket protocol - Bypass firewalls/DPI - one-click-script 4 | 5 | ## Install 6 | ``` 7 | bash <(curl -fsSL https://raw.githubusercontent.com/Ptechgithub/wstunnel/main/install.sh) 8 | ``` 9 | ![13](https://raw.githubusercontent.com/Ptechgithub/configs/main/media/14.jpg) 10 | 11 | - این اسکریپ نصب wstunnel برای ایجاد یک تونل امن از طریق پروتکل WebSocket استفاده می‌شود. 12 | - تانل بر بستر websocket 13 | - تانل بین دو سرور یا (سرور - کلاینت ) 14 | - تانل معکوس 15 | - امکان نصب روی Termux جهت دور زدن محدودیت پورت udp 16 | 17 | ### جهت نصب دستی Custom از لیست زیر میتوانید استفاده کنید. 18 | 19 | ## لیست کامل دستورات 20 | 21 | ``` 22 | Use the websockets protocol to tunnel {TCP,UDP} traffic 23 | wsTunnelClient <---> wsTunnelServer <---> RemoteHost 24 | Use secure connection (wss://) to bypass proxies 25 | 26 | Client: 27 | Usage: wstunnel client [OPTIONS] 28 | 29 | Arguments: 30 | Address of the wstunnel server 31 | Example: With TLS wss://wstunnel.example.com or without ws://wstunnel.example.com 32 | 33 | Options: 34 | -L, --local-to-remote <{tcp,udp,socks5,stdio}://[BIND:]PORT:HOST:PORT> 35 | Listen on local and forwards traffic from remote. Can be specified multiple times 36 | examples: 37 | 'tcp://1212:google.com:443' => listen locally on tcp on port 1212 and forward to google.com on port 443 38 | 39 | 'udp://1212:1.1.1.1:53' => listen locally on udp on port 1212 and forward to cloudflare dns 1.1.1.1 on port 53 40 | 'udp://1212:1.1.1.1:53?timeout_sec=10' timeout_sec on udp force close the tunnel after 10sec. Set it to 0 to disable the timeout [default: 30] 41 | 42 | 'socks5://[::1]:1212' => listen locally with socks5 on port 1212 and forward dynamically requested tunnel 43 | 44 | 'tproxy+tcp://[::1]:1212' => listen locally on tcp on port 1212 as a *transparent proxy* and forward dynamically requested tunnel 45 | 'tproxy+udp://[::1]:1212?timeout_sec=10' listen locally on udp on port 1212 as a *transparent proxy* and forward dynamically requested tunnel 46 | linux only and requires sudo/CAP_NET_ADMIN 47 | 48 | 'stdio://google.com:443' => listen for data from stdio, mainly for `ssh -o ProxyCommand="wstunnel client -L stdio://%h:%p ws://localhost:8080" my-server` 49 | -R, --remote-to-local <{tcp,udp}://[BIND:]PORT:HOST:PORT> 50 | Listen on remote and forwards traffic from local. Can be specified multiple times. 51 | examples: 52 | 'tcp://1212:google.com:443' => listen on server for incoming tcp cnx on port 1212 and forward to google.com on port 443 from local machine 53 | 'udp://1212:1.1.1.1:53' => listen on server for incoming udp on port 1212 and forward to cloudflare dns 1.1.1.1 on port 53 from local machine 54 | 'socks://[::1]:1212' => listen on server for incoming socks5 request on port 1212 and forward dynamically request from local machine 55 | --socket-so-mark 56 | (linux only) Mark network packet with SO_MARK sockoption with the specified value. 57 | You need to use {root, sudo, capabilities} to run wstunnel when using this option 58 | -c, --connection-min-idle 59 | Client will maintain a pool of open connection to the server, in order to speed up the connection process. 60 | This option set the maximum number of connection that will be kept open. 61 | This is useful if you plan to create/destroy a lot of tunnel (i.e: with socks5 to navigate with a browser) 62 | It will avoid the latency of doing tcp + tls handshake with the server [default: 0] 63 | --tls-sni-override 64 | Domain name that will be use as SNI during TLS handshake 65 | Warning: If you are behind a CDN (i.e: Cloudflare) you must set this domain also in the http HOST header. 66 | or it will be flagged as fishy and your request rejected 67 | --tls-verify-certificate 68 | Enable TLS certificate verification. 69 | Disabled by default. The client will happily connect to any server with self signed certificate. 70 | -p, --http-proxy 71 | If set, will use this http proxy to connect to the server 72 | --http-upgrade-path-prefix 73 | Use a specific prefix that will show up in the http path during the upgrade request. 74 | Useful if you need to route requests server side but don't have vhosts [default: morille] 75 | --http-upgrade-credentials 76 | Pass authorization header with basic auth credentials during the upgrade request. 77 | If you need more customization, you can use the http_headers option. 78 | --websocket-ping-frequency-sec 79 | Frequency at which the client will send websocket ping to the server. [default: 30] 80 | --websocket-mask-frame 81 | Enable the masking of websocket frames. Default is false 82 | Enable this option only if you use unsecure (non TLS) websocket server and you see some issues. Otherwise, it is just overhead. 83 | -H, --http-headers 84 | Send custom headers in the upgrade request 85 | Can be specified multiple time 86 | -h, --help 87 | Print help 88 | 89 | Server: 90 | Usage: wstunnel server [OPTIONS] 91 | 92 | Arguments: 93 | Address of the wstunnel server to bind to 94 | Example: With TLS wss://0.0.0.0:8080 or without ws://[::]:8080 95 | 96 | Options: 97 | --socket-so-mark 98 | (linux only) Mark network packet with SO_MARK sockoption with the specified value. 99 | You need to use {root, sudo, capabilities} to run wstunnel when using this option 100 | --websocket-ping-frequency-sec 101 | Frequency at which the server will send websocket ping to client. 102 | --websocket-mask-frame 103 | Enable the masking of websocket frames. Default is false 104 | Enable this option only if you use unsecure (non TLS) websocket server and you see some issues. Otherwise, it is just overhead. 105 | --restrict-to 106 | Server will only accept connection from the specified tunnel information. 107 | Can be specified multiple time 108 | Example: --restrict-to "google.com:443" --restrict-to "localhost:22" 109 | -r, --restrict-http-upgrade-path-prefix 110 | Server will only accept connection from if this specific path prefix is used during websocket upgrade. 111 | Useful if you specify in the client a custom path prefix and you want the server to only allow this one. 112 | The path prefix act as a secret to authenticate clients 113 | Disabled by default. Accept all path prefix. Can be specified multiple time 114 | --tls-certificate 115 | [Optional] Use custom certificate (.crt) instead of the default embedded self signed certificate. 116 | --tls-private-key 117 | [Optional] Use a custom tls key (.key) that the server will use instead of the default embedded one 118 | -h, --help 119 | Print help 120 | ``` 121 | 122 | 123 | ### مثال: 124 | 125 | ### ساده‌ترین 126 | On your remote host, start the wstunnel's server by typing this command in your terminal 127 | - سرور (خارج) 128 | ```bash 129 | wstunnel server ws://[::]:8080 130 | ``` 131 | This will create a websocket server listening on any interface on port 8080. 132 | On the client side use this command to forward traffic through the websocket tunnel 133 | - کلاینت (سرور داخل) 134 | ```bash 135 | wstunnel client -L socks5://127.0.0.1:8888 --connection-min-idle 5 ws://myRemoteHost:8080 136 | ``` 137 | 138 | [لینک اصلی پروژه](https://github.com/erebe/wstunnel/tree/main) 139 | 140 | 141 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | red='\033[0;31m' 4 | green='\033[0;32m' 5 | yellow='\033[0;33m' 6 | blue='\033[0;34m' 7 | purple='\033[0;35m' 8 | cyan='\033[0;36m' 9 | white='\033[0;37m' 10 | rest='\033[0m' 11 | 12 | display_progress() { 13 | local duration=$1 14 | local sleep_interval=0.1 15 | local progress=0 16 | local bar_length=40 17 | local colors=("" "" "" "" "" "" "") 18 | 19 | while [ $progress -lt $duration ]; do 20 | echo -ne "\r${colors[$((progress % 7))]}" 21 | for ((i = 0; i < bar_length; i++)); do 22 | if [ $i -lt $((progress * bar_length / duration)) ]; then 23 | echo -ne "█" 24 | else 25 | echo -ne "░" 26 | fi 27 | done 28 | echo -ne " ${progress}%" 29 | progress=$((progress + 1)) 30 | sleep $sleep_interval 31 | done 32 | echo -ne "\r${colors[0]}" 33 | for ((i = 0; i < bar_length; i++)); do 34 | echo -ne " " 35 | done 36 | echo -ne " 100%" 37 | echo 38 | } 39 | 40 | # Check if running as root 41 | root_access() { 42 | if [ "$EUID" -ne 0 ]; then 43 | echo "Please run as root." 44 | exit 1 45 | fi 46 | } 47 | 48 | # Detect Linux distribution 49 | detect_distribution() { 50 | local supported_distributions=("ubuntu" "debian" "centos" "fedora") 51 | 52 | if [ -f /etc/os-release ]; then 53 | source /etc/os-release 54 | if [[ "${ID}" = "ubuntu" || "${ID}" = "debian" || "${ID}" = "centos" || "${ID}" = "fedora" ]]; then 55 | pm="apt-get" 56 | [ "${ID}" = "centos" ] && pm="yum" 57 | [ "${ID}" = "fedora" ] && pm="dnf" 58 | else 59 | echo "Unsupported distribution!" 60 | exit 1 61 | fi 62 | else 63 | echo "Unsupported distribution!" 64 | exit 1 65 | fi 66 | } 67 | 68 | #Check dependencies 69 | check_dependencies() { 70 | root_access 71 | detect_distribution 72 | display_progress 8 73 | "${pm}" update -y 74 | local dependencies=("wget" "tar") 75 | for dep in "${dependencies[@]}"; do 76 | if ! command -v "${dep}" &> /dev/null; then 77 | echo "${dep} is not installed. Installing..." 78 | sudo "${pm}" install "${dep}" -y 79 | fi 80 | done 81 | } 82 | 83 | #Check installed service 84 | check_installed() { 85 | if systemctl is-enabled --quiet wstunnel.service > /dev/null 2>&1; then 86 | echo "The WsTunnel service is already installed." 87 | exit 1 88 | fi 89 | } 90 | 91 | #Install wstunnel 92 | install_wstunnel() { 93 | check_installed 94 | mkdir wstunnel && cd wstunnel 95 | check_dependencies 96 | 97 | # Determine system architecture 98 | if [[ $(arch) == "x86_64" ]]; then 99 | latest_version=$(curl -s https://api.github.com/repos/erebe/wstunnel/releases/latest | grep -oP '"tag_name": "\K(.*?)(?=")') 100 | wstunnel_file="wstunnel_${latest_version//v}_linux_amd64.tar.gz" 101 | elif [[ $(arch) == "aarch64" ]]; then 102 | wstunnel_file="wstunnel_${latest_version//v}_linux_arm64.tar.gz" 103 | elif [[ $(arch) == "armv7l" ]]; then 104 | wstunnel_file="wstunnel_${latest_version//v}_linux_armv7.tar.gz" 105 | elif [[ $(uname) == "Darwin" ]]; then 106 | wstunnel_file="wstunnel_${latest_version//v}_darwin_amd64.tar.gz" 107 | else 108 | echo "Unsupported architecture!" 109 | exit 1 110 | fi 111 | 112 | # Download and extract wstunnel 113 | wget "https://github.com/erebe/wstunnel/releases/download/${latest_version}/${wstunnel_file}" -q 114 | tar -xvf "$wstunnel_file" > /dev/null 115 | chmod +x wstunnel 116 | # Move wstunnel binary to /usr/local/bin (adjust if necessary) 117 | sudo mv wstunnel /usr/local/bin/wstunnel 118 | cd .. 119 | rm -rf wstunnel 120 | } 121 | 122 | 123 | # Get inputs 124 | get_inputs() { 125 | clear 126 | PS3=$'\n'"# Please Enter your choice: " 127 | options=("External-[server]" "Internal-[client]" "Exit") 128 | 129 | select server_type in "${options[@]}"; do 130 | case "$REPLY" in 131 | 1) 132 | read -p "Please Enter Connection Port (server <--> client) [default, 443]: " port 133 | port=${port:-443} 134 | read -p "Do you want to use TLS? (yes/no) [default: yes]: " use_tls 135 | use_tls=${use_tls:-yes} 136 | 137 | if [ "$use_tls" = "yes" ]; then 138 | use_tls="wss" 139 | else 140 | use_tls="ws" 141 | fi 142 | 143 | argument="server $use_tls://[::]:$port" 144 | break 145 | ;; 146 | 2) 147 | read -p "Enter foreign IP [External-server]: " foreign_ip 148 | read -p "Please Enter Your config [vpn] Port :" config_port 149 | read -p "Please Enter Connection Port (server <--> client) [default, 443]: " port 150 | port=${port:-443} 151 | read -p "Do you want to use TLS? (yes/no) [default: yes]: " use_tls 152 | use_tls=${use_tls:-yes} 153 | 154 | if [ "$use_tls" = "yes" ]; then 155 | use_tls="wss" 156 | else 157 | use_tls="ws" 158 | fi 159 | 160 | echo -e "Enter connection type: 161 | 1) tcp ${purple}[vless , vmess , trojan , ...]${rest} 162 | 2) udp ${purple}[Wireguard , hysteria, tuic , ...]${rest} 163 | 3) socks5 164 | 4) stdio" 165 | echo "" 166 | read -p "Enter number (default is: 1--> tcp): " choice 167 | 168 | case $choice in 169 | 1) connection_type="tcp" ;; 170 | 2) connection_type="udp" ;; 171 | 3) connection_type="socks5" ;; 172 | 4) connection_type="stdio" ;; 173 | *) connection_type="tcp" ;; 174 | esac 175 | read -p "Do you want to use SNI? (yes/no) [default: yes]: " use_sni 176 | use_sni=${use_sni:-yes} 177 | if [ "$use_sni" = "yes" ]; then 178 | read -p "Please Enter SNI [default: google.com]: " tls_sni 179 | tls_sni=${tls_sni:-google.com} 180 | tls_sni_argument="--tls-sni-override $tls_sni" 181 | fi 182 | 183 | # Add ?timeout_sec=0 only for UDP 184 | if [ "$connection_type" = "udp" ]; then 185 | timeout_argument="?timeout_sec=0" 186 | else 187 | timeout_argument="" 188 | fi 189 | 190 | read -p "Do you want to add more ports? (yes/no) [default: no]: " add_port 191 | add_port=${add_port:-no} 192 | 193 | if [ "$add_port" == "yes" ]; then 194 | read -p "Enter ports separated by commas (e.g., 2096,8080): " port_list 195 | IFS=',' read -ra ports <<< "$port_list" 196 | 197 | for new_port in "${ports[@]}"; do 198 | argument+=" -L '$connection_type://[::]:$new_port:localhost:$new_port$timeout_argument'" 199 | done 200 | fi 201 | 202 | argument="client -L '$connection_type://[::]:$config_port:localhost:$config_port$timeout_argument'$argument $use_tls://$foreign_ip:$port $tls_sni_argument" 203 | break 204 | ;; 205 | 3) 206 | echo "Exiting..." 207 | exit 0 208 | ;; 209 | *) 210 | echo "Invalid choice. Please Enter a valid number." 211 | ;; 212 | esac 213 | done 214 | 215 | create_service 216 | } 217 | 218 | 219 | get_inputs_Reverse() { 220 | clear 221 | PS3=$'\n'"# Please Enter your choice: " 222 | options=("Internal-[client]" "External-[server]" "Exit") 223 | 224 | select server_type in "${options[@]}"; do 225 | case "$REPLY" in 226 | 1) 227 | read -p "Please Enter Connection Port (server <--> client) [default, 443]: " port 228 | port=${port:-443} 229 | read -p "Do you want to use TLS? (yes/no) [default: yes]: " use_tls 230 | use_tls=${use_tls:-yes} 231 | 232 | if [ "$use_tls" = "yes" ]; then 233 | use_tls="wss" 234 | else 235 | use_tls="ws" 236 | fi 237 | 238 | argument="server $use_tls://[::]:$port" 239 | break 240 | ;; 241 | 2) 242 | echo -e "${yellow}Please install on [Internal-client] first. If you have installed it, press Enter to continue...${rest}" 243 | read -r 244 | read -p "Enter Internal IP [Internal-client]: " foreign_ip 245 | read -p "Please Enter Your config [vpn] Port :" config_port 246 | read -p "Please Enter Connection Port (server <--> client) [default, 443]: " port 247 | port=${port:-443} 248 | read -p "Do you want to use TLS? (yes/no) [default: yes]: " use_tls 249 | use_tls=${use_tls:-yes} 250 | 251 | if [ "$use_tls" = "yes" ]; then 252 | use_tls="wss" 253 | else 254 | use_tls="ws" 255 | fi 256 | 257 | echo -e "Enter connection type: 258 | 1) tcp ${purple}[vless , vmess , trojan , ...]${rest} 259 | 2) udp ${purple}[Wireguard , hysteria, tuic , ...]${rest} 260 | 3) socks5 261 | 4) stdio" 262 | echo "" 263 | read -p "Enter number (default is: 1--> tcp): " choice 264 | 265 | case $choice in 266 | 1) connection_type="tcp" ;; 267 | 2) connection_type="udp" ;; 268 | 3) connection_type="socks5" ;; 269 | 4) connection_type="stdio" ;; 270 | *) connection_type="tcp" ;; 271 | esac 272 | read -p "Do you want to use SNI? (yes/no) [default: yes]: " use_sni 273 | use_sni=${use_sni:-yes} 274 | if [ "$use_sni" = "yes" ]; then 275 | read -p "Please Enter SNI [default: google.com]: " tls_sni 276 | tls_sni=${tls_sni:-google.com} 277 | tls_sni_argument="--tls-sni-override $tls_sni" 278 | fi 279 | 280 | # Add ?timeout_sec=0 only for UDP 281 | if [ "$connection_type" = "udp" ]; then 282 | timeout_argument="?timeout_sec=0" 283 | else 284 | timeout_argument="" 285 | fi 286 | 287 | read -p "Do you want to add more ports? (yes/no) [default: no]: " add_port 288 | add_port=${add_port:-no} 289 | 290 | if [ "$add_port" == "yes" ]; then 291 | read -p "Enter ports separated by commas (e.g., 2096,8080): " port_list 292 | IFS=',' read -ra ports <<< "$port_list" 293 | 294 | for new_port in "${ports[@]}"; do 295 | argument+=" -R '$connection_type://[::]:$new_port:localhost:$new_port$timeout_argument'" 296 | done 297 | fi 298 | 299 | argument="client -R '$connection_type://[::]:$config_port:localhost:$config_port$timeout_argument'$argument $use_tls://$foreign_ip:$port $tls_sni_argument" 300 | break 301 | ;; 302 | 3) 303 | echo "Exiting..." 304 | exit 0 305 | ;; 306 | *) 307 | echo "Invalid choice. Please Enter a valid number." 308 | ;; 309 | esac 310 | done 311 | 312 | create_service 313 | } 314 | 315 | # Create service 316 | create_service() { 317 | cd /etc/systemd/system 318 | 319 | cat <> wstunnel.service 320 | [Unit] 321 | Description=WsTunnel 322 | After=network.target 323 | Wants=network.target 324 | 325 | [Service] 326 | Type=simple 327 | ExecStart=/usr/local/bin/wstunnel $argument 328 | 329 | [Install] 330 | WantedBy=multi-user.target 331 | EOL 332 | 333 | sudo systemctl daemon-reload 334 | sudo systemctl enable wstunnel.service 335 | sudo systemctl start wstunnel.service 336 | } 337 | 338 | 339 | 340 | 341 | install_custom() { 342 | install_wstunnel 343 | cd /etc/systemd/system 344 | echo "" 345 | read -p "Enter Your custom arguments (Example: wstunnel server wss://[::]:443): " arguments 346 | 347 | # Create the custom_tunnel.service file with user input 348 | cat <> wstunnel.service 349 | [Unit] 350 | Description=WsTunnel 351 | After=network.target 352 | 353 | [Service] 354 | Type=simple 355 | ExecStart=/usr/local/bin/$arguments 356 | 357 | [Install] 358 | WantedBy=multi-user.target 359 | EOL 360 | 361 | sudo systemctl daemon-reload 362 | sudo systemctl enable wstunnel.service 363 | sudo systemctl start wstunnel.service 364 | sleep 1 365 | check_tunnel_status 366 | } 367 | 368 | install() { 369 | if systemctl is-active --quiet wstunnel.service; then 370 | echo "The wstunnel service is already installed. and actived." 371 | else 372 | install_wstunnel 373 | get_inputs 374 | fi 375 | check_tunnel_status 376 | } 377 | 378 | install_reverse() { 379 | if systemctl is-active --quiet wstunnel.service; then 380 | echo "The wstunnel service is already installed. and actived." 381 | else 382 | install_wstunnel 383 | get_inputs_Reverse 384 | fi 385 | sleep 1 386 | check_tunnel_status 387 | } 388 | 389 | 390 | #Uninstall 391 | uninstall() { 392 | if ! systemctl is-enabled --quiet wstunnel.service > /dev/null 2>&1; then 393 | echo "WsTunnel is not installed." 394 | return 395 | else 396 | 397 | sudo systemctl stop wstunnel.service 398 | sudo systemctl disable wstunnel.service 399 | sudo rm /etc/systemd/system/wstunnel.service 400 | sudo systemctl daemon-reload 401 | sudo rm /usr/local/bin/wstunnel 402 | 403 | echo "WsTunnel has been uninstalled." 404 | fi 405 | } 406 | 407 | check_tunnel_status() { 408 | # Check the status of the tunnel service 409 | if systemctl is-active --quiet wstunnel.service; then 410 | echo -e "${yellow}~~~~~~~~~~~~~~~~~~~~~~~~~~~${rest}" 411 | echo -e "${cyan}WS Tunnel ==>:${purple}[${green}running ✔${purple}]${rest}" 412 | else 413 | echo -e "${cyan}WS Tunnel ==>:${purple}[${red}Not running ✗ ${purple}]${rest}" 414 | fi 415 | } 416 | 417 | #Termux check_dependencies_termux 418 | check_dependencies_termux() { 419 | local dependencies=("wget" "curl" "tar") 420 | 421 | for dep in "${dependencies[@]}"; do 422 | if ! command -v "${dep}" &> /dev/null; then 423 | echo "${dep} is not installed. Installing..." 424 | pkg install "${dep}" -y 425 | fi 426 | done 427 | } 428 | #Termux install wstunnel 429 | install_ws_termux() { 430 | if [ -e "$PATH/wstunnel" ]; then 431 | echo -e "${green}wstunnel already Installed. Skipping installation.${rest}" 432 | sleep 1 433 | else 434 | pkg update -y 435 | pkg upgrade -y 436 | pkg update 437 | check_dependencies_termux 438 | latest_version=$(curl -s https://api.github.com/repos/erebe/wstunnel/releases/latest | grep -oP '"tag_name": "\K(.*?)(?=")') 439 | wstunnel_file="wstunnel_${latest_version//v}_linux_arm64.tar.gz" 440 | wget "https://github.com/erebe/wstunnel/releases/download/${latest_version}/${wstunnel_file}" 441 | tar -xvf "$wstunnel_file" > /dev/null 442 | chmod +x wstunnel 443 | mv wstunnel "$PATH/" 444 | rm "$wstunnel_file" LICENSE README.md 445 | fi 446 | inputs_termux 447 | } 448 | 449 | uninstall_ws_termux() { 450 | if [ -e "$PATH/run" ]; then 451 | rm "$PATH/run" 452 | echo -e "${green}Ws Tunnel has been uninstalled.${rest}" 453 | else 454 | echo -e "${red}Ws Tunnel is not installed.${rest}" 455 | fi 456 | } 457 | 458 | #Termux get inputs 459 | inputs_termux() { 460 | clear 461 | read -p "Enter foreign IP [External-server]: " foreign_ip 462 | read -p "Please Enter Your config [vpn] Port: " config_port 463 | read -p "Please Enter Connection Port (server <--> client) [default, 443]: " port 464 | port=${port:-443} 465 | 466 | read -p "Do you want to use TLS? (yes/no) [default: yes]: " use_tls 467 | use_tls=${use_tls:-yes} 468 | use_tls_option="wss" # default to wss 469 | [ "$use_tls" = "no" ] && use_tls_option="ws" 470 | 471 | echo -e "Enter connection type: 472 | 1) tcp ${purple}[vless , vmess , trojan , ...]${rest} 473 | 2) udp ${purple}[Wireguard , hysteria, tuic , ...]${rest} 474 | 3) socks5 475 | 4) stdio" 476 | echo "" 477 | read -p "Enter number (default is: 1--> tcp): " choice 478 | 479 | case $choice in 480 | 1) connection_type="tcp" ;; 481 | 2) connection_type="udp" ;; 482 | 3) connection_type="socks5" ;; 483 | 4) connection_type="stdio" ;; 484 | *) connection_type="tcp" ;; 485 | esac 486 | 487 | read -p "Do you want to use SNI? (yes/no) [default: yes]: " use_sni 488 | use_sni=${use_sni:-yes} 489 | if [ "$use_sni" = "yes" ]; then 490 | read -p "Please Enter SNI [default: google.com]: " tls_sni 491 | tls_sni=${tls_sni:-google.com} 492 | tls_sni_argument="--tls-sni-override $tls_sni" 493 | fi 494 | 495 | # Add ?timeout_sec=0 only for UDP 496 | if [ "$connection_type" = "udp" ]; then 497 | timeout_argument="?timeout_sec=0" 498 | else 499 | timeout_argument="" 500 | fi 501 | argument="wstunnel client -L $connection_type://[::]:$config_port:localhost:$config_port$timeout_argument $use_tls_option://$foreign_ip:$port $tls_sni_argument" 502 | echo -e "${yellow}------------Your-Arguments------------${rest}" 503 | echo "$argument" 504 | echo -e "${yellow}--------------------------------------${rest}" 505 | echo "" 506 | save "$argument" 507 | run 508 | } 509 | 510 | save() { 511 | if [ -z "$1" ]; then 512 | echo "Usage: save " 513 | else 514 | echo -n "$1" > run 515 | chmod +x run 516 | mv run "$PATH/" 517 | echo "Argument saved to 'run' binary file." 518 | echo -e "${yellow}--------------------------------------${rest}" 519 | echo -e "${green}** To Run Tunnel again, you can only type 'run' and press Enter **${rest}" 520 | echo -e "${yellow}--------------------------------------${rest}" 521 | fi 522 | } 523 | 524 | main_menu_termux() { 525 | if [ "$(uname -o)" != "Android" ]; then 526 | echo -e "${red}Please Run script in Termux.${rest}" 527 | exit 1 528 | fi 529 | 530 | clear 531 | echo -e "${purple}-----Ws tunnel in Termux----${rest}" 532 | echo "" 533 | echo -e "${purple}1) ${green}Install Ws Tunnel${rest}" 534 | echo "" 535 | echo -e "${purple}2) ${red}Uninstall Ws Tunnel${rest}" 536 | echo "" 537 | echo -e "${purple}3) ${cyan}Back to Menu${rest}" 538 | echo "" 539 | echo -e "${purple}0) ${red}Exit${rest}" 540 | echo "" 541 | read -p "Enter your choice: " choice 542 | case "$choice" in 543 | 1) 544 | install_ws_termux 545 | ;; 546 | 2) 547 | uninstall_ws_termux 548 | ;; 549 | 3) 550 | main_menu 551 | ;; 552 | 0) 553 | exit 554 | ;; 555 | *) 556 | echo "Invalid choice. Please select a valid option." 557 | ;; 558 | esac 559 | } 560 | 561 | # Main menu 562 | main_menu() { 563 | clear 564 | echo -e "${white}By --> Peyman * Github.com/Ptechgithub * ${rest}" 565 | echo -e "${cyan}#===- ${purple}W${yellow}s ${purple}T${yellow}u${purple}n${yellow}n${purple}e${yellow}l ${cyan}-===#${rest}" 566 | echo "" 567 | check_tunnel_status 568 | echo -e "${yellow}~~~~~~~~~~~~~~~~~~~~~~~~~~~${rest}" 569 | echo -e "${purple}1) ${green}In${cyan}st${green}all${cyan} Ws${green}Tu${cyan}nn${green}el${rest}" 570 | echo "" 571 | echo -e "${purple}2) ${cyan}In${green}st${cyan}all Ws${green} Re${cyan}ve${green}rs${cyan}e T${green}un${cyan}ne${green}l${reset}" 572 | echo "" 573 | echo -e "${purple}3) ${green}In${cyan}st${green}all C${cyan}us${green}to${cyan}m${reset}" 574 | echo "" 575 | echo -e "${purple}4) ${yellow}Un${red}in${yellow}st${red}al${yellow}l w${red}s${yellow}tu${red}nn${yellow}el${reset}" 576 | echo "" 577 | echo -e "${purple}5) ${white}In${cyan}sta${white}ll ${cyan}on ${purple}Termux ${yellow}(no root)${rest}" 578 | echo "" 579 | echo -e "${purple}0) Exit${rest}" 580 | echo -e "${yellow}~~~~~~~~~~~~~~~~~~~~~~~~~~~${rest}" 581 | read -p "Please choose: " choice 582 | 583 | case $choice in 584 | 1) 585 | install 586 | ;; 587 | 2) 588 | install_reverse 589 | ;; 590 | 3) 591 | install_custom 592 | ;; 593 | 4) 594 | uninstall 595 | ;; 596 | 5) 597 | main_menu_termux 598 | ;; 599 | 0) 600 | exit 601 | ;; 602 | *) 603 | echo "Invalid choice. Please try again." 604 | ;; 605 | esac 606 | } 607 | 608 | main_menu --------------------------------------------------------------------------------