Compare commits

...

48 Commits

Author SHA1 Message Date
Frank Denis 822c73e26f
Merge pull request #253 from DNSCrypt/dependabot/cargo/sieve-cache-0.2.0
Bump sieve-cache from 0.1.4 to 0.2.0
2 weeks ago
dependabot[bot] b6b2353d59
Bump sieve-cache from 0.1.4 to 0.2.0
Bumps [sieve-cache](https://github.com/jedisct1/rust-sieve-cache) from 0.1.4 to 0.2.0.
- [Commits](https://github.com/jedisct1/rust-sieve-cache/commits/0.2.0)

---
updated-dependencies:
- dependency-name: sieve-cache
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks ago
Frank Denis 6f93f5cf7f Update deps 2 weeks ago
Frank Denis 058781cb9e Update deps 1 month ago
Frank Denis 1b56119744 Update deps 1 month ago
Frank Denis 5979876dc7 Update Cargo.lock 1 month ago
Frank Denis 99d8517ea7 Merge branch 'master' of github.com:jedisct1/rust-dnscrypt-server
* 'master' of github.com:jedisct1/rust-dnscrypt-server:
  Bump rustls from 0.22.2 to 0.22.4
1 month ago
Frank Denis 6c8dbfbf10 Add fritz.box to undelegated zones 1 month ago
Frank Denis 0789909ceb
Merge pull request #241 from DNSCrypt/dependabot/cargo/rustls-0.22.4
Bump rustls from 0.22.2 to 0.22.4
1 month ago
dependabot[bot] 82f21df279
Bump rustls from 0.22.2 to 0.22.4
Bumps [rustls](https://github.com/rustls/rustls) from 0.22.2 to 0.22.4.
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.22.2...v/0.22.4)

---
updated-dependencies:
- dependency-name: rustls
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
Frank Denis 7da1e42ac7 Update deps 3 months ago
Frank Denis ab7a76af4b Update libsodium-sys-stable 3 months ago
Frank Denis c7a739f966 Bump 3 months ago
Frank Denis aac90e243b Merge branch 'master' of github.com:jedisct1/rust-dnscrypt-server
* 'master' of github.com:jedisct1/rust-dnscrypt-server:
  Add note about domain filtering not working with the tls upstream_addr option
3 months ago
Frank Denis 5d03c77ab8 Update deps 3 months ago
Frank Denis 07c3f90ad5
Merge pull request #75 from dapphp/master
Add note about domain filtering not working with the tls upstream_addr option
3 months ago
Frank Denis cee7168976 Update softprops/action-gh-release 3 months ago
Frank Denis cefbfb497a Update a couple deps 3 months ago
Frank Denis 996e6cd2ec
Merge pull request #231 from lifenjoiner/ci 5 months ago
YX Hao b66fce7978 Update CI actions version 5 months ago
Frank Denis 9ceb72da92 Ignore 5 months ago
Frank Denis f67ba113de Bump 5 months ago
Frank Denis 11fa174f80 2024 5 months ago
Frank Denis 2b98b4c6ca Format 5 months ago
Frank Denis 7a22e94e32 Switch from clockpro-cache to sieve-cache 5 months ago
Frank Denis 3feb000d62 Doh 5 months ago
Frank Denis c3ff5170b2 Update deps 5 months ago
Frank Denis 971bb2fd14 Update deps 8 months ago
Frank Denis 89a8460936 Remove the need for unsafe_unwrap 9 months ago
Frank Denis 66167649a3 Update deps 9 months ago
Frank Denis 6ba9d36dcf Add a debug mode 10 months ago
Frank Denis 07d12e1606 Update deps 10 months ago
Frank Denis 5c4c6c181e The first byte of QUIC packets is in the [64,127] range. 10 months ago
Frank Denis 5a95346c52 Bump 11 months ago
Frank Denis 74b2745982 Update deps 11 months ago
Frank Denis e9946cd40f Add "mail" to the undelegated names
We already had home.arpa

See https://github.com/DNSCrypt/dnscrypt-proxy/pull/2438
11 months ago
Frank Denis 2068aa4a93 Bump hyper, again 1 year ago
Frank Denis c0667c0626 Update deps, especially Hyper 1 year ago
Frank Denis 610f71320c Update deps 1 year ago
Frank Denis 5a29c43ffa Update deps 1 year ago
Frank Denis 80cdaaad24 Better nail down where QUIC is possibly being used 1 year ago
Frank Denis 606276398c Mention where we actually may have a QUIC/HTTP/3 packet
We may want to support QUIC the same way we forward TLS
1 year ago
Frank Denis 5c1dcebe10 Update deps 1 year ago
Frank Denis 0706ad1fc1
Merge pull request #186 from DNSCrypt/dependabot/cargo/toml-0.7.1
Bump toml from 0.7.0 to 0.7.1
1 year ago
dependabot[bot] ddc761e2a4
Bump toml from 0.7.0 to 0.7.1
Bumps [toml](https://github.com/toml-rs/toml) from 0.7.0 to 0.7.1.
- [Release notes](https://github.com/toml-rs/toml/releases)
- [Commits](https://github.com/toml-rs/toml/compare/toml-v0.7.0...toml-v0.7.1)

---
updated-dependencies:
- dependency-name: toml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
Frank Denis 54b9c772a4 Remove old badge 1 year ago
Frank Denis 5e9e44f884 Update CI badge link 1 year ago
dapphp e4f81a1c13 Add note about domain filtering not working with the tls upstream_addr option 3 years ago

@ -29,11 +29,11 @@ jobs:
ARCHIVE_PATH: encrypted-dns_${{ github.ref_name }}_${{ matrix.target_alias }}${{ matrix.archive_suffix }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: goto-bus-stop/setup-zig@v2
- uses: hecrj/setup-rust-action@master
- uses: hecrj/setup-rust-action@v2
with:
rust-version: stable
targets: ${{ matrix.target }}
@ -63,12 +63,12 @@ jobs:
cargo install cargo-deb
cargo deb --output=encrypted-dns_${{ github.ref_name }}_amd64.deb --no-build
- uses: actions/upload-artifact@master
- uses: actions/upload-artifact@v4
with:
name: encrypted-dns_${{ matrix.target_alias }}
path: ${{ env.ARCHIVE_PATH }}
- uses: actions/upload-artifact@master
- uses: actions/upload-artifact@v4
if: ${{ matrix.os == 'ubuntu-20.04' }}
with:
name: encrypted-dns_deb-amd64
@ -81,10 +81,10 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
- name: Create release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:

@ -10,8 +10,8 @@ jobs:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@master
- uses: hecrj/setup-rust-action@master
- uses: actions/checkout@v4
- uses: hecrj/setup-rust-action@v2
with:
rust-version: nightly
- name: Check Cargo availability

2
.gitignore vendored

@ -3,3 +3,5 @@
/target/
encrypted-dns.state
encrypted-dns.toml
a.rb
sizes.txt

929
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
[package]
name = "encrypted-dns"
version = "0.9.12"
version = "0.9.15"
authors = ["Frank Denis <github@pureftpd.org>"]
edition = "2018"
description = "A modern encrypted DNS server (DNSCrypt v2, Anonymized DNSCrypt, DoH)"
@ -12,41 +12,41 @@ categories = ["asynchronous", "network-programming", "command-line-utilities"]
readme = "README.md"
[dependencies]
anyhow = "1.0.68"
byteorder = "1.4.3"
clap = { version = "3.2.23", default-features = false, features = [
anyhow = "1.0.86"
byteorder = "1.5.0"
clap = { version = "3.2.25", default-features = false, features = [
"std",
"cargo",
"wrap_help",
] }
clockpro-cache = "0.1.10"
coarsetime = "0.1.22"
coarsetime = "0.1.34"
daemonize-simple = "0.1.5"
derivative = "2.2.0"
dnsstamps = "0.1.9"
env_logger = { version = "0.10.0", default-features = false, features = [
env_logger = { version = "0.11.3", default-features = false, features = [
"humantime",
] }
futures = { version = "0.3.26", features = ["async-await"] }
hyper = { version = "0.14.23", default-features = false, features = [
futures = { version = "0.3.30", features = ["async-await"] }
hyper = { version = "0.14.28", default-features = false, features = [
"server",
"http1",
], optional = true }
ipext = "0.1.0"
libsodium-sys-stable = "1.19.27"
log = { version = "0.4.17", features = ["std", "release_max_level_debug"] }
mimalloc = { version = "0.1.34", default-features = false }
socket2 = "0.4.7"
parking_lot = "0.12.1"
libsodium-sys-stable = "1.20.8"
log = { version = "0.4.21", features = ["std", "release_max_level_debug"] }
mimalloc = { version = "0.1.42", default-features = false }
socket2 = "0.5.7"
parking_lot = "0.12.2"
rand = "0.8.5"
rlimit = "0.9.1"
rlimit = "0.10.1"
rustc-hash = "1.1.0"
serde = "1.0.152"
serde_derive = "1.0.152"
serde-big-array = "0.4.1"
siphasher = "0.3.10"
slabigator = "0.2.0"
tokio = { version = "1.25.0", features = [
serde = "1.0.202"
serde_derive = "1.0.202"
serde-big-array = "0.5.1"
sieve-cache = "0.2.0"
siphasher = "1.0.1"
slabigator = "0.9.2"
tokio = { version = "1.37.0", features = [
"net",
"io-std",
"io-util",
@ -54,10 +54,10 @@ tokio = { version = "1.25.0", features = [
"time",
"rt-multi-thread"
] }
toml = "0.7.0"
toml = "0.8.13"
[target.'cfg(target_family = "unix")'.dependencies]
privdrop = "0.5.3"
privdrop = "0.5.4"
[dependencies.prometheus]
optional = true

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2019-2023 Frank Denis
Copyright (c) 2019-2024 Frank Denis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

@ -1,5 +1,5 @@
# ![Encrypted DNS Server](logo.png)
![Github CI status](https://img.shields.io/github/workflow/status/jedisct1/encrypted-dns-server/Rust)
![Github CI status](https://img.shields.io/github/actions/workflow/status/jedisct1/encrypted-dns-server/test.yml?branch=master)
[![Gitter chat](https://badges.gitter.im/gitter.svg)](https://gitter.im/dnscrypt-operators/Lobby)
An easy to install, high-performance, zero maintenance proxy to run an encrypted DNS server.
@ -97,7 +97,7 @@ Putting it in a directory that is only readable by the super-user is not a bad i
## Filtering
Domains can be filtered directly by the proxy, see the `[filtering]` section of the configuration file.
Domains can be filtered directly by the proxy, see the `[filtering]` section of the configuration file. Note: Filtering only works with the DNSCrypt protocol and does not apply to DNS-over-HTTP (DoH) forwarding.
## Access control

@ -1,8 +1,8 @@
use std::sync::Arc;
use clockpro_cache::ClockProCache;
use coarsetime::{Duration, Instant};
use parking_lot::{Mutex, MutexGuard};
use sieve_cache::SieveCache;
use crate::dns;
@ -55,7 +55,7 @@ impl CachedResponse {
#[derivative(Debug)]
pub struct Cache {
#[derivative(Debug = "ignore")]
cache: Arc<Mutex<ClockProCache<u128, CachedResponse>>>,
cache: Arc<Mutex<SieveCache<u128, CachedResponse>>>,
pub ttl_min: u32,
pub ttl_max: u32,
pub ttl_error: u32,
@ -63,13 +63,13 @@ pub struct Cache {
impl Cache {
pub fn new(
clockpro_cache: ClockProCache<u128, CachedResponse>,
sieve_cache: SieveCache<u128, CachedResponse>,
ttl_min: u32,
ttl_max: u32,
ttl_error: u32,
) -> Self {
Cache {
cache: Arc::new(Mutex::new(clockpro_cache)),
cache: Arc::new(Mutex::new(sieve_cache)),
ttl_min,
ttl_max,
ttl_error,
@ -77,7 +77,7 @@ impl Cache {
}
#[inline]
pub fn lock(&self) -> MutexGuard<'_, ClockProCache<u128, CachedResponse>> {
pub fn lock(&self) -> MutexGuard<'_, SieveCache<u128, CachedResponse>> {
self.cache.lock()
}
}

@ -126,3 +126,7 @@ pub fn encrypt(
)?;
Ok(wrapped_packet)
}
pub fn may_be_quic(packet: &[u8]) -> bool {
!packet.is_empty() && ((80..=127).contains(&packet[0]) || (192..=255).contains(&packet[0]))
}

@ -4,10 +4,10 @@ use std::sync::Arc;
use std::time::SystemTime;
use byteorder::{BigEndian, ByteOrder};
use clockpro_cache::ClockProCache;
use parking_lot::Mutex;
use rand::prelude::*;
use serde_big_array::BigArray;
use sieve_cache::SieveCache;
use crate::anonymized_dns::*;
use crate::config::*;
@ -108,7 +108,7 @@ pub struct DNSCryptEncryptionParams {
resolver_kp: CryptKeyPair,
#[serde(skip)]
#[derivative(Debug = "ignore")]
pub key_cache: Option<Arc<Mutex<ClockProCache<[u8; DNSCRYPT_QUERY_PK_SIZE], SharedKey>>>>,
pub key_cache: Option<Arc<Mutex<SieveCache<[u8; DNSCRYPT_QUERY_PK_SIZE], SharedKey>>>>,
}
impl DNSCryptEncryptionParams {
@ -140,7 +140,7 @@ impl DNSCryptEncryptionParams {
}
if now >= ts_start {
let dnscrypt_cert = DNSCryptCert::new(provider_kp, &resolver_kp, ts_start);
let cache = ClockProCache::new(key_cache_capacity).unwrap();
let cache = SieveCache::new(key_cache_capacity).unwrap();
active_params.push(DNSCryptEncryptionParams {
dnscrypt_cert,
resolver_kp,
@ -154,7 +154,7 @@ impl DNSCryptEncryptionParams {
let ts_start = now - (now % DNSCRYPT_CERTS_RENEWAL);
let resolver_kp = CryptKeyPair::from_seed(seed);
let dnscrypt_cert = DNSCryptCert::new(provider_kp, &resolver_kp, ts_start);
let cache = ClockProCache::new(key_cache_capacity).unwrap();
let cache = SieveCache::new(key_cache_capacity).unwrap();
active_params.push(DNSCryptEncryptionParams {
dnscrypt_cert,
resolver_kp,
@ -165,7 +165,7 @@ impl DNSCryptEncryptionParams {
}
pub fn add_key_cache(&mut self, cache_capacity: usize) {
let cache = ClockProCache::new(cache_capacity).unwrap();
let cache = SieveCache::new(cache_capacity).unwrap();
self.key_cache = Some(Arc::new(Mutex::new(cache)));
}

@ -49,7 +49,6 @@ use blacklist::*;
use byteorder::{BigEndian, ByteOrder};
use cache::*;
use clap::Arg;
use clockpro_cache::ClockProCache;
use config::*;
use crypto::*;
use dns::*;
@ -66,6 +65,7 @@ use parking_lot::RwLock;
#[cfg(target_family = "unix")]
use privdrop::PrivDrop;
use rand::prelude::*;
use sieve_cache::SieveCache;
use siphasher::sip128::SipHasher13;
use slabigator::Slab;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
@ -196,23 +196,31 @@ async fn handle_client_query(
Ok(x) => x,
Err(_) => {
let packet = encrypted_packet;
if let Some(synth_packet) = serve_certificates(
match serve_certificates(
&packet,
&globals.provider_name,
&dnscrypt_encryption_params_set,
)? {
return encrypt_and_respond_to_query(
globals,
client_ctx,
packet,
synth_packet,
original_packet_size,
None,
None,
)
.await;
}
bail!("Unencrypted query");
) {
Ok(Some(synth_packet)) => {
return encrypt_and_respond_to_query(
globals,
client_ctx,
packet,
synth_packet,
original_packet_size,
None,
None,
)
.await
}
Ok(None) => return Ok(()),
Err(_) => {
if may_be_quic(&packet) {
bail!("Likely a QUIC packet") // RFC 9443
}
bail!("Unencrypted query or different protocol")
}
};
}
};
ensure!(packet.len() >= DNS_HEADER_SIZE, "Short packet");
@ -345,12 +353,16 @@ async fn tcp_acceptor(globals: Arc<Globals>, tcp_listener: TcpListener) -> Resul
#[cfg(feature = "metrics")]
varz.inflight_tcp_queries.set(_count.saturating_sub(1) as _);
if let Ok(Either::Right(_)) = either {
if let Ok(Either::Right(e)) = either {
// Removing the active connection was already done during
// cancellation.
debug!("TCP query canceled: {:?}", e.0)
} else {
let mut active_connections = active_connections.lock();
_ = active_connections.remove(tx_channel_index);
if let Ok(Either::Left(e)) = either {
debug!("TCP query error: {:?}", e.0)
}
}
}));
}
@ -406,12 +418,16 @@ async fn udp_acceptor(
#[cfg(feature = "metrics")]
varz.inflight_udp_queries.set(_count.saturating_sub(1) as _);
if let Ok(Either::Right(_)) = either {
if let Ok(Either::Right(e)) = either {
// Removing the active connection was already done during
// cancellation.
debug!("UDP query canceled: {:?}", e.0)
} else {
let mut active_connections = active_connections.lock();
_ = active_connections.remove(tx_channel_index);
if let Ok(Either::Left(e)) = either {
debug!("UDP query error: {:?}", e.0)
}
}
}));
}
@ -557,16 +573,6 @@ fn set_limits(config: &Config) -> Result<(), Error> {
}
fn main() -> Result<(), Error> {
env_logger::Builder::from_default_env()
.write_style(env_logger::WriteStyle::Never)
.format_module_path(false)
.format_timestamp(None)
.filter_level(log::LevelFilter::Info)
.target(env_logger::Target::Stdout)
.init();
crypto::init()?;
let time_updater = coarsetime::Updater::new(1000).start()?;
let matches = clap::command!()
.arg(
Arg::new("config")
@ -590,8 +596,31 @@ fn main() -> Result<(), Error> {
.takes_value(false)
.help("Only print the connection information and quit"),
)
.arg(
Arg::new("debug")
.long("debug")
.takes_value(false)
.help("Enable debug logs"),
)
.get_matches();
let log_level = if matches.is_present("debug") {
log::LevelFilter::Debug
} else {
log::LevelFilter::Info
};
env_logger::Builder::from_default_env()
.write_style(env_logger::WriteStyle::Never)
.format_module_path(false)
.format_timestamp(None)
.filter_level(log_level)
.target(env_logger::Target::Stdout)
.init();
crypto::init()?;
let time_updater = coarsetime::Updater::new(1000).start()?;
let config_path = matches.value_of("config").unwrap();
let config = Config::from_path(config_path)?;
if let Err(e) = set_limits(&config) {
@ -706,14 +735,14 @@ fn main() -> Result<(), Error> {
let hasher = SipHasher13::new_with_keys(sh_k0, sh_k1);
let cache = Cache::new(
ClockProCache::new(cache_capacity)
SieveCache::new(cache_capacity)
.map_err(|e| anyhow!("Unable to create the DNS cache: [{}]", e))?,
config.cache_ttl_min,
config.cache_ttl_max,
config.cache_ttl_error,
);
let cert_cache = Cache::new(
ClockProCache::new(RELAYED_CERT_CACHE_SIZE)
SieveCache::new(RELAYED_CERT_CACHE_SIZE)
.map_err(|e| anyhow!("Unable to create the relay cert cache: [{}]", e))?,
RELAYED_CERT_CACHE_TTL,
RELAYED_CERT_CACHE_TTL,

@ -111,6 +111,7 @@ domain
envoy
example
f.f.ip6.arpa
fritz.box
grp
gw==
home
@ -128,6 +129,7 @@ local
localdomain
localhost
localnet
mail
modem
mynet
myrouter

Loading…
Cancel
Save