mirror of
https://github.com/jedisct1/encrypted-dns-server
synced 2024-11-12 13:10:44 +00:00
ADd a key cache and improve logging
This commit is contained in:
parent
f0c6235d33
commit
e681e43070
@ -77,6 +77,11 @@ tcp_max_active_connections = 100
|
||||
provider_name = "secure.dns.test"
|
||||
|
||||
|
||||
## Key cache capacity, per certificate
|
||||
|
||||
key_cache_capacity = 10000
|
||||
|
||||
|
||||
|
||||
###############################
|
||||
# TLS settings #
|
||||
|
@ -12,6 +12,7 @@ use tokio::prelude::*;
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct DNSCryptConfig {
|
||||
pub provider_name: String,
|
||||
pub key_cache_capacity: usize,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -60,9 +61,12 @@ pub struct State {
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(key_cache_capacity: usize) -> Self {
|
||||
let provider_kp = SignKeyPair::new();
|
||||
let dnscrypt_encryption_params_set = vec![DNSCryptEncryptionParams::new(&provider_kp)];
|
||||
let dnscrypt_encryption_params_set = vec![DNSCryptEncryptionParams::new(
|
||||
&provider_kp,
|
||||
key_cache_capacity,
|
||||
)];
|
||||
State {
|
||||
provider_kp,
|
||||
dnscrypt_encryption_params_set,
|
||||
@ -82,11 +86,14 @@ impl State {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
|
||||
pub fn from_file<P: AsRef<Path>>(path: P, key_cache_capacity: usize) -> Result<Self, Error> {
|
||||
let mut fp = File::open(path.as_ref())?;
|
||||
let mut state_bin = vec![];
|
||||
fp.read_to_end(&mut state_bin)?;
|
||||
let state = toml::from_slice(&state_bin)?;
|
||||
let mut state: State = toml::from_slice(&state_bin)?;
|
||||
for params_set in &mut state.dnscrypt_encryption_params_set {
|
||||
params_set.add_key_cache(key_cache_capacity);
|
||||
}
|
||||
Ok(state)
|
||||
}
|
||||
}
|
||||
|
@ -65,8 +65,31 @@ pub fn decrypt(
|
||||
|
||||
let mut nonce = [0u8; DNSCRYPT_FULL_NONCE_SIZE as usize];
|
||||
nonce[..DNSCRYPT_QUERY_NONCE_SIZE].copy_from_slice(client_nonce);
|
||||
let resolver_kp = dnscrypt_encryption_params.resolver_kp();
|
||||
let shared_key = resolver_kp.compute_shared_key(client_pk)?;
|
||||
|
||||
let cached_shared_key = {
|
||||
let mut cache = dnscrypt_encryption_params.cache.as_ref().unwrap().lock();
|
||||
match cache.get(&client_pk[..]) {
|
||||
None => None,
|
||||
Some(cached_shared_key) => Some((*cached_shared_key).clone()),
|
||||
}
|
||||
};
|
||||
let shared_key = match cached_shared_key {
|
||||
Some(cached_shared_key) => cached_shared_key,
|
||||
None => {
|
||||
let shared_key = dnscrypt_encryption_params
|
||||
.resolver_kp()
|
||||
.compute_shared_key(client_pk)?;
|
||||
let mut client_pk_ = [0u8; DNSCRYPT_QUERY_PK_SIZE];
|
||||
client_pk_.copy_from_slice(&client_pk[..]);
|
||||
dnscrypt_encryption_params
|
||||
.cache
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.insert(client_pk_, shared_key.clone());
|
||||
shared_key
|
||||
}
|
||||
};
|
||||
let packet = shared_key.decrypt(&nonce, encrypted_packet)?;
|
||||
rand::thread_rng().fill_bytes(&mut nonce[DNSCRYPT_QUERY_NONCE_SIZE..]);
|
||||
|
||||
|
@ -1,9 +1,13 @@
|
||||
use crate::config::*;
|
||||
use crate::crypto::*;
|
||||
use crate::dnscrypt::*;
|
||||
use crate::errors::*;
|
||||
use crate::globals::*;
|
||||
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use clockpro_cache::ClockProCache;
|
||||
use coarsetime::Clock;
|
||||
use parking_lot::Mutex;
|
||||
use std::mem;
|
||||
use std::slice;
|
||||
use std::sync::Arc;
|
||||
@ -90,22 +94,33 @@ impl DNSCryptCert {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[derive(Serialize, Deserialize, Clone, Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct DNSCryptEncryptionParams {
|
||||
dnscrypt_cert: DNSCryptCert,
|
||||
resolver_kp: CryptKeyPair,
|
||||
#[serde(skip)]
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub cache: Option<Arc<Mutex<ClockProCache<[u8; DNSCRYPT_QUERY_PK_SIZE], SharedKey>>>>,
|
||||
}
|
||||
|
||||
impl DNSCryptEncryptionParams {
|
||||
pub fn new(provider_kp: &SignKeyPair) -> Self {
|
||||
pub fn new(provider_kp: &SignKeyPair, cache_capacity: usize) -> Self {
|
||||
let resolver_kp = CryptKeyPair::new();
|
||||
let dnscrypt_cert = DNSCryptCert::new(&provider_kp, &resolver_kp);
|
||||
let cache = ClockProCache::new(cache_capacity).unwrap();
|
||||
DNSCryptEncryptionParams {
|
||||
dnscrypt_cert,
|
||||
resolver_kp,
|
||||
cache: Some(Arc::new(Mutex::new(cache))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_key_cache(&mut self, cache_capacity: usize) {
|
||||
let cache = ClockProCache::new(cache_capacity).unwrap();
|
||||
self.cache = Some(Arc::new(Mutex::new(cache)));
|
||||
}
|
||||
|
||||
pub fn client_magic(&self) -> &[u8] {
|
||||
self.dnscrypt_cert.client_magic()
|
||||
}
|
||||
@ -139,7 +154,10 @@ impl DNSCryptEncryptionParamsUpdater {
|
||||
}
|
||||
}
|
||||
}
|
||||
let new_params = DNSCryptEncryptionParams::new(&self.globals.provider_kp);
|
||||
let new_params = DNSCryptEncryptionParams::new(
|
||||
&self.globals.provider_kp,
|
||||
self.globals.key_cache_capacity,
|
||||
);
|
||||
new_params_set.push(Arc::new(new_params));
|
||||
let state = State {
|
||||
provider_kp: self.globals.provider_kp.clone(),
|
||||
@ -150,6 +168,7 @@ impl DNSCryptEncryptionParamsUpdater {
|
||||
let _ = state.async_save(state_file).await;
|
||||
});
|
||||
*self.globals.dnscrypt_encryption_params_set.write() = Arc::new(new_params_set);
|
||||
debug!("New certificate issued");
|
||||
}
|
||||
|
||||
pub async fn run(self) {
|
||||
|
@ -30,4 +30,5 @@ pub struct Globals {
|
||||
pub tcp_max_active_connections: u32,
|
||||
pub udp_active_connections: Arc<Mutex<VecDeque<oneshot::Sender<()>>>>,
|
||||
pub tcp_active_connections: Arc<Mutex<VecDeque<oneshot::Sender<()>>>>,
|
||||
pub key_cache_capacity: usize,
|
||||
}
|
||||
|
20
src/main.rs
20
src/main.rs
@ -369,7 +369,13 @@ async fn start(globals: Arc<Globals>, runtime: Arc<Runtime>) -> Result<(), Error
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
env_logger::init();
|
||||
env_logger::Builder::from_default_env()
|
||||
.default_format_module_path(false)
|
||||
.default_format_timestamp(false)
|
||||
.filter_level(log::LevelFilter::Info)
|
||||
.target(env_logger::Target::Stdout)
|
||||
.init();
|
||||
|
||||
crypto::init()?;
|
||||
let updater = coarsetime::Updater::new(1000).start()?;
|
||||
mem::forget(updater);
|
||||
@ -414,16 +420,17 @@ fn main() -> Result<(), Error> {
|
||||
runtime_builder.name_prefix("encrypted-dns-");
|
||||
let runtime = Arc::new(runtime_builder.build()?);
|
||||
|
||||
let key_cache_capacity = config.dnscrypt.key_cache_capacity;
|
||||
let state_file = &config.state_file;
|
||||
let state = match State::from_file(state_file) {
|
||||
let state = match State::from_file(state_file, key_cache_capacity) {
|
||||
Err(_) => {
|
||||
println!("No state file found... creating a new provider key");
|
||||
let state = State::new();
|
||||
warn!("No state file found... creating a new provider key");
|
||||
let state = State::new(key_cache_capacity);
|
||||
runtime.block_on(state.async_save(state_file))?;
|
||||
state
|
||||
}
|
||||
Ok(state) => {
|
||||
println!(
|
||||
info!(
|
||||
"State file [{}] found; using existing provider key",
|
||||
state_file.as_os_str().to_string_lossy()
|
||||
);
|
||||
@ -445,7 +452,7 @@ fn main() -> Result<(), Error> {
|
||||
.with_informal_property(InformalProperty::NoLogs)
|
||||
.serialize()
|
||||
.unwrap();
|
||||
println!("DNS Stamp: {}", stamp);
|
||||
info!("DNS Stamp: {}", stamp);
|
||||
}
|
||||
let dnscrypt_encryption_params_set = state
|
||||
.dnscrypt_encryption_params_set
|
||||
@ -477,6 +484,7 @@ fn main() -> Result<(), Error> {
|
||||
tcp_active_connections: Arc::new(Mutex::new(VecDeque::with_capacity(
|
||||
config.tcp_max_active_connections as _,
|
||||
))),
|
||||
key_cache_capacity,
|
||||
});
|
||||
let updater = DNSCryptEncryptionParamsUpdater::new(globals.clone());
|
||||
runtime.spawn(updater.run());
|
||||
|
Loading…
Reference in New Issue
Block a user