Configurable multiple dns resolvers

This commit is contained in:
Slatian
2023-08-04 00:00:21 +02:00
parent cd8c0455dc
commit 104a072fd6
7 changed files with 441 additions and 100 deletions

99
src/config/dns.rs Normal file
View File

@ -0,0 +1,99 @@
use serde::{Deserialize,Serialize};
use trust_dns_resolver::config::Protocol;
use trust_dns_resolver::Name;
use std::collections::HashMap;
use std::net::SocketAddr;
#[derive(Deserialize, Clone)]
pub struct DnsConfig {
pub allow_forward_lookup: bool,
pub allow_reverse_lookup: bool,
pub hidden_suffixes: Vec<String>,
#[serde(default="default_dns_resolver_name")]
pub default_resolver: String,
pub resolver: HashMap<String,DnsResolverConfig>,
}
#[derive(Deserialize, Serialize, Clone)]
pub enum DnsProtocol {
Udp,
Tcp,
Tls,
Https,
Quic,
}
pub fn default_dns_resolver_name() -> String {
"default".to_string()
}
#[derive(Deserialize, Serialize, Clone)]
pub struct DnsResolverConfig {
pub display_name: String,
#[serde(default="zero")]
pub weight: i32,
pub servers: Vec<SocketAddr>,
#[serde(default)]
pub search: Vec<String>,
pub protocol: DnsProtocol,
pub tls_dns_name: Option<String>,
pub bind_address: Option<SocketAddr>,
#[serde(default="default_true")]
pub trust_nx_responses: bool,
}
fn zero() -> i32 {
return 0;
}
fn default_true() -> bool {
return true;
}
impl Default for DnsConfig {
fn default() -> Self {
DnsConfig {
allow_forward_lookup: true,
allow_reverse_lookup: false,
hidden_suffixes: Vec::new(),
default_resolver: "default".to_string(),
resolver: Default::default(),
}
}
}
impl Into<Protocol> for DnsProtocol {
fn into(self) -> Protocol {
match self {
Self::Udp => Protocol::Udp,
Self::Tcp => Protocol::Tcp,
Self::Tls => Protocol::Tls,
Self::Https => Protocol::Https,
Self::Quic => Protocol::Quic,
}
}
}
impl DnsResolverConfig {
pub fn to_trust_resolver_config(&self) -> trust_dns_resolver::config::ResolverConfig {
let mut resolver = trust_dns_resolver::config::ResolverConfig::new();
for server in &self.servers {
resolver.add_name_server(trust_dns_resolver::config::NameServerConfig{
socket_addr: *server,
protocol: self.protocol.clone().into(),
tls_dns_name: self.tls_dns_name.clone(),
trust_nx_responses: self.trust_nx_responses,
tls_config: None,
bind_addr: self.bind_address,
});
}
for search in &self.search {
if let Ok(name) = Name::from_str_relaxed(search) {
resolver.add_search(name);
}
}
return resolver;
}
}

88
src/config/mod.rs Normal file
View File

@ -0,0 +1,88 @@
use axum_client_ip::SecureClientIpSource;
use serde::Deserialize;
use std::net::SocketAddr;
use std::num::NonZeroU32;
mod dns;
pub use crate::config::dns::{DnsConfig, DnsProtocol, DnsResolverConfig};
#[derive(Deserialize, Default, Clone)]
pub struct EchoIpServiceConfig {
pub server: ServerConfig,
pub dns: DnsConfig,
pub geoip: GeoIpConfig,
pub template: TemplateConfig,
pub ratelimit: RatelimitConfig,
}
#[derive(Deserialize, Clone)]
pub struct ServerConfig {
pub listen_on: SocketAddr,
pub ip_header: SecureClientIpSource,
pub allow_private_ip_lookup: bool,
pub static_location: Option<String>,
}
#[derive(Deserialize, Clone)]
pub struct GeoIpConfig {
pub asn_database: Option<String>,
pub location_database: Option<String>,
}
#[derive(Deserialize, Clone)]
pub struct TemplateConfig {
pub template_location: String,
pub extra_config: Option<String>,
pub text_user_agents: Vec<String>,
}
#[derive(Deserialize, Clone)]
pub struct RatelimitConfig {
pub per_minute: NonZeroU32,
pub burst: NonZeroU32,
}
impl Default for ServerConfig {
fn default() -> Self {
ServerConfig {
listen_on: "127.0.0.1:3000".parse().unwrap(),
ip_header: SecureClientIpSource::ConnectInfo,
allow_private_ip_lookup: false,
static_location: None,
}
}
}
impl Default for GeoIpConfig {
fn default() -> Self {
GeoIpConfig {
asn_database: Some("mmdb/GeoLite2-ASN.mmdb".to_string()),
location_database: Some("mmdb/GeoLite2-City.mmdb".to_string()),
}
}
}
impl Default for TemplateConfig {
fn default() -> Self {
TemplateConfig {
template_location: "templates/".to_string(),
extra_config: None,
text_user_agents: vec!["curl/".to_string()],
}
}
}
impl Default for RatelimitConfig {
fn default() -> Self {
RatelimitConfig {
per_minute: NonZeroU32::new(20).unwrap(),
burst: NonZeroU32::new(15).unwrap(),
}
}
}