Skip to content

Commit

Permalink
Using scramble instead noise_injection
Browse files Browse the repository at this point in the history
  • Loading branch information
Jackarain committed Nov 24, 2023
1 parent 5930bb8 commit bcda34e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 11 deletions.
47 changes: 39 additions & 8 deletions proxy/include/proxy/proxy_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ namespace proxy {
using io_util::write;


//////////////////////////////////////////////////////////////////////////

inline const char* version_string =
R"x*x*x(nginx/1.20.2)x*x*x";

Expand Down Expand Up @@ -202,6 +204,8 @@ R"x*x*x(<html>
L"<a href=\"{}\">{}</a>{} {} {}\r\n";


//////////////////////////////////////////////////////////////////////////

// udp_session_expired_time 用于指定 udp session 的过期时间, 单位为秒.
inline const int udp_session_expired_time = 600;

Expand All @@ -220,6 +224,8 @@ R"x*x*x(<html>
};


//////////////////////////////////////////////////////////////////////////

// proxy server 参数选项, 用于指定 proxy server 的各种参数.
struct proxy_server_option
{
Expand Down Expand Up @@ -323,16 +329,27 @@ R"x*x*x(<html>
// 加密连接.
bool disable_insecure_{ false };

// 启用噪声注入以干扰流量分析.
// 启用噪声注入以干扰流量分析, 从而达到数据安全的目的.
// 此功能必须在 server/client 两端同时启用才有效, 此功能表示在启
// 用 ssl 协议时, 在 ssl 握手后双方互相发送一段随机长度的随机数据
// 以干扰流量分析.
// 启用后会增加一定的流量消耗以及延迟, 此选项默认不启用, 除非有确定
// 证据证明代理流量被分析或干扰, 此时可以启用此选项.
// 注意:此选项当前未实现.
bool noise_injection_{ false };
// 在双方接收到对方的随机数据后, 将对整个随机数据进行 hash 计算, 得
// 到的结果将会作为后续数据的加密密钥, 从而达到加密通信的目的.
// 加密算法仅仅是简单的异或运算, 但是由于密钥是随机的, 因此即使是
// 同样的明文, 也会得到不同的密文, 从而达到加密通信的目的.
// 密钥在一轮(密钥长度)使用完后, 将会通过 hash(hash) 重新计算得到
// 新的密钥, 用于下一轮的加密通信.
// hash 算法采用快速的 xxhash, 但是由于 xxhash 本身的特性. 因此
// 密钥长度不能太长, 否则会影响性能, 所在固定密钥长度为 16 字节.
// 此功能可以有效的防止流量分析, 但是会增加一定的流量消耗以及延迟,
// 此选项默认不启用, 除非有确定证据证明代理流量被分析或干扰, 此时可
// 以启用此选项.
bool scramble_{ false };
};


//////////////////////////////////////////////////////////////////////////

inline int start_position(std::mt19937& gen)
{
const static int pos[] =
Expand Down Expand Up @@ -417,6 +434,9 @@ R"x*x*x(<html>
return data;
}


//////////////////////////////////////////////////////////////////////////

// proxy server 虚基类, 任何 proxy server 的实现, 必须基于这个基类.
// 这样 proxy_session 才能通过虚基类指针访问proxy server的具体实
// 现以及虚函数方法.
Expand All @@ -428,6 +448,9 @@ R"x*x*x(<html>
virtual const proxy_server_option& option() = 0;
};


//////////////////////////////////////////////////////////////////////////

// proxy session 虚基类.
class proxy_session_base {
public:
Expand All @@ -436,6 +459,9 @@ R"x*x*x(<html>
virtual void close() = 0;
};


//////////////////////////////////////////////////////////////////////////

// proxy_session 抽象类, 它被设计为一个模板抽象类, 模板参数Stream
// 指定与本地通信的stream对象, 默认使用tcp::socket, 可根据此
// async_read/async_write等接口实现专用的stream类, 比如实现加密.
Expand Down Expand Up @@ -2346,7 +2372,7 @@ R"x*x*x(<html>

// 如果启用了 noise, 则在向上游代理服务器发起 tcp 连接成功后, 发送 noise
// 数据以及接收 noise 数据.
if (m_option.noise_injection_)
if (m_option.scramble_)
{
ec = co_await start_noise(remote_socket);
if (ec)
Expand Down Expand Up @@ -3339,6 +3365,7 @@ R"x*x*x(<html>
bool m_abort{ false };
};


//////////////////////////////////////////////////////////////////////////

class proxy_server
Expand Down Expand Up @@ -3780,7 +3807,7 @@ R"x*x*x(<html>

new_session->start();
}
else if (noise && m_option.noise_injection_)
else if (noise && m_option.scramble_)
{
// 进入噪声过滤协议, 同时返回一段噪声给客户端.
XLOG_DBG << "connection id: "
Expand Down Expand Up @@ -3822,7 +3849,11 @@ R"x*x*x(<html>
}

socket.set_option(keep_alive_opt, error);
if (m_option.noise_injection_)

// 在启用 scramble 时, 刻意开启 Nagle's algorithm 以尽量保证数据包
// 被重组, 尽最大可能避免观察者通过观察 ip 数据包大小的规律来分析 tcp
// 数据发送调用, 从而增加噪声加扰的强度.
if (m_option.scramble_)
socket.set_option(delay_opt, error);
else
socket.set_option(no_delay_opt, error);
Expand Down
6 changes: 3 additions & 3 deletions server/proxy_server/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ std::string log_directory;
bool disable_http = false;
bool disable_socks = false;
bool disable_insecure = true;
bool noise_injection = false;
bool scramble = false;
bool disable_logs;
bool autoindex = false;

Expand Down Expand Up @@ -112,7 +112,7 @@ start_proxy_server(net::io_context& ioc, server_ptr& server)
opt.disable_http_ = disable_http;
opt.disable_socks_ = disable_socks;
opt.disable_insecure_ = disable_insecure;
opt.noise_injection_ = noise_injection;
opt.scramble_ = scramble;
opt.local_ip_ = local_ip;

opt.reuse_port_ = reuse_port;
Expand Down Expand Up @@ -254,7 +254,7 @@ int main(int argc, char** argv)
("disable_http", po::value<bool>(&disable_http)->value_name("")->default_value(false), "Disable HTTP protocol.")
("disable_socks", po::value<bool>(&disable_socks)->value_name("")->default_value(false), "Disable SOCKS proxy protocol.")
("disable_insecure", po::value<bool>(&disable_insecure)->value_name("")->default_value(false), "Disable insecure protocol.")
("noise_injection", po::value<bool>(&noise_injection)->value_name("")->default_value(false), "Enable RLH(random-length headers) protocol.")
("scramble", po::value<bool>(&scramble)->value_name("")->default_value(false), "Noise-based data security.")
;

// 解析命令行.
Expand Down

0 comments on commit bcda34e

Please sign in to comment.