From 86284cce4b5aa39ca3b0c761c002fc45334c7a80 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 20 Feb 2024 15:59:52 +0100 Subject: [PATCH] add `explore` example --- Cargo.lock | 22 +++++ packages/dns-test/Cargo.toml | 3 + packages/dns-test/examples/explore.rs | 116 ++++++++++++++++++++++++++ packages/dns-test/src/client.rs | 4 + packages/dns-test/src/name_server.rs | 8 +- packages/dns-test/src/resolver.rs | 4 + 6 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 packages/dns-test/examples/explore.rs diff --git a/Cargo.lock b/Cargo.lock index 35d020f5..2a3639b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,6 +88,16 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "ctrlc" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b" +dependencies = [ + "nix", + "windows-sys", +] + [[package]] name = "darling" version = "0.20.5" @@ -137,6 +147,7 @@ dependencies = [ name = "dns-test" version = "0.1.0" dependencies = [ + "ctrlc", "minijinja", "serde", "serde_json", @@ -303,6 +314,17 @@ dependencies = [ "serde", ] +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "libc", +] + [[package]] name = "num-conv" version = "0.1.0" diff --git a/packages/dns-test/Cargo.toml b/packages/dns-test/Cargo.toml index 20b13d33..7dc0924a 100644 --- a/packages/dns-test/Cargo.toml +++ b/packages/dns-test/Cargo.toml @@ -15,3 +15,6 @@ url = "2.5.0" [lib] doctest = false + +[dev-dependencies] +ctrlc = "3.4.2" diff --git a/packages/dns-test/examples/explore.rs b/packages/dns-test/examples/explore.rs new file mode 100644 index 00000000..112c211d --- /dev/null +++ b/packages/dns-test/examples/explore.rs @@ -0,0 +1,116 @@ +use std::sync::mpsc; + +use dns_test::client::Client; +use dns_test::name_server::NameServer; +use dns_test::record::RecordType; +use dns_test::zone_file::Root; +use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN}; + +fn main() -> Result<()> { + let network = Network::new()?; + + println!("building docker image..."); + let mut root_ns = NameServer::new(FQDN::ROOT, &network)?; + println!("DONE"); + + println!("setting up name servers..."); + let mut com_ns = NameServer::new(FQDN::COM, &network)?; + + let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?, &network)?; + nameservers_ns + .a(root_ns.fqdn().clone(), root_ns.ipv4_addr()) + .a(com_ns.fqdn().clone(), com_ns.ipv4_addr()); + let nameservers_ns = nameservers_ns.sign()?; + let nameservers_ds = nameservers_ns.ds().clone(); + let nameservers_ns = nameservers_ns.start()?; + + com_ns + .referral( + nameservers_ns.zone().clone(), + nameservers_ns.fqdn().clone(), + nameservers_ns.ipv4_addr(), + ) + .ds(nameservers_ds); + let com_ns = com_ns.sign()?; + let com_ds = com_ns.ds().clone(); + let com_ns = com_ns.start()?; + + root_ns + .referral(FQDN::COM, com_ns.fqdn().clone(), com_ns.ipv4_addr()) + .ds(com_ds); + let root_ns = root_ns.sign()?; + let root_ksk = root_ns.key_signing_key().clone(); + let root_zsk = root_ns.zone_signing_key().clone(); + + let root_ns = root_ns.start()?; + + let roots = &[Root::new(root_ns.fqdn().clone(), root_ns.ipv4_addr())]; + println!("DONE"); + + let trust_anchor = TrustAnchor::from_iter([root_ksk.clone(), root_zsk.clone()]); + println!("building docker image..."); + let resolver = Resolver::start(dns_test::subject(), roots, &trust_anchor, &network)?; + println!("DONE\n\n"); + + let resolver_addr = resolver.ipv4_addr(); + let client = Client::new(&network)?; + // generate `/etc/bind.keys` + client.delv(resolver_addr, RecordType::SOA, &FQDN::ROOT, &trust_anchor)?; + + let (tx, rx) = mpsc::channel(); + + ctrlc::set_handler(move || tx.send(()).expect("could not forward signal"))?; + + println!(". (root) name server's IP address: {}", root_ns.ipv4_addr()); + println!( + "attach to this container with: `docker exec -it {} bash`\n", + root_ns.container_id() + ); + + println!("com. name server's IP address: {}", com_ns.ipv4_addr()); + println!( + "attach to this container with: `docker exec -it {} bash`\n", + com_ns.container_id() + ); + + println!( + "nameservers.com. name server's IP address: {}", + nameservers_ns.ipv4_addr() + ); + println!( + "attach to this container with: `docker exec -it {} bash`\n", + nameservers_ns.container_id() + ); + + println!("resolver's IP address: {resolver_addr}"); + println!( + "attach to this container with: `docker exec -it {} bash`\n", + resolver.container_id() + ); + + println!("client's IP address: {}", client.ipv4_addr()); + println!( + "attach to this container with: `docker exec -it {} bash`\n\n", + client.container_id() + ); + + println!("example queries (run these in the client container):\n"); + println!("`dig @{resolver_addr} SOA .`\n"); + println!( + "`delv -a /etc/bind.keys @{resolver_addr} SOA .` (you MUST use the `-a` flag with delv)\n\n" + ); + + println!( + "to print the DNS traffic flowing through the resolver run this command in +the resolver container before performing queries:\n" + ); + println!("`tshark -f 'udp port 53' -O dns`\n\n"); + + println!("press Ctrl+C to take down the network"); + + rx.recv()?; + + println!("\ntaking down network..."); + + Ok(()) +} diff --git a/packages/dns-test/src/client.rs b/packages/dns-test/src/client.rs index b66b73ca..e283498d 100644 --- a/packages/dns-test/src/client.rs +++ b/packages/dns-test/src/client.rs @@ -17,6 +17,10 @@ impl Client { }) } + pub fn container_id(&self) -> &str { + self.inner.id() + } + pub fn ipv4_addr(&self) -> Ipv4Addr { self.inner.ipv4_addr() } diff --git a/packages/dns-test/src/name_server.rs b/packages/dns-test/src/name_server.rs index 8033b676..dc97b89f 100644 --- a/packages/dns-test/src/name_server.rs +++ b/packages/dns-test/src/name_server.rs @@ -156,10 +156,6 @@ impl<'a> NameServer<'a, Stopped> { state: Running { child }, }) } - - pub fn container_id(&self) -> &str { - self.container.id() - } } const ZONES_DIR: &str = "/etc/nsd/zones"; @@ -245,6 +241,10 @@ kill -TERM $(cat {pidfile})" } impl<'a, S> NameServer<'a, S> { + pub fn container_id(&self) -> &str { + self.container.id() + } + pub fn ipv4_addr(&self) -> Ipv4Addr { self.container.ipv4_addr() } diff --git a/packages/dns-test/src/resolver.rs b/packages/dns-test/src/resolver.rs index 091e59b1..c6773ab7 100644 --- a/packages/dns-test/src/resolver.rs +++ b/packages/dns-test/src/resolver.rs @@ -77,6 +77,10 @@ impl Resolver { self.container.eavesdrop() } + pub fn container_id(&self) -> &str { + self.container.id() + } + pub fn ipv4_addr(&self) -> Ipv4Addr { self.container.ipv4_addr() }