mirror of
https://github.com/edu4rdshl/rusolver.git
synced 2026-07-17 23:24:55 +00:00
Add double verification step.
If no `--no-verify` is provided, every resolved host is double-checked against a list of trustable DNS resolvers, ensuring that only **real** alive hosts are given to the user. Signed-off-by: Edu4rdSHL <edu4rdshl@protonmail.com>
This commit is contained in:
parent
8cbcb2d39b
commit
9de7ab225c
1 changed files with 53 additions and 33 deletions
86
src/main.rs
86
src/main.rs
|
|
@ -68,6 +68,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.takes_value(false)
|
.takes_value(false)
|
||||||
.help("Show the discovered IP addresses. Default: false"),
|
.help("Show the discovered IP addresses. Default: false"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("no-verify")
|
||||||
|
.long("no-verify")
|
||||||
|
.takes_value(false)
|
||||||
|
.help("Disables the double verification algorithm for valid subdomains -NOT RECOMMENDED-. Default: false"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("quiet")
|
Arg::with_name("quiet")
|
||||||
.short("q")
|
.short("q")
|
||||||
|
|
@ -83,6 +89,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let timeout = value_t!(matches.value_of("timeout"), u64).unwrap_or_else(|_| 1);
|
let timeout = value_t!(matches.value_of("timeout"), u64).unwrap_or_else(|_| 1);
|
||||||
let retries = value_t!(matches.value_of("retries"), usize).unwrap_or_else(|_| 0);
|
let retries = value_t!(matches.value_of("retries"), usize).unwrap_or_else(|_| 0);
|
||||||
let quiet_flag = matches.is_present("quiet");
|
let quiet_flag = matches.is_present("quiet");
|
||||||
|
let custom_resolvers = matches.is_present("resolvers");
|
||||||
|
let disable_double_check = matches.is_present("no-verify") && custom_resolvers;
|
||||||
|
|
||||||
// Resolver opts
|
// Resolver opts
|
||||||
let options = ResolverOpts {
|
let options = ResolverOpts {
|
||||||
|
|
@ -93,41 +101,44 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create resolvers
|
let built_in_nameservers: HashSet<String> = vec![
|
||||||
let mut nameserver_ips = HashSet::new();
|
// Cloudflare
|
||||||
|
"1.1.1.1:53",
|
||||||
|
"1.0.0.1:53",
|
||||||
|
// Google
|
||||||
|
"8.8.8.8:53",
|
||||||
|
"8.8.4.4:53",
|
||||||
|
// Quad9
|
||||||
|
"9.9.9.9:53",
|
||||||
|
"149.112.112.112:53",
|
||||||
|
// OpenDNS
|
||||||
|
"208.67.222.222:53",
|
||||||
|
"208.67.220.220:53",
|
||||||
|
// Verisign
|
||||||
|
"64.6.64.6:53",
|
||||||
|
"64.6.65.6:53",
|
||||||
|
// UncensoredDNS
|
||||||
|
"91.239.100.100:53",
|
||||||
|
"89.233.43.71:53",
|
||||||
|
// dns.watch
|
||||||
|
"84.200.69.80:53",
|
||||||
|
"84.200.70.40:53",
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
if matches.is_present("resolvers") {
|
// Create resolvers
|
||||||
|
let nameserver_ips;
|
||||||
|
|
||||||
|
if custom_resolvers {
|
||||||
nameserver_ips =
|
nameserver_ips =
|
||||||
return_file_lines(value_t!(matches.value_of("resolvers"), String).unwrap()).await;
|
return_file_lines(value_t!(matches.value_of("resolvers"), String).unwrap()).await;
|
||||||
} else {
|
} else {
|
||||||
let built_in_nameservers = vec![
|
nameserver_ips = built_in_nameservers.clone();
|
||||||
// Cloudflare
|
|
||||||
"1.1.1.1:53",
|
|
||||||
"1.0.0.1:53",
|
|
||||||
// Google
|
|
||||||
"8.8.8.8:53",
|
|
||||||
"8.8.4.4:53",
|
|
||||||
// Quad9
|
|
||||||
"9.9.9.9:53",
|
|
||||||
"149.112.112.112:53",
|
|
||||||
// OpenDNS
|
|
||||||
"208.67.222.222:53",
|
|
||||||
"208.67.220.220:53",
|
|
||||||
// Verisign
|
|
||||||
"64.6.64.6:53",
|
|
||||||
"64.6.65.6:53",
|
|
||||||
// UncensoredDNS
|
|
||||||
"91.239.100.100:53",
|
|
||||||
"89.233.43.71:53",
|
|
||||||
// dns.watch
|
|
||||||
"84.200.69.80:53",
|
|
||||||
"84.200.70.40:53",
|
|
||||||
];
|
|
||||||
for ip in built_in_nameservers {
|
|
||||||
nameserver_ips.insert(ip.to_string());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let resolvers = return_tokio_asyncresolver(nameserver_ips, options);
|
let resolvers = return_tokio_asyncresolver(nameserver_ips, options);
|
||||||
|
let trustable_resolver = return_tokio_asyncresolver(built_in_nameservers, options);
|
||||||
let mut wildcard_ips = HashSet::new();
|
let mut wildcard_ips = HashSet::new();
|
||||||
|
|
||||||
// Read stdin
|
// Read stdin
|
||||||
|
|
@ -148,13 +159,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
futures::stream::iter(hosts.into_iter().map(|host| {
|
futures::stream::iter(hosts.into_iter().map(|host| {
|
||||||
let resolver_fut = resolvers.ipv4_lookup(host.clone());
|
let resolver_fut = resolvers.ipv4_lookup(host.clone());
|
||||||
|
let trustable_resolver_fut = trustable_resolver.ipv4_lookup(host.clone());
|
||||||
let wildcard_ips = wildcard_ips.clone();
|
let wildcard_ips = wildcard_ips.clone();
|
||||||
async move {
|
async move {
|
||||||
if let Ok(ip) = resolver_fut.await {
|
if let Ok(ip) = resolver_fut.await {
|
||||||
let ips = ip
|
let mut ips = HashSet::new();
|
||||||
.into_iter()
|
if disable_double_check {
|
||||||
.map(|x| x.to_string())
|
ips = ip
|
||||||
.collect::<HashSet<String>>();
|
.into_iter()
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.collect::<HashSet<String>>();
|
||||||
|
} else if let Ok(ip) = trustable_resolver_fut.await {
|
||||||
|
ips = ip
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.collect::<HashSet<String>>();
|
||||||
|
}
|
||||||
if show_ip_adress && !ips.iter().all(|ip| wildcard_ips.contains(ip)) {
|
if show_ip_adress && !ips.iter().all(|ip| wildcard_ips.contains(ip)) {
|
||||||
println!("{};{:?}", host, ips)
|
println!("{};{:?}", host, ips)
|
||||||
} else if !ips.iter().all(|ip| wildcard_ips.contains(ip)) {
|
} else if !ips.iter().all(|ip| wildcard_ips.contains(ip)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue