enable multiple dns servers
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -161,6 +161,7 @@ name = "dns-comunications"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"dns-config",
|
||||
"dns-update",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
[key]
|
||||
[zone]
|
||||
root_domain = "root.domain.example"
|
||||
|
||||
[[server]]
|
||||
conection_str = "tcp://127.0.0.1:53"
|
||||
|
||||
[server.key]
|
||||
name = "key name"
|
||||
value = "key in base64"
|
||||
|
||||
[zone]
|
||||
root_domain = "root.domain.example"
|
||||
conection_str = "tcp://127.0.0.1:53"
|
||||
[[server]]
|
||||
conection_str = "udp://192.168.1.1:53"
|
||||
|
||||
[server.key]
|
||||
name = "key name"
|
||||
value = "key in base64"
|
||||
|
||||
@@ -6,3 +6,4 @@ edition = "2024"
|
||||
[dependencies]
|
||||
dns-update = "0.1"
|
||||
base64 = "*"
|
||||
dns-config = {path = "../dns-config"}
|
||||
|
||||
@@ -1,39 +1,53 @@
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use dns_update::{DnsRecord, DnsRecordType, DnsUpdater, TsigAlgorithm};
|
||||
use base64::engine::general_purpose::STANDARD;
|
||||
use base64::Engine;
|
||||
use base64::engine::general_purpose::STANDARD;
|
||||
use dns_update::{DnsUpdater, TsigAlgorithm};
|
||||
|
||||
use dns_config::ServerZonesConnection;
|
||||
|
||||
mod utils;
|
||||
|
||||
pub struct DnsManager {
|
||||
pub dns_updater: DnsUpdater,
|
||||
pub zone: String
|
||||
pub dns_updaters: Vec<DnsUpdater>,
|
||||
pub zone: String,
|
||||
}
|
||||
|
||||
impl DnsManager {
|
||||
pub fn new(conection_str: String, key_name: String, key: String, zone: String) -> Self {
|
||||
Self {
|
||||
dns_updater: DnsUpdater::new_rfc2136_tsig(
|
||||
conection_str,
|
||||
key_name,
|
||||
STANDARD.decode(key).unwrap(),
|
||||
TsigAlgorithm::HmacSha256.into()
|
||||
).unwrap(),
|
||||
zone
|
||||
pub fn new(zones_data: ServerZonesConnection) -> Result<Self, dns_update::Error> {
|
||||
let mut dns_updaters = Vec::new();
|
||||
for zone_data in zones_data.servers_data {
|
||||
dns_updaters.push(DnsUpdater::new_rfc2136_tsig(
|
||||
zone_data.conection_str,
|
||||
zone_data.key_name,
|
||||
#[allow(unreachable_code)]
|
||||
STANDARD.decode(zone_data.key).unwrap_or(continue),
|
||||
TsigAlgorithm::HmacSha256.into(),
|
||||
)?);
|
||||
}
|
||||
Ok(Self {
|
||||
dns_updaters,
|
||||
zone: zones_data.root_domain,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn add_domain(&self, domain_name: &String, domain_ip: Ipv4Addr) {
|
||||
pub async fn add_domain(
|
||||
&self,
|
||||
domain_name: &String,
|
||||
domain_ip: Ipv4Addr,
|
||||
) -> Result<(), dns_update::Error> {
|
||||
let domain = format!("{}.{}", domain_name, self.zone);
|
||||
self.dns_updater.create(
|
||||
domain,
|
||||
DnsRecord::A { content: domain_ip },
|
||||
300,
|
||||
self.zone.clone()
|
||||
).await.unwrap();
|
||||
for dns_updater in &self.dns_updaters {
|
||||
utils::add_domain(dns_updater, &domain, &self.zone, domain_ip).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn del_domain(&self, domain_name: &String) {
|
||||
pub async fn del_domain(&self, domain_name: &String) -> Result<(), dns_update::Error> {
|
||||
let domain = format!("{}.{}", domain_name, self.zone);
|
||||
self.dns_updater.delete(domain, self.zone.clone(), DnsRecordType::A).await.unwrap();
|
||||
for dns_updater in &self.dns_updaters {
|
||||
utils::del_domain(dns_updater, &domain, &self.zone).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
22
dns-comunications/src/utils.rs
Normal file
22
dns-comunications/src/utils.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use dns_update::{DnsRecord, DnsRecordType, DnsUpdater};
|
||||
|
||||
pub async fn add_domain(
|
||||
dns_updater: &DnsUpdater,
|
||||
domain: &str,
|
||||
zone: &str,
|
||||
domain_ip: Ipv4Addr,
|
||||
) -> Result<(), dns_update::Error> {
|
||||
dns_updater
|
||||
.create(domain, DnsRecord::A { content: domain_ip }, 300, zone)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn del_domain(
|
||||
dns_updater: &DnsUpdater,
|
||||
domain: &str,
|
||||
zone: &str,
|
||||
) -> Result<(), dns_update::Error> {
|
||||
dns_updater.delete(domain, zone, DnsRecordType::A).await
|
||||
}
|
||||
@@ -1,36 +1,46 @@
|
||||
use std::fs::read_to_string;
|
||||
use toml::Table;
|
||||
|
||||
pub struct KeyData {
|
||||
pub struct ZoneConnectionData {
|
||||
pub conection_str: String,
|
||||
pub key_name: String,
|
||||
pub key: String,
|
||||
}
|
||||
|
||||
pub struct ZoneData {
|
||||
pub struct ServerZonesConnection {
|
||||
pub root_domain: String,
|
||||
pub conection_str: String,
|
||||
pub servers_data: Vec<ZoneConnectionData>,
|
||||
}
|
||||
|
||||
impl KeyData {
|
||||
pub fn get_config(file_name: &String) -> Self {
|
||||
impl ZoneConnectionData {
|
||||
pub fn get_config(file_name: &String) -> Vec<Self> {
|
||||
let mut ret = Vec::new();
|
||||
let key_toml = read_to_string(file_name).unwrap().parse::<Table>().unwrap();
|
||||
let name: String = key_toml["key"]["name"].as_str().unwrap().to_string();
|
||||
let value: String = key_toml["key"]["value"].as_str().unwrap().to_string();
|
||||
Self {
|
||||
key_name: name,
|
||||
key: value
|
||||
for servers in key_toml["server"].as_array().unwrap() {
|
||||
let conection_str: String = servers["connection_str"].as_str().unwrap().to_string();
|
||||
let key_name: String = servers["key"]["name"].as_str().unwrap().to_string();
|
||||
let key: String = servers["key"]["value"].as_str().unwrap().to_string();
|
||||
ret.push(Self {
|
||||
conection_str,
|
||||
key_name,
|
||||
key,
|
||||
});
|
||||
}
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl ZoneData {
|
||||
impl ServerZonesConnection {
|
||||
pub fn get_config(file_name: &String) -> Self {
|
||||
let key_toml = read_to_string(file_name).unwrap().parse::<Table>().unwrap();
|
||||
let root_domain: String = key_toml["zone"]["root_domain"].as_str().unwrap().to_string();
|
||||
let conection_str: String = key_toml["zone"]["conection_str"].as_str().unwrap().to_string();
|
||||
let root_domain: String = key_toml["zone"]["root_domain"]
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
Self {
|
||||
root_domain,
|
||||
conection_str
|
||||
servers_data: ZoneConnectionData::get_config(file_name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
src/main.rs
18
src/main.rs
@@ -5,14 +5,14 @@ use dns_config;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let key = dns_config::KeyData::get_config(&"config.toml".to_string());
|
||||
let zone = dns_config::ZoneData::get_config(&"config.toml".to_string());
|
||||
let dns_manager = dns_comunications::DnsManager::new(
|
||||
zone.conection_str,
|
||||
key.key_name,
|
||||
key.key,
|
||||
zone.root_domain);
|
||||
let zone_data = dns_config::ServerZonesConnection::get_config(&"config.toml".to_string());
|
||||
let dns_manager = dns_comunications::DnsManager::new(zone_data).unwrap();
|
||||
|
||||
dns_manager.add_domain(&"test001".to_string(), Ipv4Addr::from_str("1.1.1.1").unwrap()).await;
|
||||
dns_manager.del_domain(&"test000".to_string()).await;
|
||||
_ = dns_manager
|
||||
.add_domain(
|
||||
&"testzone".to_string(),
|
||||
Ipv4Addr::from_str("1.1.1.1").unwrap(),
|
||||
)
|
||||
.await;
|
||||
_ = dns_manager.del_domain(&"testzone".to_string()).await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user