2
0
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:
Frank Denis 2019-09-20 10:39:42 +02:00
parent f0c6235d33
commit e681e43070
6 changed files with 78 additions and 15 deletions

View File

@ -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 #

View File

@ -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)
}
}

View File

@ -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..]);

View File

@ -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) {

View File

@ -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,
}

View File

@ -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());