Merge pull request #31 from ferrous-systems/ja-explore-opt-in-dnssec
`explore`: make DNSSEC opt-in
This commit is contained in:
commit
3a54e693fa
|
@ -1,3 +1,5 @@
|
|||
use std::env;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::sync::mpsc;
|
||||
|
||||
use dns_test::client::Client;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()?;
|
||||
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()?
|
||||
};
|
||||
|
||||
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();
|
||||
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()?
|
||||
};
|
||||
|
||||
let root_ns = 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,
|
||||
|
@ -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"))?;
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user