The servers used to retrieve public IP via DNS are now customizable.

This commit is contained in:
Vegard Berg 2023-06-08 21:54:55 +02:00
parent f810677a43
commit a43c5e9020
4 changed files with 56 additions and 26 deletions

View File

@ -1,4 +1,9 @@
# api_key = "MY API KEY" # api_key = "MY API KEY"
#
# [dns]
# ips = ["208.67.222.222", "208.67.220.220", "2620:119:35::35", "2620:119:53::53"]
# # Note the final period!!
# domain = "myip.opendns.com."
# #
# [[domain]] # [[domain]]
# name = "mydomain.com" # name = "mydomain.com"

View File

@ -6,9 +6,40 @@ const SAMPLE_CONFIG: &str = include_str!("../config.sample.toml");
pub struct Configuration { pub struct Configuration {
pub api_key: String, pub api_key: String,
#[serde(default)]
pub dns: Dns,
#[serde(rename = "domain")] #[serde(rename = "domain")]
pub domains: Vec<Domain>, pub domains: Vec<Domain>,
} }
#[derive(Debug,Serialize, Deserialize, PartialEq)]
pub struct Dns {
#[serde(default = "default_ips")]
pub ips: Vec<String>,
#[serde(default = "default_domain")]
pub domain: String,
}
impl Default for Dns {
fn default() -> Self {
Self { ips: default_ips(), domain: default_domain() }
}
}
fn default_ips() -> Vec<String> {
vec![
String::from("208.67.222.222"),
String::from("208.67.220.220"),
String::from("2620:119:35::35"),
String::from("2620:119:53::53"),
]
}
fn default_domain() -> String {
String::from("myip.opendns.com.")
}
#[derive(Debug, Serialize, Deserialize, std::cmp::PartialEq)] #[derive(Debug, Serialize, Deserialize, std::cmp::PartialEq)]
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub struct Domain { pub struct Domain {

View File

@ -3,39 +3,33 @@ use trust_dns_resolver::{
Resolver, Resolver,
}; };
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::{net::{IpAddr, Ipv4Addr, Ipv6Addr}, str::FromStr};
pub fn get_ext_ip() -> anyhow::Result<(Option<Ipv4Addr>, Option<Ipv6Addr>)> { pub fn get_ext_ip(config: &crate::config::Configuration) -> anyhow::Result<(Option<Ipv4Addr>, Option<Ipv6Addr>)> {
let ip_addrs: Vec<IpAddr> = vec![
Ipv4Addr::new(208, 67, 222, 222).into(), let ip_strs = &config.dns.ips;
Ipv4Addr::new(208, 67, 220, 220).into(), let domain = config.dns.domain.as_str();
Ipv6Addr::new(0x2620, 0x119, 0x35, 0, 0, 0, 0, 0x35).into(), let ip_addrs: Vec<IpAddr> = ip_strs.into_iter().filter_map(|ip| IpAddr::from_str(ip).ok()).collect();
Ipv6Addr::new(0x2620, 0x119, 0x53, 0, 0, 0, 0, 0x53).into(),
];
let nscg = NameServerConfigGroup::from_ips_clear(ip_addrs.as_slice(), 53, true); let nscg = NameServerConfigGroup::from_ips_clear(ip_addrs.as_slice(), 53, true);
let resolver_cfg = ResolverConfig::from_parts(None, vec![], nscg); let resolver_cfg = ResolverConfig::from_parts(None, vec![], nscg);
let resolver = Resolver::new(resolver_cfg, ResolverOpts::default())?; let resolver = Resolver::new(resolver_cfg, ResolverOpts::default())?;
let ip4: Vec<Ipv4Addr> = match resolver.ipv4_lookup("myip.opendns.com.") { let ip4= match resolver.ipv4_lookup(domain) {
Ok(ips) => ips.into_iter().collect(), Ok(ips) => ips.into_iter()
Err(_) => vec![], .collect::<Vec<Ipv4Addr>>()
.first()
.map(|x| x.to_owned()),
Err(_) => None,
}; };
let ip6: Vec<Ipv6Addr> = match resolver.ipv6_lookup("myip.opendns.com.") { let ip6 = match resolver.ipv6_lookup(domain) {
Ok(ips) => ips.into_iter().collect(), Ok(ips) => ips.into_iter()
Err(_) => vec![], .collect::<Vec<Ipv6Addr>>()
.first()
.map(|x| x.to_owned()),
Err(_) => None,
}; };
Ok((ip4, ip6))
let ip4_opt = match ip4.first() {
Some(addr) => Some(addr.to_owned()),
None => None,
};
let ip6_opt = match ip6.first() {
Some(addr) => Some(addr.to_owned()),
None => None,
};
Ok((ip4_opt, ip6_opt))
} }

View File

@ -22,7 +22,7 @@ fn main() -> anyhow::Result<()> {
} }
let conf: config::Configuration = config::Configuration::read_config(args.config.as_deref())?; let conf: config::Configuration = config::Configuration::read_config(args.config.as_deref())?;
let (ip4, ip6) = dns::get_ext_ip()?; let (ip4, ip6) = dns::get_ext_ip(&conf)?;
gandi::update_domains(conf, ip4, ip6)?; gandi::update_domains(conf, ip4, ip6)?;
Ok(()) Ok(())