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 std::sync::mpsc;
|
||||||
|
|
||||||
use dns_test::client::Client;
|
use dns_test::client::Client;
|
||||||
@ -7,6 +9,8 @@ use dns_test::zone_file::Root;
|
|||||||
use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN};
|
use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN};
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
|
let args = Args::from_env()?;
|
||||||
|
|
||||||
let network = Network::new()?;
|
let network = Network::new()?;
|
||||||
let peer = &dns_test::PEER;
|
let peer = &dns_test::PEER;
|
||||||
|
|
||||||
@ -21,32 +25,60 @@ fn main() -> Result<()> {
|
|||||||
nameservers_ns
|
nameservers_ns
|
||||||
.add(Record::a(root_ns.fqdn().clone(), root_ns.ipv4_addr()))
|
.add(Record::a(root_ns.fqdn().clone(), root_ns.ipv4_addr()))
|
||||||
.add(Record::a(com_ns.fqdn().clone(), com_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
|
let nameservers_ns = if args.dnssec {
|
||||||
.referral(
|
let nameservers_ns = nameservers_ns.sign()?;
|
||||||
nameservers_ns.zone().clone(),
|
com_ns.add(nameservers_ns.ds().clone());
|
||||||
nameservers_ns.fqdn().clone(),
|
nameservers_ns.start()?
|
||||||
nameservers_ns.ipv4_addr(),
|
} else {
|
||||||
)
|
nameservers_ns.start()?
|
||||||
.add(nameservers_ds);
|
};
|
||||||
let com_ns = com_ns.sign()?;
|
|
||||||
let com_ds = com_ns.ds().clone();
|
|
||||||
let com_ns = com_ns.start()?;
|
|
||||||
|
|
||||||
root_ns
|
com_ns.referral(
|
||||||
.referral(FQDN::COM, com_ns.fqdn().clone(), com_ns.ipv4_addr())
|
nameservers_ns.zone().clone(),
|
||||||
.add(com_ds);
|
nameservers_ns.fqdn().clone(),
|
||||||
let root_ns = root_ns.sign()?;
|
nameservers_ns.ipv4_addr(),
|
||||||
let root_ksk = root_ns.key_signing_key().clone();
|
);
|
||||||
let root_zsk = root_ns.zone_signing_key().clone();
|
|
||||||
|
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");
|
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...");
|
println!("building docker image...");
|
||||||
let resolver = Resolver::new(
|
let resolver = Resolver::new(
|
||||||
&network,
|
&network,
|
||||||
@ -56,11 +88,6 @@ fn main() -> Result<()> {
|
|||||||
.start(&dns_test::SUBJECT)?;
|
.start(&dns_test::SUBJECT)?;
|
||||||
println!("DONE\n\n");
|
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();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
ctrlc::set_handler(move || tx.send(()).expect("could not forward signal"))?;
|
ctrlc::set_handler(move || tx.send(()).expect("could not forward signal"))?;
|
||||||
@ -86,7 +113,8 @@ fn main() -> Result<()> {
|
|||||||
nameservers_ns.container_id()
|
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!(
|
println!(
|
||||||
"attach to this container with: `docker exec -it {} bash`\n",
|
"attach to this container with: `docker exec -it {} bash`\n",
|
||||||
resolver.container_id()
|
resolver.container_id()
|
||||||
@ -99,10 +127,13 @@ fn main() -> Result<()> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
println!("example queries (run these in the client container):\n");
|
println!("example queries (run these in the client container):\n");
|
||||||
println!("`dig @{resolver_addr} SOA .`\n");
|
let adflag = if args.dnssec { "+adflag" } else { "+noadflag" };
|
||||||
println!(
|
println!("`dig @{resolver_addr} {adflag} SOA .`\n");
|
||||||
"`delv -a /etc/bind.keys @{resolver_addr} SOA .` (you MUST use the `-a` flag with delv)\n\n"
|
if args.dnssec {
|
||||||
);
|
println!(
|
||||||
|
"`delv -a /etc/bind.keys @{resolver_addr} SOA .` (you MUST use the `-a` flag with delv)\n\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"to print the DNS traffic flowing through the resolver run this command in
|
"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(())
|
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