diff --git a/Cargo.toml b/Cargo.toml index 1b9e2bd..6c357f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "encrypted-dns" -version = "0.2.10" +version = "0.3.0" authors = ["Frank Denis "] edition = "2018" description = "A modern encrypted DNS server (DNSCrypt v2, Anonymized DNSCrypt, DoH)" @@ -21,7 +21,7 @@ derivative = "1.0.3" dnsstamps = "0.1.2" env_logger = { version="0.7.0", default-features = false, features = ["humantime"]} failure = "0.1.6" -futures-preview = { version = "=0.3.0-alpha.19", features = ["async-await", "unstable", "cfg-target-has-atomic"] } +futures-preview = { version = "=0.3.0-alpha.19", features = ["async-await"] } jemallocator = "0.3.2" libsodium-sys-stable="1.18.1" log = { version = "0.4.8", features = ["std", "release_max_level_debug"] } diff --git a/README.md b/README.md index 3966a1c..c82d490 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ An easy to install, high-performance, zero maintenance proxy to run an encrypted The proxy aims at supporting the following protocols: - [DNSCrypt v2](https://github.com/DNSCrypt/dnscrypt-protocol/blob/master/DNSCRYPT-V2-PROTOCOL.txt) -- [Anonymized DNSCrypt](https://github.com/DNSCrypt/dnscrypt-protocol/blob/master/ANONYMIZED-DNSCRYPT.txt) (WIP) +- [Anonymized DNSCrypt](https://github.com/DNSCrypt/dnscrypt-protocol/blob/master/ANONYMIZED-DNSCRYPT.txt) - DNS-over-HTTP (DoH) All of these can be served simultaneously, on the same port (usually port 443). The proxy automatically detects what protocol is being used by each client. @@ -108,3 +108,7 @@ Domains can be filtered directly by the proxy, see the `[filtering]` section of ## Prometheus metrics Prometheus metrics can optionally be enabled in order to monitor performance, cache efficiency, and more. + +## Anonymized DNSCrypt + +Enabling Anonymized DNSCrypt allows the server to be used as an encrypted DNS relay. diff --git a/example-encrypted-dns.toml b/example-encrypted-dns.toml index 042723b..50d3f13 100644 --- a/example-encrypted-dns.toml +++ b/example-encrypted-dns.toml @@ -189,4 +189,17 @@ key_cache_capacity = 10000 [anonymized_dns] + +# Enable relaying support for Anonymized DNS + enabled = false + + +# Allowed upstream ports + +allowed_ports = [ 443 ] + + +# Blacklisted upstream IP addresses + +blacklisted_ips = [ "93.184.216.34" ] \ No newline at end of file diff --git a/src/anonymized_dns.rs b/src/anonymized_dns.rs index 6f3ac34..c0b5a57 100644 --- a/src/anonymized_dns.rs +++ b/src/anonymized_dns.rs @@ -39,8 +39,15 @@ pub async fn handle_anonymized_dns( globals.varz.anonymized_queries.inc(); ensure!(ip.is_global(), "Forbidden upstream address"); + ensure!( + !globals.anonymized_dns_blacklisted_ips.contains(&ip), + "Blacklisted upstream IP" + ); let port = BigEndian::read_u16(&encrypted_packet[16..18]); - ensure!([443].contains(&port), "Forbidden upstream port"); + ensure!( + globals.anonymized_dns_allowed_ports.contains(&port), + "Forbidden upstream port" + ); let upstream_address = SocketAddr::new(ip, port); ensure!( !globals.listen_addrs.contains(&upstream_address) diff --git a/src/config.rs b/src/config.rs index 11f849a..3101ea5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,6 +12,8 @@ use tokio::prelude::*; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct AnonymizedDNSConfig { pub enabled: bool, + pub allowed_ports: Vec, + pub blacklisted_ips: Vec, } #[cfg(feature = "metrics")] diff --git a/src/globals.rs b/src/globals.rs index 1a99b70..67d44d4 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -8,7 +8,7 @@ use crate::varz::*; use parking_lot::{Mutex, RwLock}; use siphasher::sip128::SipHasher13; use std::collections::vec_deque::VecDeque; -use std::net::SocketAddr; +use std::net::{IpAddr, SocketAddr}; use std::path::PathBuf; use std::sync::atomic::AtomicU32; use std::sync::Arc; @@ -40,8 +40,10 @@ pub struct Globals { pub hasher: SipHasher13, pub cache: Cache, pub blacklist: Option, + pub anonymized_dns_enabled: bool, + pub anonymized_dns_allowed_ports: Vec, + pub anonymized_dns_blacklisted_ips: Vec, #[cfg(feature = "metrics")] #[derivative(Debug = "ignore")] pub varz: Varz, - pub anonymized_dns_enabled: bool, } diff --git a/src/main.rs b/src/main.rs index 7a0cfa5..de99742 100644 --- a/src/main.rs +++ b/src/main.rs @@ -557,6 +557,16 @@ fn main() -> Result<(), Error> { } let stamp = stamp.serialize().unwrap(); info!("DNS Stamp: {}", stamp); + + if let Some(anonymized_dns) = &config.anonymized_dns { + if anonymized_dns.enabled { + let relay_stamp = dnsstamps::DNSCryptRelayBuilder::new() + .with_addr(listen_addr_s.external.to_string()) + .serialize() + .unwrap(); + info!("DNS Stamp for Anonymized DNS relaying: {}", relay_stamp); + } + } } if matches.is_present("dry-run") { return Ok(()); @@ -584,10 +594,16 @@ fn main() -> Result<(), Error> { .map_err(|e| format_err!("Unable to load the blacklist [{:?}]: [{}]", path, e))?, ), }; - let anonymized_dns_enabled = match config.anonymized_dns { - None => false, - Some(anonymized_dns) => anonymized_dns.enabled, - }; + let (anonymized_dns_enabled, anonymized_dns_allowed_ports, anonymized_dns_blacklisted_ips) = + match config.anonymized_dns { + None => (false, vec![], vec![]), + Some(anonymized_dns) => ( + anonymized_dns.enabled, + anonymized_dns.allowed_ports, + anonymized_dns.blacklisted_ips, + ), + }; + let globals = Arc::new(Globals { runtime: runtime.clone(), state_file: state_file.to_path_buf(), @@ -616,9 +632,11 @@ fn main() -> Result<(), Error> { hasher, cache, blacklist, + anonymized_dns_enabled, + anonymized_dns_allowed_ports, + anonymized_dns_blacklisted_ips, #[cfg(feature = "metrics")] varz: Varz::default(), - anonymized_dns_enabled, }); let updater = DNSCryptEncryptionParamsUpdater::new(globals.clone()); if !state_is_new {