mirror of
https://codeberg.org/slatian/service.echoip-slatecave.git
synced 2025-07-17 06:23:29 +02:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
c56cc6edbd | |||
5c74de5685 | |||
223abdd804 | |||
639d4579e9 | |||
4b3a8d5e08 | |||
53da9023da | |||
4876fb7ea0 | |||
2aa6baaa57 | |||
daa68bbd5d | |||
231e46a688 | |||
2fe1b69174 | |||
2e1f6a77ac | |||
1fe59d24d5 | |||
51d7954d71 |
486
Cargo.lock
generated
486
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "echoip-slatecave"
|
||||
version = "0.1.0"
|
||||
version = "1.1.3"
|
||||
edition = "2021"
|
||||
authors = ["Slatian <baschdel@disroot.org>"]
|
||||
|
||||
@ -16,7 +16,7 @@ idna = "0.3"
|
||||
lazy_static = "1.4.0"
|
||||
parking_lot = "0.12"
|
||||
regex = "1.7"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde = { version = "1", features = ["derive","rc"] }
|
||||
tokio = { version = "1", features = ["macros","signal"] }
|
||||
tera = "1"
|
||||
toml = "0.7"
|
||||
|
@ -72,7 +72,7 @@ This configuration option will not be exposed over the webinterface.
|
||||
|
||||
By default echoip-slatecave uses the system configuration for dns like most other programs.
|
||||
|
||||
In case this is undesired one can difable it by setting `enable_system_resolver` to false.
|
||||
In case this is undesired one can disable it by setting `enable_system_resolver` to false.
|
||||
|
||||
```toml
|
||||
[dns]
|
||||
@ -90,10 +90,6 @@ In case you want to use the system resolver and customize it.
|
||||
`system_resolver_weight`
|
||||
: Equivalent to the `weight` of a custom resolver, default: 1000
|
||||
|
||||
### `search`
|
||||
|
||||
This is for a work in progress feature that allows confiuring search domains for all custom dns resolvers.
|
||||
|
||||
### Custom resolvers
|
||||
|
||||
It is possible to confgure custom resolvers in plce of or in addition to the default system resolver.
|
||||
|
@ -67,9 +67,9 @@ The default configuration is pretty liberal so that the average human probably w
|
||||
|
||||
## TODO
|
||||
|
||||
* [ ] Investigate why search isn't working for global TLDs
|
||||
* [ ] Add a way to configure just the dns server addresses and derive the port from the protocol.
|
||||
* [ ] Add an about page for the system resolver
|
||||
* [ ] Expose DNS responses from the additional on the web interface
|
||||
|
||||
## License
|
||||
|
||||
|
@ -28,9 +28,6 @@ allow_reverse_lookup = true
|
||||
# that end with one of these suffixes don't exist
|
||||
hidden_suffixes = [".com"]
|
||||
|
||||
# doesn't really work 🙁
|
||||
search = ["org","net"]
|
||||
|
||||
[geoip]
|
||||
# Path to geoip databses
|
||||
# Currently only the mmdb format is supported
|
||||
@ -116,7 +113,7 @@ tls_dns_name = "cloudflare-dns.com"
|
||||
|
||||
[dns.resolver.google]
|
||||
display_name = "Google"
|
||||
info_url = "https://www.cloudflare.com/dns/"
|
||||
info_url = "https://developers.google.com/speed/public-dns/docs/using"
|
||||
aliases = ["goo","8888"]
|
||||
weight = 440
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use serde::{Deserialize,Serialize};
|
||||
use trust_dns_resolver::config::Protocol;
|
||||
use trust_dns_resolver::Name;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
@ -11,13 +11,12 @@ pub struct DnsConfig {
|
||||
pub allow_forward_lookup: bool,
|
||||
pub allow_reverse_lookup: bool,
|
||||
pub hidden_suffixes: Vec<String>,
|
||||
pub search: Vec<String>,
|
||||
pub resolver: HashMap<String,DnsResolverConfig>,
|
||||
pub resolver: HashMap<Arc<str>,DnsResolverConfig>,
|
||||
|
||||
pub enable_system_resolver: bool,
|
||||
pub system_resolver_name: String,
|
||||
pub system_resolver_name: Arc<str>,
|
||||
pub system_resolver_weight: i32,
|
||||
pub system_resolver_id: String,
|
||||
pub system_resolver_id: Arc<str>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone)]
|
||||
@ -32,18 +31,16 @@ pub enum DnsProtocol {
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone)]
|
||||
pub struct DnsResolverConfig {
|
||||
pub display_name: String,
|
||||
pub display_name: Arc<str>,
|
||||
#[serde(default)]
|
||||
pub info_url: Option<String>,
|
||||
pub info_url: Option<Arc<str>>,
|
||||
#[serde(default)]
|
||||
pub aliases: Vec<String>,
|
||||
pub aliases: Vec<Arc<str>>,
|
||||
#[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 tls_dns_name: Option<Arc<str>>,
|
||||
#[serde(skip_serializing)] //Don't leak our bind address to the outside
|
||||
pub bind_address: Option<SocketAddr>,
|
||||
#[serde(default="default_true")]
|
||||
@ -65,12 +62,11 @@ impl Default for DnsConfig {
|
||||
allow_reverse_lookup: false,
|
||||
hidden_suffixes: Vec::new(),
|
||||
resolver: Default::default(),
|
||||
search: Vec::new(),
|
||||
|
||||
enable_system_resolver: true,
|
||||
system_resolver_name: "System".to_string(),
|
||||
system_resolver_name: "System".into(),
|
||||
system_resolver_weight: 1000,
|
||||
system_resolver_id: "system".to_string(),
|
||||
system_resolver_id: "system".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,30 +85,23 @@ impl Into<Protocol> for DnsProtocol {
|
||||
|
||||
impl DnsResolverConfig {
|
||||
pub fn to_trust_resolver_config(
|
||||
&self,
|
||||
additional_search: &Vec<String>,
|
||||
&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(),
|
||||
tls_dns_name: self.tls_dns_name.clone().map(|s| s.to_string()),
|
||||
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);
|
||||
}
|
||||
}
|
||||
for search in additional_search {
|
||||
if let Ok(name) = Name::from_str_relaxed(search) {
|
||||
resolver.add_search(name);
|
||||
}
|
||||
}
|
||||
// Not configuring domain search here because searching
|
||||
// on the resolver level is a bad idea unless we are
|
||||
// taling about the system resolver which we
|
||||
// can't tell what to do (which is good!)
|
||||
return resolver;
|
||||
}
|
||||
}
|
||||
|
103
src/main.rs
103
src/main.rs
@ -22,6 +22,7 @@ use serde::{Deserialize,Serialize};
|
||||
use tera::Tera;
|
||||
use tower::ServiceBuilder;
|
||||
use tower_http::services::ServeDir;
|
||||
use trust_dns_resolver::Name;
|
||||
use trust_dns_resolver::TokioAsyncResolver;
|
||||
|
||||
use tokio::signal::unix::{
|
||||
@ -75,26 +76,26 @@ pub struct IpResult {
|
||||
asn: Option<AsnResult>,
|
||||
location: Option<LocationResult>,
|
||||
ip_info: AddressInfo,
|
||||
used_dns_resolver: Option<String>,
|
||||
used_dns_resolver: Option<Arc<str>>,
|
||||
}
|
||||
|
||||
// We need this one to hide the partial lookup field when irelevant
|
||||
pub fn not(b: &bool) -> bool { !b }
|
||||
|
||||
#[derive(Serialize, Default, Clone)]
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct DigResult {
|
||||
records: simple_dns::DnsLookupResult,
|
||||
#[serde(skip_serializing_if = "IdnaName::was_ascii")]
|
||||
idn: IdnaName,
|
||||
#[serde(skip_serializing_if = "not")]
|
||||
partial_lookup: bool,
|
||||
used_dns_resolver: String,
|
||||
used_dns_resolver: Arc<str>,
|
||||
}
|
||||
|
||||
struct ServiceSharedState {
|
||||
templating_engine: templating_engine::Engine,
|
||||
dns_resolvers: HashMap<String,TokioAsyncResolver>,
|
||||
dns_resolver_aliases: HashMap<String,String>,
|
||||
dns_resolvers: HashMap<Arc<str>,TokioAsyncResolver>,
|
||||
dns_resolver_aliases: HashMap<Arc<str>,Arc<str>>,
|
||||
asn_db: geoip::MMDBCarrier,
|
||||
location_db: geoip::MMDBCarrier,
|
||||
config: config::EchoIpServiceConfig,
|
||||
@ -104,7 +105,7 @@ struct ServiceSharedState {
|
||||
#[derive(Clone)]
|
||||
struct DerivedConfiguration {
|
||||
dns_resolver_selectables: Vec<Selectable>,
|
||||
default_resolver: String,
|
||||
default_resolver: Arc<str>,
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
@ -233,8 +234,8 @@ async fn main() {
|
||||
println!("Initalizing dns resolvers ...");
|
||||
|
||||
let mut dns_resolver_selectables = Vec::<Selectable>::new();
|
||||
let mut dns_resolver_map: HashMap<String,TokioAsyncResolver> = HashMap::new();
|
||||
let mut dns_resolver_aliases: HashMap<String,String> = HashMap::new();
|
||||
let mut dns_resolver_map: HashMap<Arc<str>,TokioAsyncResolver> = HashMap::new();
|
||||
let mut dns_resolver_aliases: HashMap<Arc<str>,Arc<str>> = HashMap::new();
|
||||
|
||||
if config.dns.enable_system_resolver {
|
||||
println!("Initalizing System resolver ...");
|
||||
@ -258,7 +259,7 @@ async fn main() {
|
||||
for (key, resolver_config) in &config.dns.resolver {
|
||||
println!("Initalizing {} resolver ...", key);
|
||||
let resolver = TokioAsyncResolver::tokio(
|
||||
resolver_config.to_trust_resolver_config(&config.dns.search),
|
||||
resolver_config.to_trust_resolver_config(),
|
||||
Default::default()
|
||||
).unwrap();
|
||||
dns_resolver_map.insert(key.clone(), resolver);
|
||||
@ -289,7 +290,7 @@ async fn main() {
|
||||
dns_resolver_selectables.sort_by(|a,b| b.weight.cmp(&a.weight));
|
||||
let default_resolver = dns_resolver_selectables.get(0)
|
||||
.map(|s| s.id.clone() )
|
||||
.unwrap_or("none".to_string());
|
||||
.unwrap_or("none".into());
|
||||
let derived_config = DerivedConfiguration {
|
||||
dns_resolver_selectables: dns_resolver_selectables,
|
||||
default_resolver: default_resolver,
|
||||
@ -363,10 +364,10 @@ async fn settings_query_middleware<B>(
|
||||
let mut dns_resolver_id = derived_config.default_resolver;
|
||||
|
||||
if let Some(resolver_id) = query.dns {
|
||||
dns_resolver_id = resolver_id;
|
||||
dns_resolver_id = resolver_id.into();
|
||||
} else if let Some(cookie_header) = cookie_header {
|
||||
if let Some(resolver_id) = cookie_header.0.get("dns_resolver") {
|
||||
dns_resolver_id = resolver_id.to_string();
|
||||
dns_resolver_id = resolver_id.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,7 +448,7 @@ async fn handle_default_route(
|
||||
}
|
||||
}
|
||||
|
||||
let result = get_ip_result(&address, &settings.lang, &"default".to_string(), &state).await;
|
||||
let result = get_ip_result(&address, &settings.lang, &"default".into(), &state).await;
|
||||
|
||||
let user_agent: Option<String> = match user_agent_header {
|
||||
Some(TypedHeader(user_agent)) => Some(user_agent.to_string()),
|
||||
@ -492,11 +493,11 @@ async fn handle_search_request(
|
||||
}
|
||||
|
||||
if let Some(via_cap) = VIA_REGEX.captures(&search_query) {
|
||||
if let Some(via) = via_cap.get(1).map(|c| c.as_str().to_string()) {
|
||||
if let Some(via) = via_cap.get(1) {
|
||||
let state = Arc::clone(&arc_state);
|
||||
if state.dns_resolvers.contains_key(&via) {
|
||||
settings.dns_resolver_id = via;
|
||||
} else if let Some(alias) = state.dns_resolver_aliases.get(&via) {
|
||||
if state.dns_resolvers.contains_key(via.as_str()) {
|
||||
settings.dns_resolver_id = via.as_str().into();
|
||||
} else if let Some(alias) = state.dns_resolver_aliases.get(via.as_str()) {
|
||||
settings.dns_resolver_id = alias.clone();
|
||||
}
|
||||
}
|
||||
@ -536,7 +537,7 @@ async fn handle_dns_resolver_route_with_path(
|
||||
extract::Path(query): extract::Path<String>,
|
||||
) -> Response {
|
||||
let state = Arc::clone(&arc_state);
|
||||
if let Some(resolver) = state.config.dns.resolver.get(&query) {
|
||||
if let Some(resolver) = state.config.dns.resolver.get(query.as_str()) {
|
||||
state.templating_engine.render_view(
|
||||
&settings,
|
||||
&View::DnsResolver{ config: resolver.clone() },
|
||||
@ -583,7 +584,7 @@ async fn handle_ip_request(
|
||||
async fn get_ip_result(
|
||||
address: &IpAddr,
|
||||
lang: &String,
|
||||
dns_resolver_name: &String,
|
||||
dns_resolver_name: &Arc<str>,
|
||||
state: &ServiceSharedState,
|
||||
) -> IpResult {
|
||||
|
||||
@ -604,7 +605,7 @@ async fn get_ip_result(
|
||||
|
||||
// do reverse lookup
|
||||
let mut hostname: Option<String> = None;
|
||||
let mut used_dns_resolver: Option<String> = None;
|
||||
let mut used_dns_resolver: Option<Arc<str>> = None;
|
||||
if state.config.dns.allow_reverse_lookup {
|
||||
if let Some(dns_resolver) = &state.dns_resolvers.get(dns_resolver_name) {
|
||||
hostname = simple_dns::reverse_lookup(&dns_resolver, &address).await;
|
||||
@ -672,39 +673,61 @@ async fn handle_dig_request(
|
||||
|
||||
async fn get_dig_result(
|
||||
dig_query: &String,
|
||||
dns_resolver_name: &String,
|
||||
dns_resolver_name: &Arc<str>,
|
||||
state: &ServiceSharedState,
|
||||
do_full_lookup: bool,
|
||||
) -> DigResult {
|
||||
let name = &dig_query.trim().trim_end_matches(".").to_string();
|
||||
let idna_name = IdnaName::from_string(&name);
|
||||
if let Some(dns_resolver) = &state.dns_resolvers.get(dns_resolver_name) {
|
||||
if match_domain_hidden_list(&name, &state.config.dns.hidden_suffixes) {
|
||||
// Try to hide the fact that we didn't do dns resolution at all
|
||||
// We resolve example.org as basic avoidance of timing sidechannels.
|
||||
// WARNING: this timing sidechannel avoidance is very crude.
|
||||
simple_dns::lookup(
|
||||
if let Some(dns_resolver) = state.dns_resolvers.get(dns_resolver_name) {
|
||||
if let Ok(domain_name) = Name::from_str_relaxed(name.to_owned()+".") {
|
||||
if match_domain_hidden_list(&name, &state.config.dns.hidden_suffixes) {
|
||||
// Try to hide the fact that we didn't do dns resolution at all
|
||||
// We resolve example.org as basic avoidance of timing sidechannels.
|
||||
// WARNING: this timing sidechannel avoidance is very crude.
|
||||
simple_dns::lookup(
|
||||
&dns_resolver,
|
||||
&Name::from_ascii("example.org.").expect("Static Dummy Name"),
|
||||
do_full_lookup).await;
|
||||
return DigResult {
|
||||
records: DnsLookupResult{ nxdomain: true , ..Default::default() },
|
||||
idn: idna_name,
|
||||
partial_lookup: !do_full_lookup,
|
||||
used_dns_resolver: dns_resolver_name.clone(),
|
||||
}
|
||||
} else {
|
||||
return DigResult {
|
||||
records: simple_dns::lookup(
|
||||
&dns_resolver,
|
||||
&("example.org.".to_string()),
|
||||
do_full_lookup).await;
|
||||
DigResult {
|
||||
records: DnsLookupResult{ nxdomain: true , ..Default::default() },
|
||||
idn: idna_name,
|
||||
partial_lookup: !do_full_lookup,
|
||||
used_dns_resolver: dns_resolver_name.clone(),
|
||||
&domain_name,
|
||||
do_full_lookup).await,
|
||||
idn: idna_name,
|
||||
partial_lookup: !do_full_lookup,
|
||||
used_dns_resolver: dns_resolver_name.clone(),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DigResult {
|
||||
records: simple_dns::lookup(
|
||||
&dns_resolver,
|
||||
&(idna_name.idn.clone().unwrap_or(name.to_owned())+"."),
|
||||
do_full_lookup).await,
|
||||
// Invalid domain name
|
||||
return DigResult {
|
||||
records: DnsLookupResult{
|
||||
invalid_name: true,
|
||||
.. Default::default()
|
||||
},
|
||||
idn: idna_name,
|
||||
partial_lookup: !do_full_lookup,
|
||||
used_dns_resolver: dns_resolver_name.clone(),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Default::default();
|
||||
// Unknown resolver name
|
||||
return DigResult {
|
||||
records: DnsLookupResult{
|
||||
unkown_resolver: true,
|
||||
.. Default::default()
|
||||
},
|
||||
idn: idna_name,
|
||||
partial_lookup: !do_full_lookup,
|
||||
used_dns_resolver: "unkown_resolver".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
use serde::{Deserialize,Serialize};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
/* Response format */
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone, Copy)]
|
||||
@ -39,13 +41,13 @@ pub struct QuerySettings {
|
||||
pub format: ResponseFormat,
|
||||
pub lang: String,
|
||||
pub available_dns_resolvers: Vec<Selectable>,
|
||||
pub dns_resolver_id: String,
|
||||
pub dns_resolver_id: Arc<str>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone)]
|
||||
pub struct Selectable {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub id: Arc<str>,
|
||||
pub name: Arc<str>,
|
||||
pub weight: i32,
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ use trust_dns_resolver::{
|
||||
error::ResolveError,
|
||||
error::ResolveErrorKind,
|
||||
lookup::Lookup,
|
||||
Name,
|
||||
TokioAsyncResolver,
|
||||
};
|
||||
|
||||
@ -37,10 +38,12 @@ pub struct DnsLookupResult {
|
||||
pub txt: Option<Vec<String>>,
|
||||
pub srv: Option<Vec<SrvRecord>>,
|
||||
pub caa: Option<Vec<String>>,
|
||||
pub other_error: bool,
|
||||
pub dns_error: bool,
|
||||
pub nxdomain: bool,
|
||||
pub timeout: bool,
|
||||
pub other_error: bool,
|
||||
pub dns_error: bool,
|
||||
pub nxdomain: bool,
|
||||
pub timeout: bool,
|
||||
pub invalid_name: bool,
|
||||
pub unkown_resolver: bool,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize, Clone, PartialEq)]
|
||||
@ -171,8 +174,14 @@ pub fn integrate_lookup_result(dig_result: &mut DnsLookupResult, lookup_result:
|
||||
RecordType::TXT => set_default_if_none(&mut dig_result.txt),
|
||||
_ => { /* This should not happen */ },
|
||||
};
|
||||
for record in lookup.iter() {
|
||||
add_record_to_lookup_result(dig_result, record);
|
||||
let name = lookup.query().name();
|
||||
for record in lookup.record_iter() {
|
||||
if name == record.name() {
|
||||
if let Some(data) = record.data() {
|
||||
add_record_to_lookup_result(dig_result, data);
|
||||
}
|
||||
}
|
||||
//TODO: handle additional responses
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
@ -210,7 +219,7 @@ pub fn integrate_lookup_result(dig_result: &mut DnsLookupResult, lookup_result:
|
||||
// records will be fetched.
|
||||
pub async fn lookup(
|
||||
resolver: &TokioAsyncResolver,
|
||||
name: &String,
|
||||
name: &Name,
|
||||
do_full_lookup: bool,
|
||||
) -> DnsLookupResult {
|
||||
let (
|
||||
@ -219,10 +228,10 @@ pub async fn lookup(
|
||||
cname_lookup_res,
|
||||
aname_lookup_res
|
||||
) = join!(
|
||||
resolver.lookup(name, RecordType::A),
|
||||
resolver.lookup(name, RecordType::AAAA),
|
||||
resolver.lookup(name, RecordType::CNAME),
|
||||
resolver.lookup(name, RecordType::ANAME),
|
||||
resolver.lookup(name.clone(), RecordType::A),
|
||||
resolver.lookup(name.clone(), RecordType::AAAA),
|
||||
resolver.lookup(name.clone(), RecordType::CNAME),
|
||||
resolver.lookup(name.clone(), RecordType::ANAME),
|
||||
);
|
||||
|
||||
// initlize an empty lookup result
|
||||
@ -243,12 +252,12 @@ pub async fn lookup(
|
||||
srv_lookup_res,
|
||||
txt_lookup_res
|
||||
) = join!(
|
||||
resolver.lookup(name, RecordType::MX),
|
||||
resolver.lookup(name, RecordType::NS),
|
||||
resolver.lookup(name, RecordType::SOA),
|
||||
resolver.lookup(name, RecordType::CAA),
|
||||
resolver.lookup(name, RecordType::SRV),
|
||||
resolver.lookup(name, RecordType::TXT),
|
||||
resolver.lookup(name.clone(), RecordType::MX),
|
||||
resolver.lookup(name.clone(), RecordType::NS),
|
||||
resolver.lookup(name.clone(), RecordType::SOA),
|
||||
resolver.lookup(name.clone(), RecordType::CAA),
|
||||
resolver.lookup(name.clone(), RecordType::SRV),
|
||||
resolver.lookup(name.clone(), RecordType::TXT),
|
||||
);
|
||||
|
||||
integrate_lookup_result(&mut dig_result, mx_lookup_res);
|
||||
|
@ -120,7 +120,7 @@ impl Engine {
|
||||
View::NotFound => *response.status_mut() = StatusCode::NOT_FOUND,
|
||||
_ => {},
|
||||
}
|
||||
let cookie = Cookie::build("dns_resolver",settings.dns_resolver_id.clone())
|
||||
let cookie = Cookie::build("dns_resolver",settings.dns_resolver_id.to_string())
|
||||
.path("/")
|
||||
.same_site(cookie::SameSite::Strict)
|
||||
.finish();
|
||||
|
@ -26,8 +26,16 @@
|
||||
<section>
|
||||
<h2>DNS Records</h2>
|
||||
|
||||
{% if r.nxdomain %}
|
||||
<p class="error box">Our DNS-Server claims that this domain doesn't exist, there shouldn't be any results.</p>
|
||||
{% set show_nonpresent = true %}
|
||||
{% if r.unkown_resolver %}
|
||||
<p class="error box">The resolver you chose is not one of the available ones, if you can reproduce this error by just using the UI <a href="https://codeberg.org/slatian/service.echoip-slatecave/issues/new">please report it</a>.</p>
|
||||
{% set show_nonpresent = false %}
|
||||
{% elif r.invalid_name %}
|
||||
<p class="error box">This domain name does not conform to <a href="https://www.rfc-editor.org/info/std3">the dns specification (std3)</a> rules and was therefore not resolved.</p>
|
||||
{% set show_nonpresent = false %}
|
||||
{% elif r.nxdomain %}
|
||||
<p class="error box">The DNS-Server claims that this domain doesn't exist, there shouldn't be any results.</p>
|
||||
{% set show_nonpresent = false %}
|
||||
{% elif r.timeout %}
|
||||
<p class="error box">There was at least one timeout error while resolving this domain, the results below are incomplete.</p>
|
||||
{% elif r.other_error %}
|
||||
@ -66,7 +74,7 @@
|
||||
<li>{{ helper::ip(extra=extra, ip=address) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not r.nxdomain %}
|
||||
{% elif show_nonpresent %}
|
||||
<p>No <code>A</code> (IPv4) Records.</p>
|
||||
{% endif %}
|
||||
|
||||
@ -77,7 +85,7 @@
|
||||
<li>{{ helper::ip(extra=extra, ip=address) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not r.nxdomain %}
|
||||
{% elif show_nonpresent %}
|
||||
<p>No <code>AAAA</code> (IPv6) Records.</p>
|
||||
{% endif %}
|
||||
|
||||
@ -90,7 +98,7 @@
|
||||
<li>{{ helper::dig(extra=extra, name=mx.exchange, fqdn=true, prefix=mx.preference) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not r.nxdomain %}
|
||||
{% elif show_nonpresent %}
|
||||
<p id="mx">No <code>MX</code> (Mail Exchange) records.</p>
|
||||
{% endif %}
|
||||
|
||||
@ -116,7 +124,7 @@
|
||||
</dl></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not r.nxdomain %}
|
||||
{% elif show_nonpresent %}
|
||||
<p id="soa">No <code>SOA</code> records.</p>
|
||||
{% endif %}
|
||||
|
||||
@ -129,7 +137,7 @@
|
||||
<li>{{ helper::dig(extra=extra, name=ns) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not r.nxdomain %}
|
||||
{% elif show_nonpresent %}
|
||||
<p id="ns">No <code>NS</code> (Name Server) records.</p>
|
||||
{% endif %}
|
||||
|
||||
@ -141,7 +149,7 @@
|
||||
<li><code>{{caa}}</code></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not r.nxdomain %}
|
||||
{% elif show_nonpresent %}
|
||||
<p id="caa">No <code>CAA</code> (<a target="_blank" href="https://de.wikipedia.org/wiki/DNS_Certification_Authority_Authorization">Certification Authority Authorization</a>) records.</p>
|
||||
{% endif %}
|
||||
|
||||
@ -152,7 +160,7 @@
|
||||
<li><code>{{txt}}</code></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not r.nxdomain %}
|
||||
{% elif show_nonpresent %}
|
||||
<p id="txt">No <code>TXT</code> records.</p>
|
||||
{% endif %}
|
||||
|
||||
@ -172,7 +180,7 @@
|
||||
</dl></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not r.nxdomain %}
|
||||
{% elif show_nonpresent %}
|
||||
<p id="srv">No <code>SRV</code> records.</p>
|
||||
<p><code>SRV</code> or Service records usually live on their own subdomains like {{ helper::dig(extra=extra, name="_xmpp-client._tcp."~data.query) }}.
|
||||
{% endif %}
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
{% block path %}dig/{{ data.query | urlencode_strict }}{% endblock %}
|
||||
|
||||
{% block content -%}
|
||||
{% set r = data.result.records %}
|
||||
{%- block content -%}
|
||||
# dig {{data.query}} via {{ data.result.used_dns_resolver }}
|
||||
|
||||
{% if data.result.idn -%}
|
||||
@ -25,7 +26,16 @@ Your IDN would decode to
|
||||
|
||||
{% set r = data.result.records -%}
|
||||
## DNS Records
|
||||
{% if r.nxdomain %}
|
||||
{% if r.unkown_resolver %}
|
||||
{%- set show_nonpresent = false %}
|
||||
The resolver you chose is not one of the available ones.
|
||||
=> {{ extra.base_url }}/dns_resolver
|
||||
{% elif r.invalid_name %}
|
||||
{%- set show_nonpresent = false %}
|
||||
This domain name does not conform to the dns specification (std3) rules and was therefore not resolved.
|
||||
=> https://www.rfc-editor.org/info/std3
|
||||
{% elif r.nxdomain %}
|
||||
{%- set show_nonpresent = false %}
|
||||
Our DNS-Server claims that this domain doesn't exist, there shouldn't be any results.
|
||||
{%- elif r.timeout -%}
|
||||
There was at least one timeout error while resolving this domain, the results below are incomplete.
|
||||
@ -61,7 +71,7 @@ A (IPv4) records:
|
||||
{% for address in r.a -%}
|
||||
* {{ address }}
|
||||
{% endfor %}
|
||||
{%- elif not r.nxdomain %}
|
||||
{%- elif show_nonpresent %}
|
||||
No A (IPv4) Records.
|
||||
{% endif -%}
|
||||
|
||||
@ -70,7 +80,7 @@ AAAA (IPv6) records:
|
||||
{% for address in r.aaaa -%}
|
||||
* {{ address }}
|
||||
{% endfor %}
|
||||
{%- elif not r.nxdomain %}
|
||||
{%- elif show_nonpresent %}
|
||||
No AAAA (IPv6) Records.
|
||||
{% endif -%}
|
||||
|
||||
@ -81,7 +91,7 @@ MX (Mail Exchange) records:
|
||||
{% for mx in r.mx | sort(attribute="preference") | reverse -%}
|
||||
* {{ mx.preference }} {{ mx.exchange }}
|
||||
{% endfor %}
|
||||
{%- elif not r.nxdomain %}
|
||||
{%- elif show_nonpresent %}
|
||||
No MX (Mail Exchange) records.
|
||||
{% endif %}
|
||||
|
||||
@ -96,7 +106,7 @@ SOA (Source Of Authority) records:
|
||||
* expire: {{soa.expire / 3600 | round(precision=2)}}h
|
||||
* minimum: {{soa.minimum / 60 | round(precision=2)}}m TTL
|
||||
{% endfor %}
|
||||
{%- elif not r.nxdomain %}
|
||||
{%- elif show_nonpresent %}
|
||||
No SOA (Source Of Authority) records.
|
||||
{% endif %}
|
||||
|
||||
@ -105,7 +115,7 @@ NS (Name Server) records:
|
||||
{% for ns in r.ns -%}
|
||||
* {{ns}}
|
||||
{% endfor %}
|
||||
{%- elif not r.nxdomain %}
|
||||
{%- elif show_nonpresent %}
|
||||
No NS (Name Server) records.
|
||||
{% endif %}
|
||||
|
||||
@ -114,7 +124,7 @@ CAA (Certification Authority Authorization) records:
|
||||
{% for caa in r.caa -%}
|
||||
* {{caa}}
|
||||
{% endfor %}
|
||||
{%- elif not r.nxdomain %}
|
||||
{%- elif show_nonpresent %}
|
||||
No CAA (Certification Authority Authorization) records.
|
||||
{% endif %}
|
||||
|
||||
@ -123,7 +133,7 @@ TXT records:
|
||||
{% for txt in r.txt -%}
|
||||
* {{txt}}
|
||||
{% endfor %}
|
||||
{%- elif not r.nxdomain %}
|
||||
{%- elif show_nonpresent %}
|
||||
No TXT records.
|
||||
{% endif %}
|
||||
|
||||
@ -135,7 +145,7 @@ SRV records:
|
||||
* Port: {{srv.port}}
|
||||
* Target: {{srv.target}}
|
||||
{% endfor %}
|
||||
{%- elif not r.nxdomain %}
|
||||
{%- elif show_nonpresent %}
|
||||
No SRV records.
|
||||
|
||||
SRV or Service records usually live on their own subdomains like {{ "_xmpp-client._tcp."~data.query }}.
|
||||
|
@ -31,12 +31,6 @@
|
||||
<dd>{{ helper::dig(extra=extra, name=c.tls_dns_name) }}</dd>
|
||||
{%- endif %}
|
||||
|
||||
{%- if c.search | length > 0 %}
|
||||
<dt>Search</dt>
|
||||
{%- for s in c.search %}
|
||||
<dd>{{s}}</dd>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
</dl>
|
||||
{%- if c.info_url %}
|
||||
<p class="button-paragraph"><a href="{{c.info_url}}">More about the {{c.display_name}} DNS Server <small>(external link)</small></a></p>
|
||||
|
@ -16,14 +16,6 @@ Protocol: {{ c.protocol }}
|
||||
{%-if c.tls_dns_name %}
|
||||
DNS Name: {{ c.tls_dns_name }}
|
||||
{%- endif %}
|
||||
{%- if c.search | length == 1 %}
|
||||
Search: {{ c.search | first }}
|
||||
{%- elif c.search | length > 1 %}
|
||||
Search:
|
||||
{%- for s in c.search %}
|
||||
* {{s}}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- if c.aliases | length == 1 %}
|
||||
Alias: {{ c.aliases | first }}
|
||||
{%- elif c.aliases | length > 1 %}
|
||||
|
@ -380,6 +380,8 @@ a:visited {
|
||||
color: var(--page-link-visited);
|
||||
}
|
||||
|
||||
a.sitename { display: inline-block; }
|
||||
|
||||
h1, a.sitename {
|
||||
margin: var(--heading-mg);
|
||||
padding: var(--heading-pad);
|
||||
|
Reference in New Issue
Block a user