remove rustls
This commit is contained in:
parent
9689d2815c
commit
bb042d0f9d
@ -4,9 +4,7 @@ version = "0.1.2"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
openssl = { version = "0.10.68", optional = true }
|
openssl = "0.10.68"
|
||||||
rustls = { version = "0.23.21", optional = true }
|
|
||||||
rustls-pemfile = { version = "2.2.0", optional = true }
|
|
||||||
serde_yml = "0.0.12"
|
serde_yml = "0.0.12"
|
||||||
log = "0.4.25"
|
log = "0.4.25"
|
||||||
colog = "1.3.0"
|
colog = "1.3.0"
|
||||||
@ -14,8 +12,3 @@ threadpool = "1.8.1"
|
|||||||
wildcard_ex = "0.1.2"
|
wildcard_ex = "0.1.2"
|
||||||
websocket = "0.27.1"
|
websocket = "0.27.1"
|
||||||
serde_json = "1.0.136"
|
serde_json = "1.0.136"
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["use-openssl"]
|
|
||||||
use-openssl = ["dep:openssl"]
|
|
||||||
use-rustls = ["dep:rustls", "dep:rustls-pemfile"]
|
|
@ -8,9 +8,10 @@ Features:
|
|||||||
- Sending IP in header (X-Real-IP)
|
- Sending IP in header (X-Real-IP)
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- Rustls support
|
|
||||||
- Remove panics
|
- Remove panics
|
||||||
- Creating trees of flowgate
|
- Creating trees of flowgate
|
||||||
|
- Filter by headers
|
||||||
|
- Modify response headers
|
||||||
|
|
||||||
## IP forwarding types
|
## IP forwarding types
|
||||||
|
|
||||||
@ -27,10 +28,6 @@ TODO:
|
|||||||
|
|
||||||
You need [Rust](https://www.rust-lang.org/) installed with cargo!
|
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
|
```sh
|
||||||
cargo run # --------------------------------- # Run
|
cargo run # --------------------------------- # Run
|
||||||
cargo run --release # ----------------------- # Run release
|
cargo run --release # ----------------------- # Run release
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod ssl_cert;
|
pub mod ssl_cert;
|
||||||
pub mod closeable;
|
|
||||||
pub mod websocket;
|
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 log::info;
|
||||||
|
use openssl::ssl::SslStream;
|
||||||
use threadpool::ThreadPool;
|
use threadpool::ThreadPool;
|
||||||
|
|
||||||
use super::{closeable::Closeable, config::{Config,SiteConfig,IpForwarding}};
|
use super::config::{Config,SiteConfig,IpForwarding};
|
||||||
|
|
||||||
pub struct FlowgateServer {
|
pub struct FlowgateServer {
|
||||||
config: Arc<RwLock<Config>>,
|
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 {
|
struct Connection {
|
||||||
stream: TcpStream,
|
stream: TcpStream,
|
||||||
config: SiteConfig,
|
config: SiteConfig,
|
||||||
@ -24,30 +41,34 @@ impl FlowgateServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(&self) {
|
pub fn start(&self) {
|
||||||
|
let pool = ThreadPool::new(self.config.read().unwrap().threadpool_size);
|
||||||
|
let pool = Arc::new(pool);
|
||||||
|
|
||||||
thread::spawn({
|
thread::spawn({
|
||||||
let config = Arc::clone(&self.config);
|
let config = Arc::clone(&self.config);
|
||||||
|
let pool = Arc::clone(&pool);
|
||||||
|
|
||||||
move || {
|
move || {
|
||||||
Self::run_http(config)
|
Self::run_http(config, pool)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
thread::spawn({
|
thread::spawn({
|
||||||
let config = Arc::clone(&self.config);
|
let config = Arc::clone(&self.config);
|
||||||
|
let pool = Arc::clone(&pool);
|
||||||
|
|
||||||
move || {
|
move || {
|
||||||
Self::run_https(config)
|
Self::run_https(config, pool)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_http(
|
pub fn run_http(
|
||||||
config: Arc<RwLock<Config>>
|
config: Arc<RwLock<Config>>,
|
||||||
|
pool: Arc<ThreadPool>
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
let listener = TcpListener::bind(&config.read().ok()?.http_host).ok()?;
|
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);
|
info!("HTTP server runned on {}", &config.read().ok()?.http_host);
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
@ -75,9 +96,9 @@ impl FlowgateServer {
|
|||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "use-openssl")]
|
|
||||||
pub fn run_https(
|
pub fn run_https(
|
||||||
config: Arc<RwLock<Config>>
|
config: Arc<RwLock<Config>>,
|
||||||
|
pool: Arc<ThreadPool>
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
use openssl::ssl::{NameType, SniError, SslAcceptor, SslAlert, SslMethod, SslRef};
|
use openssl::ssl::{NameType, SniError, SslAcceptor, SslAlert, SslMethod, SslRef};
|
||||||
|
|
||||||
@ -99,8 +120,6 @@ impl FlowgateServer {
|
|||||||
|
|
||||||
let cert = cert.build();
|
let cert = cert.build();
|
||||||
|
|
||||||
let pool = ThreadPool::new(config.read().ok()?.threadpool_size);
|
|
||||||
|
|
||||||
info!("HTTPS server runned on {}", &config.read().ok()?.https_host);
|
info!("HTTPS server runned on {}", &config.read().ok()?.https_host);
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
@ -131,62 +150,6 @@ impl FlowgateServer {
|
|||||||
Some(())
|
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(
|
pub fn accept_stream(
|
||||||
config: Arc<RwLock<Config>>,
|
config: Arc<RwLock<Config>>,
|
||||||
stream: &mut (impl Read + Write + Closeable),
|
stream: &mut (impl Read + Write + Closeable),
|
||||||
@ -211,9 +174,9 @@ impl FlowgateServer {
|
|||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_request<'a>(
|
fn read_request(
|
||||||
config: Arc<RwLock<Config>>,
|
config: Arc<RwLock<Config>>,
|
||||||
stream: &'a mut (impl Read + Write + Closeable),
|
stream: &mut (impl Read + Write + Closeable),
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
https: bool,
|
https: bool,
|
||||||
conn: Option<Connection>
|
conn: Option<Connection>
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
#[cfg(feature = "use-openssl")]
|
|
||||||
use openssl::ssl::SslContext;
|
use openssl::ssl::SslContext;
|
||||||
|
|
||||||
#[cfg(feature = "use-openssl")]
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SslCert {
|
pub struct SslCert {
|
||||||
context: SslContext,
|
context: SslContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "use-openssl")]
|
|
||||||
fn generate_ctx(cert_file: &str, key_file: &str) -> Option<SslContext> {
|
fn generate_ctx(cert_file: &str, key_file: &str) -> Option<SslContext> {
|
||||||
use openssl::ssl::{SslFiletype, SslMethod};
|
use openssl::ssl::{SslFiletype, SslMethod};
|
||||||
|
|
||||||
@ -18,7 +15,6 @@ fn generate_ctx(cert_file: &str, key_file: &str) -> Option<SslContext> {
|
|||||||
Some(ctx.build())
|
Some(ctx.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "use-openssl")]
|
|
||||||
impl SslCert {
|
impl SslCert {
|
||||||
pub fn new(cert_file: &str, key_file: &str) -> Option<SslCert> {
|
pub fn new(cert_file: &str, key_file: &str) -> Option<SslCert> {
|
||||||
Some(SslCert {
|
Some(SslCert {
|
||||||
@ -30,82 +26,3 @@ impl SslCert {
|
|||||||
self.context.clone()
|
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