Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ podman rm kartograf-run

#### rpki-client

Kartograf requires `rpki-client` version 8.4 or higher to be installed locally. Many package managers have `rpki-client`, however please note that typically only the latest version is available. Kartograf is currently tested to work with `rpki-client` 8.4 - 9.7. If a new release is available that breaks compatibility, you may need to build a compatible `rpki-client` version yourself if your preferred package manager does not have a compatible version available. In that case, see the [instructions in the rpki-client-portable project](https://github.com/rpki-client/rpki-client-portable/blob/master/INSTALL).
Kartograf requires `rpki-client` version 9.6 or higher to be installed locally. Many package managers have `rpki-client`, however please note that typically only the latest version is available. Kartograf is currently tested to work with `rpki-client` 9.6 - 9.7. If a new release is available that breaks compatibility, you may need to build a compatible `rpki-client` version yourself if your preferred package manager does not have a compatible version available. In that case, see the [instructions in the rpki-client-portable project](https://github.com/rpki-client/rpki-client-portable/blob/master/INSTALL).

```
# Linux/BSD
Expand Down
37 changes: 27 additions & 10 deletions kartograf/rpki/fetch.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import re
import subprocess
import sys

Expand Down Expand Up @@ -73,26 +74,34 @@ def fetch_rpki_db(context):
# Download TALs and presist them in the RPKI data folder
download_rir_tals(context)
tal_options = [item for path in data_tals(context) for item in ('-t', path)]
run_args = ["rpki-client", "-d", context.data_dir_rpki_cache] + tal_options
run_args = ["rpki-client", "-d", context.data_dir_rpki_cache,
"-P", context.epoch] + tal_options
print("Downloading RPKI Data, this may take a while.")

if context.stable_repos:
for url in STABLE_REPO_URLS:
run_args += ["-H", url]
print("Using only stable RPKI repositories.")

# rpki-client requires a writable output directory as a positional
# argument. Without one it falls back to a compiled-in default that
# is not writable in some environments (e.g. nix), which makes it
# exit before emitting the CCR hashes.
run_args.append(context.out_dir_rpki)

result = subprocess.run(run_args,
capture_output=True,
check=False)

if context.debug_log:
with open(context.debug_log, 'a') as logs:
logs.write("=== RPKI Download ===\n")
logs.flush() # Without this the line above is not appearing first in the logs
subprocess.run(run_args,
stdout=logs,
stderr=logs,
check=False)
else:
subprocess.run(run_args,
capture_output=True,
check=False)
if result.stdout:
logs.write(result.stdout.decode())
if result.stderr:
logs.write(result.stderr.decode())

parse_ccr_hashes(result.stdout.decode() if result.stdout else "")

print(f"Downloaded RPKI Data, hash sum: {calculate_sha256_directory(context.data_dir_rpki_cache)}")

Expand Down Expand Up @@ -158,3 +167,11 @@ def process_files_batch(batch):
json.dump(s, f)

print(f"{len(results_json)} RKPI ROAs validated\nSaved to: {result_path.name}\nFile hash: {calculate_sha256(result_path)}")


def parse_ccr_hashes(output):
"""Extract and print CCR hashes from rpki-client stdout."""
for line in output.splitlines():
match = re.match(r"^(CCR .+ hash): (.+)$", line)
if match:
print(f"{match.group(1)}: {match.group(2)}")
16 changes: 16 additions & 0 deletions kartograf/rpki/parse.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import subprocess
from pathlib import Path
from typing import Dict

Expand All @@ -7,12 +8,16 @@
is_bogon_asn,
is_out_of_encoding_range,
)
from kartograf.rpki.fetch import data_tals, parse_ccr_hashes
from kartograf.timed import timed
from kartograf.util import parse_pfx


@timed
def parse_rpki(context):
if context.reproduce:
compute_ccr_hashes(context)

raw_input = Path(context.out_dir_rpki) / "rpki_raw.json"
rpki_res = Path(context.out_dir_rpki) / "rpki_final.txt"

Expand Down Expand Up @@ -113,3 +118,14 @@ def parse_rpki(context):
print(f'Invalids found: {invalids}')
print(f'Incompletes: {incompletes}')
print(f'Non-ROA files: {not_roas}')


def compute_ccr_hashes(context):
"""Run rpki-client in offline mode to compute and print CCR hashes."""
tal_options = [item for path in data_tals(context) for item in ('-t', path)]
run_args = ["rpki-client", "-n", "-d", context.data_dir_rpki_cache,
"-P", context.epoch] + tal_options + [context.out_dir_rpki]
result = subprocess.run(run_args,
capture_output=True,
check=False)
parse_ccr_hashes(result.stdout.decode() if result.stdout else "")
4 changes: 2 additions & 2 deletions kartograf/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ def check_compatibility():

if local_version is None:
raise RuntimeError("Could not determine rpki-client version. Is it installed?")
if local_version < 8.4:
raise Exception("Error: rpki-client version 8.4 or higher is required.")
if local_version < 9.6:
raise Exception("Error: rpki-client version 9.6 or higher is required.")

if local_version == latest_version:
print(f"Using rpki-client version {local_version} (recommended).")
Expand Down
Loading