Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TLS support for http #39

Merged
merged 17 commits into from
May 30, 2022
746 changes: 522 additions & 224 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ members = ["chaos-tproxy-controller", "chaos-tproxy-proxy", "tests"]
anyhow = "1.0"
clap = "2.33.3"
futures = "0.3.10"
http = "0.2.3"
http = "0.2.7"
humantime-serde = "1.0"
hyper = {git = "https://github.com/Andrewmatilde/hyper.git", features = ["runtime", "client", "server", "http1", "http2", "stream", "error_return"]}
iptables = "0.4"
Expand All @@ -44,6 +44,12 @@ bincode = "1.3.3"
default-net = "0.9.0"
system_gateway = {git="https://github.com/aruntomar/system_gateway"}
base64 = "0.13.0"
tokio-rustls = "0.23.4"
rustls = "0.20.4"
derivative = "2.2.0"
rustls-pemfile = "1.0.0"
webpki-roots = "0.22"
hyper-rustls = { git = "https://github.com/Andrewmatilde/hyper-rustls.git", features = ["http2"] }
rtnetlink = "0.9.1"
iproute2-rs = {git="https://github.com/chaos-mesh/iproute2-rs.git"}
futures-util = "0.3"
Expand Down
12 changes: 9 additions & 3 deletions chaos-tproxy-controller/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ path = "src/lib.rs"
anyhow = "1.0"
clap = "2.33.3"
futures = "0.3.10"
http = "0.2.3"
http = "0.2.7"
humantime-serde = "1.0"
hyper = {version = "0.14.4", features = ["runtime", "client", "server", "http1", "http2", "stream"]}
hyper = {git = "https://github.com/Andrewmatilde/hyper.git", features = ["runtime", "client", "server", "http1", "http2", "stream", "error_return"]}
iptables = "0.4"
libc = {version = "0.2.81", features = ["std"]}
paw = "1.0"
Expand Down Expand Up @@ -45,4 +45,10 @@ pnet = "0.28.0"
default-net = "0.9.0"
rtnetlink = "0.9.1"
iproute2-rs = {git="https://github.com/chaos-mesh/iproute2-rs.git"}
system_gateway = {git="https://github.com/aruntomar/system_gateway"}
system_gateway = {git="https://github.com/aruntomar/system_gateway"}
tokio-rustls = "0.23.4"
rustls = "0.20.4"
derivative = "2.2.0"
rustls-pemfile = "1.0.0"
webpki-roots = "0.22"
hyper-rustls = { git = "https://github.com/Andrewmatilde/hyper-rustls.git", features = ["http2"] }
9 changes: 7 additions & 2 deletions chaos-tproxy-controller/src/proxy/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ impl TryFrom<RawConfig> for Config {
Some(rules) => rules,
None => vec![],
},
tls: raw.tls,
},
})
}
Expand Down Expand Up @@ -76,6 +77,7 @@ mod tests {
safe_mode: None,
interface: None,
rules: None,
tls: None,

listen_port: None,
proxy_mark: None,
Expand All @@ -92,7 +94,8 @@ mod tests {
listen_port: get_free_port(None).unwrap(),
safe_mode: false,
interface: None,
rules: vec![]
rules: vec![],
tls: None
}
}
);
Expand All @@ -102,6 +105,7 @@ mod tests {
safe_mode: Some(true),
interface: Some("ens33".parse().unwrap()),
rules: None,
tls: None,

listen_port: None,
proxy_mark: None,
Expand All @@ -118,7 +122,8 @@ mod tests {
listen_port: 1027u16,
safe_mode: true,
interface: Some("ens33".parse().unwrap()),
rules: vec![]
rules: vec![],
tls: None
}
}
);
Expand Down
3 changes: 2 additions & 1 deletion chaos-tproxy-controller/src/raw_config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use chaos_tproxy_proxy::raw_config::RawRule;
use chaos_tproxy_proxy::raw_config::{RawRule, TLSRawConfig};
use serde::{Deserialize, Serialize};

#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize, Default)]
Expand All @@ -8,6 +8,7 @@ pub struct RawConfig {
pub safe_mode: Option<bool>,
pub interface: Option<String>,
pub rules: Option<Vec<RawRule>>,
pub tls: Option<TLSRawConfig>,

// Useless options now. Keep these options for upward compatible.
pub listen_port: Option<u16>,
Expand Down
8 changes: 7 additions & 1 deletion chaos-tproxy-proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ edition = "2018"
anyhow = "1.0"
clap = "2.33.3"
futures = "0.3.10"
http = "0.2.3"
http = "0.2.7"
humantime-serde = "1.0"
hyper = {git = "https://github.com/Andrewmatilde/hyper.git", features = ["runtime", "client", "server", "http1", "http2", "stream", "error_return"]}
iptables = "0.4"
Expand All @@ -34,5 +34,11 @@ bincode = "1.3.3"
tempfile = "3.2.0"
uuid = { version = "0.8", features = ["serde", "v4"] }
base64 = "0.13.0"
tokio-rustls = "0.23.4"
rustls = "0.20.4"
derivative = "2.2.0"
rustls-pemfile = "1.0.0"
webpki-roots = "0.22"
hyper-rustls = { git = "https://github.com/Andrewmatilde/hyper-rustls.git", features = ["http2"] }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can use dependency override to replace hyper globally instead of modifying it in each dependency.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not the common use case of dependency override

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lucky, something we need just merged rust-lang/cargo#10497

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know what's the problem , I will fix it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems dependency override not fix the problem.

rtnetlink = "0.9.1"
futures-util = "0.3"
16 changes: 15 additions & 1 deletion chaos-tproxy-proxy/src/proxy/http/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
use rustls::{ClientConfig, ServerConfig};

use crate::handler::http::rule::Rule;

#[derive(Debug, Clone)]
#[derive(Clone)]
pub struct Config {
pub http_config: HTTPConfig,
pub tls_config: Option<TLSConfig>,
Hexilee marked this conversation as resolved.
Show resolved Hide resolved
}

#[derive(Clone, Debug)]
pub struct HTTPConfig {
pub proxy_port: u16,
pub rules: Vec<Rule>,
}

#[derive(Clone)]
pub struct TLSConfig {
pub tls_client_config: ClientConfig,
pub tls_server_config: ServerConfig,
}
42 changes: 6 additions & 36 deletions chaos-tproxy-proxy/src/proxy/http/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ use std::net::SocketAddr;
use std::pin::Pin;
use std::task::{Context, Poll};

use anyhow::{anyhow, Error, Result};
use http::uri::Scheme;
use anyhow::{Error, Result};
use http::Uri;
use hyper::client::connect::dns::GaiResolver;
use hyper::service::Service;
use tokio::net::TcpStream;
use tracing::{instrument, trace};
Expand All @@ -15,22 +13,20 @@ use crate::proxy::tcp::transparent_socket::TransparentSocket;

#[derive(Debug, Clone)]
pub struct HttpConnector {
resolver: GaiResolver,
target: SocketAddr,
socket: TransparentSocket,
}

impl HttpConnector {
pub fn new(src: SocketAddr) -> Self {
pub fn new(dst: SocketAddr,src: SocketAddr) -> Self {
Self {
resolver: GaiResolver::new(),
target: dst,
socket: TransparentSocket::new(src),
}
}

async fn connect(mut self, dist: Uri) -> Result<TcpStream> {
let addr = resolve(&mut self.resolver, &dist).await?;
trace!("resolved addr({})", dist);
Ok(self.socket.conn(addr).await?)
async fn connect(self, _: Uri) -> Result<TcpStream> {
Ok(self.socket.conn(self.target).await?)
}
}

Expand All @@ -43,7 +39,6 @@ impl Service<Uri> for HttpConnector {

#[instrument]
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
futures::ready!(self.resolver.poll_ready(cx))?;
trace!("connector is ready");
Poll::Ready(Ok(()))
}
Expand All @@ -53,28 +48,3 @@ impl Service<Uri> for HttpConnector {
Box::pin(self.clone().connect(dst))
}
}

/// This function resolve uri and select uri with scheme like `http://`
/// and get host addrs and dst port from Uri.
pub(crate) async fn resolve(resolver: &mut GaiResolver, dst: &Uri) -> Result<SocketAddr, Error> {
if dst
.scheme()
.filter(|scheme| **scheme != Scheme::HTTP)
.is_some()
{
return Err(anyhow!("https connector cannot handle http request"));
}

let host = dst
.host()
.ok_or_else(|| anyhow!("target uri has no host"))?;
let mut addrs = resolver.call(host.parse()?).await?;
let mut addr = addrs
.next()
.ok_or_else(|| anyhow!("cannot resolve {}", host))?;

if let Some(port) = dst.port() {
addr.set_port(port.as_u16());
}
Ok(addr)
}
Loading