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")
  • 相关阅读:
    Spring基础知识
    Hibernate基础知识
    Struts2基础知识
    在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因
    java后台获取cookie里面值得方法
    ckplayer 中的style.swf 中的 style.xml 中的修改方法
    java hql case when 的用法
    Windows下Mongodb安装及配置
    Mongodb中经常出现的错误(汇总)child process failed, exited with error number
    Mac 安装mongodb
  • 原文地址:https://www.cnblogs.com/ningci/p/5446681.html
Copyright © 2011-2022 走看看