-
Notifications
You must be signed in to change notification settings - Fork 265
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
1,263 additions
and
314 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,28 @@ | ||
[package] | ||
authors = ["ihciah <[email protected]>"] | ||
description = "A proxy to expose real tls handshake to the firewall." | ||
edition = "2021" | ||
keywords = ["proxy", "tls", "shadowsocks"] | ||
license = "MIT/Apache-2.0" | ||
name = "shadow-tls" | ||
version = "0.1.0" | ||
readme = "README.md" | ||
repository = "https://github.com/ihciah/shadow-tls" | ||
version = "0.2.0" | ||
|
||
[dependencies] | ||
monoio = {version = "0.0.8"} | ||
monoio-rustls = {version = "0.0.6"} | ||
|
||
anyhow = "1" | ||
clap = {version = "3", features = ["derive"]} | ||
hmac = "0.12" | ||
pin-project-lite = "0.2" | ||
rustls = {version = "0.20", default-features = false} | ||
sha1 = "0.10" | ||
tracing = "0.1" | ||
tracing-subscriber = "0.3" | ||
webpki-roots = "0.22" | ||
|
||
[features] | ||
default = ["zero-copy"] | ||
|
||
# Relay data with splice syscall for linux. | ||
zero-copy = ["monoio/splice"] | ||
|
||
[profile.release] | ||
lto = true | ||
opt-level = 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,49 @@ | ||
# Shadow TLS | ||
一个**可以使用别人的受信证书**的 TLS 伪装代理。 | ||
|
||
它和 [trojan](https://github.com/trojan-gfw/trojan) 的表现类似,但它在做真实 TLS 握手的同时,可以直接使用别人的受信证书(如某些大公司或机构的域名),而不需要自己签发证书。当直接使用浏览器打开时,可以正常显示对应可信域名的网页内容。 | ||
|
||
--- | ||
|
||
A proxy to expose real tls handshake to the firewall. | ||
|
||
It works like [trojan](https://github.com/trojan-gfw/trojan) but it does not require signing certificate. The firewall will see **real** tls handshake with **valid certificate** that you choose. | ||
|
||
## Run | ||
Check comments in `docker-compose.yml`. | ||
## How to Use It | ||
这个服务需要双边部署,并且它一般需要搭配一个加密代理(因为本项目不包含数据加密和代理请求封装功能,这不是我们的目标)。 | ||
|
||
通常,你可以在同机部署 shadowsocks-server 和 shadowtls-server;之后在防火墙的另一端部署 shadowsocks-client 和 shadowtls-client。 | ||
|
||
有两种方式部署这个服务。 | ||
1. 使用 Docker + Docker Compose | ||
|
||
修改 `docker-compose.yml` 后直接 `docker-compose up -d`。 | ||
2. 使用预编译的二进制 | ||
|
||
从 [Release 页面](https://github.com/ihciah/shadow-tls/releases)下载对应平台的二进制文件, 然后运行即可。运行指南可以 `./shadow-tls client --help` 或 `./shadow-tls server --help` 看到。 | ||
--- | ||
|
||
Normally you need to deploy this service on both sides of the firewall. And it is usually used with an encryption proxy (because this project does not include encryption and proxy request encapsulation, which is not our goal). | ||
|
||
1. Run with Docker + Docker Compose | ||
Modfy `docker-compose.yml` and run `docker-compose up -d`. | ||
|
||
2. Use prebuilt binary | ||
Download the binary from [Release page](https://github.com/ihciah/shadow-tls/releases) and run it. | ||
|
||
|
||
## How it Works | ||
On client side, just do tls handshake. And for server, we have to relay data as well as parsing tls handshake to handshaking server which will provide valid certificate. We need to know when the tls handshaking is finished. Once finished, we can relay data to our real server. | ||
|
||
[Full design doc is here](./docs/protocol-en.md). | ||
|
||
[完整的协议设计点这](./docs/protocol-cn.md). | ||
|
||
## Note | ||
This project relies on [Monoio](https://github.com/bytedance/monoio) which is a high performance rust async runtime with io_uring. However, it does not support windows yet. So this project does not support windows. | ||
|
||
However, if this project is used widely, we will support it by conditional compiling. | ||
However, if this project is used widely, we will support it by conditional compiling. | ||
|
||
Also, you may need to [modify some system limitations](https://github.com/bytedance/monoio/blob/master/docs/en/memlock.md) to make it work. If it does not work, you can add environ `MONOIO_FORCE_LEGACY_DRIVER=1` to use epoll instead of io_uring. | ||
|
||
你可能需要修改某些系统设置来让它工作,[参考这里](https://github.com/bytedance/monoio/blob/master/docs/en/memlock.md)。如果它不起作用,您可以添加环境变量 `MONOIO_FORCE_LEGACY_DRIVER=1` 以使用 epoll 而不是 io_uring。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
--- | ||
title: ShadowTLS 协议设计 | ||
date: 2022-10-02 11:00:00 | ||
author: ihciah | ||
--- | ||
|
||
# 协议 | ||
|
||
ShadowTLS 协议有两个版本。 | ||
|
||
第一个版本是一个简单的协议,只能将真正的 TLS 握手暴露给中间人,但不能防御主动检测,而且 TLS 握手后的流量也很容易区分。 | ||
|
||
第二个版本比较复杂,但是可以防御主动检测,tls握手后的流量很难区分。如果攻击者使用浏览器访问服务端,它能将像真正的 Web 服务器一样工作。 | ||
|
||
![protocol design](../.github/resources/shadow-tls.png) | ||
|
||
## V1 | ||
在这个版本中,我们只想让中间人观测到 TLS 握手,并且握手使用其他人的合法证书。这是我们最初的目标。 | ||
|
||
中间人将看到有效的受信任证书的握手流量。如果假设中间人不会主动探测,并且不会分析在 TLS 握手完成后的流量,这个版本可以用来防御: | ||
1. 基于流量特征的封锁:我们看起来像正常的 TLS 流量,而不是 shadowsocks 那样的无法理解的随机数据。 | ||
2. 基于 SNI 的封锁:我们使用合法且受信任的证书(比如可能某些大型公司或政府机构的域名是被标记为受信任的),因此会被认为是合法数据。 | ||
|
||
V1 版本的最后一个实现是 [v0.1.4](https://github.com/ihciah/shadow-tls/releases/tag/v0.1.4). | ||
|
||
### 客户端 | ||
客户端连接服务器并进行 TLS 握手。握手后,所有客户端流量将不加修改地发送到服务器(包括加密和数据封装等)。 | ||
|
||
1. 与 example.trusted-server.domain 进行 TLS 握手。 | ||
2. 中继流量(不加修改)。 | ||
|
||
但是,TLS 握手后的实际流量是带有 Application Data 封装的数据包,所以流量很容易区分。 | ||
|
||
现在流量看起来像是与受信任服务器的 TLS 连接(因为我们可以使用受信任的域和证书),但实际上它不是 http 服务,而使用 TLS 但不使用 http 的服务器非常少,这可能也会是一个特征。 | ||
|
||
### 服务端 | ||
服务器在客户端和 2 个后端之间中继数据。一个后端是 TLS 握手服务器,它提供有效的证书(不属于我们);另一个后端是我们的数据服务器。握手完成后,服务器将在客户端和数据服务器之间中继流量。 | ||
|
||
1. 接受连接。 | ||
2. 在客户端和 TLS 握手服务器之间中继流量(例如 example.trusted-server.domain:443)。它还将监视流量以查看握手是否完成。 | ||
3. 握手完成后在客户端和我们的真实服务器之间中继流量。 | ||
|
||
由于我们需要感知握手结束,所以这个版本我们只能使用 TLS1.2。 | ||
|
||
## V2 | ||
该版本旨在解决流量分析和主动检测问题。此外,它可以支持 TLS 1.3。 | ||
|
||
### 客户端 | ||
客户端连接服务器并进行 TLS 握手。 握手后: | ||
1. 所有数据都将打包在 TLS Application Data 中。 | ||
2. 在第一个 Application Data 包的数据的最前面插入一个 8 字节的 hmac。 | ||
|
||
hmac 是使用服务器发送的所有数据计算的(服务器发送的所有数据被用作 challenge,因为客户端无法完全控制它,并且有一定随机性)。hmac 可以被视为对 challenge 的响应,用于识别。 | ||
|
||
### 服务端 | ||
服务器在客户端和 2 个后端(模式和 V1 一样)之间中继数据。 不同的是:我们不会观察流量来查看握手是否完成;相反,我们使用 hmac。所以我们更容易解析流量和切换后端。此外,还支持 TLS1.3 或其他版本。 | ||
|
||
1. 接受连接。 | ||
2. 在客户端和 tls 握手服务器之间中继流量(例如 example.trusted-server.domain:443)。服务器发送的所有数据将用于计算 hmac。如果客户端发送的某个 Application Data 包的前缀有有效的hmac,我们会将流量切换到我们的数据服务器。 | ||
3. 如果不切换,流量将被中继到 TLS 握手服务器。使用浏览器访问服务器的用户将能够访问握手服务器上的 http 服务。为了效率,我们只能对前 N 个数据包进行 hmac 检查(在我们的实现中 N = 3,hmac 算法为 HMAC-SHA1)。 |
Oops, something went wrong.