├── config └── empty ├── openvpn ├── empty ├── jp454.nordvpn.com.tcp443.ovpn │ ├── secret │ └── vpn.ovpn └── hk-hkg.prod.surfshark.comsurfshark_openvpn_tcp.ovpn │ ├── secret │ └── vpn.ovpn ├── template ├── allowed_ip.txt ├── docker-compose.yml └── squid.conf ├── setup ├── composer.json ├── generate.php └── composer.lock ├── proxyList.txt ├── public_proxy_cron.sh ├── LICENSE └── README.md /config/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /openvpn/empty: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/allowed_ip.txt: -------------------------------------------------------------------------------- 1 | 127.0.0.1 2 | 172.17.0.1 3 | 172.21.0.1 4 | 172.24.0.1 -------------------------------------------------------------------------------- /openvpn/jp454.nordvpn.com.tcp443.ovpn/secret: -------------------------------------------------------------------------------- 1 | yourNordVPNUsername 2 | yourNordVPNPassword -------------------------------------------------------------------------------- /setup/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "symfony/yaml": "^5.1" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /proxyList.txt: -------------------------------------------------------------------------------- 1 | 159.89.206.161:2434:socks5:vpn:unlimited 2 | 142.93.68.63:2434:socks5:vpn:unlimited 3 | 82.196.7.200:2434:socks5:vpn:unlimited -------------------------------------------------------------------------------- /openvpn/hk-hkg.prod.surfshark.comsurfshark_openvpn_tcp.ovpn/secret: -------------------------------------------------------------------------------- 1 | yourSurfSharkVPNUsernameNotLoginAccount 2 | yourSurfSharkVPNPasswordNotLoginAccount -------------------------------------------------------------------------------- /public_proxy_cron.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | curl -sSf "https://raw.githubusercontent.com/clarketm/proxy-list/master/proxy-list-raw.txt" > proxyList.txt 3 | docker run --rm -it -v "$(pwd):/app/" php:7.4-cli php /app/setup/generate.php 4 | docker kill --signal=SIGHUP dockersquid_rotate -------------------------------------------------------------------------------- /template/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.4" 2 | services: 3 | squid: 4 | ports: 5 | - 3128:3128 6 | image: b4tman/squid:5.8 7 | volumes: 8 | - './config:/etc/squid/conf.d:ro' 9 | container_name: dockersquid_rotate 10 | environment: 11 | - 'SQUID_CONFIG_FILE=/etc/squid/conf.d/squid.conf' 12 | extra_hosts: 13 | - "host.docker.internal:host-gateway" 14 | healthcheck: 15 | test: [ "CMD-SHELL", "export https_proxy=127.0.0.1:3128 && export http_proxy=127.0.0.1:3128 && wget -q -Y on -O - http://httpbin.org/ip || exit 1" ] 16 | retries: 5 17 | timeout: "10s" 18 | start_period: "60s" 19 | interval: "300s" 20 | ulimits: 21 | nofile: 22 | soft: 65536 23 | hard: 65536 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /template/squid.conf: -------------------------------------------------------------------------------- 1 | http_port 3128 2 | acl localnet src 10.0.0.0/8 # RFC1918 possible internal network 3 | acl localnet src 172.16.0.0/12 # RFC1918 possible internal network 4 | acl localnet src 192.168.0.0/16 # RFC1918 possible internal network 5 | acl localnet src fc00::/7 # RFC 4193 local private network range 6 | acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines 7 | 8 | acl Allowed_IP src "/etc/squid/conf.d/allowed_ip.txt" 9 | http_access allow Allowed_IP 10 | acl NOCACHE src all 11 | 12 | acl SSL_ports port 443 13 | acl Safe_ports port 80 14 | acl Safe_ports port 443 15 | acl CONNECT method CONNECT 16 | 17 | http_access deny !Safe_ports 18 | http_access deny CONNECT !SSL_ports 19 | http_access allow localnet 20 | http_access allow localhost manager 21 | http_access deny manager 22 | http_access deny all 23 | 24 | 25 | cache deny NOCACHE 26 | visible_hostname unkown 27 | forwarded_for off 28 | request_header_access X-Forwarded-For deny all 29 | request_header_access Via deny all 30 | request_header_access Cache-Control deny all 31 | reply_header_access X-Forwarded-For deny all 32 | reply_header_access Via deny all 33 | reply_header_access X-Squid-Error deny all 34 | reply_header_access Cache-Control deny all 35 | never_direct allow all 36 | 37 | # because if client connection request failed and use a same connection will be always get 502 errors until create a new connection. 38 | server_persistent_connections off 39 | client_persistent_connections off 40 | 41 | #dns_nameservers 1.1.1.1 8.8.8.8 42 | 43 | access_log stdio:/proc/self/fd/1 combined 44 | -------------------------------------------------------------------------------- /openvpn/jp454.nordvpn.com.tcp443.ovpn/vpn.ovpn: -------------------------------------------------------------------------------- 1 | client 2 | dev tun 3 | proto tcp 4 | remote 89.187.161.54 443 5 | resolv-retry infinite 6 | remote-random 7 | nobind 8 | tun-mtu 1500 9 | tun-mtu-extra 32 10 | mssfix 1450 11 | persist-key 12 | persist-tun 13 | ping 15 14 | ping-restart 0 15 | ping-timer-rem 16 | reneg-sec 0 17 | comp-lzo no 18 | 19 | remote-cert-tls server 20 | 21 | auth-user-pass secret 22 | verb 3 23 | pull 24 | fast-io 25 | cipher AES-256-CBC 26 | auth SHA512 27 | 28 | -----BEGIN CERTIFICATE----- 29 | MIIFCjCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA5MQswCQYDVQQGEwJQQTEQ 30 | MA4GA1UEChMHTm9yZFZQTjEYMBYGA1UEAxMPTm9yZFZQTiBSb290IENBMB4XDTE2 31 | MDEwMTAwMDAwMFoXDTM1MTIzMTIzNTk1OVowOTELMAkGA1UEBhMCUEExEDAOBgNV 32 | BAoTB05vcmRWUE4xGDAWBgNVBAMTD05vcmRWUE4gUm9vdCBDQTCCAiIwDQYJKoZI 33 | hvcNAQEBBQADggIPADCCAgoCggIBAMkr/BYhyo0F2upsIMXwC6QvkZps3NN2/eQF 34 | kfQIS1gql0aejsKsEnmY0Kaon8uZCTXPsRH1gQNgg5D2gixdd1mJUvV3dE3y9FJr 35 | XMoDkXdCGBodvKJyU6lcfEVF6/UxHcbBguZK9UtRHS9eJYm3rpL/5huQMCppX7kU 36 | eQ8dpCwd3iKITqwd1ZudDqsWaU0vqzC2H55IyaZ/5/TnCk31Q1UP6BksbbuRcwOV 37 | skEDsm6YoWDnn/IIzGOYnFJRzQH5jTz3j1QBvRIuQuBuvUkfhx1FEwhwZigrcxXu 38 | MP+QgM54kezgziJUaZcOM2zF3lvrwMvXDMfNeIoJABv9ljw969xQ8czQCU5lMVmA 39 | 37ltv5Ec9U5hZuwk/9QO1Z+d/r6Jx0mlurS8gnCAKJgwa3kyZw6e4FZ8mYL4vpRR 40 | hPdvRTWCMJkeB4yBHyhxUmTRgJHm6YR3D6hcFAc9cQcTEl/I60tMdz33G6m0O42s 41 | Qt/+AR3YCY/RusWVBJB/qNS94EtNtj8iaebCQW1jHAhvGmFILVR9lzD0EzWKHkvy 42 | WEjmUVRgCDd6Ne3eFRNS73gdv/C3l5boYySeu4exkEYVxVRn8DhCxs0MnkMHWFK6 43 | MyzXCCn+JnWFDYPfDKHvpff/kLDobtPBf+Lbch5wQy9quY27xaj0XwLyjOltpiST 44 | LWae/Q4vAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqG 45 | SIb3DQEBDQUAA4ICAQC9fUL2sZPxIN2mD32VeNySTgZlCEdVmlq471o/bDMP4B8g 46 | nQesFRtXY2ZCjs50Jm73B2LViL9qlREmI6vE5IC8IsRBJSV4ce1WYxyXro5rmVg/ 47 | k6a10rlsbK/eg//GHoJxDdXDOokLUSnxt7gk3QKpX6eCdh67p0PuWm/7WUJQxH2S 48 | DxsT9vB/iZriTIEe/ILoOQF0Aqp7AgNCcLcLAmbxXQkXYCCSB35Vp06u+eTWjG0/ 49 | pyS5V14stGtw+fA0DJp5ZJV4eqJ5LqxMlYvEZ/qKTEdoCeaXv2QEmN6dVqjDoTAo 50 | k0t5u4YRXzEVCfXAC3ocplNdtCA72wjFJcSbfif4BSC8bDACTXtnPC7nD0VndZLp 51 | +RiNLeiENhk0oTC+UVdSc+n2nJOzkCK0vYu0Ads4JGIB7g8IB3z2t9ICmsWrgnhd 52 | NdcOe15BincrGA8avQ1cWXsfIKEjbrnEuEk9b5jel6NfHtPKoHc9mDpRdNPISeVa 53 | wDBM1mJChneHt59Nh8Gah74+TM1jBsw4fhJPvoc7Atcg740JErb904mZfkIEmojC 54 | VPhBHVQ9LHBAdM8qFI2kRK0IynOmAZhexlP/aT/kpEsEPyaZQlnBn3An1CRz8h0S 55 | PApL8PytggYKeQmRhl499+6jLxcZ2IegLfqq41dzIjwHwTMplg+1pKIOVojpWA== 56 | -----END CERTIFICATE----- 57 | 58 | key-direction 1 59 | 60 | # 61 | # 2048 bit OpenVPN static key 62 | # 63 | -----BEGIN OpenVPN Static key V1----- 64 | e685bdaf659a25a200e2b9e39e51ff03 65 | 0fc72cf1ce07232bd8b2be5e6c670143 66 | f51e937e670eee09d4f2ea5a6e4e6996 67 | 5db852c275351b86fc4ca892d78ae002 68 | d6f70d029bd79c4d1c26cf14e9588033 69 | cf639f8a74809f29f72b9d58f9b8f5fe 70 | fc7938eade40e9fed6cb92184abb2cc1 71 | 0eb1a296df243b251df0643d53724cdb 72 | 5a92a1d6cb817804c4a9319b57d53be5 73 | 80815bcfcb2df55018cc83fc43bc7ff8 74 | 2d51f9b88364776ee9d12fc85cc7ea5b 75 | 9741c4f598c485316db066d52db4540e 76 | 212e1518a9bd4828219e24b20d88f598 77 | a196c9de96012090e333519ae18d3509 78 | 9427e7b372d348d352dc4c85e18cd4b9 79 | 3f8a56ddb2e64eb67adfc9b337157ff4 80 | -----END OpenVPN Static key V1----- 81 | 82 | -------------------------------------------------------------------------------- /openvpn/hk-hkg.prod.surfshark.comsurfshark_openvpn_tcp.ovpn/vpn.ovpn: -------------------------------------------------------------------------------- 1 | client 2 | dev tun 3 | proto tcp 4 | remote hk-hkg.prod.surfshark.com 1443 5 | resolv-retry infinite 6 | remote-random 7 | nobind 8 | tun-mtu 1500 9 | tun-mtu-extra 32 10 | mssfix 1450 11 | persist-key 12 | persist-tun 13 | ping 15 14 | ping-restart 0 15 | ping-timer-rem 16 | reneg-sec 0 17 | 18 | remote-cert-tls server 19 | 20 | auth-user-pass secret 21 | 22 | #comp-lzo 23 | verb 3 24 | pull 25 | fast-io 26 | cipher AES-256-CBC 27 | 28 | auth SHA512 29 | 30 | 31 | -----BEGIN CERTIFICATE----- 32 | MIIFTTCCAzWgAwIBAgIJAMs9S3fqwv+mMA0GCSqGSIb3DQEBCwUAMD0xCzAJBgNV 33 | BAYTAlZHMRIwEAYDVQQKDAlTdXJmc2hhcmsxGjAYBgNVBAMMEVN1cmZzaGFyayBS 34 | b290IENBMB4XDTE4MDMxNDA4NTkyM1oXDTI4MDMxMTA4NTkyM1owPTELMAkGA1UE 35 | BhMCVkcxEjAQBgNVBAoMCVN1cmZzaGFyazEaMBgGA1UEAwwRU3VyZnNoYXJrIFJv 36 | b3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDEGMNj0aisM63o 37 | SkmVJyZPaYX7aPsZtzsxo6m6p5Wta3MGASoryRsBuRaH6VVa0fwbI1nw5ubyxkua 38 | Na4v3zHVwuSq6F1p8S811+1YP1av+jqDcMyojH0ujZSHIcb/i5LtaHNXBQ3qN48C 39 | c7sqBnTIIFpmb5HthQ/4pW+a82b1guM5dZHsh7q+LKQDIGmvtMtO1+NEnmj81BAp 40 | FayiaD1ggvwDI4x7o/Y3ksfWSCHnqXGyqzSFLh8QuQrTmWUm84YHGFxoI1/8AKdI 41 | yVoB6BjcaMKtKs/pbctk6vkzmYf0XmGovDKPQF6MwUekchLjB5gSBNnptSQ9kNgn 42 | TLqi0OpSwI6ixX52Ksva6UM8P01ZIhWZ6ua/T/tArgODy5JZMW+pQ1A6L0b7egIe 43 | ghpwKnPRG+5CzgO0J5UE6gv000mqbmC3CbiS8xi2xuNgruAyY2hUOoV9/BuBev8t 44 | tE5ZCsJH3YlG6NtbZ9hPc61GiBSx8NJnX5QHyCnfic/X87eST/amZsZCAOJ5v4EP 45 | SaKrItt+HrEFWZQIq4fJmHJNNbYvWzCE08AL+5/6Z+lxb/Bm3dapx2zdit3x2e+m 46 | iGHekuiE8lQWD0rXD4+T+nDRi3X+kyt8Ex/8qRiUfrisrSHFzVMRungIMGdO9O/z 47 | CINFrb7wahm4PqU2f12Z9TRCOTXciQIDAQABo1AwTjAdBgNVHQ4EFgQUYRpbQwyD 48 | ahLMN3F2ony3+UqOYOgwHwYDVR0jBBgwFoAUYRpbQwyDahLMN3F2ony3+UqOYOgw 49 | DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAn9zV7F/XVnFNZhHFrt0Z 50 | S1Yqz+qM9CojLmiyblMFh0p7t+Hh+VKVgMwrz0LwDH4UsOosXA28eJPmech6/bjf 51 | ymkoXISy/NUSTFpUChGO9RabGGxJsT4dugOw9MPaIVZffny4qYOc/rXDXDSfF2b+ 52 | 303lLPI43y9qoe0oyZ1vtk/UKG75FkWfFUogGNbpOkuz+et5Y0aIEiyg0yh6/l5Q 53 | 5h8+yom0HZnREHhqieGbkaGKLkyu7zQ4D4tRK/mBhd8nv+09GtPEG+D5LPbabFVx 54 | KjBMP4Vp24WuSUOqcGSsURHevawPVBfgmsxf1UCjelaIwngdh6WfNCRXa5QQPQTK 55 | ubQvkvXONCDdhmdXQccnRX1nJWhPYi0onffvjsWUfztRypsKzX4dvM9k7xnIcGSG 56 | EnCC4RCgt1UiZIj7frcCMssbA6vJ9naM0s7JF7N3VKeHJtqe1OCRHMYnWUZt9vrq 57 | X6IoIHlZCoLlv39wFW9QNxelcAOCVbD+19MZ0ZXt7LitjIqe7yF5WxDQN4xru087 58 | FzQ4Hfj7eH1SNLLyKZkA1eecjmRoi/OoqAt7afSnwtQLtMUc2bQDg6rHt5C0e4dC 59 | LqP/9PGZTSJiwmtRHJ/N5qYWIh9ju83APvLm/AGBTR2pXmj9G3KdVOkpIC7L35dI 60 | 623cSEC3Q3UZutsEm/UplsM= 61 | -----END CERTIFICATE----- 62 | 63 | key-direction 1 64 | 65 | # 66 | # 2048 bit OpenVPN static key 67 | # 68 | -----BEGIN OpenVPN Static key V1----- 69 | b02cb1d7c6fee5d4f89b8de72b51a8d0 70 | c7b282631d6fc19be1df6ebae9e2779e 71 | 6d9f097058a31c97f57f0c35526a44ae 72 | 09a01d1284b50b954d9246725a1ead1f 73 | f224a102ed9ab3da0152a15525643b2e 74 | ee226c37041dc55539d475183b889a10 75 | e18bb94f079a4a49888da566b9978346 76 | 0ece01daaf93548beea6c827d9674897 77 | e7279ff1a19cb092659e8c1860fbad0d 78 | b4ad0ad5732f1af4655dbd66214e552f 79 | 04ed8fd0104e1d4bf99c249ac229ce16 80 | 9d9ba22068c6c0ab742424760911d463 81 | 6aafb4b85f0c952a9ce4275bc821391a 82 | a65fcd0d2394f006e3fba0fd34c4bc4a 83 | b260f4b45dec3285875589c97d3087c9 84 | 134d3a3aa2f904512e85aa2dc2202498 85 | -----END OpenVPN Static key V1----- 86 | 87 | -------------------------------------------------------------------------------- /setup/generate.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | [ 46 | $port . ':' . $port, 47 | ], 48 | 'image' => 'ginuerzh/gost:latest', 49 | 'container_name'=>'dockergost_'.$i, 50 | 'command' => sprintf('-L=:%d -F=%s://%s%s:%d', $port, $proxyInfo['scheme'], $cred, $proxyInfo['host'], $proxyInfo['port']) 51 | ]; 52 | $squid_conf[] = sprintf($squid_default, 'dockergost_'.$i, $port, 'gost'.$i); 53 | $port++; 54 | } 55 | if($squid_conf){ 56 | file_put_contents(__DIR__.'/squid.conf', PHP_EOL . implode(' ', $squid_conf), FILE_APPEND); 57 | } 58 | $i++; 59 | } 60 | //openvpn support 61 | if(file_exists(__DIR__.'/../openvpn')){ 62 | foreach(glob(__DIR__.'/../openvpn/*') as $fileOrDir){ 63 | if(!is_dir($fileOrDir)){ 64 | continue; 65 | } 66 | 67 | $config_ovpn = glob(__DIR__.'/../openvpn/'.basename($fileOrDir).'/*.ovpn'); 68 | if(empty($config_ovpn[0])){ 69 | throw new \RuntimeException("OpenVPN Configuration File Not Found:".$fileOrDir); 70 | } 71 | 72 | $config_secret = glob(__DIR__.'/../openvpn/'.basename($fileOrDir).'/secret'); 73 | $config_ovpn = realpath($config_ovpn[0]); 74 | 75 | //If a hostname is present in the Config, convert it to an IP address. (To prevent IP address leaks) 76 | $config_lists = file($config_ovpn,FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); 77 | foreach($config_lists as $key=>$config_list){ 78 | if(preg_match("/^remote\s+([\w.-]+)(?:\s+(\d+))?$/",$config_list,$matches)){ 79 | $remote = 'remote '.gethostbyname($matches[1]); 80 | if(isset($matches[2])){ 81 | $remote.= ' '.$matches[2]; 82 | } 83 | $config_lists[$key] = $remote; 84 | 85 | file_put_contents($config_ovpn,implode(PHP_EOL,$config_lists)); 86 | break; 87 | } 88 | } 89 | 90 | $credentials = null; 91 | $env = [ 92 | 'VPN_SERVICE_PROVIDER=custom', 93 | 'VPN_TYPE=openvpn', 94 | 'OPENVPN_CUSTOM_CONFIG=/gluetun/'.basename($config_ovpn), 95 | 'HTTPPROXY=on', 96 | 'HTTPPROXY_USER=', 97 | 'HTTPPROXY_PASSWORD=', 98 | 'HTTPPROXY_STEALTH=on', 99 | ]; 100 | 101 | if(!empty($config_secret[0])) { 102 | $credentials = file($config_secret[0],FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); 103 | $env = array_merge($env,[ 104 | 'OPENVPN_USER='.$credentials[0], 105 | 'OPENVPN_PASSWORD='.$credentials[1], 106 | ]); 107 | } 108 | 109 | $to['services']['vpn' . $i] = [ 110 | 'ports' => [ 111 | $port . ':'.$gluetun_http_port.'/tcp', 112 | $port_shadow_socks . ':8388', 113 | ], 114 | 'image' => 'qmcgaw/gluetun', 115 | 'container_name'=>'dockervpn_'.$i, 116 | 'devices'=>[ 117 | '/dev/net/tun:/dev/net/tun' 118 | ], 119 | 'cap_add'=>[ 120 | 'NET_ADMIN' 121 | ], 122 | 'volumes'=>[ 123 | './openvpn/'.basename($fileOrDir).':/gluetun' 124 | ], 125 | 'environment'=>$env 126 | ]; 127 | file_put_contents(__DIR__.'/squid.conf', PHP_EOL . sprintf($squid_default, 'dockervpn_'.$i, $gluetun_http_port, 'vpn'.$i), FILE_APPEND); 128 | 129 | $i++; 130 | $port++; 131 | $port_shadow_socks++; 132 | 133 | } 134 | } 135 | 136 | 137 | file_put_contents(__DIR__.'/../docker-compose.yml', Yaml::dump($to,4,4)); 138 | rename(__DIR__.'/squid.conf',__DIR__.'/../config/squid.conf'); 139 | copy(__DIR__.'/../template/allowed_ip.txt',__DIR__.'/../config/allowed_ip.txt'); 140 | 141 | 142 | function isArm64() { 143 | $architecture = php_uname('m'); 144 | 145 | if ($architecture === 'aarch64' || $architecture === 'arm64') { 146 | return true; 147 | } 148 | 149 | return false; 150 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker Rotating Proxy Config Generator 2 | 3 | - Fully Optimized for Web Scraping Usage. 4 | - HTTP/HTTPS Support (see wiki) 5 | - socks5 with Authorization Proxy to HTTP(S) proxy convert compatible by [Gost](https://github.com/ginuerzh/gost) 6 | - You can use a VPN as an HTTP proxy.(powered by [gluetun](https://github.com/qdm12/gluetun) ) 7 | - Making it IP address based authentication makes it easier to use in your program.(selenium,puppeteer etc) 8 | 9 | 10 | ``` 11 | Docker Container 12 | ---------------------------------- 13 | Client <----> Squid <-> HTTP/HTTPS Rotate Proxies---\ 14 | | 15 | ---------------|-> Gost <-> Socks5 Proxy --- Internet 16 | | 17 | --------------<-> VPN to HTTP Proxy <--------/ 18 | 19 | 20 | 21 | It can be used in two ways. 22 | 1.Automatically control the proxy and rotate each request -> use Squid 23 | 2.Control the proxy programmatically -> use Gost Port 24 | 25 | ``` 26 | 27 | 28 | ## Usage Example 29 | 30 | ### Configuring IPs to allow the use of the Rotating Proxy 31 | If you want to use it from outside, please specify the **your** IP address to allowed_ip.txt 32 | 33 | http://httpbin.org/ip 34 | 35 | Example: 36 | ``` 37 | 93.184.216.34 38 | 108.62.57.53 39 | ``` 40 | 41 | ### 1. Create your proxyList.txt(If HTTP/Socks is provided) 42 | Search FreeProxy List or Paid/Subscribe ProxyService Provider. 43 | 44 | example : https://github.com/clarketm/proxy-list 45 | 46 | #### Format 47 | ``` 48 | IPAddress:Port:Type(socks5 or http or https or httpsquid):Username:Password 49 | IPAddress:Port:Type(socks5 or http or https or httpsquid) 50 | IPAddress:Port 51 | ``` 52 | 53 | ### 1.1 Create Your OpenVPN Config(If HTTP/Socks is NOT provided) 54 | see [example](openvpn/) 55 | 56 | ### Format 57 | ``` 58 | openvpn/{name} 59 | openvpn/{name}/{name2}.ovpn 60 | openvpn/{name}/secret 61 | ``` 62 | 63 | ### 2. Generate docker-compose.yml 64 | ``` 65 | git clone https://github.com/39ff/docker-rotating-proxy 66 | cd docker-rotating-proxy && cd setup 67 | docker run --rm -it -v "$(pwd):/app" composer install 68 | cd .. 69 | # If you don't want to set up OpenVPN, please remove it. 70 | rm -rf ./openvpn/* 71 | docker run --rm -it -v "$(pwd):/app/" php:7.4-cli php /app/setup/generate.php 72 | cat docker-compose.yml 73 | docker-compose up -d 74 | curl https://httpbin.org/ip --proxy http://127.0.0.1:3128 75 | ``` 76 | 77 | ### How to it works? 78 | ![pattern1](https://user-images.githubusercontent.com/7544687/97991581-fdc2f380-1e24-11eb-99f3-df9885d627a2.png) 79 | 80 | - Sometimes you may need the same IP address for a series of steps. 81 | To deal with this problem, we have built a new relay server via gost. 82 | 83 | - Most open proxies will be unavailable in a few days. 84 | Therefore, it is useless to build a server for every open proxy, so we use squid's cache_peer to rotate a large number of open proxies. 85 | 86 | ### proxyList.txt Example1 87 | 88 | ``` 89 | 127.0.0.1:1080:socks5:yourUsername:yourPassword 90 | 127.0.0.1:44129:httpsquid:mysquidproxy:mysquidpassword 91 | 127.0.0.1:29128:httpsquid:rotatingserviceUsername:password 92 | 169.254.0.1:1080:socks5:paidsocksUsername:paidsocksPassword 93 | 127.0.0.1:80 94 | 172.31.22.222:8080 95 | ``` 96 | 97 | ## proxyList.txt Example2 98 | Here are some practical examples. 99 | 100 | using NordVPN,TorGuard,Luminati 101 | 102 | ``` 103 | 89.187.161.86:80:httpsquid:yourNordVPNEmail@example.com:NordVPNPassword 104 | 173.254.222.146:1080:socks5:yourTorGuardUsername:Password 105 | zproxy.lum-superproxy.io:22225:httpsquid:yourLuminatiUsername:Password 106 | ``` 107 | 108 | 109 | 110 | ## Generated docker-compose.yml example 111 | ``` 112 | version: '3.4' 113 | services: 114 | squid: 115 | ports: 116 | - '3128:3128' 117 | image: 'b4tman/squid:5.8' 118 | volumes: 119 | - './config:/etc/squid/conf.d:ro' 120 | container_name: dockersquid_rotate 121 | environment: 122 | - SQUID_CONFIG_FILE=/etc/squid/conf.d/squid.conf 123 | extra_hosts: 124 | - 'host.docker.internal:host-gateway' 125 | healthcheck: 126 | test: [CMD-SHELL, 'export https_proxy=127.0.0.1:3128 && export http_proxy=127.0.0.1:3128 && wget -q -Y on -O - https://checkip.amazonaws.com || exit 1'] 127 | retries: 5 128 | timeout: 10s 129 | start_period: 10s 130 | interval: 300s 131 | proxy1: 132 | ports: 133 | - '30000:30000' 134 | image: 'ginuerzh/gost:latest' 135 | container_name: dockergost_1 136 | command: '-L=:30000 -F=socks5://vpn:unlimited@82.196.7.200:2434' 137 | vpn2: 138 | ports: 139 | - '30001:8888/tcp' 140 | - '50000:8388' 141 | image: qmcgaw/gluetun 142 | container_name: dockervpn_2 143 | devices: 144 | - '/dev/net/tun:/dev/net/tun' 145 | cap_add: 146 | - NET_ADMIN 147 | volumes: 148 | - './openvpn/hk-hkg.prod.surfshark.comsurfshark_openvpn_tcp.ovpn:/gluetun' 149 | environment: 150 | - VPN_SERVICE_PROVIDER=custom 151 | - VPN_TYPE=openvpn 152 | - OPENVPN_CUSTOM_CONFIG=/gluetun/vpn.ovpn 153 | - HTTPPROXY=on 154 | - HTTPPROXY_USER= 155 | - HTTPPROXY_PASSWORD= 156 | - HTTPPROXY_STEALTH=on 157 | - OPENVPN_USER=xxxxx 158 | - OPENVPN_PASSWORD=yyyyy 159 | vpn3: 160 | ports: 161 | - '30002:8888/tcp' 162 | - '50001:8388' 163 | image: qmcgaw/gluetun 164 | container_name: dockervpn_3 165 | devices: 166 | - '/dev/net/tun:/dev/net/tun' 167 | cap_add: 168 | - NET_ADMIN 169 | volumes: 170 | - './openvpn/jp454.nordvpn.com.tcp443.ovpn:/gluetun' 171 | environment: 172 | - VPN_SERVICE_PROVIDER=custom 173 | - VPN_TYPE=openvpn 174 | - OPENVPN_CUSTOM_CONFIG=/gluetun/vpn.ovpn 175 | - HTTPPROXY=on 176 | - HTTPPROXY_USER= 177 | - HTTPPROXY_PASSWORD= 178 | - HTTPPROXY_STEALTH=on 179 | - OPENVPN_USER=xxxxx 180 | - OPENVPN_PASSWORD=yyyyy 181 | ``` 182 | 183 | ## Now try it out 184 | ``` 185 | port 3128 is rotation port. 186 | Recommended for one-time requests that do not require browser rendering, such as curl 187 | 188 | sh-4.2# curl https://httpbin.org/ip --proxy https://127.0.0.1:3128 189 | { 190 | "origin": "82.196.7.200" 191 | } 192 | sh-4.2# curl https://httpbin.org/ip --proxy https://127.0.0.1:3128 193 | { 194 | "origin": "89.187.161.56" 195 | } 196 | sh-4.2# curl https://httpbin.org/ip --proxy https://127.0.0.1:3128 197 | { 198 | "origin": "84.17.37.159" 199 | } 200 | sh-4.2# curl https://httpbin.org/ip --proxy https://127.0.0.1:3128 201 | { 202 | "origin": "81.171.85.49" 203 | } 204 | sh-4.2# 205 | 206 | and.. try static ip gateway 207 | Recommended in selenium, puppeteer and playwright 208 | 209 | # curl httpbin.org/ip --proxy http://127.0.0.1:30000 210 | { 211 | "origin": "82.196.7.200" 212 | } 213 | # curl httpbin.org/ip --proxy http://127.0.0.1:30000 214 | { 215 | "origin": "82.196.7.200" 216 | } 217 | 218 | # curl httpbin.org/ip --proxy http://127.0.0.1:30001 219 | { 220 | "origin": "84.17.37.159" 221 | } 222 | # curl httpbin.org/ip --proxy http://127.0.0.1:30001 223 | { 224 | "origin": "84.17.37.159" 225 | } 226 | ``` 227 | 228 | 229 | ## Warning 230 | By default, ports can be used without authentication. 231 | Some VPSs that are directly exposed globally may require appropriate modifications to the docker-compose. 232 | 233 | 234 | ## Example of using a large number of public proxies with real-time updates 235 | see [public_proxy_cron.sh](public_proxy_cron.sh) 236 | ``` 237 | 0 * * * * /your_sh_path_here/public_proxy_cron.sh 238 | ``` 239 | 240 | ## TODO 241 | - [ ] Username/Password Auth for Enterprise -------------------------------------------------------------------------------- /setup/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "b20f8dd3d8b03786cf5eb51fd1097f6b", 8 | "packages": [ 9 | { 10 | "name": "symfony/deprecation-contracts", 11 | "version": "v2.2.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/symfony/deprecation-contracts.git", 15 | "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", 20 | "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=7.1" 25 | }, 26 | "type": "library", 27 | "extra": { 28 | "branch-alias": { 29 | "dev-master": "2.2-dev" 30 | }, 31 | "thanks": { 32 | "name": "symfony/contracts", 33 | "url": "https://github.com/symfony/contracts" 34 | } 35 | }, 36 | "autoload": { 37 | "files": [ 38 | "function.php" 39 | ] 40 | }, 41 | "notification-url": "https://packagist.org/downloads/", 42 | "license": [ 43 | "MIT" 44 | ], 45 | "authors": [ 46 | { 47 | "name": "Nicolas Grekas", 48 | "email": "p@tchwork.com" 49 | }, 50 | { 51 | "name": "Symfony Community", 52 | "homepage": "https://symfony.com/contributors" 53 | } 54 | ], 55 | "description": "A generic function and convention to trigger deprecation notices", 56 | "homepage": "https://symfony.com", 57 | "funding": [ 58 | { 59 | "url": "https://symfony.com/sponsor", 60 | "type": "custom" 61 | }, 62 | { 63 | "url": "https://github.com/fabpot", 64 | "type": "github" 65 | }, 66 | { 67 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 68 | "type": "tidelift" 69 | } 70 | ], 71 | "time": "2020-09-07T11:33:47+00:00" 72 | }, 73 | { 74 | "name": "symfony/polyfill-ctype", 75 | "version": "v1.20.0", 76 | "source": { 77 | "type": "git", 78 | "url": "https://github.com/symfony/polyfill-ctype.git", 79 | "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" 80 | }, 81 | "dist": { 82 | "type": "zip", 83 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", 84 | "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", 85 | "shasum": "" 86 | }, 87 | "require": { 88 | "php": ">=7.1" 89 | }, 90 | "suggest": { 91 | "ext-ctype": "For best performance" 92 | }, 93 | "type": "library", 94 | "extra": { 95 | "branch-alias": { 96 | "dev-main": "1.20-dev" 97 | }, 98 | "thanks": { 99 | "name": "symfony/polyfill", 100 | "url": "https://github.com/symfony/polyfill" 101 | } 102 | }, 103 | "autoload": { 104 | "psr-4": { 105 | "Symfony\\Polyfill\\Ctype\\": "" 106 | }, 107 | "files": [ 108 | "bootstrap.php" 109 | ] 110 | }, 111 | "notification-url": "https://packagist.org/downloads/", 112 | "license": [ 113 | "MIT" 114 | ], 115 | "authors": [ 116 | { 117 | "name": "Gert de Pagter", 118 | "email": "BackEndTea@gmail.com" 119 | }, 120 | { 121 | "name": "Symfony Community", 122 | "homepage": "https://symfony.com/contributors" 123 | } 124 | ], 125 | "description": "Symfony polyfill for ctype functions", 126 | "homepage": "https://symfony.com", 127 | "keywords": [ 128 | "compatibility", 129 | "ctype", 130 | "polyfill", 131 | "portable" 132 | ], 133 | "funding": [ 134 | { 135 | "url": "https://symfony.com/sponsor", 136 | "type": "custom" 137 | }, 138 | { 139 | "url": "https://github.com/fabpot", 140 | "type": "github" 141 | }, 142 | { 143 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 144 | "type": "tidelift" 145 | } 146 | ], 147 | "time": "2020-10-23T14:02:19+00:00" 148 | }, 149 | { 150 | "name": "symfony/yaml", 151 | "version": "v5.1.8", 152 | "source": { 153 | "type": "git", 154 | "url": "https://github.com/symfony/yaml.git", 155 | "reference": "f284e032c3cefefb9943792132251b79a6127ca6" 156 | }, 157 | "dist": { 158 | "type": "zip", 159 | "url": "https://api.github.com/repos/symfony/yaml/zipball/f284e032c3cefefb9943792132251b79a6127ca6", 160 | "reference": "f284e032c3cefefb9943792132251b79a6127ca6", 161 | "shasum": "" 162 | }, 163 | "require": { 164 | "php": ">=7.2.5", 165 | "symfony/deprecation-contracts": "^2.1", 166 | "symfony/polyfill-ctype": "~1.8" 167 | }, 168 | "conflict": { 169 | "symfony/console": "<4.4" 170 | }, 171 | "require-dev": { 172 | "symfony/console": "^4.4|^5.0" 173 | }, 174 | "suggest": { 175 | "symfony/console": "For validating YAML files using the lint command" 176 | }, 177 | "bin": [ 178 | "Resources/bin/yaml-lint" 179 | ], 180 | "type": "library", 181 | "autoload": { 182 | "psr-4": { 183 | "Symfony\\Component\\Yaml\\": "" 184 | }, 185 | "exclude-from-classmap": [ 186 | "/Tests/" 187 | ] 188 | }, 189 | "notification-url": "https://packagist.org/downloads/", 190 | "license": [ 191 | "MIT" 192 | ], 193 | "authors": [ 194 | { 195 | "name": "Fabien Potencier", 196 | "email": "fabien@symfony.com" 197 | }, 198 | { 199 | "name": "Symfony Community", 200 | "homepage": "https://symfony.com/contributors" 201 | } 202 | ], 203 | "description": "Symfony Yaml Component", 204 | "homepage": "https://symfony.com", 205 | "funding": [ 206 | { 207 | "url": "https://symfony.com/sponsor", 208 | "type": "custom" 209 | }, 210 | { 211 | "url": "https://github.com/fabpot", 212 | "type": "github" 213 | }, 214 | { 215 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 216 | "type": "tidelift" 217 | } 218 | ], 219 | "time": "2020-10-24T12:03:25+00:00" 220 | } 221 | ], 222 | "packages-dev": [], 223 | "aliases": [], 224 | "minimum-stability": "stable", 225 | "stability-flags": [], 226 | "prefer-stable": false, 227 | "prefer-lowest": false, 228 | "platform": [], 229 | "platform-dev": [], 230 | "plugin-api-version": "1.1.0" 231 | } 232 | --------------------------------------------------------------------------------