Dear all,
I introduced a 'shortlist' feature in rpki-client(8). If the operator
specifies one or more '-q' options followed by FQDNs, the utility will
*only* connect to those hosts and skip all others.
$ doas rpki-client -q rpki.ripe.net -q chloe.sobornost.net
Processing time 84 seconds (75 seconds user, 10 seconds system)
Skiplist entries: 0
Route Origin Authorizations: 32459 (0 failed parse, 0 invalid)
AS Provider Attestations: 0 (0 failed parse, 0 invalid)
BGPsec Router Certificates: 2
Certificates: 18750 (0 invalid)
Trust Anchor Locators: 5 (0 invalid)
Manifests: 18586 (0 failed parse, 0 stale)
Certificate revocation lists: 18586
Ghostbuster records: 1
Trust Anchor Keys: 0
Repositories: 8
Cleanup: removed 1 files, 1270 directories, 67 superfluous
VRP Entries: 179160 (179160 unique)
VAP Entries: 0 (0 unique)
$ ls -lahtr /var/cache/rpki-client/
total 28
drwxr-xr-x 4 root wheel 512B Nov 10 21:07 ..
drwxr-xr-x 2 _rpki-client wheel 512B Nov 17 17:35 .rsync
drwxr-xr-x 7 _rpki-client wheel 512B Nov 17 17:45 ta
drwxr-xr-x 3 _rpki-client wheel 512B Nov 17 17:47 rpki.ripe.net
drwxr-xr-x 3 _rpki-client wheel 512B Nov 17 17:47 chloe.sobornost.net
drwxr-xr-x 7 _rpki-client wheel 1.0K Nov 17 17:47 .
drwxr-xr-x 5 _rpki-client wheel 512B Nov 17 17:48 .rrdp
This functionality is handy if you want to inspect only specific
repositories and ignore the rest of the world. Useful for monitoring
too.
OK? Feedback?
Kind regards,
Job
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.159
diff -u -p -r1.159 extern.h
--- extern.h 4 Nov 2022 12:05:36 -0000 1.159
+++ extern.h 17 Nov 2022 17:47:34 -0000
@@ -34,6 +34,15 @@ struct skiplistentry {
LIST_HEAD(skiplist, skiplistentry);
/*
+ * Shortlist of hosts to connect to (loaded via -q arguments).
+ */
+struct shortlistentry {
+ LIST_ENTRY(shortlistentry) entry;
+ char *value; /* FQDN */
+};
+LIST_HEAD(shortlist, shortlistentry);
+
+/*
* Enumeration for ASN.1 explicit tags in RSC eContent
*/
enum rsc_resourceblock_tag {
Index: main.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
retrieving revision 1.220
diff -u -p -r1.220 main.c
--- main.c 2 Nov 2022 12:43:02 -0000 1.220
+++ main.c 17 Nov 2022 17:47:34 -0000
@@ -64,11 +64,13 @@ const char *bird_tablename = "ROAS";
int verbose;
int noop;
int filemode;
+int shortlistmode;
int rrdpon = 1;
int repo_timeout;
time_t deadline;
struct skiplist skiplist = LIST_HEAD_INITIALIZER(skiplist);
+struct shortlist shortlist = LIST_HEAD_INITIALIZER(shortlist);
struct stats stats;
@@ -448,21 +450,35 @@ queue_add_from_cert(const struct cert *c
{
struct repo *repo;
struct skiplistentry *sle;
+ struct shortlistentry *she;
char *nfile, *npath, *host;
const char *uri, *repouri, *file;
size_t repourisz;
+ int shortlisted = 0;
- LIST_FOREACH(sle, &skiplist, entry) {
- if (strncmp(cert->repo, "rsync://", 8) != 0)
- errx(1, "unexpected protocol");
- host = cert->repo + 8;
+ if (strncmp(cert->repo, "rsync://", 8) != 0)
+ errx(1, "unexpected protocol");
+ host = cert->repo + 8;
+ LIST_FOREACH(sle, &skiplist, entry) {
if (strncasecmp(host, sle->value, strcspn(host, "/")) == 0) {
warnx("skipping %s (listed in skiplist)", cert->repo);
return;
}
}
+ LIST_FOREACH(she, &shortlist, entry) {
+ if (strncasecmp(host, she->value, strcspn(host, "/")) == 0) {
+ shortlisted = 1;
+ break;
+ }
+ }
+ if (shortlistmode && shortlisted == 0) {
+ if (verbose)
+ warnx("skipping %s (not shortlisted)", cert->repo);
+ return;
+ }
+
repo = repo_lookup(cert->talid, cert->repo,
rrdpon ? cert->notify : NULL);
if (repo == NULL)
@@ -760,6 +776,26 @@ load_skiplist(const char *slf)
free(line);
}
+/*
+ * Load shortlist entries.
+ */
+static void
+load_shortlist(const char *fqdn)
+{
+ struct shortlistentry *she;
+
+ if (!valid_uri(fqdn, strlen(fqdn), NULL))
+ errx(1, "invalid fqdn passed to -q: %s", fqdn);
+
+ if ((she = malloc(sizeof(struct shortlistentry))) == NULL)
+ err(1, NULL);
+
+ if ((she->value = strdup(fqdn)) == NULL)
+ err(1, NULL);
+
+ LIST_INSERT_HEAD(&shortlist, she, entry);
+}
+
static void
check_fs_size(int fd, const char *cachedir)
{
@@ -865,7 +901,7 @@ main(int argc, char *argv[])
"proc exec unveil", NULL) == -1)
err(1, "pledge");
- while ((c = getopt(argc, argv, "b:Bcd:e:fjnorRs:S:t:T:vV")) != -1)
+ while ((c = getopt(argc, argv, "b:Bcd:e:fjnorq:Rs:S:t:T:vV")) != -1)
switch (c) {
case 'b':
bind_addr = optarg;
@@ -895,6 +931,10 @@ main(int argc, char *argv[])
case 'o':
outformats |= FORMAT_OPENBGPD;
break;
+ case 'q':
+ shortlistmode = 1;
+ load_shortlist(optarg);
+ break;
case 'R':
rrdpon = 0;
break;
@@ -1330,8 +1370,9 @@ usage:
fprintf(stderr,
"usage: rpki-client [-BcjnoRrVv] [-b sourceaddr] [-d cachedir]"
" [-e rsync_prog]\n"
- " [-S skiplist] [-s timeout] [-T table] [-t tal]"
- " [outputdir]\n"
+ " [-q fqdn ] [-S skiplist] [-s timeout] [-T
table]"
+ " [-t tal]\n"
+ " [outputdir]\n"
" rpki-client [-Vv] [-d cachedir] [-j] [-t tal] -f file ..."
"\n");
return 1;
Index: rpki-client.8
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/rpki-client.8,v
retrieving revision 1.79
diff -u -p -r1.79 rpki-client.8
--- rpki-client.8 10 Nov 2022 13:22:55 -0000 1.79
+++ rpki-client.8 17 Nov 2022 17:47:34 -0000
@@ -26,6 +26,7 @@
.Op Fl b Ar sourceaddr
.Op Fl d Ar cachedir
.Op Fl e Ar rsync_prog
+.Op Fl q Ar fqdn
.Op Fl S Ar skiplist
.Op Fl s Ar timeout
.Op Fl T Ar table
@@ -146,6 +147,16 @@ If the
and
.Fl j
options are not specified this is the default.
+.It Fl q Ar fqdn
+Create a shortlist and add
+.Ar fqdn
+to the shortlist.
+.Nm
+only connects to shortlisted hosts.
+The shortlist filter is enforced during processing of the
+.Em Subject Information Access Pq SIA
+extension in CA certificates, thus applies to both RSYNC and RRDP connections.
+This option can be used multiple times.
.It Fl R
Synchronize via RSYNC only.
.It Fl r