mirror of
https://codeberg.org/slatian/service.echoip-slatecave.git
synced 2025-07-17 14:33:27 +02:00
Configurable multiple dns resolvers
This commit is contained in:
99
src/config/dns.rs
Normal file
99
src/config/dns.rs
Normal 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
88
src/config/mod.rs
Normal 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user