Commit 46610354 authored by Pavel Tvrdík's avatar Pavel Tvrdík Committed by Pavel Tvrdik
Browse files

RPKI protocol with one cache server per protocol

The RPKI protocol (RFC 6810) using the RTRLib
(http://rpki.realmv6.org/) that is integrated inside
the BIRD's code.

Implemeted transports are:
 - unprotected transport over TCP
 - secure transport over SSHv2

Example configuration of bird.conf:
  ...
  roa4 table r4;
  roa6 table r6;

  protocol rpki {
    debug all;

    # Import both IPv4 and IPv6 ROAs
    roa4 { table r4; };
    roa6 { table r6; };

    # Set cache server (validator) address,
    # overwrite default port 323
    remote "rpki-validator.realmv6.org" port 8282;

    # Overwrite default time intervals
    retry   10;         # Default 600 seconds
    refresh 60;         # Default 3600 seconds
    expire 600;         # Default 7200 seconds
  }

  protocol rpki {
    debug all;

    # Import only IPv4 routes
    roa4 { table r4; };

    # Set cache server address to localhost,
    # use default ports tcp => 323 or ssh => 22
    remote 127.0.0.1;

    # Use SSH transport instead of unprotected transport over TCP
    ssh encryption {
      bird private key "/home/birdgeek/.ssh/id_rsa";
      remote public key "/home/birdgeek/.ssh/known_hosts";
      user "birdgeek";
    };
  }
  ...
parent dc9f0826
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ CPPFLAGS=-I$(objdir) -I$(srcdir) @CPPFLAGS@
CFLAGS=$(CPPFLAGS) @CFLAGS@
LDFLAGS=@LDFLAGS@
LIBS=@LIBS@
DAEMON_LIBS=@DAEMON_LIBS@
CLIENT_LIBS=@CLIENT_LIBS@
CC=@CC@
M4=@M4@
@@ -55,6 +56,8 @@ all: daemon cli
daemon: $(daemon)
cli: $(client)

$(daemon): LIBS += $(DAEMON_LIBS)

# Include directories
dirs := client conf doc filter lib nest $(addprefix proto/,$(protocols)) @sysdep_dirs@

+5 −1
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ fi
AC_SUBST(iproutedir)

# all_protocols="$proto_bfd bgp ospf pipe radv rip static"
all_protocols="$proto_bfd ospf pipe radv rip static"
all_protocols="$proto_bfd ospf pipe radv rip rpki static"

all_protocols=`echo $all_protocols | sed 's/ /,/g'`

@@ -226,6 +226,10 @@ if test "$enable_debug" = yes ; then
	fi
fi

DAEMON_LIBS=
AC_CHECK_LIB(dl, dlopen, DAEMON_LIBS="-ldl")
AC_SUBST(DAEMON_LIBS)

CLIENT=birdcl
CLIENT_LIBS=
if test "$enable_client" = yes ; then
+131 −1
Original line number Diff line number Diff line
@@ -464,7 +464,7 @@ protocol rip {
	Create a new ROA (Route Origin Authorization) table. ROA tables can be
	used to validate route origination of BGP routes. A ROA table contains
	ROA entries, each consist of a network prefix, a max prefix length and
	an AS number. A ROA entry specifies prefixes which could be originated
	an AS (Autonomous System) number. A ROA entry specifies prefixes which could be originated
	by that AS number. ROA tables could be filled with data from RPKI (RFC
	6480) or from public databases like Whois. ROA tables are examined by
	<cf/roa_check()/ operator in filters.
@@ -3494,6 +3494,136 @@ protocol rip {
}
</code>

<sect>RPKI

<p>The Resource Public Key Infrastructure (RPKI) to Router Protocol (RFC 6810)
is a protocol for receiving Route Origin Authorizations (ROAs) from trusted 
caches (RPKI validators). ROAs are documents used to link a set of prefixes
with an origin ASN.
The ROAs could be 
In BIRD, it is implemented only receiving prefix origin data from a trusted cache.
RPKI-based origin validation uses some of the RPKI data to allow a router
to version ... FIXME! srify that the autonomous system announcing an IP address prefix is in fact
authorized to do so. This is not crypto checked so can be violated. But it
should prevent the vast majority of accidental 'hijackings' on the internet

It is possible to configure only one remote cache server per protocol yet.

<code>
protocol rpki [&lt;name&gt;] {
        remote &lt;ip&gt; | "&lt;domain&gt;" [port &lt;num&gt;];
        port &lt;num&gt;;
        retry &lt;num&gt;;
        refresh &lt;num&gt;;
        expire &lt;num&gt;;
        ssh encryption {
                bird private key "&lt;/path/to/id_rsa&gt;";
                remote public key "&lt;/path/to/known_host&gt;";
                user "&lt;name&gt;";
        };
}
</code>

<sect1>RPKI protocol options
<descrip>
	<tag>roa table <m/name/</tag>
	Specifies the roa table into which will import the routes from cache.
	This option is required.

	<tag>remote <m/ip/ | "<m/hostname/" [port &lt;num&gt;]</tag>
	Specifies a destination address of the cache server.
	Can be specified by an IP address or by full domain name.
	Only one cache can be specified per protocol.

	<tag>port <m/num/</tag>
	Specifies the port number.
	The default port number is 323 for transport without any encryption
	and 22 for transport with SSH encryption.

	<tag>retry <m/num/</tag>
	Time period in seconds between a failed query and the next attempt.
	Default: 600 seconds

	<tag>refresh <m/num/</tag>
	Time period in seconds.
	Tells how long to wait before next attempting to poll the cache, using
	a Serial Query or Reset Query PDU. Must be lower than 1 hour.
	Default: 3600 seconds

	<tag>expire <m/num/</tag>
	Time period in seconds.
	Received records are deleted if the client was unable to refresh data
	for this time period.
	Default: 7200 seconds

	<tag>ssh encryption { <m/ssh encryption options.../ }</tag>
	This enables a SSH encryption.
	Default: off
</descrip>

<sect1>SSH encryption options in RPKI protocol
<descrip>
	<tag>bird private key "<m///path/to/id_rsa"</tag>
	A path to the BIRD's private SSH key for authentication.
	It can be a <cf/id_rsa/ file.

	<tag>remote public key "<m///path/to/known_host"</tag>
	A path to the cache's public SSH key for verification identity
	of the cache server. It could be a <cf/known_host/ file.

	<tag>user "<m/name/"</tag>
	A SSH user name for authentication. This option is a required.
</descrip>

<sect1>Examples:
<p>Typical RPKI configuration with BGP origin validation
<code>
roa4 table r4;
roa6 table r6;

protocol rpki {
	debug all;
	roa4 { table r4; };
	roa6 { table r6; };
	remote "rpki-validator.realmv6.org";
}

filter peer_in {
	if (roa_check(r4, net, bgp_path.last) = ROA_INVALID ||
	    roa_check(r6, net, bgp_path.last) = ROA_INVALID) then
	{
		print "ROA check failed for ", net, " ASN ", bgp_path.last;
		reject;
	}
	accept;
}

protocol bgp my_peer {
	local as 65000;
	neighbor 192.0.2.1 as 65001;
	import filter peer_in;
}
</code>

<p>A configuration using SSHv2 transport encryption:
<code>
roa4 table r4;
roa6 table r6;

protocol rpki {
	debug all;
	roa4 { table r4; };
	roa6 { table r6; };
	remote 127.0.0.1 port 2345;
	ssh encryption {
		bird private key "/home/birdgeek/.ssh/id_rsa";
		remote public key "/home/birdgeek/.ssh/known_hosts";
		user "birdgeek";
	};
}
</code>



<sect>Static

+6 −2
Original line number Diff line number Diff line
@@ -1277,10 +1277,14 @@ interpret(struct f_inst *what)
    }

    struct rtable *table = ((struct f_inst_roa_check *) what)->rtc->table;
    if (!table || table->addr_type != (v1.val.net->type == NET_IP4 ? NET_ROA4 : NET_ROA6))
    if (!table || (table->addr_type != NET_ROA4 && table->addr_type != NET_ROA6))
      runtime("Missing ROA table");

    res.type = T_ENUM_ROA;

    if (table->addr_type != (v1.val.net->type == NET_IP4 ? NET_ROA4 : NET_ROA6))
      res.val.i = ROA_UNKNOWN; /* Prefix and table type mismatch */
    else
      res.val.i = net_roa_check(table, v1.val.net, as);

    break;
+1 −1
Original line number Diff line number Diff line
@@ -2,6 +2,6 @@ src := bitops.c checksum.c ip.c lists.c md5.c net.c patmatch.c printf.c sha1.c s
obj := $(src-o-files)
$(all-client)

src := bitops.c checksum.c event.c idm.c ip.c lists.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
src := bitops.c checksum.c event.c idm.c ip.c libssh.c lists.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
obj := $(src-o-files)
$(all-daemon)
Loading