网络安全学习记录HTTP代理服务器搭建实验
TonglinggejimoHTTP代理服务器实验
(此实验是CUC网络安全课程中的实验,将其记录在此)
实验目的
实验环境
- Ubuntu 22.04.5 LTS (Jammy Jellyfish)(代理服务器)
- MacOS(客户端)
实验要求
实验步骤
查看客户端和代理服务器是否可以连通
nc -lvnp 4444
curl {准备做代理的服务器IP}:4444
|
然后在准备做代理的服务器上发现有客户端的请求,内容如下:
Listening on 0.0.0.0 4444 Connection received on {客户端IP} {客户端端口} GET / HTTP/1.1 Host: {准备做代理的服务器IP}:4444 User-Agent: curl/8.15.0 Accept: */*
|
这一步可以获得客户端能连接到代理服务器的对应出口IP,方便后续暴露面最小的配置正向代理的服务(只代理来自客户端网段的IP地址,其他IP地址不代理,注:
实验环境中客户端出口IP地址不会发生改变,若是配置互联网代理,在不同网络环境地域下访问时,客户端出口IP地址可能会发生改变,为了安全需要做其他配置)
在ubuntu上使用tinyproxy
搭建HTTP正向代理服务器
基础软件安装:
sudo apt update sudo apt install -y tinyproxy
|
配置文件编辑:
sudo vim /etc/tinyproxy/tinyproxy.conf
|
因为之前获得了客户端的出口IP,所以取消对应网段下Allow的行首注释。示例如:我之前获得了出口IP是10.190.0.38
,此处我要取消Allow 10.0.0.0/8行首注释
,因为10.190.0.38
是10.0.0.0/8
网段下的其中之一的IP地址。

参数解释:
- Allow:允许代理的IP地址段或IP,不写就是允许所有主机访问
- Port:代理服务器的端口,不更改就是默认8888端口
配置完成后,重启tinyproxy服务:
sudo systemctl restart tinyproxy
|
在客户端中使用代理服务器,验证代理服务是否正常
我在客户端的浏览器中安装了一个代理切换工具,Zero Omega,可以方便的切换代理服务器,在这里的配置过程如下:
新建情景模式->代理服务器->填代理服务器名称->修改代理协议为HTTP->修改代理服务器IP和端口为我们代理服务器对应的设置->应用选项

然后使用该代理访问baidu.com
,发现可以正常访问,说明代理服务器正常工作。


发现访问的已经是https站点了
在代理服务器中抓8888端口的包
此处使用tshark
抓包,所以需要安装tshark
。
sudo apt install -y tshark
|
然后使用tshark
抓包,监听8888端口。
sudo tshark -i any -w tinyproxy_traffic.pcap -f "port 8888"
|
将服务器上抓到的包scp到本地后用wireshark
打开进行分析
http.request.method eq CONNECT
查看所有HTTPS代理请求

随便看了一个tcp流,将图片发给ai后让它帮我分析了一下这个流的全过程:

首先,明确图中的角色: * **客户端 (Client)**: `192.168.33.167` * **代理服务器 (Proxy Server)**: `10.190.0.38` (这是你抓包的地方) * **目标服务器 (Destination Server)**: `www.baidu.com` (图中未直接显示其 IP 地址,但通过 `CONNECT` 请求和 `Client Hello` 中的 SNI 可知)
整个过程可以分为以下几个关键步骤:
### 步骤 1: 建立与代理服务器的 TCP 连接 (数据包 77, 78, 88)
* **No. 77, 78, 88**: 这是一个标准的 TCP 三次握手过程。 * `SYN`: 客户端 `192.168.33.167` 向代理服务器 `10.190.0.38` 的 `8888` 端口发起连接请求。 * `SYN, ACK`: 代理服务器响应并确认请求。 * `ACK`: 客户端最终确认,连接建立。 * **分析**: 此时,客户端和代理服务器之间建立了一条普通的 TCP 连接。这条连接本身是**不加密的**。
### 步骤 2: 请求建立隧道 (数据包 93)
* **No. 93**: 这是整个过程的**核心**。客户端向代理服务器发送了一个 **HTTP `CONNECT`** 请求。 * `CONNECT www.baidu.com:443 HTTP/1.1` * **分析**: * 这个 `CONNECT` 方法告诉代理服务器:“请不要为我获取任何网页,我不想访问你。我只想让你帮我打通一个到 `www.baidu.com` 的 `443` 端口的 TCP 通道,然后你就在中间原样转发数据即可。” * **非常重要的一点是**:代理服务器在这一步可以看到客户端想要访问的目标域名 (`www.baidu.com`) 和端口 (`443`)。这个 `CONNECT` 请求本身是**明文的 HTTP**。
### 步骤 3: 隧道建立成功 (数据包 106)
* **No. 106**: 代理服务器成功连接到 `www.baidu.com:443` 后,向客户端返回一个 HTTP 响应。 * `HTTP/1.0 200 Connection established` * **分析**: 这个响应告诉客户端:“好的,我已经为你和 `www.baidu.com:443` 之间建立了通道。现在开始,你们可以自由通信了,我只负责当一个‘传话筒’。” * 至此,一个透明的、端到端的数据管道(隧道)就在 **客户端** 和 **目标服务器 (Baidu)** 之间建立起来了,而代理服务器就在这个管道的中间。
### 步骤 4: 端到端的 TLS 握手 (数据包 113, 114, 131 等)
* 隧道建立后,客户端现在开始直接与百度的服务器进行通信,就好像代理不存在一样。 * **No. 113**: 客户端发送 `Client Hello`。这是 TLS 握手的开始。这个包被发送到代理,代理再原封不动地转发给百度服务器。 * **No. 114**: 百度服务器响应 `Server Hello`, `Change Cipher Spec` 等。这些信息通过代理原封不动地转发回客户端。 * **No. 131**: 客户端继续 TLS 握手的后续步骤。 * **分析**: * 整个 TLS 握手过程是在**客户端和百度服务器之间**直接进行的。 * 代理服务器**无法看到**这些 TLS 握手包的内部内容(如协商的密钥等),因为它只在转发加密的字节流。对代理来说,这些都只是无意义的数据。
### 步骤 5: 传输加密的应用数据 (数据包 1051, 1055 等)
* **No. 1051, 1055**: TLS 握手成功后,双方开始传输加密的应用数据。 * `Application Data` 就是加密后的 HTTP 请求和响应(例如 `GET /index.html` 请求和返回的网页内容)。 * **分析**: * 包 `1051` (175字节) 很可能是客户端发出的、经过 TLS 加密后的 HTTP `GET` 请求。 * 包 `1055` (2116字节) 是百度服务器返回的、经过 TLS 加密后的 HTTP 响应的开始部分。 * 代理服务器**完全无法解密或读取**这些 `Application Data` 的内容。它只知道在转发一些加密数据。
#### 步骤 5: 连接终止 (数据包 1864 - 1903) -- **【新增分析】** * 这是数据传输完毕后,关闭连接的过程。这里采用的是 TCP 的**四次挥手**来优雅地断开连接。 * **No. 1864**: **第一次挥手**。代理服务器 `10.190.0.38` 向客户端 `192.168.33.167` 发送了一个带有 `[FIN, ACK]` 标志的包。 * `FIN` (Finish) 标志表示:“我(代理)这边的数据已经全部发送完了,我准备关闭连接了。” * `ACK` 是为了确认之前收到的数据。 * **分析**: 代理之所以主动发起关闭,很可能是因为它与百度服务器之间的连接先被百度那边关闭了。于是代理将这个“关闭信号”传递给客户端。
* **No. 1899**: **第二次和第三次挥手**。客户端 `192.168.33.167` 回复代理服务器。 * 这个包也带有 `[FIN, ACK]` 标志。 * `ACK` 部分是对代理 `FIN` 包的确认(第二次挥手),表示:“好的,收到你准备关闭的请求了。” * `FIN` 部分是客户端自己发起的关闭请求(第三次挥手),表示:“我(客户端)这边的数据也发完了,我也准备关闭了。”
* **No. 1900**: **第四次挥手**。代理服务器 `10.190.0.38` 回复客户端。 * 这是一个 `[ACK]` 包,用于确认收到了客户端的 `FIN` 请求。 * **分析**: 到这里,一个标准的、优雅的四次挥手过程就完成了。理论上,双方的连接已经和平关闭。
* **No. 1903**: 客户端 `192.168.33.167` 又发送了一个 `[RST]` 包。 * `RST` (Reset) 表示一个强制、异常的连接重置。 * **分析**: 这通常发生在一方收到了非预期的包,或者上层应用(浏览器)在连接关闭后仍然尝试使用该套接字,导致操作系统内核发送 RST 来强制终止。在这个场景下,它标志着这个 TCP 会话的彻底终结。
### 总结
1. **两层连接**: 整个过程包含两层连接。第一层是客户端与代理服务器之间的明文 TCP 连接,用于协商建立隧道。第二层是客户端与目标服务器(百度)之间的加密 TLS 连接,这条连接的数据“流经”第一层建立的隧道。
2. **代理的可见性**: * **能看到**: 代理服务器知道客户端正在与哪个**域名 (`www.baidu.com`)** 和 **端口 (`443`)** 通信(从 `CONNECT` 请求中得知)。 * **看不到**: 代理服务器**无法**看到具体的通信内容,包括: * 用户访问了哪个具体的 URL 路径 (例如 `/s?wd=keyword`)。 * HTTP 请求头和响应头的具体内容。 * 传输的任何 Cookie、表单数据或网页内容。
|
针对于https的流量解密可以看Wireshark解密HTTPS流量的两种方法
实验总结
在此次试验中,我使用了tinyproxy
搭建了一个HTTP正向代理服务器,并使用客户端访问代理服务器,验证代理服务器是否正常工作。在代理服务器中抓包,分析使用HTTP代理服务器的通信过程。
参考链接
HTTP代理服务器实验
Linux环境使用Tinyproxy代理
Wireshark解密HTTPS流量的两种方法