Add TLS to API server

This commit is contained in:
Ara Sadoyan
2025-06-09 18:06:16 +02:00
parent 9d604d62e7
commit a341fa30db
8 changed files with 76 additions and 6 deletions

31
Cargo.lock generated
View File

@@ -232,6 +232,26 @@ dependencies = [
"tracing",
]
[[package]]
name = "axum-server"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "495c05f60d6df0093e8fb6e74aa5846a0ad06abaf96d76166283720bf740f8ab"
dependencies = [
"arc-swap",
"bytes",
"fs-err",
"http",
"http-body",
"hyper",
"hyper-util",
"openssl",
"pin-project-lite",
"tokio",
"tokio-openssl",
"tower-service",
]
[[package]]
name = "backtrace"
version = "0.3.74"
@@ -707,6 +727,16 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fs-err"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d7be93788013f265201256d58f04936a8079ad5dc898743aa20525f503b683"
dependencies = [
"autocfg",
"tokio",
]
[[package]]
name = "fsevent-sys"
version = "4.1.0"
@@ -812,6 +842,7 @@ dependencies = [
"arc-swap",
"async-trait",
"axum",
"axum-server",
"base16ct",
"base64",
"dashmap",

View File

@@ -25,6 +25,7 @@ log = "0.4.27"
futures = "0.3.31"
notify = "8.0.0"
axum = { version = "0.8.4" }
axum-server = { version = "0.7.2", features = ["tls-openssl"] }
reqwest = { version = "0.12.15", features = ["json", "native-tls-alpn"] }
#reqwest = { version = "0.12.15", features = ["json", "rustls-tls"] }
#reqwest = { version = "0.12.15", default-features = false, features = ["rustls-tls", "json"] }

View File

@@ -8,6 +8,9 @@ pid_file: /tmp/gazan.pid # Path to PID file
error_log: /tmp/gazan_err.log # Path to error log
upgrade_sock: /tmp/gazan.sock # Path to socket file
config_address: 0.0.0.0:3000 # HTTP API address for pushing upstreams.yaml from remote location
config_tls_address: 0.0.0.0:3001 # HTTP TLS API address for pushing upstreams.yaml from remote location
config_tls_certificate: etc/server.crt # Mandatory if config_tls_address is set
config_tls_key_file: etc/key.pem # Mandatory if config_tls_address is set
proxy_address_http: 0.0.0.0:6193 # Proxy HTTP bind address
proxy_address_tls: 0.0.0.0:6194 # Optional, Proxy TLS bind address
tls_certificate: etc/server.crt # Mandatory if proxy_address_tls is set

View File

@@ -11,6 +11,9 @@ pub struct FromFileProvider {
pub struct APIUpstreamProvider {
pub address: String,
pub masterkey: String,
pub tls_address: Option<String>,
pub tls_certificate: Option<String>,
pub tls_key_file: Option<String>,
}
pub struct ConsulProvider {
@@ -25,7 +28,7 @@ pub trait Discovery {
#[async_trait]
impl Discovery for APIUpstreamProvider {
async fn start(&self, toreturn: Sender<Configuration>) {
webserver::run_server(self.address.clone(), self.masterkey.clone(), toreturn).await;
webserver::run_server(self, toreturn).await;
}
}

View File

@@ -150,5 +150,15 @@ pub fn parce_main_config(path: &str) -> AppConfig {
}
}
};
// match cfo.config_tls_address.clone() {
// Some(tls_cert) => {
// if let Some((ip, port_str)) = tls_cert.split_once(':') {
// if let Ok(port) = port_str.parse::<u16>() {
// cfo.local_tls_server = Option::from((ip.to_string(), port));
// }
// }
// }
// None => {}
// };
cfo
}

View File

@@ -65,9 +65,12 @@ pub struct AppConfig {
pub hc_method: String,
pub upstreams_conf: String,
pub log_level: String,
pub master_key: String,
pub config_address: String,
pub proxy_address_http: String,
pub master_key: String,
pub config_tls_address: Option<String>,
pub config_tls_certificate: Option<String>,
pub config_tls_key_file: Option<String>,
pub proxy_address_tls: Option<String>,
pub proxy_port_tls: Option<u16>,
pub tls_certificate: Option<String>,

View File

@@ -34,6 +34,9 @@ impl BackgroundService for LB {
let api_load = APIUpstreamProvider {
address: self.config.config_address.clone(),
masterkey: self.config.master_key.clone(),
tls_address: self.config.config_tls_address.clone(),
tls_certificate: self.config.config_tls_certificate.clone(),
tls_key_file: self.config.config_tls_key_file.clone(),
};
let tx_api = tx.clone();
let _ = tokio::spawn(async move { api_load.start(tx_api).await });

View File

@@ -1,3 +1,4 @@
use crate::utils::discovery::APIUpstreamProvider;
use crate::utils::structs::Configuration;
use axum::body::Body;
use axum::extract::{Query, State};
@@ -5,6 +6,7 @@ use axum::http::{Response, StatusCode};
use axum::response::IntoResponse;
use axum::routing::{delete, get, head, post, put};
use axum::{Json, Router};
use axum_server::tls_openssl::OpenSSLConfig;
use futures::channel::mpsc::Sender;
use futures::SinkExt;
use jsonwebtoken::{encode, EncodingKey, Header};
@@ -12,6 +14,7 @@ use log::{error, info, warn};
use prometheus::{gather, Encoder, TextEncoder};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::net::SocketAddr;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::net::TcpListener;
@@ -34,9 +37,9 @@ struct AppState {
}
#[allow(unused_mut)]
pub async fn run_server(bindaddress: String, master_key: String, mut to_return: Sender<Configuration>) {
pub async fn run_server(config: &APIUpstreamProvider, mut to_return: Sender<Configuration>) {
let app_state = AppState {
master_key: master_key.clone(),
master_key: config.masterkey.clone(),
config_sender: to_return.clone(),
};
let app = Router::new()
@@ -49,8 +52,21 @@ pub async fn run_server(bindaddress: String, master_key: String, mut to_return:
.route("/conf", post(conf))
.route("/metrics", get(metrics))
.with_state(app_state);
let listener = TcpListener::bind(bindaddress.clone()).await.unwrap();
info!("Starting the API server on: {}", bindaddress);
if let Some(value) = &config.tls_address {
let cf = OpenSSLConfig::from_pem_file(config.tls_certificate.clone().unwrap(), config.tls_key_file.clone().unwrap()).unwrap();
let addr: SocketAddr = value.parse().expect("Unable to parse socket address");
let tls_app = app.clone();
tokio::spawn(async move {
if let Err(e) = axum_server::bind_openssl(addr, cf).serve(tls_app.into_make_service()).await {
eprintln!("TLS server failed: {}", e);
}
});
info!("Starting the TLS API server on: {}", value);
}
let listener = TcpListener::bind(config.address.clone()).await.unwrap();
info!("Starting the API server on: {}", config.address);
axum::serve(listener, app).await.unwrap();
}