Skip to content

Commit c838cdb

Browse files
author
hidu
committed
禁用 keep-alive;verify_server_cert 时打印证书信息
1 parent e6122ac commit c838cdb

2 files changed

Lines changed: 95 additions & 89 deletions

File tree

src/insecure_verifier.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use tokio_rustls::rustls;
2+
use tokio_rustls::rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
3+
use tokio_rustls::rustls::pki_types::{CertificateDer, ServerName, UnixTime};
4+
use tokio_rustls::rustls::{DigitallySignedStruct, SignatureScheme};
5+
6+
#[derive(Debug)]
7+
pub struct NoCertificateVerification;
8+
9+
impl ServerCertVerifier for NoCertificateVerification {
10+
fn verify_server_cert(
11+
&self,
12+
_end_entity: &CertificateDer<'_>,
13+
_intermediates: &[CertificateDer<'_>],
14+
server_name: &ServerName<'_>,
15+
ocsp_response: &[u8],
16+
now: UnixTime,
17+
) -> Result<ServerCertVerified, rustls::Error> {
18+
eprintln!("------------------ TLS SERVER CERT --------------------");
19+
eprintln!("server_name: {:?}", server_name);
20+
eprintln!("now: {:?}", now);
21+
eprintln!("ocsp_response length: {} bytes", ocsp_response.len());
22+
eprintln!("-------------------------------------------------------");
23+
Ok(ServerCertVerified::assertion())
24+
}
25+
26+
fn verify_tls12_signature(
27+
&self,
28+
_message: &[u8],
29+
_cert: &CertificateDer<'_>,
30+
_dss: &DigitallySignedStruct,
31+
) -> Result<HandshakeSignatureValid, rustls::Error> {
32+
Ok(HandshakeSignatureValid::assertion())
33+
}
34+
35+
fn verify_tls13_signature(
36+
&self,
37+
_message: &[u8],
38+
_cert: &CertificateDer<'_>,
39+
_dss: &DigitallySignedStruct,
40+
) -> Result<HandshakeSignatureValid, rustls::Error> {
41+
Ok(HandshakeSignatureValid::assertion())
42+
}
43+
44+
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
45+
// Support common schemes to ensure compatibility
46+
vec![
47+
SignatureScheme::RSA_PSS_SHA256,
48+
SignatureScheme::ECDSA_NISTP256_SHA256,
49+
SignatureScheme::ED25519,
50+
SignatureScheme::RSA_PKCS1_SHA256,
51+
]
52+
}
53+
}

src/main.rs

Lines changed: 42 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
mod insecure_verifier;
2+
13
use clap::Parser;
24
use colored::*;
35
use std::sync::Arc;
@@ -65,10 +67,13 @@ async fn main() -> anyhow::Result<()> {
6567

6668
let listener = tokio::net::TcpListener::bind(&args.listen).await?;
6769
let mut id: u64 = 0;
70+
let sep = "=".repeat(120).bright_yellow();
6871
loop {
6972
id = id + 1;
7073
let (client, addr) = listener.accept().await?;
74+
println!("{}", sep);
7175
println!("{}{} {}", "#".red(), id.to_string().red(), addr.to_string().red());
76+
println!("{}", sep);
7277
let cfg = args.clone();
7378
tokio::spawn(async move {
7479
if let Err(e) = proxy(id, client, cfg.clone()).await {
@@ -82,65 +87,16 @@ trait AsyncStream: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send +
8287

8388
impl<T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send + 'static> AsyncStream for T {}
8489

85-
use tokio_rustls::rustls;
86-
use tokio_rustls::rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
87-
use tokio_rustls::rustls::pki_types::{CertificateDer, ServerName, UnixTime};
88-
use tokio_rustls::rustls::{DigitallySignedStruct, SignatureScheme};
89-
90-
#[derive(Debug)]
91-
struct NoCertificateVerification;
92-
93-
impl ServerCertVerifier for NoCertificateVerification {
94-
fn verify_server_cert(
95-
&self,
96-
_end_entity: &CertificateDer<'_>,
97-
_intermediates: &[CertificateDer<'_>],
98-
_server_name: &ServerName<'_>,
99-
_ocsp_response: &[u8],
100-
_now: UnixTime,
101-
) -> Result<ServerCertVerified, rustls::Error> {
102-
// This is the "magic" line that bypasses the check
103-
Ok(ServerCertVerified::assertion())
104-
}
105-
106-
fn verify_tls12_signature(
107-
&self,
108-
_message: &[u8],
109-
_cert: &CertificateDer<'_>,
110-
_dss: &DigitallySignedStruct,
111-
) -> Result<HandshakeSignatureValid, rustls::Error> {
112-
Ok(HandshakeSignatureValid::assertion())
113-
}
114-
115-
fn verify_tls13_signature(
116-
&self,
117-
_message: &[u8],
118-
_cert: &CertificateDer<'_>,
119-
_dss: &DigitallySignedStruct,
120-
) -> Result<HandshakeSignatureValid, rustls::Error> {
121-
Ok(HandshakeSignatureValid::assertion())
122-
}
123-
124-
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
125-
// Support common schemes to ensure compatibility
126-
vec![
127-
SignatureScheme::RSA_PSS_SHA256,
128-
SignatureScheme::ECDSA_NISTP256_SHA256,
129-
SignatureScheme::ED25519,
130-
SignatureScheme::RSA_PKCS1_SHA256,
131-
]
132-
}
133-
}
13490
async fn connect(cfg: Args) -> anyhow::Result<Box<dyn AsyncStream>> {
13591
let upstream = tokio::net::TcpStream::connect(cfg.dest.clone()).await?;
13692
if !cfg.tls {
13793
return Ok(Box::new(upstream));
13894
}
13995

14096
// Set up the TLS config without verification
141-
let config = rustls::ClientConfig::builder()
97+
let config = tokio_rustls::rustls::ClientConfig::builder()
14298
.dangerous()
143-
.with_custom_certificate_verifier(Arc::new(NoCertificateVerification))
99+
.with_custom_certificate_verifier(Arc::new(insecure_verifier::NoCertificateVerification))
144100
.with_no_client_auth();
145101

146102
let connector = tokio_rustls::TlsConnector::from(Arc::new(config));
@@ -184,6 +140,8 @@ async fn connect(cfg: Args) -> anyhow::Result<Box<dyn AsyncStream>> {
184140
const BUFFER_SIZE: usize = 102400; // 100 KB
185141

186142
async fn proxy(id: u64, mut client: tokio::net::TcpStream, cfg: Args) -> anyhow::Result<()> {
143+
let start = std::time::Instant::now();
144+
187145
let upstream = connect(cfg.clone()).await?;
188146

189147
let (mut cr, mut cw) = client.split();
@@ -227,6 +185,10 @@ async fn proxy(id: u64, mut client: tokio::net::TcpStream, cfg: Args) -> anyhow:
227185

228186
tokio::try_join!(client_to_server, server_to_client)?;
229187

188+
let elapsed = start.elapsed();
189+
let msg = format!("#{} connection closed, elapsed: {:?}", id, elapsed);
190+
println!("{}", msg.bright_red());
191+
230192
Ok(())
231193
}
232194

@@ -247,19 +209,33 @@ fn fix_header(bf: &[u8], cfg: Args) -> Vec<u8> {
247209
}
248210
let (headers, body) = content.split_at(header_end_idx.unwrap());
249211
let mut lines: Vec<String> = headers.lines().map(|s| s.to_string()).collect();
250-
let mut host_found = false;
251212

252213
let domain = cfg.domain();
253-
214+
let mut host_found = false;
254215
// 遍历每一行查找 Host
255216
for line in lines.iter_mut() {
256217
if line.to_lowercase().starts_with("host:") {
218+
let msg = format!("[DEBUG] [FixHeader] replace ({} --> {})", line, domain);
219+
eprintln!("{}", msg.dimmed());
257220
*line = format!("Host: {}", domain);
258221
host_found = true;
259222
break;
260223
}
261224
}
262225

226+
// 禁用 Connection:keep-alive
227+
let mut connection_fount = false;
228+
for line in lines.iter_mut() {
229+
if line.to_lowercase().starts_with("connection:") {
230+
let msg = format!("[DEBUG] [FixHeader] replace ({} --> close)", line);
231+
eprintln!("{}", msg.dimmed());
232+
*line = "Connection: close".to_string();
233+
connection_fount = true;
234+
break;
235+
}
236+
}
237+
238+
// 禁用 gzip
263239
if cfg.strip_compression {
264240
for line in lines.iter_mut() {
265241
if line.to_lowercase().starts_with("accept-encoding:") {
@@ -273,7 +249,19 @@ fn fix_header(bf: &[u8], cfg: Args) -> Vec<u8> {
273249

274250
// 如果没找到 Host 字段,在第一行(请求行)之后插入
275251
if !host_found && lines.len() > 0 {
276-
lines.insert(1, format!("Host: {}", domain));
252+
let new_line = format!("Host: {}", domain);
253+
lines.insert(1, new_line.clone());
254+
255+
let msg = format!("[DEBUG] [FixHeader] Append ({})", new_line);
256+
eprintln!("{}", msg.dimmed());
257+
}
258+
259+
if !connection_fount && lines.len() > 0 {
260+
let new_line = "Connection: close".to_string();
261+
lines.insert(1, new_line.clone());
262+
263+
let msg = format!("[DEBUG] [FixHeader] Append ({})", new_line);
264+
eprintln!("{}", msg.dimmed());
277265
}
278266

279267
// 重新拼接 Request
@@ -372,38 +360,3 @@ fn print_binary(data: &[u8]) {
372360
println!("{}", "-".repeat(CHUNK_SIZE + 8).dimmed());
373361
}
374362
}
375-
376-
// todo: 修改为按照长度截取,每120个字符打印一次,分别打印为 Char 类型和 Hex 类型
377-
// fn print_binary(data: &[u8]){
378-
// // 按换行符 \n 切分,保留换行符在每一行末尾
379-
// let lines = data.split_inclusive(|&b| b == b'\n');
380-
//
381-
// for (idx, line) in lines.enumerate() {
382-
// // 1. 生成 Lossy 字符串预览
383-
// // 将不可见字符(除换行外)替换为点,防止终端控制符乱跳
384-
// let mut text_view = String::new();
385-
// for &b in line {
386-
// if b.is_ascii_graphic() || b == b' ' {
387-
// text_view.push(b as char);
388-
// } else if b == b'\n' {
389-
// text_view.push_str("\\n");
390-
// } else if b == b'\r' {
391-
// text_view.push_str("\\r");
392-
// } else {
393-
// text_view.push('·'); // 不可打印字符用弱化的点表示
394-
// }
395-
// }
396-
//
397-
// // 2. 生成 Hex 预览
398-
// let hex_view: String = line.iter()
399-
// .map(|b| format!("{:02x}", b))
400-
// .collect::<Vec<String>>()
401-
// .join(" ");
402-
//
403-
// // 3. 格式化输出
404-
// // 行号用灰色,文本部分用绿色,Hex 部分用黄色
405-
// println!("{:>3} | {:<40}",idx.to_string().dimmed(),text_view.green());
406-
// println!("{:>3} | {}", idx.to_string().dimmed(),hex_view.yellow().dimmed());
407-
// }
408-
// println!("{}", "--- End of Data ---".dimmed());
409-
// }

0 commit comments

Comments
 (0)