前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >云函数实现代理

云函数实现代理

作者头像
用户2700375
发布2022-06-09 14:39:48
1.5K0
发布2022-06-09 14:39:48
举报

博客貌似有很久很久没有更新了。但是其实并没有停止学习(笔记大部分写到了语雀上,有空闲时间同步到博客)。今天看了公众号里的一篇文章,自己实际操作了一下发现有一些坑,所以来做个记录

image-20220322101000686
image-20220322101000686

文章参考:https://mp.weixin.qq.com/s/HT6liYdsaKW34OMQGu3XAw

云函数实现HTTP代理

客户端挂上代理发送数据包,HTTP 代理服务器拦截数据包,提取 HTTP 报文相关信息,然后将报文以某种形式 POST 到云函数进行解析,云函数根据解析到的信息对目标发起请求,最终将结果一层一层返回。

云函数基础配置

选择自定义创建,地域自选,部署模式,代码部署,运行环境Python3.6,其余默认即可。

image-20220321145933077
image-20220321145933077
函数代码配置

然后配置函数代码,服务端代码server.py:

# -*- 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"),
    }

修改 server.py 中的 SCF_TOKEN 为随机值,该值将用于鉴权, client.py 中的 SCF_TOKEN需要与server.py中的SCF_TOKEN保持一致。

image-20220321150142795
image-20220321150142795
高级配置

云函数操作最大超时限制默认为 3 秒,可以将云函数环境配置中的执行超时时间拉满,其余默认即可

image-20220321150323424
image-20220321150323424
创建触发器

配置完上面的所有内容后,创建触发器,自定义触发器,

触发方式选择 API 网关触发,其他默认就好。

image-20220321150416561
image-20220321150416561

创建好触发器之后,基本配置就完成了,点击完成,等待函数配置完成,就会跳转到管理页面,我们找到触发管理,其中访问路径就是我们的云函数访问地址。

image-20220321150533641
image-20220321150533641

服务端就基本配置好了,下面还需要配置一下客户端。

客户端配置

本地代理这里使用的是mitmproxy,可以直接pip安装。

安装mitmproxy 注意这个版本和本机python的版本是挂钩的。我这边是Python3.7 4.0.1版本的mitmproxy才能正常使用。(这里尝试了很久,之前没指定版本的时候会报错原因就是Python版本太低而mitmproxy版本太高。具体mitmproxy的版本对应Python哪个版本,大家自己去尝试下。)

python3 -m pip install mitmproxy==4.0.1

如果需要代理 HTTPS流量需安装证书。首次运行 mitmdump命令,证书目录自动生成在 ~/.mitmproxy中,安装并信任。

img
img

双击 mitmproxy-ca-cert.pem 文件,设为始终信任。

img
img

下面需要配置客户端client.py代码,需要将触发器中的访问路径添加至 client.py 中 scf_servers变量中,以逗号 , 分隔。scf_servers 参数可以添加多个API接口,这样就可以获取更多的IP池。

import json
import pickle
from typing import List
from random import choice
from urllib.parse import urlparse
from base64 import b64encode, b64decode

import mitmproxy
from mitmproxy.net.http import Headers

#API访问地址,可以添加多个,以逗号分隔
scf_servers: List[str] = [""]

#授权Token,与云函数中的token配置一致
SCF_TOKEN = "token"


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

配置好之后就可以开启代理

mitmdump -s client.py -p 8081 --no-http2
image-20220321151253562
image-20220321151253562

在浏览器下配置http代理

image-20220321151544466
image-20220321151544466

我们查看一下ip

image-20220321151728224
image-20220321151728224

可见已经是 腾讯云的地址了。

但是https的站点这里还是会报出ssl错误

image-20220321151810549
image-20220321151810549

一些https的站还是会出问题的。这里找了很久解决办法,还是没搞定。如果大佬们看出有什么问题,请联系下小弟。

云函数实现SOCKS5代理

云函数基础配置

image-20220321155634217
image-20220321155634217
函数代码

# -*- coding: utf8 -*-
# server.py
import json
import socket
import select

bridge_ip = "ip"
bridge_port = port

def main_handler(event, context):
    data = json.loads(event["body"])
    out = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    out.connect((data["host"], data["port"]))

    bridge = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    bridge.connect((bridge_ip, bridge_port))
    bridge.send(data["uid"].encode("ascii"))

    while True:
        readable, _, _ = select.select([out, bridge], [], [])
        if out in readable:
            data = out.recv(4096)
            bridge.send(data)
        if bridge in readable:
            data = bridge.recv(4096)
            out.send(data)

修改 server.py中的 bridge_ip与 bridge_port为自己 VPS的 ip及开启监听的端口

image-20220321160423499
image-20220321160423499
高级配置

与上面http一样。

修改云函数超时时间为 900s,这样一个 SOCKS5 连接最多维持 15m

image-20220321160533076
image-20220321160533076
创建触发器

同样与上面http一样 触发方式为API网关触发

image-20220321160726976
image-20220321160726976

客户端配置

下载 https://github.com/culprits/SCFProxy.git 到我们的vps上

image-20220321170938027
image-20220321170938027

执行

Pip3 install -r requirements.txt 安装所需要的库,最后直接执行

python3 socks5.py -u "https://service-q3vrbamf-1257145077.bj.apigw.tencentcs.com/release/socks5" -bp 9001 -sp 9002 --user Sch0lar --passwd Sch0lar
  • -u 参数需要填写 API 网关提供的地址,必填
  • -l 表示本机监听的 ip,默认为 0.0.0.0
  • -sp 表示 SOCKS5 代理监听的端口,必填
  • -bp 表示用于监听来自云函数连接的端口,与 server.py 中的 bridge_port 相同,必填
  • –user–passwd 用于 SOCKS5 服务器对连接进行身份验证,客户端需配置相应的用户名和密码

后台运行

screen python3 socks5.py -u "https://service-q3vrbamf-1257145077.bj.apigw.tencentcs.com/release/socks5" -bp 9001 -sp 9002

配置好socks5代理

image-20220321171535130
image-20220321171535130
image-20220321171706359
image-20220321171706359
image-20220321211644199
image-20220321211644199
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 云函数实现HTTP代理
    • 云函数基础配置
      • 函数代码配置
      • 高级配置
      • 创建触发器
    • 客户端配置
    • 云函数实现SOCKS5代理
      • 云函数基础配置
        • 函数代码
        • 高级配置
        • 创建触发器
      • 客户端配置
      相关产品与服务
      云函数
      云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。云函数是实时文件处理和数据处理等场景下理想的计算平台。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档