remove rustls
This commit is contained in:
parent
9689d2815c
commit
bb042d0f9d
11
Cargo.toml
11
Cargo.toml
@ -4,18 +4,11 @@ version = "0.1.2"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
openssl = { version = "0.10.68", optional = true }
|
||||
rustls = { version = "0.23.21", optional = true }
|
||||
rustls-pemfile = { version = "2.2.0", optional = true }
|
||||
openssl = "0.10.68"
|
||||
serde_yml = "0.0.12"
|
||||
log = "0.4.25"
|
||||
colog = "1.3.0"
|
||||
threadpool = "1.8.1"
|
||||
wildcard_ex = "0.1.2"
|
||||
websocket = "0.27.1"
|
||||
serde_json = "1.0.136"
|
||||
|
||||
[features]
|
||||
default = ["use-openssl"]
|
||||
use-openssl = ["dep:openssl"]
|
||||
use-rustls = ["dep:rustls", "dep:rustls-pemfile"]
|
||||
serde_json = "1.0.136"
|
@ -8,9 +8,10 @@ Features:
|
||||
- Sending IP in header (X-Real-IP)
|
||||
|
||||
TODO:
|
||||
- Rustls support
|
||||
- Remove panics
|
||||
- Creating trees of flowgate
|
||||
- Filter by headers
|
||||
- Modify response headers
|
||||
|
||||
## IP forwarding types
|
||||
|
||||
@ -27,10 +28,6 @@ TODO:
|
||||
|
||||
You need [Rust](https://www.rust-lang.org/) installed with cargo!
|
||||
|
||||
Rust features:
|
||||
- use-openssl
|
||||
- use-rustls ([rustls](https://github.com/rustls/rustls) - openssl alternative)
|
||||
|
||||
```sh
|
||||
cargo run # --------------------------------- # Run
|
||||
cargo run --release # ----------------------- # Run release
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub mod config;
|
||||
pub mod server;
|
||||
pub mod ssl_cert;
|
||||
pub mod closeable;
|
||||
pub mod websocket;
|
@ -1,21 +0,0 @@
|
||||
use std::net::{Shutdown, TcpStream};
|
||||
|
||||
#[cfg(feature = "use-openssl")]
|
||||
use openssl::ssl::SslStream;
|
||||
|
||||
pub trait Closeable {
|
||||
fn close(&self);
|
||||
}
|
||||
|
||||
impl Closeable for TcpStream {
|
||||
fn close(&self) {
|
||||
let _ = self.shutdown(Shutdown::Both);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-openssl")]
|
||||
impl<T: Closeable> Closeable for SslStream<T> {
|
||||
fn close(&self) {
|
||||
self.get_ref().close();
|
||||
}
|
||||
}
|
@ -3,14 +3,31 @@ use std::{
|
||||
};
|
||||
|
||||
use log::info;
|
||||
use openssl::ssl::SslStream;
|
||||
use threadpool::ThreadPool;
|
||||
|
||||
use super::{closeable::Closeable, config::{Config,SiteConfig,IpForwarding}};
|
||||
use super::config::{Config,SiteConfig,IpForwarding};
|
||||
|
||||
pub struct FlowgateServer {
|
||||
config: Arc<RwLock<Config>>,
|
||||
}
|
||||
|
||||
pub trait Closeable {
|
||||
fn close(&mut self);
|
||||
}
|
||||
|
||||
impl Closeable for SslStream<TcpStream> {
|
||||
fn close(&mut self) {
|
||||
let _ = self.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
impl Closeable for TcpStream {
|
||||
fn close(&mut self) {
|
||||
let _ = self.shutdown(std::net::Shutdown::Both);
|
||||
}
|
||||
}
|
||||
|
||||
struct Connection {
|
||||
stream: TcpStream,
|
||||
config: SiteConfig,
|
||||
@ -24,30 +41,34 @@ impl FlowgateServer {
|
||||
}
|
||||
|
||||
pub fn start(&self) {
|
||||
let pool = ThreadPool::new(self.config.read().unwrap().threadpool_size);
|
||||
let pool = Arc::new(pool);
|
||||
|
||||
thread::spawn({
|
||||
let config = Arc::clone(&self.config);
|
||||
let pool = Arc::clone(&pool);
|
||||
|
||||
move || {
|
||||
Self::run_http(config)
|
||||
Self::run_http(config, pool)
|
||||
}
|
||||
});
|
||||
|
||||
thread::spawn({
|
||||
let config = Arc::clone(&self.config);
|
||||
let pool = Arc::clone(&pool);
|
||||
|
||||
move || {
|
||||
Self::run_https(config)
|
||||
Self::run_https(config, pool)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn run_http(
|
||||
config: Arc<RwLock<Config>>
|
||||
config: Arc<RwLock<Config>>,
|
||||
pool: Arc<ThreadPool>
|
||||
) -> Option<()> {
|
||||
let listener = TcpListener::bind(&config.read().ok()?.http_host).ok()?;
|
||||
|
||||
let pool = ThreadPool::new(10);
|
||||
|
||||
info!("HTTP server runned on {}", &config.read().ok()?.http_host);
|
||||
|
||||
for stream in listener.incoming() {
|
||||
@ -75,9 +96,9 @@ impl FlowgateServer {
|
||||
Some(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-openssl")]
|
||||
pub fn run_https(
|
||||
config: Arc<RwLock<Config>>
|
||||
config: Arc<RwLock<Config>>,
|
||||
pool: Arc<ThreadPool>
|
||||
) -> Option<()> {
|
||||
use openssl::ssl::{NameType, SniError, SslAcceptor, SslAlert, SslMethod, SslRef};
|
||||
|
||||
@ -99,8 +120,6 @@ impl FlowgateServer {
|
||||
|
||||
let cert = cert.build();
|
||||
|
||||
let pool = ThreadPool::new(config.read().ok()?.threadpool_size);
|
||||
|
||||
info!("HTTPS server runned on {}", &config.read().ok()?.https_host);
|
||||
|
||||
for stream in listener.incoming() {
|
||||
@ -131,62 +150,6 @@ impl FlowgateServer {
|
||||
Some(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-rustls")]
|
||||
pub fn run_https(
|
||||
config: Arc<RwLock<Config>>
|
||||
) -> Option<()> {
|
||||
use std::sync::Arc;
|
||||
use rustls::{server::ResolvesServerCertUsingSni, ServerConfig};
|
||||
use super::ssl_cert::AdoptedConnection;
|
||||
|
||||
let listener = TcpListener::bind(&config.https_host).ok()?;
|
||||
|
||||
let mut cert_resolver = ResolvesServerCertUsingSni::new();
|
||||
|
||||
for site in config.sites.iter() {
|
||||
if let Some(cert) = site.ssl {
|
||||
cert_resolver.add(&site.domain, cert.get_certified_key());
|
||||
}
|
||||
}
|
||||
|
||||
let mut tls_config = Arc::new(
|
||||
ServerConfig::builder()
|
||||
.with_no_client_auth()
|
||||
.with_cert_resolver(Arc::new(cert_resolver))
|
||||
);
|
||||
|
||||
let pool = ThreadPool::new(10);
|
||||
|
||||
info!("HTTPS server runned on {}", &config.https_host);
|
||||
|
||||
for stream in listener.incoming() {
|
||||
pool.execute({
|
||||
let config = config.clone();
|
||||
let tls_config = tls_config.clone();
|
||||
|
||||
move || {
|
||||
let Ok(mut stream) = stream else { return };
|
||||
|
||||
let Ok(_) = stream.set_write_timeout(Some(Duration::from_secs(10))) else { return };
|
||||
let Ok(_) = stream.set_read_timeout(Some(Duration::from_secs(10))) else { return };
|
||||
|
||||
let Ok(addr) = stream.peer_addr() else { return };
|
||||
|
||||
let Some(mut stream) = AdoptedConnection::from_config(tls_config, stream) else { return };
|
||||
|
||||
Self::accept_stream(
|
||||
config,
|
||||
&mut stream,
|
||||
addr,
|
||||
true
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Some(())
|
||||
}
|
||||
|
||||
pub fn accept_stream(
|
||||
config: Arc<RwLock<Config>>,
|
||||
stream: &mut (impl Read + Write + Closeable),
|
||||
@ -211,9 +174,9 @@ impl FlowgateServer {
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn read_request<'a>(
|
||||
fn read_request(
|
||||
config: Arc<RwLock<Config>>,
|
||||
stream: &'a mut (impl Read + Write + Closeable),
|
||||
stream: &mut (impl Read + Write + Closeable),
|
||||
addr: SocketAddr,
|
||||
https: bool,
|
||||
conn: Option<Connection>
|
||||
|
@ -1,13 +1,10 @@
|
||||
#[cfg(feature = "use-openssl")]
|
||||
use openssl::ssl::SslContext;
|
||||
|
||||
#[cfg(feature = "use-openssl")]
|
||||
#[derive(Clone)]
|
||||
pub struct SslCert {
|
||||
context: SslContext,
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-openssl")]
|
||||
fn generate_ctx(cert_file: &str, key_file: &str) -> Option<SslContext> {
|
||||
use openssl::ssl::{SslFiletype, SslMethod};
|
||||
|
||||
@ -18,7 +15,6 @@ fn generate_ctx(cert_file: &str, key_file: &str) -> Option<SslContext> {
|
||||
Some(ctx.build())
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-openssl")]
|
||||
impl SslCert {
|
||||
pub fn new(cert_file: &str, key_file: &str) -> Option<SslCert> {
|
||||
Some(SslCert {
|
||||
@ -29,83 +25,4 @@ impl SslCert {
|
||||
pub fn get_context(&self) -> SslContext {
|
||||
self.context.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-rustls")]
|
||||
use rustls::{sign::CertifiedKey, server::Acceptor, ServerConfig, ServerConnection};
|
||||
#[cfg(feature = "use-rustls")]
|
||||
use std::{net::TcpStream, sync::Arc};
|
||||
|
||||
#[cfg(feature = "use-rustls")]
|
||||
#[derive(Clone)]
|
||||
pub struct SslCert {
|
||||
cert_key: CertifiedKey,
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-rustls")]
|
||||
fn generate_cert_key(cert_file: &str, key_file: &str) -> Option<CertifiedKey> {
|
||||
use rustls::crypto::CryptoProvider;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
||||
let key = rustls_pemfile::private_key(&mut BufReader::new(File::open(key_file).ok()?)).ok()??;
|
||||
let key = CryptoProvider::get_default().unwrap().key_provider.load_private_key(key).ok()?;
|
||||
|
||||
let cert =
|
||||
rustls_pemfile::public_keys(&mut BufReader::new(File::open(cert_file).ok()?))
|
||||
.map(|o| o.unwrap().to_vec().into())
|
||||
.collect::<Vec<_>>();
|
||||
Some(CertifiedKey::new(cert, key))
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-rustls")]
|
||||
impl SslCert {
|
||||
pub fn new(cert_file: &str, key_file: &str) -> Option<SslCert> {
|
||||
Some(SslCert {
|
||||
cert_key: generate_cert_key(cert_file, key_file)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_certified_key(&self) -> CertifiedKey {
|
||||
self.cert_key.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-rustls")]
|
||||
pub struct AdoptedConnection {
|
||||
server_connection: ServerConnection,
|
||||
stream: TcpStream
|
||||
}
|
||||
|
||||
#[cfg(feature = "use-rustls")]
|
||||
impl AdoptedConnection {
|
||||
pub fn new(
|
||||
server_connection: ServerConnection,
|
||||
stream: TcpStream
|
||||
) -> AdoptedConnection {
|
||||
AdoptedConnection {
|
||||
server_connection,
|
||||
stream
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_config(
|
||||
server_config: Arc<ServerConfig>,
|
||||
mut stream: TcpStream
|
||||
) -> Option<AdoptedConnection> {
|
||||
let mut acceptor = Acceptor::default();
|
||||
let accepted = loop {
|
||||
acceptor.read_tls(&mut stream).ok()?;
|
||||
if let Some(accepted) = acceptor.accept().ok()? {
|
||||
break accepted;
|
||||
}
|
||||
};
|
||||
|
||||
Some(AdoptedConnection {
|
||||
server_connection: accepted.into_connection(server_config).ok()?,
|
||||
stream
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement Read and Write and Closeable to AdoptedConnection
|
||||
}
|
Loading…
Reference in New Issue
Block a user