mirror of
https://github.com/NLnetLabs/krill.git
synced 2026-08-17 21:25:53 +02:00
Various fixes and improvements.
- Configure Krill to run in test bed mode. - Configure nginx to proxy specific Krill locations instead of arbitrary routes. - Configure nginx to serve Krill generated RRDP files. - Configure Routinator to trust the nginx TLS certificate. - Download the Krill TAL and install it in Routinator. - Don't serve a test.txt file from nginx. - Silence nginx warning about not being able to write to /var/log/. - Add support for running Routinator in `vrps` mode and fetching the results as JSON.
This commit is contained in:
Generated
+22
-11
@@ -108,9 +108,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asn1-rs"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60"
|
||||
checksum = "b7f43a50ac4fdca5df8e885c21b835997f0a1cdee65494a6847694a98652d9d8"
|
||||
dependencies = [
|
||||
"asn1-rs-derive",
|
||||
"asn1-rs-impl",
|
||||
@@ -241,7 +241,7 @@ version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
"bit-vec 0.6.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -250,6 +250,15 @@ version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.11.0"
|
||||
@@ -596,9 +605,9 @@ checksum = "06d2e3287df1c007e74221c49ca10a95d557349e54b3a75dc2fb14712c751f04"
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.10.0"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
|
||||
checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06"
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
@@ -1638,6 +1647,7 @@ dependencies = [
|
||||
name = "krilltest"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"clap",
|
||||
"hex",
|
||||
"indoc",
|
||||
@@ -1856,9 +1866,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||
checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
@@ -2422,9 +2432,9 @@ checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
|
||||
|
||||
[[package]]
|
||||
name = "rcgen"
|
||||
version = "0.14.7"
|
||||
version = "0.14.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10b99e0098aa4082912d4c649628623db6aba77335e4f4569ff5083a6448b32e"
|
||||
checksum = "57f6d249aad744e274e682777a50283a225a32705394ee6d5fcc01efa25e4055"
|
||||
dependencies = [
|
||||
"pem",
|
||||
"ring",
|
||||
@@ -4278,10 +4288,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "yasna"
|
||||
version = "0.5.2"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
|
||||
checksum = "b5f6765e852b9b4dc8e2a76843e4d64d1cea8e79bcde0b6901aea8e7c7f08282"
|
||||
dependencies = [
|
||||
"bit-vec 0.9.1",
|
||||
"time",
|
||||
]
|
||||
|
||||
|
||||
@@ -8,14 +8,15 @@ rust-version.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
krill = { path = ".." }
|
||||
bytes = "1"
|
||||
clap = { version = "*", features = ["cargo", "derive"]}
|
||||
hex = "0.4.3"
|
||||
indoc = "2.0.7"
|
||||
krill = { path = ".." }
|
||||
nix = { version = "*", features = ["signal"] }
|
||||
rand = "0.10.2"
|
||||
rcgen = "0.14"
|
||||
reqwest = { version = "*", features = ["blocking"] }
|
||||
tempfile = "*"
|
||||
indoc = "2.0.7"
|
||||
hex = "0.4.3"
|
||||
rand = "0.10.2"
|
||||
rpki = "0.19.3"
|
||||
tempfile = "*"
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
//! The test environment.
|
||||
#![allow(unused)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::net::IpAddr;
|
||||
use std::path::PathBuf;
|
||||
use super::krill::KrillServer;
|
||||
use super::nginx::NginxServer;
|
||||
use super::routinator::Routinator;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::net::IpAddr;
|
||||
use std::path::PathBuf;
|
||||
|
||||
//------------ Environment ---------------------------------------------------
|
||||
|
||||
@@ -71,8 +69,7 @@ impl Environment {
|
||||
krill_bin,
|
||||
self.base_dir.join("krill"),
|
||||
listen,
|
||||
"https://testbed.example.com/rrdp/".into(),
|
||||
"rsync://testbed.example.com/repo/".into(),
|
||||
self.nginx.base_url(),
|
||||
true,
|
||||
);
|
||||
let name = name.to_string();
|
||||
|
||||
@@ -26,11 +26,16 @@ pub struct KrillServer {
|
||||
/// The listen address for the server.
|
||||
listen: (IpAddr, u16),
|
||||
|
||||
/// The URI for the RRDP server.
|
||||
rrdp_uri: Https,
|
||||
/// The listen address for the nginx proxy in front of Krill.
|
||||
///
|
||||
/// When Krill advertizes itself to the outside world, for example in a
|
||||
/// TAL file, it needs to mention this address, not its own address.
|
||||
public_base_url: String,
|
||||
|
||||
/// The URI for the rsync server.
|
||||
rsync_uri: Rsync,
|
||||
/// Whether or not this Krill instance should act as a testbed.
|
||||
///
|
||||
/// A testbed is a combined RPKI trust anchor and publication server.
|
||||
is_testbed: bool,
|
||||
|
||||
/// The Krill process if it is running.
|
||||
process: Option<process::Child>,
|
||||
@@ -42,22 +47,19 @@ impl KrillServer {
|
||||
krill_bin: String,
|
||||
server_dir: PathBuf,
|
||||
listen: (IpAddr, u16),
|
||||
rrdp_uri: String,
|
||||
rsync_uri: String,
|
||||
enable_ta: bool,
|
||||
public_base_url: String,
|
||||
is_testbed: bool,
|
||||
) -> Self {
|
||||
let rrdp_uri = Https::from_string(rrdp_uri).unwrap();
|
||||
let rsync_uri = Rsync::from_string(rsync_uri).unwrap();
|
||||
let mut res = Self {
|
||||
krill: krill_bin,
|
||||
server_dir,
|
||||
listen,
|
||||
rrdp_uri,
|
||||
rsync_uri,
|
||||
public_base_url,
|
||||
is_testbed,
|
||||
process: None,
|
||||
};
|
||||
fs::create_dir_all(&res.server_dir).unwrap();
|
||||
res.make_conf(enable_ta);
|
||||
res.make_conf();
|
||||
res.start();
|
||||
res
|
||||
}
|
||||
@@ -84,15 +86,29 @@ impl KrillServer {
|
||||
fn pid_file(&self) -> PathBuf {
|
||||
self.server_dir.join("krill.pid")
|
||||
}
|
||||
|
||||
/// Returns the base URL at which Krill can be contacted by clients.
|
||||
///
|
||||
/// If Krill is fronted by a proxy like nginx this will point to the
|
||||
/// proxy rather than to Krill itself.
|
||||
fn public_base_url(&self) -> &str {
|
||||
&self.public_base_url
|
||||
}
|
||||
|
||||
/// Returns the public URL at which the Trust Anchor Locator can be found.
|
||||
pub fn tal_url(&self) -> String {
|
||||
format!("{}ta/ta.tal", self.public_base_url())
|
||||
}
|
||||
}
|
||||
|
||||
/// # Setup
|
||||
impl KrillServer {
|
||||
/// Creates the Krill config.
|
||||
fn make_conf(&self, enable_ta: bool) {
|
||||
fn make_conf(&self) {
|
||||
let mut conf = File::create(self.config_path()).unwrap();
|
||||
|
||||
// Create string representations of configuration values.
|
||||
let service_uri = &self.public_base_url;
|
||||
let storage_uri =
|
||||
format!("memory://{}", hex::encode(rand::random::<[u8; 8]>()));
|
||||
// tls_keys_dir, repo_dir and pid_file must be set because we are
|
||||
@@ -122,16 +138,23 @@ impl KrillServer {
|
||||
bgp_riswhois_enabled = false
|
||||
post_protocol_msg_timeout_seconds = 10
|
||||
unix_socket = "{unix_socket}"
|
||||
service_uri = "{service_uri}"
|
||||
"#
|
||||
);
|
||||
|
||||
if enable_ta {
|
||||
let rrdp_base_uri = &self.rrdp_uri;
|
||||
let rsync_jail = &self.rsync_uri;
|
||||
let ta_aia =
|
||||
format!("rsync://{}/ta/ta.cer", rsync_jail.authority());
|
||||
let ta_uri =
|
||||
format!("https://{}/ta/ta.cer", rrdp_base_uri.authority());
|
||||
if self.is_testbed {
|
||||
// A note about rsync: we have to configure Krill with an rsync
|
||||
// URI, but Krill itself is not capable of acting as an rsync
|
||||
// server. In the rsync URIs below no port number is specified,
|
||||
// thus multiple Krill instances created with is_testbed = true
|
||||
// would refer to the same rsync server. However at the time of
|
||||
// writing there is no rsync server in our test setup and RPs are
|
||||
// expected to use RRDP rather than rsync, i.e. these URIs have to
|
||||
// be specified but will not be used.
|
||||
let rsync_jail = format!("rsync://{}/repo/", self.listen.0);
|
||||
let rrdp_base_uri = format!("{}rrdp/", self.public_base_url());
|
||||
let ta_aia = format!("rsync://{}/ta/ta.cer", self.listen.0);
|
||||
let ta_uri = format!("{}ta/ta.cer", self.public_base_url());
|
||||
|
||||
writedoc!(
|
||||
conf,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
//! Controlling an Nginx server.
|
||||
//! Controlling an Nginx server.
|
||||
use crate::utils::fmt::WriteOrPanic;
|
||||
|
||||
use std::{fs, process};
|
||||
use std::fs::File;
|
||||
use std::net::IpAddr;
|
||||
use std::path::PathBuf;
|
||||
use crate::utils::fmt::WriteOrPanic;
|
||||
use std::{fs, process};
|
||||
|
||||
use indoc::writedoc;
|
||||
|
||||
@@ -21,9 +21,6 @@ pub struct NginxServer {
|
||||
/// The listen address for the server.
|
||||
listen: (IpAddr, u16),
|
||||
|
||||
/// A map between path prefixes and directories.
|
||||
routes: Vec<(String, PathBuf)>,
|
||||
|
||||
/// The Nginx process if it is running.
|
||||
process: Option<process::Child>,
|
||||
}
|
||||
@@ -39,22 +36,14 @@ impl NginxServer {
|
||||
nginx: nginx_bin,
|
||||
server_dir,
|
||||
listen,
|
||||
routes: Default::default(),
|
||||
process: None,
|
||||
};
|
||||
|
||||
fs::create_dir_all(res.tls_path()).unwrap();
|
||||
res.make_tls();
|
||||
|
||||
fs::create_dir_all(res.root_path()).unwrap();
|
||||
fs::write(
|
||||
res.root_path().join("test.txt"),
|
||||
"test"
|
||||
).unwrap();
|
||||
|
||||
res.make_conf();
|
||||
res.start();
|
||||
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
@@ -75,7 +64,6 @@ impl Drop for NginxServer {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// # Paths to things
|
||||
impl NginxServer {
|
||||
/// Returns the directory for the TLS configuration.
|
||||
@@ -105,11 +93,14 @@ impl NginxServer {
|
||||
|
||||
/// Returns the server root path.
|
||||
fn root_path(&self) -> PathBuf {
|
||||
self.server_dir.join("http")
|
||||
// TODO: Don't hard-code the location of a specific Krill instance
|
||||
// RRDP data directory here, as we may want to serve data published by
|
||||
// multiple Krill instances.
|
||||
self.server_dir.join("../krill/data/repo/")
|
||||
}
|
||||
|
||||
/// Returns the base URL of the server.
|
||||
pub fn url(&self) -> String {
|
||||
pub fn base_url(&self) -> String {
|
||||
match self.listen.0 {
|
||||
IpAddr::V4(addr) => {
|
||||
format!("https://{}:{}/", addr, self.listen.1)
|
||||
@@ -119,11 +110,6 @@ impl NginxServer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the URL of the test file.
|
||||
pub fn test_url(&self) -> String {
|
||||
format!("{}test.txt", self.url())
|
||||
}
|
||||
}
|
||||
|
||||
/// # Setup
|
||||
@@ -154,19 +140,6 @@ impl NginxServer {
|
||||
let ssl_certificate_key = self.tls_key_path().display().to_string();
|
||||
let tmp = self.tmp_path().display().to_string();
|
||||
|
||||
let mut locations = String::new();
|
||||
for (location, alias) in &self.routes {
|
||||
let alias = alias.display().to_string();
|
||||
writedoc!(
|
||||
locations,
|
||||
r#"
|
||||
location {location} {{
|
||||
alias {alias};
|
||||
}}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
// Write the NGINX config file using the strings we just created.
|
||||
writedoc!(
|
||||
conf,
|
||||
@@ -174,6 +147,12 @@ impl NginxServer {
|
||||
events {{}}
|
||||
daemon off;
|
||||
pid {tmp}/pid;
|
||||
# error_log set here occurs too late to prevent a warning
|
||||
# during nginx startup about not being able to write to
|
||||
# /var/log/nginx/error.log, to solve that we pass -e when
|
||||
# launching nginx. We do however need to specify error_log
|
||||
# here if we want to control the level at which nginx logs.
|
||||
# error_log /dev/stdout debug;
|
||||
http {{
|
||||
proxy_temp_path {tmp};
|
||||
fastcgi_temp_path {tmp};
|
||||
@@ -187,7 +166,56 @@ impl NginxServer {
|
||||
ssl_certificate {ssl_certificate};
|
||||
ssl_certificate_key {ssl_certificate_key};
|
||||
client_body_temp_path {tmp};
|
||||
{locations}
|
||||
|
||||
# From Krill docs:
|
||||
client_max_body_size 128m;
|
||||
|
||||
# TODO: Make the location blocks below dynamically
|
||||
# generated rather than hard-coded, so that we can
|
||||
# support multiple Krill instances behind the nginx.
|
||||
|
||||
# Proxy RFC 8181 publication server requests to Krill.
|
||||
location /rfc8181 {{
|
||||
proxy_pass https://127.0.0.1:3001/rfc8181;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# krill does not use a valid certificate/tls is handled by nginx
|
||||
proxy_ssl_verify off;
|
||||
}}
|
||||
|
||||
# Proxy Krill API requests to Krill.
|
||||
location /api {{
|
||||
proxy_pass https://127.0.0.1:3001/api;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# allow IPv4 and IPv6 documentation ranges
|
||||
# allow 192.0.2.0/24;
|
||||
# allow 2001:0db8::/32;
|
||||
# deny all;
|
||||
|
||||
# krill does not use a valid certificate/tls is handled by nginx
|
||||
proxy_ssl_verify off;
|
||||
}}
|
||||
|
||||
# Serve RRDP files generated by Krill
|
||||
# This is handled by the 'root' directive above.
|
||||
|
||||
location /ta {{
|
||||
proxy_pass https://127.0.0.1:3001/ta;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# krill does not use a valid certificate/tls is handled by nginx
|
||||
proxy_ssl_verify off;
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
//! Controlling a Routinator.
|
||||
#![allow(unused)]
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use crate::utils::fmt::WriteOrPanic;
|
||||
|
||||
use std::fs::File;
|
||||
use std::net::IpAddr;
|
||||
use std::os::unix::process::CommandExt;
|
||||
use std::path::PathBuf;
|
||||
use std::{fs, process};
|
||||
|
||||
use indoc::writedoc;
|
||||
|
||||
//------------ Routinator ----------------------------------------------------
|
||||
|
||||
@@ -15,8 +21,8 @@ pub struct Routinator {
|
||||
/// The directory where Routinator will keep its stuff.
|
||||
base_dir: PathBuf,
|
||||
|
||||
/// Path to the TLS certificate used by Nginx server.
|
||||
tls_cert_path: PathBuf,
|
||||
/// The path to the TLS certificate used by the RRDP server.
|
||||
rrdp_tls_cert_path: PathBuf,
|
||||
}
|
||||
|
||||
impl Routinator {
|
||||
@@ -26,16 +32,99 @@ impl Routinator {
|
||||
pub fn new(
|
||||
routinator_bin: PathBuf,
|
||||
base_dir: PathBuf,
|
||||
tls_cert_path: PathBuf,
|
||||
rrdp_tls_cert_path: PathBuf,
|
||||
) -> Self {
|
||||
let res = Self {
|
||||
let mut res = Self {
|
||||
routinator: routinator_bin,
|
||||
base_dir,
|
||||
tls_cert_path,
|
||||
rrdp_tls_cert_path,
|
||||
};
|
||||
fs::create_dir(&res.base_dir).unwrap();
|
||||
fs::create_dir(&res.extra_tals_dir()).unwrap();
|
||||
res.make_conf();
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
/// # Paths and URLs
|
||||
impl Routinator {
|
||||
/// Returns the path to the Routinator config file.
|
||||
fn config_path(&self) -> PathBuf {
|
||||
self.base_dir.join("routinator.conf")
|
||||
}
|
||||
|
||||
/// Returns the Routinator repository directory
|
||||
fn repo_dir(&self) -> PathBuf {
|
||||
self.base_dir.join("rpki-cache")
|
||||
}
|
||||
|
||||
fn extra_tals_dir(&self) -> PathBuf {
|
||||
self.base_dir.join("extra-tals")
|
||||
}
|
||||
}
|
||||
|
||||
/// # Setup
|
||||
impl Routinator {
|
||||
fn make_conf(&self) {
|
||||
let mut conf = File::create(self.config_path()).unwrap();
|
||||
|
||||
// Create string representations of configuration values.
|
||||
let repository_dir = self.repo_dir().display().to_string();
|
||||
let rrdp_root_cert_path =
|
||||
self.rrdp_tls_cert_path.display().to_string();
|
||||
|
||||
// Write the Routinator config file using the strings we just created.
|
||||
writedoc!(
|
||||
conf,
|
||||
r#"
|
||||
repository-dir = "{repository_dir}"
|
||||
log = "stderr"
|
||||
log-level = "info"
|
||||
rrdp-root-certs = ["{rrdp_root_cert_path}"]
|
||||
allow-dubious-hosts = true
|
||||
#disable-rsync = true
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
/// Store the given TAL bytes as a file in the correct location so that
|
||||
/// Routinator will use it.
|
||||
pub fn install_tal(&self, name: &str, bytes: &[u8]) {
|
||||
let mut f = File::create_new(
|
||||
self.extra_tals_dir().join(name).with_added_extension("tal"),
|
||||
)
|
||||
.unwrap();
|
||||
std::io::Write::write_all(&mut f, bytes).unwrap();
|
||||
}
|
||||
|
||||
/// Update the local repository, validate the ROAs and return the VRPs.
|
||||
///
|
||||
/// TODO: Deserialize the JSON into Rust data types.
|
||||
pub fn vrps(&self) -> Vec<u8> {
|
||||
let output = process::Command::new(&self.routinator)
|
||||
.args([
|
||||
// Tell Routinator where to find its config file.
|
||||
"-c",
|
||||
&self.config_path().display().to_string(),
|
||||
// Don't use any of the default Trust Anchor Locators.
|
||||
"--no-rir-tals",
|
||||
// Use only the TAL of our Krill instance.
|
||||
"--extra-tals-dir",
|
||||
&self.extra_tals_dir().display().to_string(),
|
||||
// Do a one time validation run.
|
||||
"vrps",
|
||||
// Output in JSON format.
|
||||
"--format",
|
||||
"json",
|
||||
// Output to standard output.
|
||||
"--output",
|
||||
"-",
|
||||
])
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait_with_output()
|
||||
.unwrap();
|
||||
|
||||
output.stdout
|
||||
}
|
||||
}
|
||||
|
||||
+74
-10
@@ -4,12 +4,18 @@
|
||||
//! scenarios involve setting up one or more Krill instances, issue commands
|
||||
//! to them, and then verifying the results by checking the data set output
|
||||
//! by a Routinator validation run.
|
||||
use krilltest::environment::Environment;
|
||||
|
||||
use std::io::Read;
|
||||
use std::io::Write;
|
||||
use std::net::IpAddr;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use clap::Parser;
|
||||
use clap::crate_version;
|
||||
use krilltest::environment::Environment;
|
||||
use std::net::IpAddr;
|
||||
use std::path::PathBuf;
|
||||
use tempfile::TempDir;
|
||||
|
||||
//------------ main ----------------------------------------------------------
|
||||
@@ -31,15 +37,73 @@ fn main() {
|
||||
args.routinator,
|
||||
);
|
||||
|
||||
let some_free_port = args.rrdp_port + 1;
|
||||
let krill_listen = (args.listen_addr, some_free_port);
|
||||
let _krill = environment.add_krill("first", args.krill, krill_listen);
|
||||
// Add a Krill test bed to the test environment and get the location of
|
||||
// Trust Anchor Locator so that we can install it for Routinator to use.
|
||||
let tal_url = {
|
||||
// TODO: Allocate a port that isn't already in use, don't just do +1.
|
||||
let some_free_port1 = args.rrdp_port + 1;
|
||||
let krill_listen = (args.listen_addr, some_free_port1);
|
||||
let krill = environment.add_krill("first", args.krill, krill_listen);
|
||||
krill.tal_url()
|
||||
};
|
||||
|
||||
eprintln!("Hit enter to quit.");
|
||||
// Load the TLS certificate that can be used to verify that a TLS
|
||||
// connection to Krill can be trusted. The alternative would be to use the
|
||||
// reqwest `danger_accept_invalid_certs(true)` functionality but this is
|
||||
// more correct, but also more verbose.
|
||||
let tls_cert = load_tls_cert(&environment.nginx().tls_cert_path());
|
||||
|
||||
let mut buffer = String::new();
|
||||
let stdin = std::io::stdin();
|
||||
stdin.read_line(&mut buffer).unwrap();
|
||||
// Fetch the Krill TAL and install it in the Routinator extra tals
|
||||
// directory.
|
||||
let tal_bytes = fetch_url(tal_url, tls_cert, 5);
|
||||
|
||||
// Configure Routinator to use the Krill TAL.
|
||||
environment.routinator().install_tal("Krill", &tal_bytes);
|
||||
|
||||
// Do a Routinator validation run and fetch the available VRPs.
|
||||
std::io::stdout()
|
||||
.write_all(&environment.routinator().vrps())
|
||||
.unwrap();
|
||||
|
||||
// TODO: Actually add ROAs to Krill and verify that the fetched VRPs are
|
||||
// correct.
|
||||
}
|
||||
|
||||
fn load_tls_cert(tls_cert_path: &Path) -> reqwest::Certificate {
|
||||
let mut f = std::fs::File::open(tls_cert_path).unwrap();
|
||||
let mut tls_ca_cert_pem_bytes = vec![];
|
||||
f.read_to_end(&mut tls_ca_cert_pem_bytes).unwrap();
|
||||
drop(f);
|
||||
let tls_ca_cert =
|
||||
reqwest::Certificate::from_pem(&tls_ca_cert_pem_bytes).unwrap();
|
||||
tls_ca_cert
|
||||
}
|
||||
|
||||
fn fetch_url(
|
||||
url: String,
|
||||
tls_cert: reqwest::Certificate,
|
||||
max_tries: u8,
|
||||
) -> bytes::Bytes {
|
||||
let trusting_client = reqwest::blocking::Client::builder()
|
||||
.tls_certs_only([tls_cert])
|
||||
.build()
|
||||
.unwrap();
|
||||
let mut tries_left = max_tries;
|
||||
while tries_left > 0 {
|
||||
match trusting_client.get(&url).send() {
|
||||
Ok(bytes) => {
|
||||
return bytes.bytes().unwrap();
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"{url} not yet available, will retry in 1 second: {err}"
|
||||
);
|
||||
sleep(Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
tries_left -= 1;
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
//------------ Args ----------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user