feat: v1.0.3, add log4rs
This commit is contained in:
@@ -17,6 +17,7 @@ mod yubikey_hmac;
|
||||
#[cfg(feature = "yubikey")]
|
||||
mod yubikey_init_master_key;
|
||||
mod serve_datakey;
|
||||
mod serve_log;
|
||||
|
||||
pub struct DefaultCommandImpl;
|
||||
|
||||
@@ -62,6 +63,8 @@ fn inner_main() -> CommandError {
|
||||
{
|
||||
#[cfg(feature = "yubikey")]
|
||||
features.push("yubikey".to_string());
|
||||
#[cfg(feature = "harden_process")]
|
||||
features.push("harden_process".to_string());
|
||||
}
|
||||
let long_about = format!("Local mini KMS, features: [{}]", features.join(", "));
|
||||
let mut app = App::new(env!("CARGO_PKG_NAME"))
|
||||
|
||||
28
src/serve.rs
28
src/serve.rs
@@ -1,5 +1,3 @@
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::server::conn::AddrStream;
|
||||
@@ -8,10 +6,11 @@ use hyper::{Body, Client, Method, Request, Response, Server, StatusCode};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use rust_util::{failure_and_exit, information, success, warning, XResult};
|
||||
use serde_json::{json, Value};
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
use crate::serve_common::{self, GenericError, MemoryKey, Result};
|
||||
use crate::serve_encrypt_decrypt;
|
||||
use crate::serve_init;
|
||||
use crate::serve_init::InitRequest;
|
||||
use crate::serve_read_write;
|
||||
@@ -20,6 +19,11 @@ use crate::serve_status;
|
||||
use crate::yubikey_hmac;
|
||||
use crate::{db, jose, proc};
|
||||
use crate::{do_response, serve_datakey};
|
||||
use crate::{serve_encrypt_decrypt, serve_log};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref GLOBAL_REQUEST_COUNT: AtomicU64 = AtomicU64::new(0);
|
||||
}
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
@@ -32,9 +36,18 @@ impl Command for CommandImpl {
|
||||
.arg(Arg::with_name("local-db").long("local-db").short("d").takes_value(true).default_value("local-mini-kms.db").help("Local db file"))
|
||||
.arg(Arg::with_name("yubikey-challenge").long("yubikey-challenge").short("c").takes_value(true).help("Yubikey challenge"))
|
||||
.arg(Arg::with_name("init-encrypted-master-key").long("init-encrypted-master-key").short("k").takes_value(true).help("Init encrypted mater key"))
|
||||
.arg(Arg::with_name("log-level").long("log-level").takes_value(true).help("Log level: trace, debug, info, warn or error"))
|
||||
.arg(Arg::with_name("log-file").long("log-file").takes_value(true).help("Log file #DEFAULT or config file"))
|
||||
}
|
||||
|
||||
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
let log_level = sub_arg_matches.value_of("log-level");
|
||||
let log_file = sub_arg_matches.value_of("log-file");
|
||||
|
||||
if let Err(e) = serve_log::init_logger(log_level, log_file) {
|
||||
println!("[ERROR] Init logger failed: {}", e);
|
||||
}
|
||||
|
||||
let local_mini_kms_db = sub_arg_matches.value_of("local-db").expect("Get local mini kms db error");
|
||||
match init_instance(local_mini_kms_db) {
|
||||
Ok(true) => success!("Init server success"),
|
||||
@@ -61,6 +74,7 @@ impl Command for CommandImpl {
|
||||
});
|
||||
let server = Server::bind(&addr).serve(new_service);
|
||||
information!("Listening on http://{}", addr);
|
||||
log::info!("Listening on http://{}", addr);
|
||||
match server.await {
|
||||
Err(e) => failure_and_exit!("Server error: {}", e),
|
||||
Ok(_) => success!("Server ended"),
|
||||
@@ -77,11 +91,13 @@ async fn response_requests(
|
||||
req: Request<Body>,
|
||||
_client: Client<HttpConnector>,
|
||||
) -> Result<Response<Body>> {
|
||||
let request_idx = GLOBAL_REQUEST_COUNT.fetch_add(1, Ordering::Relaxed);
|
||||
let process = proc::get_process(remote_addr.port());
|
||||
match process {
|
||||
None => information!( "Receive request: {}, from: {}", req.uri(), remote_addr ),
|
||||
Some(process) => information!(
|
||||
"Receive request: {}, from: {}, process: {} {} {:?}",
|
||||
None => log::info!( "Receive request: {}, from: {}", req.uri(), remote_addr ),
|
||||
Some(process) => log::info!(
|
||||
"[{:06}] Receive request: {}, from: {}, process: {} {} {:?}",
|
||||
request_idx,
|
||||
req.uri(),
|
||||
remote_addr,
|
||||
process.pid,
|
||||
|
||||
@@ -133,7 +133,7 @@ pub fn byte_to_multi_view_map(bytes: &[u8], with_value: bool) -> Map<String, Val
|
||||
pub fn open_local_db() -> XResult<Connection> {
|
||||
let startup_rw_lock = STATUP_RW_LOCK.lock().expect("Lock read startup rw lock error");
|
||||
match &*startup_rw_lock {
|
||||
None => simple_error!("Db is not initted!"),
|
||||
None => simple_error!("Db is not initiated!"),
|
||||
Some(k) => {
|
||||
Ok(opt_result!(db::open_db(& k.database_file), "Open db failed: {}"))
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use base64::Engine;
|
||||
use hyper::body::Buf;
|
||||
use hyper::{Body, Request, Response, StatusCode};
|
||||
use rand::random;
|
||||
use rust_util::{debugging, iff, XResult};
|
||||
use rust_util::{iff, XResult};
|
||||
use seckey::SecBytes;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
@@ -32,7 +32,7 @@ async fn inner_generate(req: Request<Body>) -> XResult<(StatusCode, Value)> {
|
||||
let whole_body = hyper::body::aggregate(req).await?;
|
||||
let request: DataKeyRequest = serde_json::from_reader(whole_body.reader())?;
|
||||
|
||||
debugging!("Generate data key: {} {}", &request.r#type, &request.spec);
|
||||
log::debug!("Generate data key: {} {}", &request.r#type, &request.spec);
|
||||
let key = match get_master_key() {
|
||||
None => return serve_common::error("status_not_ready"),
|
||||
Some(key) => key,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use hyper::body::Buf;
|
||||
use hyper::{Body, Request, Response, StatusCode};
|
||||
use rust_util::{debugging, XResult};
|
||||
use rust_util::XResult;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Map, Value};
|
||||
|
||||
@@ -21,7 +21,7 @@ async fn inner_decrypt(req: Request<Body>) -> XResult<(StatusCode, Value)> {
|
||||
let whole_body = hyper::body::aggregate(req).await?;
|
||||
let data: DecryptRequest = serde_json::from_reader(whole_body.reader())?;
|
||||
|
||||
debugging!("To be decrypted value: {}", &data.encrypted_value);
|
||||
log::debug!("To be decrypted value: {}", &data.encrypted_value);
|
||||
let key = match get_master_key() {
|
||||
None => return serve_common::error("status_not_ready"),
|
||||
Some(key) => key,
|
||||
|
||||
@@ -2,7 +2,7 @@ use base64::engine::general_purpose::STANDARD;
|
||||
use base64::Engine;
|
||||
use hyper::body::Buf;
|
||||
use hyper::{Body, Request, Response, StatusCode};
|
||||
use rust_util::{debugging, information, opt_result, success, warning, XResult};
|
||||
use rust_util::{opt_result, XResult};
|
||||
use seckey::SecBytes;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
@@ -48,7 +48,7 @@ pub async fn inner_init_request(init_request: InitRequest) -> XResult<(StatusCod
|
||||
} else if let Some(clear_master_key_hex) = init_request.clear_master_key_hex {
|
||||
hex::decode(clear_master_key_hex)?
|
||||
} else if let Some(encrypted_master_key) = init_request.encrypted_master_key {
|
||||
debugging!("Received encrypted master key: {}", encrypted_master_key);
|
||||
log::debug!("Received encrypted master key: {}", encrypted_master_key);
|
||||
if let Some(k) = &*startup_rw_lock {
|
||||
let (clear_master_key, _) = jose::deserialize_jwe_rsa(&encrypted_master_key, &k.instance_rsa_key_pair)?;
|
||||
clear_master_key
|
||||
@@ -76,19 +76,19 @@ pub async fn inner_init_request(init_request: InitRequest) -> XResult<(StatusCod
|
||||
db::insert_key(&conn, &key)?;
|
||||
}
|
||||
Some(key) => {
|
||||
debugging!("Found jwe: {}", &key.encrypted_key);
|
||||
log::debug!("Found jwe: {}", &key.encrypted_key);
|
||||
let _ = opt_result!(jose::deserialize_jwe_aes(&key.encrypted_key, &clear_master_key), "Deserialize master key verification key failed: {}");
|
||||
}
|
||||
}
|
||||
information!("Set master key success");
|
||||
log::info!("Set master key success");
|
||||
|
||||
#[cfg(feature = "yubikey")]
|
||||
if let Some(yubikey_challenge) = &init_request.yubikey_challenge {
|
||||
match yubikey_hmac::yubikey_challenge_as_32_bytes(yubikey_challenge.as_bytes()) {
|
||||
Err(e) => warning!("Yubikey challenge failed: {}", e),
|
||||
Err(e) => log::warn!("Yubikey challenge failed: {}", e),
|
||||
Ok(challenge_key) => match jose::serialize_jwe_aes(&clear_master_key, &challenge_key) {
|
||||
Err(e) => warning!("Yubikey seal master key failed: {}", e),
|
||||
Ok(jwe) => success!("Yubikey sealed master key: {}", jwe)
|
||||
Err(e) => log::warn!("Yubikey seal master key failed: {}", e),
|
||||
Ok(jwe) => log::info!("Yubikey sealed master key: {}", jwe)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
66
src/serve_log.rs
Normal file
66
src/serve_log.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
use log::LevelFilter;
|
||||
use rust_util::{simple_error, XResult};
|
||||
use std::{env, fs};
|
||||
|
||||
const DEFAULT_LOG4RS_CONFIG: &str = r##"refresh_rate: 10 seconds
|
||||
appenders:
|
||||
file:
|
||||
kind: rolling_file
|
||||
path: "log/local_mini_kms_log.log"
|
||||
append: true
|
||||
encoder:
|
||||
pattern: "{d} - {m}{n}"
|
||||
policy:
|
||||
kind: compound
|
||||
trigger:
|
||||
kind: size
|
||||
limit: 100 mb
|
||||
roller:
|
||||
kind: fixed_window
|
||||
pattern: log/local_mini_kms_log.{}.log
|
||||
count: 10
|
||||
root:
|
||||
level: info
|
||||
appenders:
|
||||
- file"##;
|
||||
|
||||
pub fn init_logger(log_level: Option<&str>, log4rs_file: Option<&str>) -> XResult<()> {
|
||||
match log4rs_file {
|
||||
None => {
|
||||
let level = match env::var("LOGGER").ok().as_deref().map(get_log_level_filter) {
|
||||
Some(Ok(level)) => level,
|
||||
_ => log_level.map(get_log_level_filter).unwrap_or(Ok(LevelFilter::Debug))?,
|
||||
};
|
||||
let _ = env_logger::builder().filter_level(level).try_init();
|
||||
}
|
||||
Some(log4rs_file) => {
|
||||
let log4rs_config_file = if log4rs_file == "#DEFAULT" {
|
||||
let default_log4rs_file = "default_log4rs.yaml";
|
||||
let _ = fs::metadata(default_log4rs_file).map_err(|_| {
|
||||
fs::write(default_log4rs_file, DEFAULT_LOG4RS_CONFIG).map_err(|e| {
|
||||
println!("Write file: {} failed: {}", default_log4rs_file, e);
|
||||
})
|
||||
});
|
||||
default_log4rs_file
|
||||
} else {
|
||||
log4rs_file
|
||||
};
|
||||
log4rs::init_file(log4rs_config_file, Default::default())?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn get_log_level_filter(log_level: &str) -> XResult<LevelFilter> {
|
||||
Ok(match log_level {
|
||||
"trace" => LevelFilter::Trace,
|
||||
"debug" => LevelFilter::Debug,
|
||||
"info" => LevelFilter::Info,
|
||||
"warn" => LevelFilter::Warn,
|
||||
"error" => LevelFilter::Error,
|
||||
_ => {
|
||||
return simple_error!("invalid log_level");
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user