HTTP 代理原理及实现(二)

在上篇《HTTP 代理原理及实现(一)》里,我介绍了 HTTP 代理的两种形式,并用 Node.js 实现了一个可用的普通 / 隧道代理。普通代理可以用来承载 HTTP 流量;隧道代理可以用来承载任何 TCP 流量,包括 HTTP 和 HTTPS。今天这篇文章介绍剩余部分:如何将浏览器与代理之间的流量传输升级为 HTTPS。

上篇文章中实现的代理,是一个标准的 HTTP 服务,针对浏览器的普通请求和 CONNECT 请求,进行不同的处理。Node.js 为创建 HTTP 或 HTTPS Server 提供了高度一致的接口,要将 HTTP 服务升级为 HTTPS 特别方便,只有一点点准备工作要做。

我们知道 TLS 有三大功能:内容加密、身份认证和数据完整性。其中内容加密依赖于密钥协商机制;数据完整性依赖于 MAC(Message authentication code)校验机制;而身份认证则依赖于证书认证机制。一般操作系统或浏览器会维护一个受信任根证书列表,包含在列表之中的证书,或者由列表中的证书签发的证书都会被客户端信任。

提供 HTTPS 服务的证书可以自己生成,然后手动加入到系统根证书列表中。但是对外提供服务的 HTTPS 网站,不可能要求每个用户都手动导入你的证书,所以更常见的做法是向 CA(Certificate Authority,证书颁发机构)申请。根据证书的不同级别,CA 会进行不同级别的验证,验证通过后 CA 会用他们的证书签发网站证书,这个过程通常是收费的(有免费的证书,最近免费的 Let's Encrypt 也很火,这里不多介绍)。由于 CA 使用的证书都是由广泛内置在各系统中的根证书签发,所以从 CA 获得的网站证书会被绝大部分客户端信任。

通过 CA 申请证书很简单,本文为了方便演示,采用自己签发证书的偷懒办法。现在广泛使用的证书是 x509.v3 格式,使用以下命令可以创建:

openssl genrsa -out private.pem 2048
openssl req -new -x509 -key private.pem -out public.crt -days 99999

第二行命令运行后,需要填写一些证书信息。需要注意的是 Common Name 一定要填写后续提供 HTTPS 服务的域名或 IP。例如你打算在本地测试,Common Name 可以填写 127.0.0.1。证书创建好之后,再将 public.crt 添加到系统受信任根证书列表中。为了确保添加成功,可以用浏览器验证一下:

fake_certificate

接着,可以改造之前的 Node.js 代码了,需要改动的地方不多:

JSvar http = require('http');
var https = require('https');
var fs = require('fs');
var net = require('net');
var url = require('url');function request(cReq, cRes) {var u = url.parse(cReq.url);var options = {hostname : u.hostname, port     : u.port || 80,path     : u.path,       method     : cReq.method,headers     : cReq.headers};var pReq = http.request(options, function(pRes) {cRes.writeHead(pRes.statusCode, pRes.headers);pRes.pipe(cRes);}).on('error', function(e) {cRes.end();});cReq.pipe(pReq);
}function connect(cReq, cSock) {var u = url.parse('http://' + cReq.url);var pSock = net.connect(u.port, u.hostname, function() {cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');pSock.pipe(cSock);}).on('error', function(e) {cSock.end();});cSock.pipe(pSock);
}var options = {key: fs.readFileSync('./private.pem'),cert: fs.readFileSync('./public.crt')
};https.createServer(options).on('request', request).on('connect', connect).listen(8888, '0.0.0.0');

可以看到,除了将 http.createServer 换成 https.createServer,增加证书相关配置之外,这段代码没有任何改变。这也是引入 TLS 层的妙处,应用层不需要任何改动,就能获得诸多安全特性。

运行服务后,只需要将浏览器的代理设置为 HTTPS 127.0.0.1:8888 即可,功能照旧。这样改造,只是将浏览器到代理之间的流量升级为了 HTTPS,代理自身逻辑、与服务端的通讯方式,都没有任何变化。

最后,还是写段 Node.js 代码验证下这个 HTTPS 代理服务:

JSvar https = require('https');var options = {hostname : '127.0.0.1',port     : 8888,path     : 'imququ.com:80',method     : 'CONNECT'
};//禁用证书验证,不然自签名的证书无法建立 TLS 连接
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";var req = https.request(options);req.on('connect', function(res, socket) {socket.write('GET / HTTP/1.1\r\n' +'Host: imququ.com\r\n' +'Connection: Close\r\n' +'\r\n');socket.on('data', function(chunk) {console.log(chunk.toString());});socket.on('end', function() {console.log('socket end.');});
});req.end();

这段代码和上篇文章最后那段的区别只是 http.request 换成了 https.request,运行结果完全一样,这里就不贴了。本文所有代码可以从这个仓库获得:proxy-demo。

本文就写到这里,大家有什么问题欢迎给我评论留言。

本文链接:HTTP 代理原理及实现(二) | JerryQu 的小站,参与评论 »

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/235106.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

加工零件的题解

目录 原题描述: 题目描述 输入格式 输出格式 样例 #1 样例输入 #1 样例输出 #1 样例 #2 样例输入 #2 样例输出 #2 提示 题目大意: 主要思路: 但是我们怎么才能判断出x走到1时L是偶数还是奇数呢? 初始化:…

UML期末复习(带习题,选择题,判断题)(持续更新)

UML期末复习 UML简介UML模型图的构成UML事物UML包含4种事物:构件事物: UML模型的静态部分,描述概念或物理元素行为事物:UML模型图的动态部分,描述跨越空间和时间的行为分组事物: UML模型图的组织部分&#…

24/1/10 qt work

1. 完善对话框,点击登录对话框,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到其他界面 如果账号和密码不匹配&…

麻雀搜索算法SSA预告

麻雀搜索算法(Sparrow Search Algorithm,SSA)是一种模拟麻雀觅食行为的优化算法,由Ahmed K. Attiya在2018年提出。该算法通过模拟麻雀在觅食时的群体协作行为,以解决优化问题。 以下是麻雀搜索算法的基本原理&#xf…

Qt QCheckBox复选按钮控件

文章目录 1 属性和方法1.1 文本1.2 三态1.3 自动排他1.4 信号和槽 2 实例2.1 布局2.2 代码实现 Qt中的复选按钮类是QCheckBox它和单选按钮很相似,单选按钮常用在“多选一”的场景,而复选按钮常用在"多选多"的场景比如喜欢的水果选项中&#xf…

【C++期末编程题题库】代码+详解18道

适合期末复习c看,或者刚入门c的小白看,有的题会补充知识点,期末复习题的代码一般比较简单,所以语法上没那么严谨。本文所有题目要求全在代码块的最上面。 目录 1、设计复数类 2、设计Computer类 3、实现相加的函数模板 4、圆类…

three.js实现电子围栏效果(纹理贴图)

three.js实现电子围栏效果&#xff08;纹理贴图&#xff09; 实现步骤 围栏的坐标坐标转换为几何体顶点&#xff0c;uv顶点坐标加载贴图&#xff0c;移动 图例 代码 <template><div class"app"><div ref"canvesRef" class"canvas-…

开关电源PFC电路原理详解及matlab仿真

PFC全称“Power Factor Correction”&#xff0c;意为“功率因数校正”。PFC电路即能对功率因数进行校正&#xff0c;或者说能提高功率因数的电路。是开关电源中很常见的电路。 在电学中&#xff0c;功率因数PF指有功功率P&#xff08;单位w&#xff09;与视在功率S&#xff08…

websocket介绍并模拟股票数据推流

Websockt概念 Websockt是一种网络通信协议&#xff0c;允许客户端和服务器双向通信。最大的特点就是允许服务器主动推送数据给客户端&#xff0c;比如股票数据在客户端实时更新&#xff0c;就能利用websocket。 Websockt和http协议一样&#xff0c;并不是设置在linux内核中&a…

【昕宝爸爸定制】如何将集合变成线程安全的?

如何将集合变成线程安全的? ✅典型解析&#x1f7e2;拓展知识仓☑️Java中都有哪些线程安全的集合&#xff1f;&#x1f7e0;线程安全集合类的优缺点是什么&#x1f7e1;如何选择合适的线程安全集合类☑️如何解决线程安全集合类并发冲突问题✔️乐观锁实现方式 (具体步骤)。✅…

Kubernetes实战(十五)-Pod垂直自动伸缩VPA实战

1 介绍 VPA 全称 Vertical Pod Autoscaler&#xff0c;即垂直 Pod 自动扩缩容&#xff0c;它根据容器资源使用率自动设置 CPU 和 内存 的requests&#xff0c;从而允许在节点上进行适当的调度&#xff0c;以便为每个 Pod 提供适当的资源。 它既可以缩小过度请求资源的容器&…

Oracle regexp_substr

select regexp_substr(123|456|789, [^|], 1, 2) from dual;

C练习——N个水手分椰子

题目&#xff1a; 五个水手在岛上发现一堆椰子&#xff0c;先由第1个水手把椰子分为等量的5堆&#xff0c;还剩下1个给了猴子&#xff0c;自己藏起1堆。然后&#xff0c;第2个水手把剩下的4堆混合后重新分为等量的5堆&#xff0c;还剩下1个给了猴子&#xff0c;自己藏起1堆。以…

uniapp 解决安卓App使用uni.requestPayment实现沙箱环境支付宝支付报错

背景&#xff1a;uniapp与Java实现的安卓端app支付宝支付&#xff0c;本想先在沙箱测试环境测支付&#xff0c;但一直提示“商家订单参数异常&#xff0c;请重新发起付款。”&#xff0c;接着报错信息就是&#xff1a;{ "errMsg": "requestPayment:fail [pa…

常用注解/代码解释(仅个人使用)

目录 第一章、代码解释①trim() 方法以及(Arrays.asList(str.split(reg)));②查询字典项②构建后端镜像shell命令解释 第二章、注解解释①PropertySource注解与Configurationproperties注解的区别 第三章、小知识①Linux系统中使用$符号表示变量 友情提醒: 先看文章目录&#…

设计模式篇章(3)——七种结构型模式

结构型设计模式主要思考的是如何将对象进行合理的布局来组成一个更大的功能体或者结构体&#xff0c;这个现在讲有点抽象&#xff0c;用大白话讲就是利用现有的对象进行组合或者配合&#xff0c;使得组合后的这个系统更加好。好是相对于不使用设计模式&#xff0c;按照自己的堆…

固定翼仿真的切换

delta固定翼飞行器模型 接着这篇文章文章链接&#xff0c;我们对飞行器模型进行改进&#xff0c; 我们知道&#xff0c;我们打开仿真模型 gazebo --verbose zephyr_ardupilot_demo.world 我们注意这最后一个语句 <model name"zephyr_delta_wing_demo">//加载z…

Cesium自定义电子围栏特效材质

1.new Cesium.Viewer中添加 requestWebgl1: true, 2. 编写材质&#xff0c;主要分三步 &#xff08;1&#xff09;定义MaterialProperty &#xff08;2&#xff09;设置材质 &#xff08;3&#xff09;添加材质 DynamicWallMaterial.js //定义材质对象及变量 function Dy…

IIS+SDK+VS2010+SP1+SQL server2012全套工具包及安装教程

前言 今天花了两个半小时安装这一整套配置&#xff0c;这个文章的目标是将安装时间缩短到1个小时 正文 安装步骤如下&#xff1a; VS2010 —> service pack 1 —>SQL server2012 —> IIS —> SDK 工具包链接如下&#xff1a; https://pan.baidu.com/s/1WQD-KfiUW…

uniapp使用wxml-to-canvas开发小程序保存canvas图片

微信小程序官方解决方案&#xff1a;wxml-to-canvas 使用wxml-to-canvas要知道一些前提条件 1、只能画view&#xff0c;text&#xff0c;image 2、每个元素必须要设置宽高 3、默认是flex布局&#xff0c;可以通过flexDirection: "column"来改变排列方式 4、文字 必…