[patch] Add TCP-MD5 authentication option for RPKI protocol

Job Snijders job at fastly.com
Tue Oct 1 17:27:19 CEST 2024


Dear BIRD community,

I think many of us use good ole' TCP-MD5 to authenticate IBGP sessions,
even if TCP-MD5 is imperfect from key rolling perspective. TCP-MD5 is
easy to configure, and supported on a broad range of platforms, and
beats doing nothing.

RPKI-To-Router (RTR) sessions seem to be similar security-sensitivity as
IBGP sessions, but at the moment of writing BIRD offers a choice of
either "plain TCP" (meh) or "SSH" (secure, albeit a bit more hassle to
set up than TCP-MD5). I'd like to add TCP-MD5 as another option.
TCP-MD5 for RTR is specified through RFC 6810 section 7.3 and RFC 8210
section 9.3.

Minimal bird.conf:

    router id 10.0.0.1;
    roa4 table r4;
    roa6 table r6;
    protocol rpki rpki1 {
      roa4 { table r4; };
      roa6 { table r6; };
      remote 165.254.255.17 port 8282;
      transport tcp password "test"; /* password keyword is new here! */
      debug all;
    }

This config was tested on Linux against a WIP based on StayRTR, tcpdump
suggests this works as expected.

    job at josephine:~/bird$ ./birdc -s /tmp/bird show protocols all
    BIRD v2.15.1-29-g35f74c4b-x ready.
    Name       Proto      Table      State  Since         Info
    rpki1      RPKI       ---        up     15:16:41.677  Established
      Cache server:     165.254.255.17
      Cache port:       8282
      Status:           Established
      Transport:        TCP-MD5

I can leave the server at 165.254.255.17 port 8282 with TCP-MD5
authentication password "test" running for a bit so others can more
easily test the below patch without having to compile/run StayRTR.

Below is a changeset for your consideration! Feedback is welcome.

Kind regards,

Job

ps. It seems TCP-MD5 for BGP doesn't work out-of-the-box on OpenBSD,
downstream porters apply a few minimal patches:
https://github.com/openbsd/ports/tree/master/net/bird/2/patches
perhaps these can be upstreamed so that we can work towards TCP-MD5 RTR
support in BIRD on OpenBSD as well? :-)

Author: Job Snijders <job at fastly.com>
Date:   Wed Sep 18 10:46:06 2024 +0000

    Add RTR TCP-MD5 authentication support

diff --git a/doc/bird.sgml b/doc/bird.sgml
index e2050c13..07bedef9 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -5735,7 +5735,7 @@ protocol rpki [<name>] {
         refresh [keep] <num>;
         retry [keep] <num>;
         expire [keep] <num>;
-        transport tcp;
+        transport tcp [password <m/string/];
         transport ssh {
                 bird private key "</path/to/id_rsa>";
                 remote public key "</path/to/known_host>";
@@ -5791,9 +5791,10 @@ specify both channels.
 	instead. This may be useful for implementing loose RPKI check for
 	blackholes. Default: disabled.
 
-        <tag>transport tcp</tag> Unprotected transport over TCP. It's a default
-        transport. Should be used only on secure private networks.
-        Default: tcp
+        <tag>transport tcp [password <m/string/]</tag> transport over TCP. It's
+        the default transport. Should be used only on secure private networks.
+        If a password is specified, the session is authenticated using TCP-MD5
+        (<rfc id="2385">). Default: tcp, no authentication.
 
         <tag>transport ssh { <m/SSH transport options.../ }</tag> It enables a
         SSHv2 transport encryption. Cannot be combined with a TCP transport.
diff --git a/proto/rpki/config.Y b/proto/rpki/config.Y
index 769ebb2c..a0b678be 100644
--- a/proto/rpki/config.Y
+++ b/proto/rpki/config.Y
@@ -32,7 +32,8 @@ rpki_check_unused_transport(void)
 CF_DECLS
 
 CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER,
-	    RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH, LOCAL, ADDRESS)
+	    RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH, LOCAL, ADDRESS,
+	    PASSWORD)
 
 %type <i> rpki_keep_interval
 
@@ -109,6 +110,7 @@ rpki_cache_addr: text_or_ipa
 
 rpki_transport:
    TCP rpki_transport_tcp_init
+ | TCP PASSWORD text rpki_transport_tcp_init { RPKI_CFG->password = $3; }
  | SSH rpki_transport_ssh_init '{' rpki_transport_ssh_opts '}' rpki_transport_ssh_check
  ;
 
diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c
index 4ec48e3b..d793ee56 100644
--- a/proto/rpki/rpki.c
+++ b/proto/rpki/rpki.c
@@ -673,6 +673,12 @@ rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, st
     return NEED_RESTART;
   }
 
+  if (old->password != new->password)
+  {
+    CACHE_TRACE(D_EVENTS, cache, "MD5 authentication changed");
+    return NEED_RESTART;
+  }
+
   if (old->tr_config.type != new->tr_config.type)
   {
     CACHE_TRACE(D_EVENTS, cache, "Transport type changed");
@@ -843,7 +849,10 @@ rpki_show_proto_info(struct proto *P)
       break;
 #endif
     case RPKI_TR_TCP:
-      transport_name = "Unprotected over TCP";
+      if (cf->password == NULL)
+        transport_name = "Unprotected over TCP";
+      else
+        transport_name = "TCP-MD5";
       default_port = RPKI_TCP_PORT;
       break;
     };
diff --git a/proto/rpki/rpki.h b/proto/rpki/rpki.h
index e67eb0e3..d8fd72ce 100644
--- a/proto/rpki/rpki.h
+++ b/proto/rpki/rpki.h
@@ -127,6 +127,7 @@ struct rpki_config {
   u8 keep_retry_interval:1;		/* Do not overwrite retry interval by cache server update */
   u8 keep_expire_interval:1;		/* Do not overwrite expire interval by cache server update */
   u8 ignore_max_length:1;		/* Ignore received max length and use MAX_PREFIX_LENGTH instead */
+  const char *password;			/* Password used for MD5 authentication */
 };
 
 void rpki_check_config(struct rpki_config *cf);
diff --git a/proto/rpki/transport.c b/proto/rpki/transport.c
index 26571977..46b00822 100644
--- a/proto/rpki/transport.c
+++ b/proto/rpki/transport.c
@@ -88,6 +88,9 @@ rpki_tr_open(struct rpki_tr_sock *tr)
   sk->tos = IP_PREC_INTERNET_CONTROL;
   sk->vrf = cache->p->p.vrf;
 
+  if (cf->tr_config.type == RPKI_TR_TCP && cf->password != NULL)
+    sk->password = cf->password;
+
   if (ipa_zero(sk->daddr) && sk->host)
   {
     const char *err_msg;


More information about the Bird-users mailing list