Tunnel
Tunnel既不是给https用的,也不是给代理用的,是给https代理用的
之所以以前老觉得Https也有一个tunnel,是因为每次看https请求,fiddler本身就是http代理,本来就会有tunnel
https本身是没有Connect method的 Tunnel & CONNECT
https://www.zhihu.com/question/21955083/answer/142736329
看标签题主应该问的是技术上的HTTP隧道而不是应用软件,刚好我这两天在实现SOCKS5和HTTP代理读了一些RFC,如果有不对的地方还请大家多多指正。
先概括的说一下,HTTP tunnel是HTTP/1.1中引入的一个功能,主要为了解决明文的HTTP proxy无法代理跑在TLS中的流量(也就是https)的问题,同时提供了作为任意流量的TCP通道的能力。实在增加了HTTP tunnel功能之后,支持CONNECT报文的HTTP代理服务器和SOCKS5的代理服务器功能上已经几乎一样了(还是有不一样的地方的,详见后面)。由于CONNECT报文已经能支持任意类型TCP流量了,即使到HTTP/2也没有对它进行大的修改,基本保持了原有设计。
HTTP tunnel是哪里定义的?
tunnel以及tunnel相关的CONNECT报文最早主要定义在两个文件中:
href="https://link.zhihu.com/?target=https%3A//www.ietf.org/rfc/rfc2817.txt" RFC2616 HTTP/1.1中的5.1.1 Method,主要提到了HTTP1.1的所有报文中有一个CONNECT报文,但是写这个文件的时候CONNECT报文做什么还没有定下来。
另一是<a href="https://link.zhihu.com/?target=https%3A//www.ietf.org/rfc/rfc2817.txt" RFC2817 HTTP Upgrade to TLS ,中的多个章节(5.2、5.3等多个地方)提到了CONNECT报文要解决的问题和具体实现。
最后关于HTTP/2,在 </p><a href="https://link.zhihu.com/?target=https%3A//tools.ietf.org/html/rfc7540%23section-8.3" class=" wrap external" target="_blank" rel="nofollow noreferrer">RFC 7540 HTTP/2</a><p data-pid="SZysu2S7"> 中的8.3节对http2版本的connect报文做了定义,基本和之前的功能没有太大的出入。
HTTP proxy是怎么工作的?
在HTTP tunnel出来之前,HTTP proxy工作在中间人模式。也就是说在一次请求中,客户端(浏览器)明文的请求代理服务器。代理服务器明文去请求远端服务器(网站),拿到返回结果,再将返回结果返回给客户端。整个过程对代理服务器来说都是可见的,代理能看到你要请求的path,你请求中的header(包括例如auth头里面的用户名密码),代理也能看到网站返回给你的cookie。和中间人攻击的中间人是一种情况(笑)
这种模式要求代理对请求进行适当的改写,RFC2616 5.1.2中要求请求代理的报文中Request-URI必须使用绝对路径,这样代理才能从中解出真正请求的目标,然后代理需要对这个请求进行改写再发送给远端服务器。
例如浏览器在不使用HTTP proxy时,发送的请求如下(省略了和示例无关的header,下同):
GET / HTTP/1.1\r\n
Host: stackoverflow.com\r\n
Connection: keep-alive\r\n
\r\n
使用了代理后,发送的报文将变为:
GET http://stackoverflow.com/ HTTP/1.1\r\n
Host: stackoverflow.com\r\n
Proxy-Connection: keep-alive\r\n
\r\n
代理从请求的第一行中得知要请求的目标是stackoverflow.com,端口为默认端口(80),将第一行改写后,向网站服务器发送请求:
GET / HTTP/1.1\r\n
Host: stackoverflow.com\r\n
Connection: keep-alive\r\n
\r\n
顺带一提上面这个例子可以看到有一个Proxy-Connection的header也被改写了,这个是HTTP/1.1的一个黑历史,现在它已经不是标准header了,并在RFC7230中被建议不要使用。然而现在浏览器(比如chrome)仍然在发送这个header,因此代理服务器还是要对它做处理,处理方式就是当做Connection header改写后发送给远端。
为什么需要HTTP tunnel?
从前一条可以看出,如果我们想在复用现有的HTTP proxy的传输方式来代理HTTPS流量,那么就会变成浏览器和代理握手跑TLS,代理拿到明文的请求报文,代理和网站握手跑TLS。
但是代理没有,也不可能有网站的私钥证书,所以这么做会导致浏览器和代理之间的TLS无法建立,证书校验根本通不过。
HTTP tunnel以及CONNECT报文解决了这个问题,代理服务器不再作为中间人,不再改写浏览器的请求,而是把浏览器和远端服务器之间通信的数据原样透传,这样浏览器就可以直接和远端服务器进行TLS握手并传输加密的数据。
HTTP tunnel的工作流程是什么样的?
普通的一次HTTP请求,header部分以连续两组CRLF(\r\n)作为标记结束,如果后面还有内容,也就是content部分的话,需要在header里面加入Content-Length头,值为content部分有多长,通信的对方(无论是服务器,还是接收服务器返回结果时的客户端)会按照这个长度来读后面那么多个byte,数写错了就跑飞了(笑)
对于CONNECT报文的请求,是没有content部分的,只有Request-Line和header。Request-Line和header均为仅供代理服务器使用的,不能传给远端服务器。请求的header部分一旦结束(连续的两组CRLF),后面所有的数据都被视为应该发给远端服务器(网站)的数据,代理需要把它们直接转发,而且不限长度,直到从客户端的TCP读通道关闭。
对于CONNECT报文的返回值,代理服务器在和远端服务器成功建立连接后,可以(标准说的是可以,但是一般都会)向客户端(浏览器)返回任意一个2xx状态码,此时表示含义是和远端服务器建立连接成功,这个2xx返回报文的header部分一旦结束(连续的两组CRLF),后面所有的数据均为远端服务器返回的数据,同理代理会直接转发远端服务器的返回数据给客户端,直到从远端服务器的TCP读通道关闭。HTTP tunnel与SOCKS5代理有什么关系和区别?
其实HTTP代理服务器对于CONNECT报文的行为和SOCKS5代理服务器(<a href="https://link.zhihu.com/?target=https%3A//www.ietf.org/rfc/rfc1928.txt" ,这个很短)的行为已经非常想象了。
其中相同的地方:
都能在请求中指明要请求的目标和端口。
都会建立能传输任何流量的TCP通道,代理服务器对流量内容不关心。
都是在报文前部的描述信息结束后,将后续所有数据视为转发的客户端和服务端数据,直到通道关闭。
都可以进行客户端的身份验证,而且有多重身份验证协议可选。
不同的地方:
SOCKS5的报文无论请求还是返回,内容均是固定的。而CONNECT报文作为HTTP/1.1的报文之一,当然也包括了HTTP/1.1可以传输任何自定义header的功能,虽然一般代理不会响应CONNECT报文上的非标准header,但是自己实现一个客户端和服务器通过header传输一些其它数据也是符合标准的。
SOCKS5 request报文中的address,根据address type(ATYP)字节的值,可以显式声明为IPv4地址、IPv6地址、域名(domain)。而CONNECT报文中的Request-URI根据RFC要求必须为authority形式(即没有http://前缀,只包含host,以及可选的port,其中host和port要用“:”分隔),也就是说CONNECT报文不会显式的区分IP地址和域名,均作为host传输。
由于CONNECT报文还是http,所以也可以跑在TLS里,也就是说客户端和代理跑一层TLS,这一层里面客户端和远端服务器再跑一层TLS。这样当代理服务器需要用户名密码验证,而验证方式又是Basic时,可以通过TLS来保护代理请求报文中的明文用户名密码。
最后吐一口槽……虽然HTTP代理原理并不复杂,但是相比 SOCKS5代理,实现HTTP代理不但RFC字多,RFC多,而且还有后面RFC覆盖前面或前面的一部分的情况,需要消耗大量时间读多个版本来确认各种corner case,以及到底要不要兼容历史情况…………(微笑)
Tunnel的更多相关文章
- 外网访问内网工具ngrok tunnel 使用总结
需求分析 在软件开发测试过程中,我们会经常遇到需要网站部署测试.给客户演示.APP开发的调试这样的需求.通常的做法是申请一个域名和空间,将网站放到外网上给客户演示. 这种方法确实可行不过会有两点不好, ...
- ssh reverse tunnel
ssh反向通道的可用场景之一:从外网访问内网的主机.所必须的是你需要一个有ssh登录权限的公网主机. 步骤如下(将内网主机称作A,公网ssh主机地址为hostP ): 1.在内网A上执行 :local ...
- hdu1540 Tunnel Warfare
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- 通过ssh tunnel连接内网ECS和RDS
通过ssh tunnel连接内网ECS和RDS 这里讲了ssh tunnel的原理.很清晰. 此后又给外网访问内网增加了一种思路.感觉特别棒. 拓宽了思路:
- 【动态域名解析工具】tunnel,国内版的ngrok,花生壳可以睡觉了
在笔者的系列微信开发教程中,有一个比较基础且重要的一节:微信开发的调试.在文章中我推荐了两种动态域名解析的工具用于将本地的开发环境部署成服务器,一种是花生壳,一种是ngrok,但毕竟我等屌丝用不起或者 ...
- [POJ2892]Tunnel Warfare
[POJ2892]Tunnel Warfare 试题描述 During the War of Resistance Against Japan, tunnel warfare was carried ...
- HDU 1540 Tunnel Warfare 平衡树 / 线段树:单点更新,区间合并
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Lim ...
- zjuoj 3604 Tunnel Network
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3604 Tunnel Network Time Limit: 2 Secon ...
- POJ 2892 Tunnel Warfare(线段树单点更新区间合并)
Tunnel Warfare Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 7876 Accepted: 3259 D ...
- tunnel.p4
Tunneling: VXLAN and NVGRE (including L2/L3 Gateway), Geneve, GRE and IPinIP /* Copyright 2013-prese ...
随机推荐
- mysql转DM的日期函数转换
背景: 项目要从mysql转换为DM数据库,发现很多日期函数在DM是不能用的. 所以大概总结下有哪些,以及转换思路. 正文: INTERVAL 表示日期间隔. 看做拼接符. DATE_ADD 表示日期 ...
- 【2】java之object类
一.Object 类的基本定义 Object 类是所有类的父类,最大的一个好处就是:利用 Object 类可以接收所有类的对象(向上自动转型).如果不确定参数类型,使用 Object 类型是最好的 ...
- 常用的git提交代码命令
日常开发使用的git提交代码的方法 一.初始化本地仓库,提交代码,提交到远程git仓库 1.初始化代码仓库git init2.将当前目录下的所有文件放到暂存区git add .3.查看文件状态git ...
- Linux常用命令 转于WoW_Boom
一.常用命令 1.进入到用户根目录cd ~ 或 cd 2.查看当前所在目录pwd 3.进入到itcast用户根目录cd ~itcast 4.返回到原来目录cd - 5.返回到上一级目录cd .. 6. ...
- Vulnhub:ReconForce-01.1靶机
kali:192.168.111.111 靶机:192.168.111.200 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --script=http-enum 192.168. ...
- centOS 相关运维指令
1.检查CPU信息: cat /proc/cpuinfo lscpu 2.top输入 top 命令,然后可以再按 m 切换显示内容 其中 KiB Mem 行为物理内存情况,单位为KB 3.free - ...
- Spring随意总结
Spring框架的优点 1.使用Spring的IOC容器,将对象之间的依赖关系交给Spring,降低组件之间的耦合性,让我们更专注于应用逻辑 2.可以提供众多服务,事务管理,WS等. 3.AOP的很好 ...
- mysql存储过程游标中途自动退出
1.当在游标循环过程中select的结果集如果为空,就会触发游标continue handler for not found 提前将done置为1,导致提前退出游标. 2.游标循环中出现 select ...
- Windows 11在使用AMD时,CPU占用率持续100%的解决方案
一.现象 Windows 11在使用AMD时,CPU占用率持续100%,持续好几个系统版本都是如此 二.系统版本: 版本 Windows 11 专业工作站版版本 22H2安装日期 2022/10/ ...
- perl的学习:将分句脚本split-sentences.perl转为python脚本
初识perl,只为完成分句脚本的转换.因此本文具有极强的目的性,perl的很多好用功能就不研究了,主要内容围绕分句脚本展开,部分基础知识就不再赘述. 1.仓库的地址:https://gitee.com ...