zoukankan      html  css  js  c++  java
  • python http代理支持 https

    首先需要2个软件来抓包。

    fiddler : http 代理软件可以分析,抓包,重放。

    wireshark : 全能抓包分析软件。

    RFC 提供了非常好的设计描述。

    https://tools.ietf.org/html/rfc7230

    https://tools.ietf.org/html/rfc7231

    安装好
    Fiddler2
    Tools ->Fiddler Options…-> Connections
    Allow remotecomputers toconnect
    需要重启 Fiddler2 后生效

    Wireshark
    设置好抓包规则
    tcp.port == 8888

    全部设置好后,使用另外一台电脑,配置好浏览器,打开下面的测试地址:
    https://www.baidu.com/img/bd_logo1.png

    最好是,在2台电脑上进行,有IP 地址比较好分辩(没有2台电脑的用VM 也行)。

     

    本机为 192.168.1.127 , Fiddler 为 192.168.1.121。

    可以看到,本地在发送了一个 请求头后,直接和 192.168.1.121 进行了 TLS 协商。

    可见 HTTPS 代理也是非常容易实现。

    TCP 流:

     或者使用 curl 进行测试,firefox 自带了很多垃圾请求,不太好分辨包。

    可见 百度用的是 apache 的服务器。

    建立一个 连接到目标站点的 https socket。

    回复 HTTP/1.1 200 Connection Established

    浏览器发过来 client hello ,转发给 https socket

    普通的 HTTP 是 请求 响应模式。
    而 HTTPS 是有可能 HTTPS 也会主动发送 tcp 数据包过来,如 server hello 。
    所以实现上,还需要用到 select 来实现 fd 的检查工作。

     1 #!/usr/bin/env python
     2 #coding:utf-8
     3 import socket
     4 import sys
     5 import re
     6 import os
     7 import time
     8 import select
     9 import threading
    10 
    11 HEADER_SIZE = 4096
    12 
    13 host = '0.0.0.0'
    14 port = 8000
    15 
    16 #子进程进行socket 网络请求
    17 def http_socket(client, addr):
    18     #创建 select 检测 fd 列表
    19     inputs  = [client]
    20     outputs = []
    21     remote_socket = 0
    22     print("client connent:{0}:{1}".format(addr[0], addr[1]))
    23     while True:
    24         readable, writable, exceptional = select.select(inputs, outputs, inputs)
    25         try:
    26             for s in readable:
    27                 if s is client:
    28                     #读取 http 请求头信息
    29                     data = s.recv(HEADER_SIZE)
    30                     if remote_socket is 0:
    31                         #拆分头信息
    32                         host_url  = data.split("\r\n")[0].split(" ")
    33                         method, host_addr, protocol = map(lambda x: x.strip(), host_url)
    34                         #如果 CONNECT 代理方式
    35                         if method == "CONNECT":
    36                             host, port = host_addr.split(":")
    37                         else:
    38                             host_addr = data.split("\r\n")[1].split(":")
    39                             #如果未指定端口则为默认 80
    40                             if 2 == len(host_addr):
    41                                 host_addr.append("80")
    42                             name, host, port = map(lambda x: x.strip(), host_addr)
    43                             #建立 socket tcp 连接
    44                         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    45                         sock.connect((host, int(port)))
    46                         remote_socket = sock
    47                         inputs.append(sock)
    48                         if method == "CONNECT":
    49                             start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
    50                             s.sendall("HTTP/1.1 200 Connection Established\r\nFiddlerGateway: Direct\r\nStartTime: {0}\r\nConnection: close\r\n\r\n".format(start_time))
    51                             continue
    52                     #发送原始请求头
    53                     remote_socket.sendall(data)
    54                 else:
    55                     #接收数据并发送给浏览器
    56                     resp = s.recv(HEADER_SIZE)
    57                     if resp:
    58                         client.sendall(resp)
    59         except Exception as e:
    60             print("http socket error {0}".format(e))
    61 
    62 #创建socket对象
    63 http_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    64 try:
    65     http_server.bind((host, port))
    66 except Exception as e:
    67     sys.exit("python proxy bind error {0}".format(e))
    68 
    69 print("python proxy start")
    70 
    71 http_server.listen(1024)
    72 
    73 while True:
    74     client, addr = http_server.accept()
    75     http_thread = threading.Thread(target=http_socket, args=(client, addr))
    76     http_thread.start()
    77     time.sleep(1)
    78 
    79 #关闭所有连接
    80 http_server.close()
    81 print("python proxy close")
  • 相关阅读:
    APP上线碰到的问题:Non-public API usage
    点语法
    strlen、strcpy、strcat的实现
    2. I/O模型基本说明
    1. 同步、异步、阻塞、非阻塞
    8. 负载均衡请求转发实现
    7.负载均衡算法
    6. Nginx配置示例-高可用集群
    5. Nginx配置示例-动静分离
    4. Nginx配置示例-负载均衡
  • 原文地址:https://www.cnblogs.com/ningci/p/5446681.html
Copyright © 2011-2022 走看看