Skip to content
This repository has been archived by the owner on Jun 7, 2024. It is now read-only.

Commit

Permalink
Merge pull request #31 from ferrous-systems/ja-explore-opt-in-dnssec
Browse files Browse the repository at this point in the history
`explore`: make DNSSEC opt-in
  • Loading branch information
japaric authored May 22, 2024
2 parents a9c6e42 + 5d15aa2 commit 3a54e69
Showing 1 changed file with 100 additions and 34 deletions.
134 changes: 100 additions & 34 deletions packages/dns-test/examples/explore.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::env;
use std::net::Ipv4Addr;
use std::sync::mpsc;

use dns_test::client::Client;
Expand All @@ -7,6 +9,8 @@ use dns_test::zone_file::Root;
use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN};

fn main() -> Result<()> {
let args = Args::from_env()?;

let network = Network::new()?;
let peer = &dns_test::PEER;

Expand All @@ -21,32 +25,60 @@ fn main() -> Result<()> {
nameservers_ns
.add(Record::a(root_ns.fqdn().clone(), root_ns.ipv4_addr()))
.add(Record::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(),
)
.add(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())
.add(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 nameservers_ns = if args.dnssec {
let nameservers_ns = nameservers_ns.sign()?;
com_ns.add(nameservers_ns.ds().clone());
nameservers_ns.start()?
} else {
nameservers_ns.start()?
};

com_ns.referral(
nameservers_ns.zone().clone(),
nameservers_ns.fqdn().clone(),
nameservers_ns.ipv4_addr(),
);

let com_ns = if args.dnssec {
let com_ns = com_ns.sign()?;
root_ns.add(com_ns.ds().clone());
com_ns.start()?
} else {
com_ns.start()?
};

root_ns.referral(FQDN::COM, com_ns.fqdn().clone(), com_ns.ipv4_addr());

let mut trust_anchor = TrustAnchor::empty();
let root_ns = if args.dnssec {
let root_ns = root_ns.sign()?;
let root_ksk = root_ns.key_signing_key();
let root_zsk = root_ns.zone_signing_key();

trust_anchor.add(root_ksk.clone());
trust_anchor.add(root_zsk.clone());

root_ns.start()?
} else {
root_ns.start()?
};

println!("DONE");

let trust_anchor = TrustAnchor::from_iter([root_ksk.clone(), root_zsk.clone()]);
let client = Client::new(&network)?;
if args.dnssec {
// this will send queries to the loopback address and fail because there's no resolver
// but as a side-effect it will generate the `/etc/bind.keys` file we want
// ignore the expected error
let _ = client.delv(
Ipv4Addr::new(127, 0, 0, 1),
RecordType::SOA,
&FQDN::ROOT,
&trust_anchor,
)?;
}

println!("building docker image...");
let resolver = Resolver::new(
&network,
Expand All @@ -56,11 +88,6 @@ fn main() -> Result<()> {
.start(&dns_test::SUBJECT)?;
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"))?;
Expand All @@ -86,7 +113,8 @@ fn main() -> Result<()> {
nameservers_ns.container_id()
);

println!("resolver's IP address: {resolver_addr}");
let resolver_addr = resolver.ipv4_addr();
println!("resolver's IP address: {resolver_addr}",);
println!(
"attach to this container with: `docker exec -it {} bash`\n",
resolver.container_id()
Expand All @@ -99,10 +127,13 @@ fn main() -> Result<()> {
);

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"
);
let adflag = if args.dnssec { "+adflag" } else { "+noadflag" };
println!("`dig @{resolver_addr} {adflag} SOA .`\n");
if args.dnssec {
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
Expand All @@ -118,3 +149,38 @@ the resolver container before performing queries:\n"

Ok(())
}

struct Args {
dnssec: bool,
}

impl Args {
fn from_env() -> Result<Self> {
let args: Vec<_> = env::args().skip(1).collect();
let num_args = args.len();

let dnssec = if num_args == 0 {
false
} else if num_args == 1 {
if args[0] == "--dnssec" {
true
} else {
return cli_error();
}
} else {
return cli_error();
};

Ok(Self { dnssec })
}
}

fn cli_error<T>() -> Result<T> {
eprintln!(
"usage: explore [--dnssec]
Options:
--dnssec sign zone files to enable DNSSEC"
);

Err("CLI error".into())
}

0 comments on commit 3a54e69

Please sign in to comment.