Clean readme, replace Arcs with leaked Boxes
This commit is contained in:
parent
ad2c0909b4
commit
a95efd9ed8
4 changed files with 19 additions and 35 deletions
|
|
@ -27,12 +27,13 @@ rustls-symcrypt = { version = "0.2.1", optional = true, features = ["chacha", "x
|
|||
|
||||
[features]
|
||||
default = [
|
||||
"aws-lc",
|
||||
#"record",
|
||||
"aws-lc",# Change this to the wanted cryptographic backend (list below)
|
||||
"record",# It may be needed to remove the record feature when building with openssl
|
||||
]
|
||||
|
||||
record = ["sslrelay"]
|
||||
|
||||
# Available cryptographic backends
|
||||
aws-lc = ["tokio-rustls/aws-lc-rs", "rustls-post-quantum", "rustls-post-quantum/aws-lc-rs-unstable", "aws-lc-rs"]
|
||||
boring = ["boring-rustls-provider"]
|
||||
graviola = ["rustls-graviola"]
|
||||
|
|
|
|||
22
README.md
22
README.md
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
This program has two modes:
|
||||
* recording proxy: relays trafic with or without TLS and record requests and responses in clear. It is a TLS termination thus a certificate is needed.
|
||||
* trafic replay: run a client that sends the recorded requests, and a server that responds with the corresponding recorded responses. A proxy can be placed in between. The proxy can even alter the plain data, because the server uses hash distance to identify the requests.
|
||||
|
||||
It has been tested with HTTP trafic only. Other protocols which are not request/response (or even websocket) may not be recorded properly.
|
||||
* trafic replay: run a client that sends the recorded requests, and a server that responds with the corresponding recorded responses. Responses are replaced with the same amount of random bytes for performance.
|
||||
|
||||
It relies on the server name extension in TLS (SNI). Requests without server name may not be recorded.
|
||||
|
||||
|
|
@ -12,27 +10,21 @@ For experimental purpose. Do not use on an open network where security matters.
|
|||
|
||||
## Build
|
||||
|
||||
[Install Rust nightly.](https://rustup.rs)
|
||||
|
||||
Choose a cryptographic backend in `Cargo.toml`.
|
||||
|
||||
```bash
|
||||
RUSTFLAGS="--cfg tokio_unstable" cargo build --release
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
## Record file format
|
||||
|
||||
The record file is a list of records. Each record follows this format:
|
||||
* [1 byte] direction: ASCII 'C' for client-to-server, 'S' for server-to-client
|
||||
* [8 bytes] connection id, big endian
|
||||
* [1 byte] server name length
|
||||
* server name (TLS's SNI or HTTP's Host)
|
||||
* [8 bytes] data length, big endian
|
||||
* data
|
||||
|
||||
## SSLKEYLOGFILE
|
||||
|
||||
The `SSLKEYLOGFILE` environment variable can be set to a file path to which the connection secrets will be exported, enabling decrypting the traffic in Wireshark.
|
||||
|
||||
## License
|
||||
|
||||
GNU AGPL v3, CopyLeft 2025 Pascal Engélibert [(why copyleft?)](https://txmn.tk/blog/why-copyleft/)
|
||||
GNU AGPL v3, CopyLeft 2025-2026 Pascal Engélibert [(why copyleft?)](https://txmn.tk/blog/why-copyleft/)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License.
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
|
|
|||
|
|
@ -102,25 +102,24 @@ pub async fn play(
|
|||
) {
|
||||
// Semaphore used to limit the number of concurrent clients.
|
||||
// Its handle is released when the task panics.
|
||||
let limiter = Arc::new(Semaphore::new(concurrency));
|
||||
let counter = Arc::new(AtomicU32::new(0));
|
||||
let running = Arc::new(Mutex::new(HashSet::new()));
|
||||
let limiter: &'static _ = Box::leak(Box::new(Semaphore::new(concurrency)));
|
||||
let counter: &'static _ = Box::leak(Box::new(AtomicU32::new(0)));
|
||||
let running: &'static _ = Box::leak(Box::new(Mutex::new(HashSet::new())));
|
||||
let total = records.len() * repeat as usize;
|
||||
let connect_to = connect_to.to_socket_addrs().unwrap().next().unwrap();
|
||||
|
||||
let dummy_bytes = Arc::new(vec![0x42u8; 16 * 1024 * 1024]);
|
||||
let dummy_bytes: &'static _ = Box::leak(Box::new(vec![0x42u8; 16 * 1024 * 1024]));
|
||||
|
||||
let notify_socket = notify_addr.map(|notify_addr| {
|
||||
let socket = std::net::UdpSocket::bind("0.0.0.0:48567").unwrap();
|
||||
socket.connect(notify_addr).unwrap();
|
||||
Arc::new(socket)
|
||||
let socket: &'static _ = Box::leak(Box::new(socket));
|
||||
socket
|
||||
});
|
||||
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
|
||||
|
||||
tokio::spawn({
|
||||
let running = running.clone();
|
||||
let counter = counter.clone();
|
||||
async move {
|
||||
let mut last_count = 0;
|
||||
loop {
|
||||
|
|
@ -197,11 +196,7 @@ pub async fn play(
|
|||
let mut handles = Vec::new();
|
||||
for (conn_id, (server_name, records)) in records.iter() {
|
||||
let connector = TlsConnector::from(config.clone());
|
||||
let counter = counter.clone();
|
||||
let limiter = limiter.clone();
|
||||
let running = running.clone();
|
||||
let dummy_bytes = dummy_bytes.clone();
|
||||
let notify_socket = notify_socket.clone();
|
||||
handles.push(tokio::spawn(async move {
|
||||
let mut running_guard = running.lock().await;
|
||||
running_guard.insert(*conn_id);
|
||||
|
|
@ -294,11 +289,7 @@ pub async fn play(
|
|||
for _i in 0..repeat {
|
||||
let mut handles = Vec::new();
|
||||
for (conn_id, (_server_name, records)) in records.iter() {
|
||||
let counter = counter.clone();
|
||||
let limiter = limiter.clone();
|
||||
let running = running.clone();
|
||||
let dummy_bytes = dummy_bytes.clone();
|
||||
let notify_socket = notify_socket.clone();
|
||||
handles.push(tokio::spawn(async move {
|
||||
let mut running_guard = running.lock().await;
|
||||
running_guard.insert(*conn_id);
|
||||
|
|
@ -366,7 +357,7 @@ pub async fn play(
|
|||
println!("Client: {} / {}", cnt, total);
|
||||
}
|
||||
drop(limiter);
|
||||
if let Some(notify_socket) = ¬ify_socket {
|
||||
if let Some(notify_socket) = notify_socket {
|
||||
notify_socket.send(&cnt.to_be_bytes()).unwrap();
|
||||
}
|
||||
let mut running_guard = running.lock().await;
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ pub async fn play(
|
|||
}
|
||||
}
|
||||
|
||||
let response_map = Arc::new(response_map);
|
||||
let dummy_bytes = Arc::new(vec![0x42u8; 16 * 1024 * 1024]);
|
||||
let response_map: &'static _ = Box::leak(Box::new(response_map));
|
||||
let dummy_bytes: &'static _ = Box::leak(Box::new(vec![0x42u8; 16 * 1024 * 1024]));
|
||||
|
||||
if use_tls {
|
||||
let mut resolver = ResolvesServerCertUsingSni::new();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue