mirror of
https://github.com/telemt/telemt.git
synced 2026-10-29 03:57:15 +03:00
WEB: Resolve opt-in decoy hostnames during config preparation #929
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
@@ -345,6 +345,10 @@ fn remove_hop_by_hop(headers: &mut hyper::HeaderMap) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "decoy_dns_tests.rs"]
|
||||
mod decoy_dns_tests;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
use super::*;
|
||||
|
||||
use arc_swap::ArcSwap;
|
||||
use std::sync::Arc;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
use crate::config::WebCarrier;
|
||||
use crate::maestro::generation::test_runtime_generation;
|
||||
use crate::web::http::tests::{request, runtime_config};
|
||||
|
||||
#[tokio::test]
|
||||
async fn decoy_dns_pinned_socket_keeps_configured_hostname_in_actual_http_request() {
|
||||
let origin = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let mut config = runtime_config([17; 32], WebCarrier::Https);
|
||||
let snapshot = Arc::get_mut(config.web.runtime.as_mut().unwrap()).unwrap();
|
||||
let vhost = Arc::get_mut(snapshot.vhosts.get_mut("proxy.example.com").unwrap()).unwrap();
|
||||
// A public hostname deliberately paired with a loopback socket proves no request-time lookup.
|
||||
vhost.decoy = WebRuntimeDecoy::HttpUpstream {
|
||||
addr: origin.local_addr().unwrap(),
|
||||
authority: "bsi.bund.de:8080".to_string(),
|
||||
};
|
||||
let generation = test_runtime_generation(1, config);
|
||||
let runtime = WebProcessRuntime::start(Arc::new(ArcSwap::from(generation.clone())));
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let receive = async {
|
||||
let (mut socket, _) = origin.accept().await.unwrap();
|
||||
let mut bytes = Vec::new();
|
||||
let mut buf = [0; 1024];
|
||||
while !bytes.windows(4).any(|part| part == b"\r\n\r\n") {
|
||||
let count = socket.read(&mut buf).await.unwrap();
|
||||
assert_ne!(count, 0);
|
||||
bytes.extend_from_slice(&buf[..count]);
|
||||
}
|
||||
socket
|
||||
.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\nConnection: close\r\n\r\nOK")
|
||||
.await
|
||||
.unwrap();
|
||||
String::from_utf8(bytes).unwrap()
|
||||
};
|
||||
let (response, upstream) = tokio::time::timeout(std::time::Duration::from_secs(5), async {
|
||||
tokio::join!(request(&listener, &runtime, b"GET /site?q=1 HTTP/1.1\r\nHost: proxy.example.com\r\nX-Forwarded-For: 192.0.2.10\r\nConnection: close\r\n\r\n".to_vec()), receive)
|
||||
}).await.unwrap();
|
||||
assert!(upstream.starts_with("GET /site?q=1 HTTP/1.1\r\n"));
|
||||
assert!(
|
||||
upstream
|
||||
.to_ascii_lowercase()
|
||||
.contains("\r\nhost: bsi.bund.de:8080\r\n")
|
||||
);
|
||||
assert!(response.starts_with(b"HTTP/1.1 200"));
|
||||
assert!(response.ends_with(b"OK"));
|
||||
runtime.shutdown().await;
|
||||
generation.stop_sessions().await;
|
||||
generation.stop_background_tasks().await;
|
||||
}
|
||||
Reference in New Issue
Block a user