├── .gitignore ├── README.md ├── client ├── crontab ├── pppoe.sh ├── request.conf └── request.sh └── server ├── __init__.py ├── config.py ├── ip └── main.py /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | *.pyc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Auto Proxy 2 | ## 功能 3 | 4 | 由于DDNS生效时间过长,对于爬虫等一些时间要求比较紧迫的项目就不太适用,为此本项目根据DDNS基本原理来实现实时获取ADSL拨号主机IP。 5 | 6 | ## 基本原理 7 | 8 | client文件夹由ADSL拨号客户机运行。它会定时执行拨号操作,然后请求某个固定地址的服务器,以便让服务器获取ADSL拨号客户机的IP,主要是定时bash脚本运行。 9 | 10 | server文件夹是服务器端运行,利用Python的Flask搭建服务器,然后接收ADSL拨号客户机的请求,得到remote_addr,获取客户机拨号后的IP。 11 | 12 | ## 项目结构 13 | 14 | ### server 15 | 16 | - config.py 配置文件。 17 | - ip 客户端请求后获取的客户端IP,文本保存。 18 | - main.py Flask主程序,提供两个接口,一个是接收客户端请求,然后将IP保存,另外一个是获取当前保存的IP。 19 | 20 | ### client 21 | 22 | * crontab 定时任务命令示例。 23 | * pppoe.sh 拨号脚本,主要是实现重新拨号的几个命令。 24 | * request.sh 请求服务器的脚本,主要是实现拨号后请求服务器的操作。 25 | * request.conf 配置文件。 26 | 27 | ## 使用 28 | 29 | ### 服务器 30 | 31 | 服务器提供两个功能,record方法是客户机定时请求,然后获取客户机IP并保存。proxy方法是供我们自己用,返回保存的客户机IP,提取代理。 32 | 33 | #### 克隆项目 34 | 35 | ``` 36 | git clone https://github.com/Germey/AutoProxy.git 37 | ``` 38 | 39 | #### 安装Python 40 | 41 | 安装Python版本2.7。 42 | 43 | ###### Ubuntu、Debian、Deepin 44 | 45 | ``` 46 | sudo apt-get install python2.7 python-pip 47 | ``` 48 | 49 | ##### CentOS、RedHat 50 | 51 | ``` 52 | sudo yum install python27 python-pip 53 | ``` 54 | 55 | #### 安装Python包 56 | 57 | ``` 58 | pip install flask werkzeug itsdangerous click 59 | ``` 60 | 61 | #### 修改配置 62 | 63 | 修改config.py文件 64 | 65 | * KEY 是客户端请求服务器时的凭证,在client的request.conf也有相同的配置,二者保持一致即可。 66 | 67 | * NEED_AUTH 在获取当前保存的IP(即代理的IP)的时候,为防止自己的主机代理被滥用,在获取IP的时候,需要加权限验证。 68 | 69 | * AUTH_USER和AUTH_PASSWORD分别是认证用户名密码。 70 | 71 | * PORT默认端口,返回保存的结果中会自动添加这个端口,组成一个IP:PORT的代理形式。 72 | 73 | 注意默认是8888,你需要用Squid或者TinyProxy配置下代理,端口是8888,这里端口8888即默认的拨号VPS的代理端口,这里配置下保证输出结果自动拼接端口。 74 | 75 | ### 运行 76 | 77 | ``` 78 | cd server 79 | nohup python main.py & 80 | ``` 81 | 82 | 这样就会在5000端口启动服务,如果想修改端口,可以手动修改main.py里面的端口5000为其他。 83 | 84 | ### ADSL客户机 85 | 86 | #### 克隆项目 87 | 88 | ``` 89 | git clone https://github.com/Germey/AutoProxy.git 90 | ``` 91 | 92 | #### 修改配置 93 | 94 | 修改request.conf文件 95 | 96 | * KEY 是客户端请求服务器时的凭证,在server的config.py也有相同的配置,二者保持一致即可。 97 | * SERVER是服务器项目运行后的地址,一般为http://<服务器IP>:<服务端口>/record。如`http://120.27.14.24:5000/record`。 98 | 99 | 修改pppoe.sh文件 100 | 101 | 这里面写上重新拨号的几条命令,记得在前两行配置一下环境变量,配置上拨号命令所在的目录,以防出现脚本无法运行的问题。 102 | 103 | 比如我的是 104 | 105 | ``` 106 | pppoe-stop 107 | pppoe-start 108 | ``` 109 | 110 | 当然有的主机可能是 111 | 112 | ``` 113 | adsl-stop 114 | adsl-start 115 | ``` 116 | 117 | 不同主机拨号命令不一样,在这里把停止和启动拨号的命令写上。具体请看服务商提供的拨号命令。 118 | 119 | ### 运行 120 | 121 | 设置定时任务 122 | 123 | ``` 124 | crontab -e 125 | ``` 126 | 127 | 输入crontab的实例命令 128 | 129 | ``` 130 | */5 * * * * /var/py/AutoProxy/client/request.sh /var/py/AutoProxy/client/request.conf >> /var/py/AutoProxy/client/request.log 131 | ``` 132 | 133 | 注意修改路径,你的项目在哪里,都统一修改成自己项目的路径。 134 | 135 | 最前面的*/5是5分钟执行一次。 136 | 137 | 好了,保存之后,定时任务就会开启。 138 | 139 | ## 验证结果 140 | 141 | 这样一来,访问服务器地址,就可以得到ADSL拨号客户机的IP了。 142 | 143 | ```python 144 | import requests 145 | 146 | url = 'http://120.27.14.24:5000' 147 | proxy = requests.get(url, auth=('admin', '123')).text 148 | print(proxy) 149 | ``` 150 | 151 | 实例结果: 152 | 153 | ``` 154 | 116.208.97.22:8888 155 | ``` 156 | 157 | ## 扩展 158 | 159 | 如果你有域名,可以自己解析一个域名,这样就可以直接请求自己的域名,拿到实时好用的代理了,而且定时更新。 160 | 161 | ![](http://opencdn.cuiqingcai.com/proxy.png) 162 | 163 | ## 代理设置 164 | 165 | ### urllib2 166 | 167 | ```python 168 | import urllib2 169 | proxy_handler = urllib2.ProxyHandler({"http": 'http://' + proxy}) 170 | opener = urllib2.build_opener(proxy_handler) 171 | urllib2.install_opener(opener) 172 | response = urllib2.urlopen('http://httpbin.org/get') 173 | print response.read() 174 | ``` 175 | 176 | ### requests 177 | 178 | ```python 179 | import requests 180 | proxies = { 181 | 'http': 'http://' + proxy, 182 | } 183 | r = requests.get('http://httpbin.org/get', proxies=proxies) 184 | print(r.text) 185 | ``` -------------------------------------------------------------------------------- /client/crontab: -------------------------------------------------------------------------------- 1 | */5 * * * * /var/py/AutoProxy/client/request.sh /var/py/AutoProxy/client/request.conf >> /var/py/AutoProxy/client/request.log 2 | -------------------------------------------------------------------------------- /client/pppoe.sh: -------------------------------------------------------------------------------- 1 | PATH=$PATH:/usr/sbin 2 | export PATH 3 | 4 | pppoe-stop 5 | pppoe-start 6 | pppoe-status -------------------------------------------------------------------------------- /client/request.conf: -------------------------------------------------------------------------------- 1 | KEY=something 2 | SERVER=http://127.0.0.1:5000/record -------------------------------------------------------------------------------- /client/request.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | if [ "$#" != 1 ];then 6 | echo "param error." 7 | exit 0 8 | fi 9 | 10 | KEY="" 11 | SERVER="" 12 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 13 | 14 | load_config() { 15 | cfg=$1; 16 | content=`cat ${cfg}`; 17 | KEY=`echo "${content}" |grep 'KEY'| sed 's/^KEY=[\"]\(.*\)[\"]/\1/'`; 18 | SERVER=`echo "${content}" |grep 'SERVER'| sed 's/^SERVER=[\"]\(.*\)[\"]/\1/'`; 19 | KEY=${KEY:4} 20 | SERVER=${SERVER:7} 21 | } 22 | 23 | change_proxy() { 24 | . $DIR/pppoe.sh 25 | } 26 | 27 | send_request() { 28 | echo $SERVER/$KEY; 29 | curl $SERVER/$KEY; 30 | } 31 | 32 | main() { 33 | load_config $1 34 | change_proxy 35 | send_request 36 | } 37 | 38 | main $1 -------------------------------------------------------------------------------- /server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Germey/AutoProxy/98b2c32dc0f03d5819f364516adf63c529526161/server/__init__.py -------------------------------------------------------------------------------- /server/config.py: -------------------------------------------------------------------------------- 1 | KEY='something' 2 | NEED_AUTH=True 3 | AUTH_USER='admin' 4 | AUTH_PASSWORD='123456' 5 | PORT=8888 -------------------------------------------------------------------------------- /server/ip: -------------------------------------------------------------------------------- 1 | 127.0.0.1 -------------------------------------------------------------------------------- /server/main.py: -------------------------------------------------------------------------------- 1 | from flask import request, Flask, Response 2 | import config 3 | from functools import wraps 4 | 5 | 6 | def check_auth(username, password): 7 | if config.NEED_AUTH: 8 | return username == config.AUTH_USER and password == config.AUTH_PASSWORD 9 | else: 10 | return True 11 | 12 | 13 | def authenticate(): 14 | return Response( 15 | 'Could not verify your access level for that URL.\n' 16 | 'You have to login with proper credentials', 401, 17 | {'WWW-Authenticate': 'Basic realm="Login Required"'}) 18 | 19 | 20 | def requires_auth(f): 21 | @wraps(f) 22 | def decorated(*args, **kwargs): 23 | auth = request.authorization 24 | if not auth or not check_auth(auth.username, auth.password): 25 | return authenticate() 26 | return f(*args, **kwargs) 27 | 28 | return decorated 29 | 30 | 31 | app = Flask(__name__) 32 | 33 | 34 | @app.route('/record/', methods=['GET']) 35 | def record(key): 36 | if key == config.KEY: 37 | ip = request.remote_addr 38 | with open('ip', 'w') as f: 39 | f.write(ip) 40 | f.close() 41 | return ip + '\n' 42 | else: 43 | return 'Invalid Key' 44 | 45 | 46 | @app.route('/', methods=['GET']) 47 | @requires_auth 48 | def proxy(): 49 | with open('ip', 'r') as f: 50 | ip = f.read().strip() 51 | f.close() 52 | if ip: 53 | return ip + ':' + str(config.PORT) 54 | return '0' 55 | 56 | 57 | if __name__ == '__main__': 58 | app.run(host='0.0.0.0', port=5000) 59 | --------------------------------------------------------------------------------