您现在的位置是:首页 >技术杂谈 >18 隐私模式下面发送 http 请求不成功网站首页技术杂谈

18 隐私模式下面发送 http 请求不成功

蓝风9 2023-05-20 20:00:02
简介18 隐私模式下面发送 http 请求不成功

前言

是这样的一个情况, 最近 我们服务存在这样的一个问题 

是在登录界面, 假设我用户名 或者 密码输入错误, 能够得到真确的结果, 拿到了 正常的 http 响应, 回来 "用户名 或者 密码 不正确 "

但是 假设是在 隐私模式下面, 同样的输入, 同样的服务, 但是结果 不一样, 等待 十多秒之后 请求挂了, CONNECTION RESET 

错误信息 大概是如下, 呵呵 这个很神奇 

另外 还有一个问题就是  当我启动 fiddler 之后, 这个网站的服务就发送发送不出去了 

效果 和上面的这个一样, 但是 差别是在于 上面的会 pending 15秒, 但是 启动 fiddler 之后里面就请求失败 

问题的调试

通过 抓包 发现, 隐私模式下面发送的请求 

发送了一次 /token 请求之后, 后面又进行了 五六次的 tcp 重传 

大概的猜测就是 对方服务器 拿到了 tcp 请求之后, 丢弃了该 tcp 包?? 

呵呵 所以 我写了一套 checksum 计算, 来校验 隐私模式下面出问题的包的 checksum, 但是 发现是 完全对的上的 

wireshark 抓包, 发送方正常情况如下 

wireshark 抓包, 发送方异常情况如下 

通过 http 请求的对比, tcp 整个报文的对比, 发现 二者报文 没有太大的差异 

但是 异常情况下, 对方服务器没有确认该包, 然后 发送方进行了重传 

tcpdump 抓包, 接收方来查看请求情况如下 

我测试的时候, 正常情况测试了三次, 异常情况测试了 三次 

但是 抓包的结果, 只能看到 正常情况的这三次请求 

另外 tcpdump 日志信息如下, 没有被 内核丢弃的包 

[root@localhost sxxzx2019]# tcpdump tcp -i ens192 port 80 -w target.cap 
tcpdump: listening on ens192, link-type EN10MB (Ethernet), capture size 262144 bytes
^C47954 packets captured
48001 packets received by filter
0 packets dropped by kernel

但是 还有不确认的地方就是 

我们客户端 -> 网闸 -> 互联网服务器, 这个过程中, 网闸上面的情况 我们接触不到 

所以 网闸是否接收到 "/token" 的 tcp 包, 这个我们确认不了 

另外 这整个问题也很奇怪 

这里的配置 之前是有一个 vpn 的, 但是我删除了之后(不确定是否重启) 似乎 隐私模式下面就能够正常访问了?  是因为请求被代理到了这个 vpn??

当然 这个结论待证实 

但是打开 fiddler 之后, 来访问该网站, 还是报错 

这个 也是遗留下来的问题, 日志如下 

# 开启 fidder 之后 发送 http 请求失败 
-= Fiddler Event Log =-

17:11:02:7699 [Fiddler] No HTTP request was received from (chrome:6800) new client socket, port 54233.
17:11:04:0902 Fiddler.Network.AutoProxy> AutoProxy Detection failed.
17:11:04:0902 AutoProxy failed. Disabling for this network.
17:11:24:1592 [Fiddler] No HTTP request was received from (chrome:6800) new client socket, port 54247.
17:11:24:2568 [Fiddler] No HTTP request was received from (chrome:6800) new client socket, port 54248.
17:11:24:4004 [Fiddler] No HTTP request was received from (chrome:6800) new client socket, port 54249.
17:11:24:5367 [Fiddler] No HTTP request was received from (chrome:6800) new client socket, port 54252.

chrome 中的错误日志如下 

Access to XMLHttpRequest at 'http://61.185.228.1:33111/auth/oauth/token' from origin 'http://61.185.228.1:33111' has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space `local`.
auth/oauth/token:1 Failed to load resource: net::ERR_FAILED

可以参考这篇文章 

The request client is not a secure context and the resource is in more-private address ...
https://blog.csdn.net/tianzhonghaoqing/article/details/124328920

chrome://flags/#block-insecure-private-network-requests 

允许发送 不安全的私有网络请求 即可 

Block insecure private network requests.
Prevents non-secure contexts from making sub-resource requests to more-private IP addresses. An IP address IP1 is more private than IP2 if 1) IP1 is localhost and IP2 is not, or 2) IP1 is private and IP2 is public. This is a first step towards full enforcement of CORS-RFC1918: https://wicg.github.io/cors-rfc1918 ®C Mac, Windows, Linux, Chrome OS, Android

#block-insecure-private-network-requests

客户端 本身的域是 61.185.228.1:33111 

然后 fiddler 启动之后, 将 61.185.228.1:33111 请求先走 127.0.0.1:8888, 然后 fiddler 代理到目标服务 61.185.228.1:33111 

走的是 more-private 的域, 因此 触发了 浏览器的 CROS 保护策略 

至于这个 more-private 怎么定义, 多半是一个是 外网, 一个是 本地, 本地会比外网 more private 把

fiddler 一分钟定时捕获失败

默认的 8888 端口是否被占用, 如果被占用, 调整 代理端口 

找到 可疑 的 vpn 服务, 关闭 

Test01CalcTcpChecksum

为了这个问题, 特地写了一个 tcp 的 checksum 的计算的小程序, 呵呵 分享一下 

tcpBody 就贴 从 wireshark 中复制出来的二进制的报文即可 

/**
 * Test01CalcTcpChecksum
 *
 * @author Jerry.X.He
 * @version 1.0
 * @date 2022/10/31 16:20
 */
public class Test01CalcTcpChecksum {

    private static int startIpOffset = 0x1a;
    private static int tcpLenOffset = 0x2d;
    private static int ethHeaderSize = 14, ipHeaderSize = 20, tcpHeaderSize = 20;
    private static int totalHeaderSize = ethHeaderSize + ipHeaderSize + tcpHeaderSize;

    // Test01CalcTcpChecksum
    public static void main(String[] args) {

        String tcpBody = "0000   58 25 75 c3 9c b7 b0 6e bf cf 63 db 08 00 45 00
" +
                "0010   05 8a 23 a8 40 00 80 06 b1 51 c0 a8 33 38 3d b9
" +
                "0020   ee da f2 73 83 b0 02 59 f3 05 73 ab 0e 0b 50 18
";

        int[] bytes = loadByteStream(tcpBody);
        int tcpBodySize = bytes.length - totalHeaderSize;

        Integer zeroAndProtocol = 0x0006;
        Integer tcpHeaderAndDataSize = tcpHeaderSize + tcpBodySize;

        int dummyHeaderCheckSum = locateInteger(bytes, startIpOffset) + locateInteger(bytes, startIpOffset + 2)
                + locateInteger(bytes, startIpOffset + 4) + locateInteger(bytes, startIpOffset + 6)
                + zeroAndProtocol + tcpHeaderAndDataSize;
        int tcpHeaderCheckSum = calcTcpHeaderCheckSum(bytes);
        int tcpBodyCheckSum = calcTcpDataCheckSum(bytes, tcpBodySize);

        int totalSum = dummyHeaderCheckSum + tcpHeaderCheckSum + tcpBodyCheckSum;
        int trimmedTotalSum = ((totalSum & 0xffff0000) >> 16) + (totalSum & 0xffff);
        int reversedTotalSum = ~trimmedTotalSum;

        String checkSumHexStr = Integer.toHexString(reversedTotalSum).substring(4);
        int checkSumInPacket = locateInteger(bytes, ethHeaderSize + ipHeaderSize + tcpHeaderSize - 4);
        String checkSumInPacketStr = Integer.toHexString(checkSumInPacket);
        // 0x2a80
        System.out.println(String.format("%s - %s", checkSumHexStr, checkSumInPacketStr));
        if (!Objects.equals(checkSumHexStr, checkSumInPacketStr)) {
            throw new RuntimeException(" unexpected checksum ");
        }
        int x = 0;

    }

    public static int[] loadByteStream(String lines) {
        List<Integer> list = new ArrayList<>();
        for (String line : lines.split("
")) {
            String[] splits = line.split("\s+");
            for (int i = 1; i < splits.length; i++) {
                int b = Integer.parseInt(splits[i], 16);
                list.add(b);
            }
        }

        int[] result = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            result[i] = list.get(i);
        }
        return result;
    }

    public static int locateInteger(int[] bytes, int startIdx) {
        int byteWeight = (1 << 8);
        // 如果是最后一个元素, 补充 0
        if (startIdx + 1 >= bytes.length) {
            return bytes[startIdx] * byteWeight + 0x00;
//            return 0x00 * byteWeight + bytes[startIdx];
        }

        return bytes[startIdx] * byteWeight + bytes[startIdx + 1];
    }

    public static int calcTcpHeaderCheckSum(int[] bytes) {
        int checkSum = 0;
        int checkSumOffset = ethHeaderSize + ipHeaderSize, checkSumIteMax = tcpHeaderSize / 2;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < checkSumIteMax; i++) {
            int checkSumByte = locateInteger(bytes, checkSumOffset);
            // if is checksum, update checksum to 0
            if (i == (checkSumIteMax - 2)) {
                checkSumByte = 0;
            }
            checkSum += checkSumByte;
            checkSumOffset += 2;
            sb.append(" ").append(Integer.toHexString(checkSumByte));
        }
//        System.out.println(sb.toString());
        return checkSum;
    }

    public static int calcTcpDataCheckSum(int[] bytes, int tcpBodySize) {
        int checkSum = 0;
        int checkSumOffset = ethHeaderSize + ipHeaderSize + tcpHeaderSize, checkSumIteMax = (tcpBodySize + 1) / 2;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < checkSumIteMax; i++) {
            int checkSumByte = locateInteger(bytes, checkSumOffset);
            checkSum += checkSumByte;
            checkSumOffset += 2;
            sb.append(" ").append(Integer.toHexString(checkSumByte));
        }
//        System.out.println(sb.toString());
        return checkSum;
    }

}

执行效果如下  

Test02CalcIpChecksum

为了这个问题, 特地写了一个 ip 的 checksum 的计算的小程序, 呵呵 分享一下 

tcpBody 就贴 从 wireshark 中复制出来的二进制的报文即可 

package com.hx.test14;

import java.util.Objects;

import static com.hx.test14.Test01CalcTcpChecksum.loadByteStream;
import static com.hx.test14.Test01CalcTcpChecksum.locateInteger;

/**
 * Test01CalcTcpChecksum
 *
 * @author Jerry.X.He
 * @version 1.0
 * @date 2022/10/31 16:20
 */
public class Test02CalcIpChecksum {

    private static int startIpOffset = 0x1a;
    private static int tcpLenOffset = 0x2d;
    private static int ethHeaderSize = 14, ipHeaderSize = 20, tcpHeaderSize = 20;
    private static int totalHeaderSize = ethHeaderSize + ipHeaderSize + tcpHeaderSize;

    // Test01CalcTcpChecksum
    public static void main(String[] args) {

        String tcpBody = "0000   58 25 75 c3 9c b7 b0 6e bf cf 63 db 08 00 45 00
" +
                "0010   05 8f 23 a4 40 00 80 06 b1 50 c0 a8 33 38 3d b9
" +
                "0020   ee da f2 1f 83 b0 e9 62 05 3b cb 80 60 a8 50 18
";

        int[] bytes = loadByteStream(tcpBody);

        int ipHeaderCheckSum = calcIpHeaderCheckSum(bytes);
        int totalSum = ipHeaderCheckSum;
        int trimmedTotalSum = ((totalSum & 0xffff0000) >> 16) + (totalSum & 0xffff);
        int reversedTotalSum = ~trimmedTotalSum;

        String checkSumHexStr = Integer.toHexString(reversedTotalSum).substring(4);
        int checkSumInPacket = locateInteger(bytes, ethHeaderSize + ipHeaderSize - 10);
        String checkSumInPacketStr = Integer.toHexString(checkSumInPacket);
        // 0xb150
        System.out.println(String.format("%s - %s", checkSumHexStr, checkSumInPacketStr));
        if (!Objects.equals(checkSumHexStr, checkSumInPacketStr)) {
            throw new RuntimeException(" unexpected checksum ");
        }
        int x = 0;

    }

    public static int calcIpHeaderCheckSum(int[] bytes) {
        int checkSum = 0;
        int checkSumOffset = ethHeaderSize, checkSumIteMax = ipHeaderSize / 2;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < checkSumIteMax; i++) {
            int checkSumByte = locateInteger(bytes, checkSumOffset);
            // if is checksum, update checksum to 0
            if (i == (checkSumIteMax - 5)) {
                checkSumByte = 0;
            }
            checkSum += checkSumByte;
            checkSumOffset += 2;
            sb.append(" ").append(Integer.toHexString(checkSumByte));
        }
        System.out.println(sb.toString());
        return checkSum;
    }


}

执行效果如下  

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。