云函数可以用来搭建一个轻量代理池或 IP 中转机制,原理上跟传统代理池类似,虽然匿名性不如高匿商业代理,但在做扫描器等任务时依然方便实用,前提是控制好访问频率和风险
配置函数代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 # -*- coding: utf8 -*- import json import pickle from base64 import b64decode, b64encode import requests SCF_TOKEN = "TOKEN" #需要自定义随机值,用于鉴权 def authorization(): return { "isBase64Encoded": False, "statusCode": 401, "headers": {}, "body": "Please provide correct SCF-Token", } def main_handler(event: dict, context: dict): try: token = event["headers"]["scf-token"] except KeyError: return authorization() if token != SCF_TOKEN: return authorization() data = event["body"] kwargs = json.loads(data) kwargs['data'] = b64decode(kwargs['data']) r = requests.request(**kwargs, verify=False, allow_redirects=False) serialized_resp = pickle.dumps(r) return { "isBase64Encoded": False, "statusCode": 200, "headers": {}, "body": b64encode(serialized_resp).decode("utf-8"), }
接下来创建函数URL,替代触发器的作用,因为触发器中的API网关类型下线了,不过可以直接使用函数URL来调用对应的云函数
这样就能通过这个API调用我们部署的云函数了
部署客户端 本地 windows 端 本地代理使用 mitmproxy,可以直接 pip 安装
如果需要代理 HTTPS流量的话,需安装证书
安装好了mitmproxy后,首次运行 mitmdump命令,证书就会自动生成在在 ~/.mitmproxy中,一般在C:\Users\xxx.mitmproxy\ 目录下,双击运行就能安装了
下面配置客户端client.py代码,需要将前面配置的函数URL,也就是触发云函数的API接口,添加至 client.py 中 scf_servers变量中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 # -*- coding: utf8 -*- # 命名只能是client.py import json import pickle from typing import List from random import choice from urllib.parse import urlparse from base64 import b64encode, b64decode import mitmproxy scf_servers: List[str] = ["https://111111-zzzzz.ap-beijing.tencentscf.com","http://111111-zzzzz.ap-beijing.tencentscf.com"] #API接口地址,也就是函数URL SCF_TOKEN = "TOKEN" #与server.py保持一致 def request(flow: mitmproxy.http.HTTPFlow): scf_server = choice(scf_servers) r = flow.request data = { "method": r.method, "url": r.pretty_url, "headers": dict(r.headers), "cookies": dict(r.cookies), "params": dict(r.query), "data": b64encode(r.raw_content).decode("ascii"), } flow.request = flow.request.make( "POST", url=scf_server, content=json.dumps(data), headers={ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, compress", "Accept-Language": "en-us;q=0.8", "Cache-Control": "max-age=0", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", "Connection": "close", "Host": urlparse(scf_server).netloc, "SCF-Token": SCF_TOKEN, }, ) def response(flow: mitmproxy.http.HTTPFlow): if flow.response.status_code != 200: mitmproxy.ctx.log.warn("Error") if flow.response.status_code == 401: flow.response.headers = Headers(content_type="text/html;charset=utf-8") return if flow.response.status_code == 433: flow.response.headers = Headers(content_type="text/html;charset=utf-8") flow.response.text = "<html><body>操作超时,可在函数配置中修改执行超时时间</body></html>" return if flow.response.status_code == 200: body = flow.response.content.decode("utf-8") resp = pickle.loads(b64decode(body)) r = flow.response.make( status_code=resp.status_code, headers=dict(resp.headers), content=resp.content, ) flow.response = r
以上全部配置好之后,就可以开启本地代理了
1 mitmdump -s client.py -p 9999 --no-http2
到此我们本地 9999 端口就开启了一个代理的入口,然后我们让想走代理的应用经过这个 9999 端口,就能调用部署好的云函数了,利用云函数的多出口特性,就达到了每次请求别人我们的ip都不一样,就模拟出了代理池的部分效果