使用 ssl 模块的 HTTPS 代理隧道

2023-11-23

我想手动(使用socket and ssl模块)制作一个HTTPS通过本身使用的代理请求HTTPS.

我可以执行初始操作CONNECT交换就好:

import ssl, socket

PROXY_ADDR = ("proxy-addr", 443)
CONNECT = "CONNECT example.com:443 HTTP/1.1\r\n\r\n"

sock = socket.create_connection(PROXY_ADDR)
sock = ssl.wrap_socket(sock)
sock.sendall(CONNECT)
s = ""
while s[-4:] != "\r\n\r\n":
    s += sock.recv(1)
print repr(s)

上面的代码打印HTTP/1.1 200 Connection established加上一些标题,这正是我所期望的。所以现在我应该准备好提出请求,例如

sock.sendall("GET / HTTP/1.1\r\n\r\n")

但上面的代码返回

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
</body></html>

这也很有意义,因为我仍然需要与example.com我正在通过隧道连接到的服务器。但是,如果不是立即发送GET要求我说

sock = ssl.wrap_socket(sock)

与远程服务器握手,然后我得到一个异常:

Traceback (most recent call last):
  File "so_test.py", line 18, in <module>
    ssl.wrap_socket(sock)
  File "/usr/lib/python2.6/ssl.py", line 350, in wrap_socket
    suppress_ragged_eofs=suppress_ragged_eofs)
  File "/usr/lib/python2.6/ssl.py", line 118, in __init__
    self.do_handshake()
  File "/usr/lib/python2.6/ssl.py", line 293, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [Errno 1] _ssl.c:480: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

那么我怎样才能与远程进行SSL握手呢?example.com server?

编辑:我很确定在我第二次致电之前没有可用的其他数据wrap_socket因为打电话sock.recv(1)无限期地阻止。


如果 CONNECT 字符串重写如下,这应该可以工作:

CONNECT = "CONNECT %s:%s HTTP/1.0\r\nConnection: close\r\n\r\n" % (server, port)

不确定为什么会这样,但也许与我使用的代理有关。这是一个示例代码:

from OpenSSL import SSL
import socket

def verify_cb(conn, cert, errun, depth, ok):
        return True

server = 'mail.google.com'
port = 443
PROXY_ADDR = ("proxy.example.com", 3128)
CONNECT = "CONNECT %s:%s HTTP/1.0\r\nConnection: close\r\n\r\n" % (server, port)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(PROXY_ADDR)
s.send(CONNECT)
print s.recv(4096)      

ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.set_verify(SSL.VERIFY_PEER, verify_cb)
ss = SSL.Connection(ctx, s)

ss.set_connect_state()
ss.do_handshake()
cert = ss.get_peer_certificate()
print cert.get_subject()
ss.shutdown()
ss.close()

请注意如何首先打开套接字,然后打开放置在 SSL 上下文中的套接字。然后我手动初始化 SSL 握手。并输出:

HTTP/1.1 200 连接已建立

它基于 pyOpenSSL,因为我也需要获取无效证书,并且 Python 内置 ssl 模块将始终尝试验证证书(如果收到)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ssl 模块的 HTTPS 代理隧道 的相关文章

随机推荐

  • Sql Server 网络配置协议不可用

    安装 SQL Server 2008 32 位后 我尝试将其配置为允许远程访问 所以我打开 SSCM sql server 配置管理器 将协议设置为启用 我在Sql Server网络配置下没有找到任何协议 我尝试过修复 卸载并重新安装 注册
  • 如何转储mysql数据库?

    我想只转储 mysql 数据库有数据的表 你能给我你的建议吗 这更有帮助 感谢和问候 瓦拉 库马尔 您可以使用 忽略表选项 但您必须首先找出哪些表是空的 因为这不能直接使用 mysqldump 实现 所以你可以做 mysqldump u u
  • 在CSS文件中使用相对URL,它相对于什么位置?

    当在CSS文件中定义背景图片URL之类的东西时 当使用相对URL时 它是相对于哪里的 例如 假设文件 stylesheets base styles css包含 div header background image url images
  • iOS中如何获取个人热点的子网掩码和广播地址

    我需要找到一种方法来查找 iOS 中我的个人热点的子网掩码和广播地址 我正在使用以下方法来查找设备的 IP 地址 如果它连接到 WiFi 但无法弄清楚如何获取个人热点的网络属性 NSString localIPAddress NSStrin
  • 从 Codeigniter 中的 URL 中删除 index.php

    我已经做了很多次了 但我又被困在这里 在不同的服务器中 并且无法弄清楚问题是什么 htaccess编辑完成
  • 在什么情况下“git pull”可能有害?

    我有一个同事声称git pull是有害的 每当有人使用它时就会感到不安 The git pull命令似乎是更新本地存储库的规范方法 是否使用git pull制造问题 它会产生什么问题 有没有更好的方法来更新 git 存储库 Summary
  • 模板和单独编译

    我想用 C 编写一个单独编译的程序 我写了这样的 main cpp include
  • 在生成器函数上使用 next()

    我有这个生成器功能 def gen for i in range 3 yield i i 现在当我打电话时next on gen 它每次都给出第一个元素 gt gt gt next gen 0 gt gt gt next gen 0 但是当
  • 如何将 R Markdown 转换为 HTML?即,“Knit HTML”在 Rstudio 0.96 中做什么?

    在 Rstudio 0 96 中的 R Markdown 文件上按 Knit HTML 时会运行哪些命令 我的动机是 当我在另一个文本编辑环境中时 我可能想运行相同的命令 或者我可能想将命令组合到更大的文本编辑器中 makefile 基本脚
  • 使用 Plink (PuTTy) 通过 Python 进行 SSH

    我正在尝试编写一个 python 脚本 它将通过 SSH 连接到服务器并执行命令 我在 Windows 上使用 Python 2 6 并安装了 plink 和 paegent 用于 ssh 密钥 并将它们全部添加到我的路径中 如果我转到命令
  • 改造 - 多部分请求:所需的 MultipartFile 参数“文件”不存在

    我正在尝试使用 Retrofit2 在服务器上发送文件 我按照文档做了一切 但总是收到 400 服务器错误 我尝试这样做 RequestBody body RequestBody create MediaType parse image p
  • 在括号中显示 p 值而不是 SE

    当使用stargazer包中 我想更改系数下括号中出现的值 默认情况下 包将输出标准错误 如何将实际 p 值包含在括号中 正如中提到的Stargazer 省略测试统计 从5 0版本开始stargazer已包括report允许用户选择要报告哪
  • 如何在自托管 Windows 代理上从 Azure DevOps 管道运行 Azure CLI 任务?

    情况 我的自托管 Windows 代理运行来自 Azure DevOps 的管道 到 管理 Azure 中的资源 我想使用 Azure CLI 任务 即使在前面的步骤中安装了 Azure CLI AzureCLI 任务也会失败 我有两个从我
  • 以编程方式执行单击 Actor libgdx

    我的问题很简单 我有一些ClickListener添加到 Actor 中 我想以编程方式对它们执行单击事件 就像是myActor performClick 您还可以使用 InputEvent event1 new InputEvent ev
  • 获取 SelectOneMenu 的选定值

    我正在 jsf 页面上测试组件 SelectOneMenu 我通过我的 ManageBean 动态地填充这个组件 将从数据库中获取所有动物 我想知道是否可以看到用户选择的 SelectOneMenu 组合框 项目 我正在尝试使用 value
  • 有主机和无主机的入口

    理解和调试入口规则确实变得越来越困难 有人可以分享一个好的参考吗 问题是在不指定主机的情况下入口如何工作 apiVersion extensions v1beta1 kind Ingress metadata annotations ngi
  • 如何使用git拉取特定目录

    我有一个使用 git 的项目 我只想克隆或拉取特定目录 例如 myproject javascript 就像 subversion 一样 进行一些更改 提交并再次推回 这是可能的 cd 到您的存储库副本的顶部 git fetch git c
  • 比较两个数组 Javascript - 关联

    我在这里搜索了一种比较 javascript 中关联数组的质量方法 我发现的唯一合适的解决方案是PHP JS项目具有一些比较数组功能 唯一的问题是这些函数将第一个数组视为第二个数组的键 在我的情况下 至少两个数组并不总是具有相同的键数或相同
  • ng-重复完成事件

    我想调用一些针对 div 和 table 的 jQuery 函数 该表填充有ng repeat 当我打电话时 document ready 我没有结果 Also scope on viewContentLoaded myFunc 没有帮助
  • 使用 ssl 模块的 HTTPS 代理隧道

    我想手动 使用socket and ssl模块 制作一个HTTPS通过本身使用的代理请求HTTPS 我可以执行初始操作CONNECT交换就好 import ssl socket PROXY ADDR proxy addr 443 CONNE