├── .gitignore ├── LICENSE ├── README.md ├── docker ├── Dockerfile ├── Dockerfile.local ├── build.sh └── start.sh ├── ipv6-proxy-server.sh └── manual └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | upload-dockerhub.txt 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Theodike Serra 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### _this fork works differently than the [original](https://github.com/Temporalitas/ipv6-proxy-server)_ 2 | 3 | # Multiple IPv6 Proxy Server 4 | 5 | Create your own IPv6 backconnect proxy server with just one script on any Linux distribution. 6 | This code is an adaptation of the original project. 7 | the original design works with an entire block of IPv6 attached to the server. 8 | This fork works with a fixed list of IPs previously attached to the server. 9 | (**And add docker support!**) 10 | 11 | ## Tutorial (VERY EASY) 12 | 13 | ### Assuming you already have docker installed and a some IPv6 attached to your server. 14 | 15 | #### Just run: 16 | ``` 17 | docker run --privileged -d -e PROXY_USER=user \ 18 | -e PROXY_PASS=pass -e START_PORT=30000 \ 19 | -e NET_INTERFACE=Your-main-network-interface \ 20 | --name ipv6-proxy --network host --restart always ethie/ipv6-multiple-proxy-server:v3 21 | ``` 22 | #### adjust the parameters below in the command above: 23 | - `PROXY_USER=` for proxy user 24 | - `PROXY_PASS=` for proxy password 25 | - `START_PORT=` for which port will start creating proxies 26 | - `NET_INTERFACE=` for the name of the system's default network interface (where ipv6 is appended) 27 |
28 |
29 |
30 | 31 | ## Another tutorial (build docker image from scratch) 32 | 33 | ### Assuming you already have docker installed and a some IPv6 attached to your server. 34 | 35 | - Download the Dockerfile inside `docker` folder 36 | - run: `docker build -t ipv6-proxy .` in the same folder of the Dockerfile. 37 | - After builds end, run: 38 | ``` 39 | docker run --privileged -d -e PROXY_USER=user \ 40 | -e PROXY_PASS=pass -e START_PORT=30000 \ 41 | -e NET_INTERFACE=Your-main-network-interface \ 42 | --name ipv6-proxy --network host --restart always ipv6-proxy 43 | ``` 44 | #### adjust the parameters below in the command above: 45 | - `PROXY_USER=` for proxy user 46 | - `PROXY_PASS=` for proxy password 47 | - `START_PORT=` for which port will start creating proxies 48 | - `NET_INTERFACE=` for the name of the system's default network interface (where ipv6 is appended) 49 | 50 | ## The script will create a endpoint proxy for each ipv6 available on the server 51 | ### use the `netstat -antp` command to see if it worked correctly, you will see a list of open ports starting with the port defined in `START_PORT` 52 | Ex: 53 | ``` 54 | 0.0.0.0:30000 55 | 0.0.0.0:30001 56 | 0.0.0.0:30002 57 | ... 58 | ``` 59 | ## If you prefer manual installation (without docker), see the [manual](https://github.com/erickythierry/ipv6-multiple-proxy-server/tree/master/manual) folder 60 | 61 |
62 |
63 | 64 | # 🇧🇷 65 | ### _Este fork funciona de forma diferente do [original](https://github.com/Temporalitas/ipv6-proxy-server)_ 66 | 67 | # Servidor Multi Proxy IPv6 68 | 69 | Crie seu próprio servidor de proxy de backconnect IPv6 com apenas um script em qualquer distribuição Linux. 70 | Este código é uma adaptação do projeto original. 71 | O design original funciona com um bloco inteiro de IPv6 anexado ao servidor. 72 | Este fork funciona com uma lista fixa de IPs previamente anexados ao servidor. 73 | (**E adiciona suporte ao Docker!**) 74 | 75 | ## Tutorial (Muito Fácil) 76 | 77 | ### Assumindo que você já tem o Docker instalado e alguns IPv6 anexados ao seu servidor. 78 | 79 | #### Só executar: 80 | ``` 81 | docker run --privileged -d -e PROXY_USER=user \ 82 | -e PROXY_PASS=pass -e START_PORT=30000 \ 83 | -e NET_INTERFACE=Your-main-network-interface \ 84 | --name ipv6-proxy --network host --restart always ethie/ipv6-multiple-proxy-server:v3 85 | ``` 86 | #### Ajuste esses parametros abaixo no comando acima: 87 | - `PROXY_USER=` para o usuário do proxy 88 | - `PROXY_PASS=` para a senha do proxy 89 | - `START_PORT=` para qual porta deve iniciar a criação dos proxies 90 | - `NET_INTERFACE=` para o nome da interface de rede do sistema onde estão os IPv6 91 |
92 |
93 |
94 | 95 | ## Outro tutorial (criando a imagem docker do zero) 96 | 97 | ### Assumindo que você já tem o Docker instalado e alguns IPv6 anexados ao seu servidor. 98 | 99 | - Obtenha o `Dockerfile` na pasta `docker` 100 | - execute: `docker build -t ipv6-proxy .` na mesma pasta do `Dockerfile` 101 | - Após o término do build, execute: 102 | 103 | ``` 104 | docker run --privileged -d -e PROXY_USER=user \ 105 | -e PROXY_PASS=pass -e START_PORT=30000 \ 106 | -e NET_INTERFACE=Your-main-network-interface \ 107 | --name ipv6-proxy --network host --restart always ipv6-proxy 108 | ``` 109 | #### Ajuste no comando acima esses parametros abaixo: 110 | - `PROXY_USER=` para o usuário do proxy 111 | - `PROXY_PASS=` para a senha do proxy 112 | - `START_PORT=` para qual porta deve iniciar a criação dos proxies 113 | - `NET_INTERFACE=` para o nome da interface de rede do sistema onde estão os IPv6 114 | 115 | ## O script criará um endpoint de proxy para cada ipv6 disponível no servidor 116 | ### use o comando `netstat -antp` para ver se funcionou corretamente, você verá uma lista de portas abertas começando com a porta definida em `START_PORT` 117 | Ex: 118 | ``` 119 | 0.0.0.0:30000 120 | 0.0.0.0:30001 121 | 0.0.0.0:30002 122 | ... 123 | ``` 124 | 125 |
126 | 127 | ## Se preferir instalação manual (sem docker), veja a pasta [manual](https://github.com/erickythierry/ipv6-multiple-proxy-server/tree/master/manual) 128 |
129 | 130 | ### Licence 131 | 132 | #### [MIT](https://opensource.org/licenses/MIT) -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | RUN apt-get update && \ 3 | apt-get install -y \ 4 | make \ 5 | g++ \ 6 | wget \ 7 | curl \ 8 | cron \ 9 | iproute2 \ 10 | iputils-ping \ 11 | tar \ 12 | apt-transport-https \ 13 | gnupg && \ 14 | apt-get clean 15 | 16 | RUN wget https://raw.githubusercontent.com/erickythierry/ipv6-multiple-proxy-server/master/docker/build.sh && chmod +x build.sh && ./build.sh 17 | RUN wget https://raw.githubusercontent.com/erickythierry/ipv6-multiple-proxy-server/master/docker/start.sh && chmod +x start.sh 18 | 19 | 20 | CMD ["sh", "-c", "./start.sh -u $PROXY_USER -p $PROXY_PASS --start-port $START_PORT -b 0.0.0.0 --interface $NET_INTERFACE"] 21 | -------------------------------------------------------------------------------- /docker/Dockerfile.local: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | RUN apt-get update && \ 3 | apt-get install -y \ 4 | make \ 5 | g++ \ 6 | wget \ 7 | curl \ 8 | cron \ 9 | iproute2 \ 10 | iputils-ping \ 11 | tar \ 12 | apt-transport-https \ 13 | gnupg && \ 14 | apt-get clean 15 | COPY . . 16 | RUN chmod +x build.sh && chmod +x start.sh 17 | RUN ./build.sh 18 | CMD ["sh", "-c", "./start.sh -u $PROXY_USER -p $PROXY_PASS --start-port $START_PORT -b 0.0.0.0 --interface $NET_INTERFACE"] -------------------------------------------------------------------------------- /docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Set default values for optional arguments 4 | start_port=30000 5 | use_random_auth=false 6 | backconnect_proxies_file="default" 7 | # Log file for script execution 8 | script_log_file="/var/tmp/ipv6-proxy-server-logs.log" 9 | proxy_count=1 10 | 11 | function log_err() { 12 | echo $1 1>&2 13 | echo -e "$1\n" &>>$script_log_file 14 | } 15 | 16 | function log_err_and_exit() { 17 | log_err "$1" 18 | exit 1 19 | } 20 | 21 | # Define all needed paths to scripts / configs / etc 22 | bash_location="$(which bash)" 23 | # Get user home dir absolute path 24 | cd ~ 25 | user_home_dir="$(pwd)" 26 | # Path to dir with all proxies info 27 | proxy_dir="$user_home_dir/proxyserver" 28 | # Path to file with config for backconnect proxy server 29 | proxyserver_config_path="$proxy_dir/3proxy/3proxy.cfg" 30 | # Path to file with nformation about running proxy server in user-readable format 31 | proxyserver_info_file="$proxy_dir/running_server.info" 32 | # Path to file with all result (external) ipv6 addresses 33 | random_ipv6_list_file="$proxy_dir/ipv6.list" 34 | # Path to file with proxy random usernames/password 35 | random_users_list_file="$proxy_dir/random_users.list" 36 | # Define correct path to file with backconnect proxies list, if it isn't defined by user 37 | if [[ $backconnect_proxies_file == "default" ]]; then backconnect_proxies_file="$proxy_dir/backconnect_proxies.list"; fi 38 | # Script on server startup (generate random ids and run proxy daemon) 39 | startup_script_path="$proxy_dir/proxy-startup.sh" 40 | # Cron config path (start proxy server after linux reboot and IPs rotations) 41 | cron_script_path="$proxy_dir/proxy-server.cron" 42 | # Last opened port for backconnect proxy 43 | last_port=$(($start_port + $proxy_count - 1)) 44 | # Proxy credentials - username and password, delimited by ':', if exist, or empty string, if auth == false 45 | credentials=$(is_auth_used && [[ $use_random_auth == false ]] && echo -n ":$user:$password" || echo -n "") 46 | 47 | function is_proxyserver_installed() { 48 | if [ -d $proxy_dir ] && [ "$(ls -A $proxy_dir)" ]; then return 0; fi 49 | return 1 50 | } 51 | 52 | function is_package_installed() { 53 | if [ $(dpkg-query -W -f='${Status}' $1 2>/dev/null | grep -c "ok installed") -eq 0 ]; then return 1; else return 0; fi 54 | } 55 | 56 | function delete_file_if_exists() { 57 | if test -f $1; then rm $1; fi 58 | } 59 | 60 | function install_package() { 61 | if ! is_package_installed $1; then 62 | apt install $1 -y &>>$script_log_file 63 | if ! is_package_installed $1; then 64 | log_err_and_exit "Error: cannot install \"$1\" package" 65 | fi 66 | fi 67 | } 68 | 69 | # Install required libraries 70 | function install_requred_packages() { 71 | apt update &>>$script_log_file 72 | 73 | requred_packages=("make" "g++" "wget" "curl" "cron") 74 | for package in ${requred_packages[@]}; do install_package $package; done 75 | 76 | echo -e "\nAll required packages installed successfully" 77 | } 78 | 79 | function install_3proxy() { 80 | 81 | mkdir $proxy_dir && cd $proxy_dir 82 | 83 | echo -e "\nDownloading proxy server source..." 84 | ( # Install proxy server 85 | wget https://github.com/3proxy/3proxy/archive/refs/tags/0.9.5.tar.gz &>/dev/null 86 | tar -xf 0.9.5.tar.gz 87 | rm 0.9.5.tar.gz 88 | mv 3proxy-0.9.5 3proxy 89 | ) &>>$script_log_file 90 | echo "Proxy server source code downloaded successfully" 91 | 92 | echo -e "\nStart building proxy server execution file from source..." 93 | # Build proxy server 94 | cd 3proxy 95 | make -f Makefile.Linux &>>$script_log_file 96 | if test -f "$proxy_dir/3proxy/bin/3proxy"; then 97 | echo "Proxy server builded successfully" 98 | else 99 | log_err_and_exit "Error: proxy server build from source code failed." 100 | fi 101 | cd .. 102 | } 103 | 104 | delete_file_if_exists $script_log_file 105 | if is_proxyserver_installed; then 106 | echo -e "Proxy server already installed, reconfiguring:\n" 107 | else 108 | install_requred_packages 109 | install_3proxy 110 | fi 111 | 112 | exit 0 113 | -------------------------------------------------------------------------------- /docker/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Script must be running from root 3 | if [ "$EUID" -ne 0 ]; then 4 | echo "Please run as root" 5 | exit 1 6 | fi 7 | 8 | # Program help info for users 9 | function usage() { 10 | echo "Usage: $0 11 | [-u | --username proxy auth username] 12 | [-p | --password proxy password] 13 | [--random generate random username/password for each IPv4 backconnect proxy instead of predefined (default false)] 14 | [-t | --proxies-type result proxies type (default socks5)] 15 | [--start-port <5000-65536> start port for backconnect ipv4 (default 30000)] 16 | [-l | --localhost allow connections only for localhost (backconnect on 127.0.0.1)] 17 | [-f | --backconnect-proxies-file path to file, in which backconnect proxies list will be written 18 | when proxies start working (default \`~/proxyserver/backconnect_proxies.list\`)] 19 | [-m | --ipv6-mask constant ipv6 address mask, to which the rotated part is added (or gateaway) 20 | use only if the gateway is different from the subnet address] 21 | [-i | --interface full name of ethernet interface, on which IPv6 subnet was allocated 22 | automatically parsed by default, use ONLY if you have non-standard/additional interfaces on your server] 23 | [-b | --backconnect-ip server IPv4 backconnect address for proxies 24 | automatically parsed by default, use ONLY if you have non-standard ip allocation on your server] 25 | [--allowed-hosts allowed hosts or IPs (3proxy format), for example "google.com,*.google.com,*.gstatic.com" 26 | if at least one host is allowed, the rest are banned by default] 27 | [--denied-hosts banned hosts or IP addresses in quotes (3proxy format)] 28 | [--uninstall disable active proxies, uninstall server and clear all metadata] 29 | [--info print info about running proxy server] 30 | " 1>&2 31 | exit 1 32 | } 33 | 34 | options=$(getopt -o ldhs:c:u:p:t:r:m:f:i:b: --long help,localhost,disable-inet6-ifaces-check,random,uninstall,info,subnet:,proxy-count:,username:,password:,proxies-type:,rotating-interval:,ipv6-mask:,interface:,start-port:,backconnect-proxies-file:,backconnect-ip:,allowed-hosts:,denied-hosts: -- "$@") 35 | 36 | # Throw error and chow help message if user don`t provide any arguments 37 | if [ $? != 0 ]; then 38 | echo "Error: no arguments provided. Terminating..." >&2 39 | usage 40 | fi 41 | 42 | # Parse command line options 43 | eval set -- "$options" 44 | 45 | # Set default values for optional arguments 46 | subnet=64 47 | proxies_type="socks5" 48 | start_port=30000 49 | rotating_interval=0 50 | use_localhost=false 51 | use_random_auth=false 52 | uninstall=false 53 | print_info=false 54 | inet6_network_interfaces_configuration_check=false 55 | backconnect_proxies_file="default" 56 | # Global network inteface name 57 | interface_name="$(ip -br l | awk '$1 !~ "lo|vir|wl|@NONE" { print $1 }' | awk 'NR==1')" 58 | # Log file for script execution 59 | script_log_file="/var/tmp/ipv6-proxy-server-logs.log" 60 | backconnect_ipv4="" 61 | proxy_count=1 62 | 63 | while true; do 64 | case "$1" in 65 | -h | --help) 66 | usage 67 | shift 68 | ;; 69 | -s | --subnet) 70 | subnet="$2" 71 | shift 2 72 | ;; 73 | -c | --proxy-count) 74 | proxy_count="$2" 75 | shift 2 76 | ;; 77 | -u | --username) 78 | user="$2" 79 | shift 2 80 | ;; 81 | -p | --password) 82 | password="$2" 83 | shift 2 84 | ;; 85 | -t | --proxies-type) 86 | proxies_type="$2" 87 | shift 2 88 | ;; 89 | -m | --ipv6-mask) 90 | subnet_mask="$2" 91 | shift 2 92 | ;; 93 | -b | --backconnect-ip) 94 | backconnect_ipv4="$2" 95 | shift 2 96 | ;; 97 | -f | --backconnect_proxies_file) 98 | backconnect_proxies_file="$2" 99 | shift 2 100 | ;; 101 | -i | --interface) 102 | interface_name="$2" 103 | shift 2 104 | ;; 105 | -l | --localhost) 106 | use_localhost=true 107 | shift 108 | ;; 109 | --allowed-hosts) 110 | allowed_hosts="$2" 111 | shift 2 112 | ;; 113 | --denied-hosts) 114 | denied_hosts="$2" 115 | shift 2 116 | ;; 117 | --uninstall) 118 | uninstall=true 119 | shift 120 | ;; 121 | --info) 122 | print_info=true 123 | shift 124 | ;; 125 | --start-port) 126 | start_port="$2" 127 | shift 2 128 | ;; 129 | --random) 130 | use_random_auth=true 131 | shift 132 | ;; 133 | --) 134 | shift 135 | break 136 | ;; 137 | *) break ;; 138 | esac 139 | done 140 | 141 | function log_err() { 142 | echo $1 1>&2 143 | echo -e "$1\n" &>>$script_log_file 144 | } 145 | 146 | function log_err_and_exit() { 147 | log_err "$1" 148 | exit 1 149 | } 150 | 151 | function log_err_print_usage_and_exit() { 152 | log_err "$1" 153 | usage 154 | } 155 | 156 | function is_valid_ip() { 157 | if [[ "$1" =~ ^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]]; then return 0; else return 1; fi 158 | } 159 | 160 | function is_auth_used() { 161 | if [ -z $user ] && [ -z $password] && [ $use_random_auth = false ]; then 162 | false 163 | return 164 | else 165 | true 166 | return 167 | fi 168 | } 169 | 170 | function check_startup_parameters() { 171 | # Check validity of user provided arguments 172 | re='^[0-9]+$' 173 | 174 | if ([ -z $user ] || [ -z $password ]) && is_auth_used && [ $use_random_auth = false ]; then 175 | log_err_print_usage_and_exit "Error: user and password for proxy with auth is required (specify both '--username' and '--password' startup parameters)" 176 | fi 177 | 178 | if ([[ -n $user ]] || [[ -n $password ]]) && [ $use_random_auth = true ]; then 179 | log_err_print_usage_and_exit "Error: don't provide user or password as arguments, if '--random' flag is set." 180 | fi 181 | 182 | if [ $proxies_type != "http" ] && [ $proxies_type != "socks5" ]; then 183 | log_err_print_usage_and_exit "Error: invalid value of '-t' (proxy type) parameter" 184 | fi 185 | 186 | if [ $start_port -lt 5000 ] || (($start_port - $proxy_count > 65536)); then 187 | log_err_print_usage_and_exit "Wrong '--start-port' parameter value, it must be more than 5000 and '--start-port' + '--proxy-count' must be lower than 65536, 188 | because Linux has only 65536 potentially ports" 189 | fi 190 | 191 | if [ ! -z $backconnect_ipv4 ]; then 192 | if ! is_valid_ip $backconnect_ipv4; then 193 | log_err_and_exit "Error: ip provided in 'backconnect-ip' argument is invalid. Provide valid IP or don't use this argument" 194 | fi 195 | fi 196 | 197 | if [ -n "$allowed_hosts" ] && [ -n "$denied_hosts" ]; then 198 | log_err_print_usage_and_exit "Error: if '--allow-hosts' is specified, you cannot use '--deny-hosts', the rest that isn't allowed is denied by default" 199 | fi 200 | 201 | if cat /sys/class/net/$interface_name/operstate 2>&1 | grep -q "No such file or directory"; then 202 | log_err_print_usage_and_exit "Incorrect ethernet interface name \"$interface_name\", provide correct name using parameter '--interface'" 203 | fi 204 | } 205 | 206 | # Define all needed paths to scripts / configs / etc 207 | bash_location="$(which bash)" 208 | # Get user home dir absolute path 209 | cd ~ 210 | user_home_dir="$(pwd)" 211 | # Path to dir with all proxies info 212 | proxy_dir="$user_home_dir/proxyserver" 213 | # Path to file with config for backconnect proxy server 214 | proxyserver_config_path="$proxy_dir/3proxy/3proxy.cfg" 215 | # Path to file with nformation about running proxy server in user-readable format 216 | proxyserver_info_file="$proxy_dir/running_server.info" 217 | # Path to file with all result (external) ipv6 addresses 218 | random_ipv6_list_file="$proxy_dir/ipv6.list" 219 | # Path to file with proxy random usernames/password 220 | random_users_list_file="$proxy_dir/random_users.list" 221 | # Define correct path to file with backconnect proxies list, if it isn't defined by user 222 | if [[ $backconnect_proxies_file == "default" ]]; then backconnect_proxies_file="$proxy_dir/backconnect_proxies.list"; fi 223 | # Script on server startup (generate random ids and run proxy daemon) 224 | startup_script_path="$proxy_dir/proxy-startup.sh" 225 | # Cron config path (start proxy server after linux reboot and IPs rotations) 226 | cron_script_path="$proxy_dir/proxy-server.cron" 227 | # Last opened port for backconnect proxy 228 | last_port=$(($start_port + $proxy_count - 1)) 229 | # Proxy credentials - username and password, delimited by ':', if exist, or empty string, if auth == false 230 | credentials=$(is_auth_used && [[ $use_random_auth == false ]] && echo -n ":$user:$password" || echo -n "") 231 | 232 | function is_proxyserver_installed() { 233 | if [ -d $proxy_dir ] && [ "$(ls -A $proxy_dir)" ]; then return 0; fi 234 | return 1 235 | } 236 | 237 | function is_proxyserver_running() { 238 | if ps aux | grep 3proxy; then return 0; else return 1; fi 239 | } 240 | 241 | function is_package_installed() { 242 | if [ $(dpkg-query -W -f='${Status}' $1 2>/dev/null | grep -c "ok installed") -eq 0 ]; then return 1; else return 0; fi 243 | } 244 | 245 | function create_random_string() { 246 | tr -dc A-Za-z0-9 >$script_log_file 263 | if ! is_package_installed $1; then 264 | log_err_and_exit "Error: cannot install \"$1\" package" 265 | fi 266 | fi 267 | } 268 | 269 | # DONT use before curl package is installed 270 | function get_backconnect_ipv4() { 271 | if [ $use_localhost == true ]; then 272 | echo "127.0.0.1" 273 | return 274 | fi 275 | if [ ! -z "$backconnect_ipv4" -a "$backconnect_ipv4" != " " ]; then 276 | echo $backconnect_ipv4 277 | return 278 | fi 279 | 280 | local maybe_ipv4=$(ip addr show $interface_name | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}') 281 | if is_valid_ip $maybe_ipv4; then 282 | echo $maybe_ipv4 283 | return 284 | fi 285 | 286 | if ! is_package_installed "curl"; then install_package "curl"; fi 287 | 288 | (maybe_ipv4=$(curl https://ipinfo.io/ip)) &>/dev/null 289 | if is_valid_ip $maybe_ipv4; then 290 | echo $maybe_ipv4 291 | return 292 | fi 293 | 294 | log_err_and_exit "Error: curl package not installed and cannot parse valid IP from interface info" 295 | } 296 | 297 | function check_ipv6() { 298 | # Check is ipv6 enabled or not 299 | if test -f /proc/net/if_inet6; then 300 | echo "IPv6 interface is enabled" 301 | else 302 | log_err_and_exit "Error: inet6 (ipv6) interface is not enabled. Enable IP v6 on your system." 303 | fi 304 | 305 | if [[ $(ip -6 addr show scope global) ]]; then 306 | echo "IPv6 global address is allocated on server successfully" 307 | else 308 | log_err_and_exit "Error: IPv6 global address is not allocated on server, allocate it or contact your VPS/VDS support." 309 | fi 310 | 311 | local ifaces_config="/etc/network/interfaces" 312 | if [ $inet6_network_interfaces_configuration_check = true ]; then 313 | if [ ! -f $ifaces_config ]; then log_err_and_exit "Error: interfaces config ($ifaces_config) doesn't exist"; fi 314 | 315 | if grep 'inet6' $ifaces_config >/dev/null; then 316 | echo "Network interfaces for IPv6 configured correctly" 317 | else 318 | log_err_and_exit "Error: $ifaces_config has no inet6 (IPv6) configuration." 319 | fi 320 | fi 321 | 322 | if [[ $(ping6 -c 1 google.com) != *"Network is unreachable"* ]] &>/dev/null; then 323 | echo "Test ping google.com using IPv6 successfully" 324 | else 325 | log_err_and_exit "Error: test ping google.com through IPv6 failed, network is unreachable." 326 | fi 327 | 328 | } 329 | 330 | function configure_ipv6() { 331 | # Enable sysctl options for rerouting and bind ips from subnet to default interface 332 | required_options=("conf.$interface_name.proxy_ndp" "conf.all.proxy_ndp" "conf.default.forwarding" "conf.all.forwarding" "ip_nonlocal_bind") 333 | for option in ${required_options[@]}; do 334 | full_option="net.ipv6.$option=1" 335 | if ! cat /etc/sysctl.conf | grep -v "#" | grep -q $full_option; then echo $full_option >>/etc/sysctl.conf; fi 336 | done 337 | sysctl -p &>>$script_log_file 338 | 339 | if [[ $(cat /proc/sys/net/ipv6/conf/$interface_name/proxy_ndp) == 1 ]] && [[ $(cat /proc/sys/net/ipv6/ip_nonlocal_bind) == 1 ]]; then 340 | echo "IPv6 network sysctl data configured successfully" 341 | else 342 | cat /etc/sysctl.conf &>>$script_log_file 343 | log_err_and_exit "Error: cannot configure IPv6 config" 344 | fi 345 | } 346 | 347 | function generate_random_users_if_needed() { 348 | # No need to generate random usernames and passwords for proxies, if auth=none or one username/password for all proxies provided 349 | if [ $use_random_auth != true ]; then return; fi 350 | delete_file_if_exists $random_users_list_file 351 | 352 | for i in $(seq 1 $proxy_count); do 353 | echo $(create_random_string 8):$(create_random_string 8) >>$random_users_list_file 354 | done 355 | } 356 | # função nova que evita ipv6 link local 357 | function get_ipv6_addresses() { 358 | local ipv6_addresses 359 | ipv6_addresses=($(ip -6 addr | awk '/inet6 .* global/ { print $2 }' | cut -d'/' -f1)) 360 | 361 | for ip in "${ipv6_addresses[@]}"; do 362 | # Verifica se o endereço IPv6 é global (começa com 2xxx: ou 3xxx:) 363 | if [[ $ip =~ ^2[0-9a-fA-F]{3}:.*$ || $ip =~ ^3[0-9a-fA-F]{3}:.*$ ]]; then 364 | echo $ip >>"$random_ipv6_list_file" 365 | # echo "echo $ip >> \"$random_ipv6_list_file\"" 366 | fi 367 | done 368 | } 369 | 370 | function create_startup_script() { 371 | delete_file_if_exists $random_ipv6_list_file 372 | get_ipv6_addresses 373 | 374 | is_auth_used 375 | local use_auth=$? 376 | 377 | # Add main script that runs proxy server and rotates external ip's, if server is already running 378 | cat >$startup_script_path <<-EOF 379 | #!$bash_location 380 | 381 | # Remove leading whitespaces in every string in text 382 | function dedent() { 383 | local -n reference="\$1" 384 | reference="\$(echo "\$reference" | sed 's/^[[:space:]]*//')" 385 | } 386 | 387 | # Save old 3proxy daemon pids, if exists 388 | proxyserver_process_pids=() 389 | while read -r pid; do 390 | proxyserver_process_pids+=(\$pid) 391 | done < <(ps -ef | awk '/[3]proxy/{print $2}'); 392 | 393 | 394 | immutable_config_part="daemon 395 | nserver 8.8.8.8 396 | nserver 8.8.4.4 397 | nserver 1.1.1.1 398 | nserver 1.0.0.1 399 | maxconn 10000 400 | nscache 65536 401 | nscache6 65536 402 | timeouts 1 5 30 60 60 60 15 60 403 | setgid 65535 404 | setuid 65535" 405 | 406 | auth_part="auth iponly" 407 | if [ $use_auth -eq 0 ]; then 408 | auth_part=" 409 | auth strong 410 | users $user:CL:$password" 411 | fi; 412 | 413 | if [ -n "$denied_hosts" ]; then 414 | access_rules_part=" 415 | deny * * $denied_hosts 416 | allow *" 417 | else 418 | access_rules_part=" 419 | allow * * $allowed_hosts 420 | deny *" 421 | fi; 422 | 423 | dedent immutable_config_part; 424 | dedent auth_part; 425 | dedent access_rules_part; 426 | 427 | echo "\$immutable_config_part"\$'\n'"\$auth_part"\$'\n'"\$access_rules_part" > $proxyserver_config_path; 428 | 429 | # Add all ipv6 backconnect proxy with random adresses in proxy server startup config 430 | port=$start_port 431 | count=0 432 | if [ "$proxies_type" = "http" ]; then proxy_startup_depending_on_type="proxy -6 -n -a"; else proxy_startup_depending_on_type="socks -6 -a"; fi; 433 | if [ $use_random_auth = true ]; then readarray -t proxy_random_credentials < $random_users_list_file; fi; 434 | 435 | for random_ipv6_address in \$(cat $random_ipv6_list_file); do 436 | if [ $use_random_auth = true ]; then 437 | IFS=":"; 438 | read -r username password <<< "\${proxy_random_credentials[\$count]}"; 439 | echo "flush" >> $proxyserver_config_path; 440 | echo "users \$username:CL:\$password" >> $proxyserver_config_path; 441 | echo "\$access_rules_part" >> $proxyserver_config_path; 442 | IFS=$' \t\n'; 443 | fi; 444 | echo "\$proxy_startup_depending_on_type -p\$port -i$backconnect_ipv4 -e\$random_ipv6_address" >> $proxyserver_config_path; 445 | ((port+=1)) 446 | ((count+=1)) 447 | done 448 | 449 | # Script that adds all random ipv6 to default interface and runs backconnect proxy server 450 | ulimit -n 600000 451 | ulimit -u 600000 452 | ${user_home_dir}/proxyserver/3proxy/bin/3proxy ${proxyserver_config_path} 453 | 454 | # Kill old 3proxy daemon, if it's working 455 | for pid in "\${proxyserver_process_pids[@]}"; do 456 | kill \$pid; 457 | done; 458 | 459 | exit 0; 460 | EOF 461 | 462 | } 463 | 464 | function close_ufw_backconnect_ports() { 465 | if ! is_package_installed "ufw" || [ $use_localhost = true ] || ! test -f $backconnect_proxies_file; then return; fi 466 | 467 | local first_opened_port=$(head -n 1 $backconnect_proxies_file | awk -F ':' '{print $2}') 468 | local last_opened_port=$(tail -n 1 $backconnect_proxies_file | awk -F ':' '{print $2}') 469 | 470 | ufw delete allow $first_opened_port:$last_opened_port/tcp >>$script_log_file 471 | ufw delete allow $first_opened_port:$last_opened_port/udp >>$script_log_file 472 | 473 | if ufw status | grep -qw $first_opened_port:$last_opened_port; then 474 | log_err "Cannot delete UFW rules for backconnect proxies" 475 | else 476 | echo "UFW rules for backconnect proxies cleared successfully" 477 | fi 478 | } 479 | 480 | function open_ufw_backconnect_ports() { 481 | close_ufw_backconnect_ports 482 | 483 | # No need open ports if backconnect proxies on localhost 484 | if [ $use_localhost = true ]; then return; fi 485 | 486 | if ! is_package_installed "ufw"; then 487 | echo "Firewall not installed, ports for backconnect proxy opened successfully" 488 | return 489 | fi 490 | 491 | if ufw status | grep -qw active; then 492 | ufw allow $start_port:$last_port/tcp >>$script_log_file 493 | ufw allow $start_port:$last_port/udp >>$script_log_file 494 | 495 | if ufw status | grep -qw $start_port:$last_port; then 496 | echo "UFW ports for backconnect proxies opened successfully" 497 | else 498 | log_err $(ufw status) 499 | log_err_and_exit "Cannot open ports for backconnect proxies, configure ufw please" 500 | fi 501 | 502 | else 503 | echo "UFW protection disabled, ports for backconnect proxy opened successfully" 504 | fi 505 | } 506 | 507 | function run_proxy_server() { 508 | if [ ! -f $startup_script_path ]; then log_err_and_exit "Error: proxy startup script doesn't exist."; fi 509 | 510 | chmod +x $startup_script_path 511 | $bash_location $startup_script_path 512 | if is_proxyserver_running; then 513 | echo -e "\nIPv6 proxy server started successfully. Backconnect IPv4 is available from $backconnect_ipv4:$start_port$credentials to $backconnect_ipv4:$last_port$credentials via $proxies_type protocol" 514 | else 515 | log_err_and_exit "Error: cannot run proxy server" 516 | fi 517 | } 518 | 519 | if [ $print_info = true ]; then 520 | if ! is_proxyserver_installed; then log_err_and_exit "Proxy server isn't installed"; fi 521 | if ! is_proxyserver_running; then log_err_and_exit "Proxy server isn't running. You can check log of previous run attempt in $script_log_file"; fi 522 | if ! test -f $proxyserver_info_file; then log_err_and_exit "File with information about running proxy server not found"; fi 523 | 524 | cat $proxyserver_info_file 525 | exit 0 526 | fi 527 | 528 | if [ $uninstall = true ]; then 529 | if ! is_proxyserver_installed; then log_err_and_exit "Proxy server is not installed"; fi 530 | 531 | kill_3proxy 532 | close_ufw_backconnect_ports 533 | rm -rf $proxy_dir 534 | delete_file_if_exists $backconnect_proxies_file 535 | echo -e "\nIPv6 proxy server successfully uninstalled. If you want to reinstall, just run this script again." 536 | exit 0 537 | fi 538 | 539 | delete_file_if_exists $script_log_file 540 | check_startup_parameters 541 | check_ipv6 542 | configure_ipv6 543 | backconnect_ipv4=$(get_backconnect_ipv4) 544 | generate_random_users_if_needed 545 | create_startup_script 546 | open_ufw_backconnect_ports 547 | run_proxy_server 548 | 549 | tail -f /dev/null -------------------------------------------------------------------------------- /ipv6-proxy-server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Script must be running from root 3 | if [ "$EUID" -ne 0 ]; 4 | then echo "Please run as root"; 5 | exit 1; 6 | fi; 7 | 8 | # Program help info for users 9 | function usage() { echo "Usage: $0 10 | [-u | --username proxy auth username] 11 | [-p | --password proxy password] 12 | [--random generate random username/password for each IPv4 backconnect proxy instead of predefined (default false)] 13 | [-t | --proxies-type result proxies type (default socks5)] 14 | [--start-port <5000-65536> start port for backconnect ipv4 (default 30000)] 15 | [-l | --localhost allow connections only for localhost (backconnect on 127.0.0.1)] 16 | [-f | --backconnect-proxies-file path to file, in which backconnect proxies list will be written 17 | when proxies start working (default \`~/proxyserver/backconnect_proxies.list\`)] 18 | [-m | --ipv6-mask constant ipv6 address mask, to which the rotated part is added (or gateaway) 19 | use only if the gateway is different from the subnet address] 20 | [-i | --interface full name of ethernet interface, on which IPv6 subnet was allocated 21 | automatically parsed by default, use ONLY if you have non-standard/additional interfaces on your server] 22 | [-b | --backconnect-ip server IPv4 backconnect address for proxies 23 | automatically parsed by default, use ONLY if you have non-standard ip allocation on your server] 24 | [--allowed-hosts allowed hosts or IPs (3proxy format), for example "google.com,*.google.com,*.gstatic.com" 25 | if at least one host is allowed, the rest are banned by default] 26 | [--denied-hosts banned hosts or IP addresses in quotes (3proxy format)] 27 | [--uninstall disable active proxies, uninstall server and clear all metadata] 28 | [--info print info about running proxy server] 29 | " 1>&2; exit 1; } 30 | 31 | options=$(getopt -o ldhs:c:u:p:t:r:m:f:i:b: --long help,localhost,disable-inet6-ifaces-check,random,uninstall,info,subnet:,proxy-count:,username:,password:,proxies-type:,rotating-interval:,ipv6-mask:,interface:,start-port:,backconnect-proxies-file:,backconnect-ip:,allowed-hosts:,denied-hosts: -- "$@") 32 | 33 | # Throw error and chow help message if user don`t provide any arguments 34 | if [ $? != 0 ] ; then echo "Error: no arguments provided. Terminating..." >&2 ; usage ; fi; 35 | 36 | # Parse command line options 37 | eval set -- "$options" 38 | 39 | # Set default values for optional arguments 40 | subnet=64 41 | proxies_type="socks5" 42 | start_port=30000 43 | rotating_interval=0 44 | use_localhost=false 45 | use_random_auth=false 46 | uninstall=false 47 | print_info=false 48 | inet6_network_interfaces_configuration_check=false 49 | backconnect_proxies_file="default" 50 | # Global network inteface name 51 | interface_name="$(ip -br l | awk '$1 !~ "lo|vir|wl|@NONE" { print $1 }' | awk 'NR==1')" 52 | # Log file for script execution 53 | script_log_file="/var/tmp/ipv6-proxy-server-logs.log" 54 | backconnect_ipv4="" 55 | proxy_count=1 56 | 57 | while true; do 58 | case "$1" in 59 | -h | --help ) usage; shift ;; 60 | -s | --subnet ) subnet="$2"; shift 2 ;; 61 | -c | --proxy-count ) proxy_count="$2"; shift 2 ;; 62 | -u | --username ) user="$2"; shift 2 ;; 63 | -p | --password ) password="$2"; shift 2 ;; 64 | -t | --proxies-type ) proxies_type="$2"; shift 2 ;; 65 | -m | --ipv6-mask ) subnet_mask="$2"; shift 2;; 66 | -b | --backconnect-ip ) backconnect_ipv4="$2"; shift 2;; 67 | -f | --backconnect_proxies_file ) backconnect_proxies_file="$2"; shift 2;; 68 | -i | --interface ) interface_name="$2"; shift 2;; 69 | -l | --localhost ) use_localhost=true; shift ;; 70 | --allowed-hosts ) allowed_hosts="$2"; shift 2;; 71 | --denied-hosts ) denied_hosts="$2"; shift 2;; 72 | --uninstall ) uninstall=true; shift ;; 73 | --info ) print_info=true; shift ;; 74 | --start-port ) start_port="$2"; shift 2;; 75 | --random ) use_random_auth=true; shift ;; 76 | -- ) shift; break ;; 77 | * ) break ;; 78 | esac 79 | done 80 | 81 | function log_err(){ 82 | echo $1 1>&2; 83 | echo -e "$1\n" &>> $script_log_file; 84 | } 85 | 86 | function log_err_and_exit(){ 87 | log_err "$1"; 88 | exit 1; 89 | } 90 | 91 | function log_err_print_usage_and_exit(){ 92 | log_err "$1"; 93 | usage; 94 | } 95 | 96 | function is_valid_ip(){ 97 | if [[ "$1" =~ ^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]]; then return 0; else return 1; fi; 98 | } 99 | 100 | function is_auth_used(){ 101 | if [ -z $user ] && [ -z $password] && [ $use_random_auth = false ]; then false; return; else true; return; fi; 102 | } 103 | 104 | function check_startup_parameters(){ 105 | # Check validity of user provided arguments 106 | re='^[0-9]+$' 107 | 108 | if ([ -z $user ] || [ -z $password ]) && is_auth_used && [ $use_random_auth = false ]; then 109 | log_err_print_usage_and_exit "Error: user and password for proxy with auth is required (specify both '--username' and '--password' startup parameters)"; 110 | fi; 111 | 112 | if ([[ -n $user ]] || [[ -n $password ]]) && [ $use_random_auth = true ]; then 113 | log_err_print_usage_and_exit "Error: don't provide user or password as arguments, if '--random' flag is set."; 114 | fi; 115 | 116 | if [ $proxies_type != "http" ] && [ $proxies_type != "socks5" ] ; then 117 | log_err_print_usage_and_exit "Error: invalid value of '-t' (proxy type) parameter"; 118 | fi; 119 | 120 | if [ $start_port -lt 5000 ] || (($start_port - $proxy_count > 65536 )); then 121 | log_err_print_usage_and_exit "Wrong '--start-port' parameter value, it must be more than 5000 and '--start-port' + '--proxy-count' must be lower than 65536, 122 | because Linux has only 65536 potentially ports"; 123 | fi; 124 | 125 | if [ ! -z $backconnect_ipv4 ]; then 126 | if ! is_valid_ip $backconnect_ipv4; then 127 | log_err_and_exit "Error: ip provided in 'backconnect-ip' argument is invalid. Provide valid IP or don't use this argument" 128 | fi; 129 | fi; 130 | 131 | if [ -n "$allowed_hosts" ] && [ -n "$denied_hosts" ]; then 132 | log_err_print_usage_and_exit "Error: if '--allow-hosts' is specified, you cannot use '--deny-hosts', the rest that isn't allowed is denied by default"; 133 | fi; 134 | 135 | if cat /sys/class/net/$interface_name/operstate 2>&1 | grep -q "No such file or directory"; then 136 | log_err_print_usage_and_exit "Incorrect ethernet interface name \"$interface_name\", provide correct name using parameter '--interface'"; 137 | fi; 138 | } 139 | 140 | # Define all needed paths to scripts / configs / etc 141 | bash_location="$(which bash)" 142 | # Get user home dir absolute path 143 | cd ~ 144 | user_home_dir="$(pwd)" 145 | # Path to dir with all proxies info 146 | proxy_dir="$user_home_dir/proxyserver" 147 | # Path to file with config for backconnect proxy server 148 | proxyserver_config_path="$proxy_dir/3proxy/3proxy.cfg" 149 | # Path to file with nformation about running proxy server in user-readable format 150 | proxyserver_info_file="$proxy_dir/running_server.info" 151 | # Path to file with all result (external) ipv6 addresses 152 | random_ipv6_list_file="$proxy_dir/ipv6.list" 153 | # Path to file with proxy random usernames/password 154 | random_users_list_file="$proxy_dir/random_users.list" 155 | # Define correct path to file with backconnect proxies list, if it isn't defined by user 156 | if [[ $backconnect_proxies_file == "default" ]]; then backconnect_proxies_file="$proxy_dir/backconnect_proxies.list"; fi; 157 | # Script on server startup (generate random ids and run proxy daemon) 158 | startup_script_path="$proxy_dir/proxy-startup.sh" 159 | # Cron config path (start proxy server after linux reboot and IPs rotations) 160 | cron_script_path="$proxy_dir/proxy-server.cron" 161 | # Last opened port for backconnect proxy 162 | last_port=$(($start_port + $proxy_count - 1)); 163 | # Proxy credentials - username and password, delimited by ':', if exist, or empty string, if auth == false 164 | credentials=$(is_auth_used && [[ $use_random_auth == false ]] && echo -n ":$user:$password" || echo -n ""); 165 | 166 | function is_proxyserver_installed(){ 167 | if [ -d $proxy_dir ] && [ "$(ls -A $proxy_dir)" ]; then return 0; fi; 168 | return 1; 169 | } 170 | 171 | function is_proxyserver_running(){ 172 | if ps aux | grep 3proxy; then return 0; else return 1; fi; 173 | } 174 | 175 | function is_package_installed(){ 176 | if [ $(dpkg-query -W -f='${Status}' $1 2>/dev/null | grep -c "ok installed") -eq 0 ]; then return 1; else return 0; fi; 177 | } 178 | 179 | function create_random_string(){ 180 | tr -dc A-Za-z0-9 > $script_log_file; 204 | if ! is_package_installed $1; then 205 | log_err_and_exit "Error: cannot install \"$1\" package"; 206 | fi; 207 | fi; 208 | } 209 | 210 | # DONT use before curl package is installed 211 | function get_backconnect_ipv4(){ 212 | if [ $use_localhost == true ]; then echo "127.0.0.1"; return; fi; 213 | if [ ! -z "$backconnect_ipv4" -a "$backconnect_ipv4" != " " ]; then echo $backconnect_ipv4; return; fi; 214 | 215 | local maybe_ipv4=$(ip addr show $interface_name | awk '$1 == "inet" {gsub(/\/.*$/, "", $2); print $2}') 216 | if is_valid_ip $maybe_ipv4; then echo $maybe_ipv4; return; fi; 217 | 218 | if ! is_package_installed "curl"; then install_package "curl"; fi; 219 | 220 | (maybe_ipv4=$(curl https://ipinfo.io/ip)) &> /dev/null 221 | if is_valid_ip $maybe_ipv4; then echo $maybe_ipv4; return; fi; 222 | 223 | log_err_and_exit "Error: curl package not installed and cannot parse valid IP from interface info"; 224 | } 225 | 226 | 227 | function check_ipv6(){ 228 | # Check is ipv6 enabled or not 229 | if test -f /proc/net/if_inet6; then 230 | echo "IPv6 interface is enabled"; 231 | else 232 | log_err_and_exit "Error: inet6 (ipv6) interface is not enabled. Enable IP v6 on your system."; 233 | fi; 234 | 235 | if [[ $(ip -6 addr show scope global) ]]; then 236 | echo "IPv6 global address is allocated on server successfully"; 237 | else 238 | log_err_and_exit "Error: IPv6 global address is not allocated on server, allocate it or contact your VPS/VDS support."; 239 | fi; 240 | 241 | local ifaces_config="/etc/network/interfaces"; 242 | if [ $inet6_network_interfaces_configuration_check = true ]; then 243 | if [ ! -f $ifaces_config ]; then log_err_and_exit "Error: interfaces config ($ifaces_config) doesn't exist"; fi; 244 | 245 | if grep 'inet6' $ifaces_config > /dev/null; then 246 | echo "Network interfaces for IPv6 configured correctly"; 247 | else 248 | log_err_and_exit "Error: $ifaces_config has no inet6 (IPv6) configuration."; 249 | fi; 250 | fi; 251 | 252 | if [[ $(ping6 -c 1 google.com) != *"Network is unreachable"* ]] &> /dev/null; then 253 | echo "Test ping google.com using IPv6 successfully"; 254 | else 255 | log_err_and_exit "Error: test ping google.com through IPv6 failed, network is unreachable."; 256 | fi; 257 | 258 | } 259 | 260 | # Install required libraries 261 | function install_requred_packages(){ 262 | apt update &>> $script_log_file; 263 | 264 | requred_packages=("make" "g++" "wget" "curl" "cron"); 265 | for package in ${requred_packages[@]}; do install_package $package; done; 266 | 267 | echo -e "\nAll required packages installed successfully"; 268 | } 269 | 270 | function install_3proxy(){ 271 | 272 | mkdir $proxy_dir && cd $proxy_dir 273 | 274 | echo -e "\nDownloading proxy server source..."; 275 | ( # Install proxy server 276 | wget https://github.com/3proxy/3proxy/archive/refs/tags/0.9.4.tar.gz &> /dev/null 277 | tar -xf 0.9.4.tar.gz 278 | rm 0.9.4.tar.gz 279 | mv 3proxy-0.9.4 3proxy) &>> $script_log_file 280 | echo "Proxy server source code downloaded successfully"; 281 | 282 | echo -e "\nStart building proxy server execution file from source..."; 283 | # Build proxy server 284 | cd 3proxy 285 | make -f Makefile.Linux &>> $script_log_file; 286 | if test -f "$proxy_dir/3proxy/bin/3proxy"; then 287 | echo "Proxy server builded successfully" 288 | else 289 | log_err_and_exit "Error: proxy server build from source code failed." 290 | fi; 291 | cd .. 292 | } 293 | 294 | function configure_ipv6(){ 295 | # Enable sysctl options for rerouting and bind ips from subnet to default interface 296 | required_options=("conf.$interface_name.proxy_ndp" "conf.all.proxy_ndp" "conf.default.forwarding" "conf.all.forwarding" "ip_nonlocal_bind"); 297 | for option in ${required_options[@]}; do 298 | full_option="net.ipv6.$option=1"; 299 | if ! cat /etc/sysctl.conf | grep -v "#" | grep -q $full_option; then echo $full_option >> /etc/sysctl.conf; fi; 300 | done; 301 | sysctl -p &>> $script_log_file; 302 | 303 | if [[ $(cat /proc/sys/net/ipv6/conf/$interface_name/proxy_ndp) == 1 ]] && [[ $(cat /proc/sys/net/ipv6/ip_nonlocal_bind) == 1 ]]; then 304 | echo "IPv6 network sysctl data configured successfully"; 305 | else 306 | cat /etc/sysctl.conf &>> $script_log_file; 307 | log_err_and_exit "Error: cannot configure IPv6 config"; 308 | fi; 309 | } 310 | 311 | function generate_random_users_if_needed(){ 312 | # No need to generate random usernames and passwords for proxies, if auth=none or one username/password for all proxies provided 313 | if [ $use_random_auth != true ]; then return; fi; 314 | delete_file_if_exists $random_users_list_file; 315 | 316 | for i in $(seq 1 $proxy_count); do 317 | echo $(create_random_string 8):$(create_random_string 8) >> $random_users_list_file; 318 | done; 319 | } 320 | 321 | # função nova que evita ipv6 link local 322 | function get_ipv6_addresses() { 323 | local ipv6_addresses 324 | ipv6_addresses=($(ip -6 addr | awk '/inet6 .* global/ { print $2 }' | cut -d'/' -f1)) 325 | 326 | for ip in "${ipv6_addresses[@]}"; do 327 | # Verifica se o endereço IPv6 é global (começa com 2xxx: ou 3xxx:) 328 | if [[ $ip =~ ^2[0-9a-fA-F]{3}:.*$ || $ip =~ ^3[0-9a-fA-F]{3}:.*$ ]]; then 329 | echo $ip >> "$random_ipv6_list_file" 330 | # echo "echo $ip >> \"$random_ipv6_list_file\"" 331 | fi 332 | done 333 | } 334 | 335 | # function get_ipv6_addresses() { 336 | # local ipv6_addresses 337 | # ipv6_addresses=($(ip -6 addr | awk '/inet6 .* global/ { print $2 }' | cut -d'/' -f1)) 338 | 339 | # for ip in "${ipv6_addresses[@]}"; do 340 | # echo $ip >> "$random_ipv6_list_file" 341 | # # echo "echo $ip >> \"$random_ipv6_list_file\"" 342 | # done 343 | # } 344 | 345 | function create_startup_script(){ 346 | delete_file_if_exists $random_ipv6_list_file; 347 | get_ipv6_addresses 348 | 349 | is_auth_used; 350 | local use_auth=$?; 351 | 352 | # Add main script that runs proxy server and rotates external ip's, if server is already running 353 | cat > $startup_script_path <<-EOF 354 | #!$bash_location 355 | 356 | # Remove leading whitespaces in every string in text 357 | function dedent() { 358 | local -n reference="\$1" 359 | reference="\$(echo "\$reference" | sed 's/^[[:space:]]*//')" 360 | } 361 | 362 | # Save old 3proxy daemon pids, if exists 363 | proxyserver_process_pids=() 364 | while read -r pid; do 365 | proxyserver_process_pids+=(\$pid) 366 | done < <(ps -ef | awk '/[3]proxy/{print $2}'); 367 | 368 | 369 | immutable_config_part="daemon 370 | nserver 8.8.8.8 371 | nserver 8.8.4.4 372 | nserver 1.1.1.1 373 | nserver 1.0.0.1 374 | maxconn 5000 375 | nscache 65536 376 | timeouts 1 5 30 60 180 60 15 60 377 | setgid 65535 378 | setuid 65535" 379 | 380 | auth_part="auth iponly" 381 | if [ $use_auth -eq 0 ]; then 382 | auth_part=" 383 | auth strong 384 | users $user:CL:$password" 385 | fi; 386 | 387 | if [ -n "$denied_hosts" ]; then 388 | access_rules_part=" 389 | deny * * $denied_hosts 390 | allow *" 391 | else 392 | access_rules_part=" 393 | allow * * $allowed_hosts 394 | deny *" 395 | fi; 396 | 397 | dedent immutable_config_part; 398 | dedent auth_part; 399 | dedent access_rules_part; 400 | 401 | echo "\$immutable_config_part"\$'\n'"\$auth_part"\$'\n'"\$access_rules_part" > $proxyserver_config_path; 402 | 403 | # Add all ipv6 backconnect proxy with random adresses in proxy server startup config 404 | port=$start_port 405 | count=0 406 | if [ "$proxies_type" = "http" ]; then proxy_startup_depending_on_type="proxy -6 -n -a"; else proxy_startup_depending_on_type="socks -6 -a"; fi; 407 | if [ $use_random_auth = true ]; then readarray -t proxy_random_credentials < $random_users_list_file; fi; 408 | 409 | for random_ipv6_address in \$(cat $random_ipv6_list_file); do 410 | if [ $use_random_auth = true ]; then 411 | IFS=":"; 412 | read -r username password <<< "\${proxy_random_credentials[\$count]}"; 413 | echo "flush" >> $proxyserver_config_path; 414 | echo "users \$username:CL:\$password" >> $proxyserver_config_path; 415 | echo "\$access_rules_part" >> $proxyserver_config_path; 416 | IFS=$' \t\n'; 417 | fi; 418 | echo "\$proxy_startup_depending_on_type -p\$port -i$backconnect_ipv4 -e\$random_ipv6_address" >> $proxyserver_config_path; 419 | ((port+=1)) 420 | ((count+=1)) 421 | done 422 | 423 | # Script that adds all random ipv6 to default interface and runs backconnect proxy server 424 | ulimit -n 600000 425 | ulimit -u 600000 426 | ${user_home_dir}/proxyserver/3proxy/bin/3proxy ${proxyserver_config_path} 427 | 428 | # Kill old 3proxy daemon, if it's working 429 | for pid in "\${proxyserver_process_pids[@]}"; do 430 | kill \$pid; 431 | done; 432 | 433 | iptables -I INPUT -j ACCEPT 434 | 435 | exit 0; 436 | EOF 437 | 438 | } 439 | 440 | function close_ufw_backconnect_ports(){ 441 | if ! is_package_installed "ufw" || [ $use_localhost = true ] || ! test -f $backconnect_proxies_file; then return; fi; 442 | 443 | local first_opened_port=$(head -n 1 $backconnect_proxies_file | awk -F ':' '{print $2}'); 444 | local last_opened_port=$(tail -n 1 $backconnect_proxies_file | awk -F ':' '{print $2}'); 445 | 446 | ufw delete allow $first_opened_port:$last_opened_port/tcp >> $script_log_file; 447 | ufw delete allow $first_opened_port:$last_opened_port/udp >> $script_log_file; 448 | 449 | if ufw status | grep -qw $first_opened_port:$last_opened_port; then 450 | log_err "Cannot delete UFW rules for backconnect proxies"; 451 | else 452 | echo "UFW rules for backconnect proxies cleared successfully"; 453 | fi; 454 | } 455 | 456 | function open_ufw_backconnect_ports(){ 457 | close_ufw_backconnect_ports; 458 | 459 | # No need open ports if backconnect proxies on localhost 460 | if [ $use_localhost = true ]; then return; fi; 461 | 462 | if ! is_package_installed "ufw"; then echo "Firewall not installed, ports for backconnect proxy opened successfully"; return; fi; 463 | 464 | if ufw status | grep -qw active; then 465 | ufw allow $start_port:$last_port/tcp >> $script_log_file; 466 | ufw allow $start_port:$last_port/udp >> $script_log_file; 467 | 468 | if ufw status | grep -qw $start_port:$last_port; then 469 | echo "UFW ports for backconnect proxies opened successfully"; 470 | else 471 | log_err $(ufw status); 472 | log_err_and_exit "Cannot open ports for backconnect proxies, configure ufw please"; 473 | fi; 474 | 475 | else 476 | echo "UFW protection disabled, ports for backconnect proxy opened successfully"; 477 | fi; 478 | } 479 | 480 | function run_proxy_server(){ 481 | if [ ! -f $startup_script_path ]; then log_err_and_exit "Error: proxy startup script doesn't exist."; fi; 482 | 483 | chmod +x $startup_script_path; 484 | $bash_location $startup_script_path; 485 | if is_proxyserver_running; then 486 | echo -e "\nIPv6 proxy server started successfully. Backconnect IPv4 is available from $backconnect_ipv4:$start_port$credentials to $backconnect_ipv4:$last_port$credentials via $proxies_type protocol"; 487 | echo "You can copy all proxies (with credentials) in this file: $backconnect_proxies_file"; 488 | else 489 | log_err_and_exit "Error: cannot run proxy server"; 490 | fi; 491 | } 492 | 493 | function write_backconnect_proxies_to_file(){ 494 | delete_file_if_exists $backconnect_proxies_file; 495 | 496 | local proxy_credentials=$credentials; 497 | if ! touch $backconnect_proxies_file &> $script_log_file; then 498 | echo "Backconnect proxies list file path: $backconnect_proxies_file" >> $script_log_file; 499 | log_err "Warning: provided invalid path to backconnect proxies list file"; 500 | return; 501 | fi; 502 | 503 | if [ $use_random_auth = true ]; then 504 | local proxy_random_credentials; 505 | local count=0; 506 | readarray -t proxy_random_credentials < $random_users_list_file; 507 | fi; 508 | 509 | for port in $(eval echo "{$start_port..$last_port}"); do 510 | if [ $use_random_auth = true ]; then 511 | proxy_credentials=":${proxy_random_credentials[$count]}"; 512 | ((count+=1)) 513 | fi; 514 | echo "$backconnect_ipv4:$port$proxy_credentials" >> $backconnect_proxies_file; 515 | done; 516 | } 517 | 518 | function write_proxyserver_info(){ 519 | delete_file_if_exists $proxyserver_info_file; 520 | 521 | cat > $proxyserver_info_file <<-EOF 522 | User info: 523 | Proxy count: $proxy_count 524 | Proxy type: $proxies_type 525 | Proxy IP: $(get_backconnect_ipv4) 526 | Proxy ports: between $start_port and $last_port 527 | Auth: $(if is_auth_used; then if [ $use_random_auth = true ]; then echo "random user/password for each proxy"; else echo "user - $user, password - $password"; fi; else echo "disabled"; fi;) 528 | Rules: $(if ([ -n "$denied_hosts" ] || [ -n "$allowed_hosts" ]); then if [ -n "$denied_hosts" ]; then echo "denied hosts - $denied_hosts, all others are allowed"; else echo "allowed hosts - $allowed_hosts, all others are denied"; fi; else echo "no rules specified, all hosts are allowed"; fi;) 529 | File with backconnect proxy list: $backconnect_proxies_file 530 | 531 | 532 | EOF 533 | 534 | cat >> $proxyserver_info_file <<-EOF 535 | Technical info: 536 | Subnet: /$subnet 537 | Subnet mask: $subnet_mask 538 | File with generated IPv6 gateway addresses: $random_ipv6_list_file 539 | EOF 540 | } 541 | 542 | if [ $print_info = true ]; then 543 | if ! is_proxyserver_installed; then log_err_and_exit "Proxy server isn't installed"; fi; 544 | if ! is_proxyserver_running; then log_err_and_exit "Proxy server isn't running. You can check log of previous run attempt in $script_log_file"; fi; 545 | if ! test -f $proxyserver_info_file; then log_err_and_exit "File with information about running proxy server not found"; fi; 546 | 547 | cat $proxyserver_info_file; 548 | exit 0; 549 | fi; 550 | 551 | if [ $uninstall = true ]; then 552 | if ! is_proxyserver_installed; then log_err_and_exit "Proxy server is not installed"; fi; 553 | 554 | kill_3proxy; 555 | # remove_ipv6_addresses_from_iface; 556 | close_ufw_backconnect_ports; 557 | rm -rf $proxy_dir; 558 | delete_file_if_exists $backconnect_proxies_file; 559 | echo -e "\nIPv6 proxy server successfully uninstalled. If you want to reinstall, just run this script again."; 560 | exit 0; 561 | fi; 562 | 563 | 564 | delete_file_if_exists $script_log_file; 565 | check_startup_parameters; 566 | check_ipv6; 567 | if is_proxyserver_installed; then 568 | echo -e "Proxy server already installed, reconfiguring:\n"; 569 | else 570 | configure_ipv6; 571 | install_requred_packages; 572 | install_3proxy; 573 | fi; 574 | backconnect_ipv4=$(get_backconnect_ipv4); 575 | generate_random_users_if_needed; 576 | create_startup_script; 577 | open_ufw_backconnect_ports; 578 | run_proxy_server; 579 | write_backconnect_proxies_to_file; 580 | write_proxyserver_info; 581 | 582 | exit 0 583 | -------------------------------------------------------------------------------- /manual/README.md: -------------------------------------------------------------------------------- 1 | ### Tutorial 2 | 3 | Assuming you already have several IPv6 attached to your server. 4 | 5 | Just run: 6 | 7 | ```bash 8 | #sudo su 9 | wget https://raw.githubusercontent.com/erickythierry/ipv6-multiple-proxy-server/master/ipv6-proxy-server.sh && chmod +x ipv6-proxy-server.sh 10 | ./ipv6-proxy-server.sh -u user -p pass --start-port 30000 11 | ``` 12 | 13 | Uncomment first line or run all commands with `sudo` if you`re not under root. 14 | 15 | 16 | 17 | If script already installed, you can just run one command to reconfigure parameters, for example: 18 | 19 | ```bash 20 | ./ipv6-proxy-server.sh -u user2 -p pass2 -t http --start-port 30000 21 | ``` 22 | 23 | Old instance will be disabled and new starts without reinstallation very quickly. 24 | 25 | 26 | #### If you want to start proxy server when reboot, add this cron routine to crontab file `/etc/crontab` 27 | ```bash 28 | @reboot /usr/bin/bash /root/proxyserver/proxy-startup.sh 29 | ``` 30 | **change the script path to the right path according to your user** 31 | 32 | 33 | 34 | #### If you want to uninstall proxy server, just run: 35 | 36 | ```bash 37 | ./ipv6-proxy-server.sh --uninstall 38 | ``` 39 | 40 | Proxy server will stopped, all configuration files, firewalls, shedulers and so on will be reset to initial state. 41 | 42 | 43 | **Command line arguments:** 44 | 45 | - `-t` or `--proxies-type` - Proxies type - `http` or `socks5`. Default `socks5`, if no value provided 46 | - `-u` or `--username` - All proxies auth login 47 | - `-p` or `--password` - All proxies auth password (if you specify neither username not password, proxy will run without authentication) 48 | - `--random` - bool parameter without value, if used, each backconnect proxy will have random username and password, that will be written in backconnect proxies file (`-f` argument) 49 | - `--start-port` - backconnect IPv4 start port. If you create 1500 proxies and `start-port` is `20000`, and server external IPv4 is, e.g,`180.113.14.28` you can connect to proxies using `180.113.14.28:20000`, `180.113.14.28:20001` and so on until `180.113.14.28:21500` 50 | - `--allowed-hosts` - list of allowed hosts, to which user can connect via proxy (comma-separated, without spaces, for example - `"google.com,*.google.com,fb.com"`). All other hosts will be denied, if this parameter is provided 51 | - `--denied-hosts` - list of denied hosts (comma-separated, without spaces, for example - `"google.com,*.google.com,fb.com"`). All others hosts will be allowed, if this parameter is provided 52 | - `-l` or `--localhost` - bool parameter without value, if used, all backconnect proxy will be available only on localhost (`127.0.0.1:30000` instead of `180.113.14.28:30000`) 53 | - `-b` or `--backconnect-ip` - server IPv4 backconnect address for proxies, use ONLY if script cannot parse IP correctly and your server has non-standard IP configuration 54 | - `-f` or `--backconnect-proxies-file` - path to file, in which backconnect proxies list will be written when proxies start working (default `~/proxyserver/backconnect_proxies.list`). You can just copy all proxies from this file and use them in your soft as list of IPv6 proxies. 55 | - `-i` or `--interface` - ethernet interface name, to which IPv6 subnet is allocated and where all proxies will be raised. Automatically parsed from system info by default, use ONLY if you have non-standard/additional interfaces on your server. 56 | - `--uninstall` - uninstall proxy server, you don't need to provide any other parameters with it. 57 | - `--info` - get info about running proxy server (proxy count, rotating, auth, etc.) 58 | 59 | ### License 60 | 61 | [MIT](https://opensource.org/licenses/MIT) 62 | --------------------------------------------------------------------------------