mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
RPKI: Accept and save BGPsec Router Keys from RPKI
Adds support for receiving Router Key PDUs, saving it to disk. The path save repository is configurable by ./configure or BIRD's configuration file.
This commit is contained in:
parent
4661035431
commit
cb064f84c4
@ -108,6 +108,7 @@ $(objdir)/sysdep/paths.h: Makefile
|
||||
echo >$@ "/* Generated by Makefile, don't edit manually! */"
|
||||
echo >>$@ "#define PATH_CONFIG_FILE \"@CONFIG_FILE@\""
|
||||
echo >>$@ "#define PATH_CONTROL_SOCKET \"@CONTROL_SOCKET@\""
|
||||
echo >>$@ "#define PATH_RPKI_STATE_DIR \"@RPKI_STATE_DIR@\""
|
||||
if test -n "@iproutedir@" ; then echo >>$@ "#define PATH_IPROUTE_DIR \"@iproutedir@\"" ; fi
|
||||
|
||||
# Finally include the computed dependencies
|
||||
|
@ -104,6 +104,7 @@ config_alloc(byte *name)
|
||||
c->tf_route = c->tf_proto = (struct timeformat){"%T", "%F", 20*3600};
|
||||
c->tf_base = c->tf_log = (struct timeformat){"%F %T", NULL, 0};
|
||||
c->gr_wait = DEFAULT_GR_WAIT;
|
||||
c->rpki_state_dir = PATH_RPKI_STATE_DIR;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ struct config {
|
||||
ip_addr listen_bgp_addr; /* Listening BGP socket should use this address */
|
||||
unsigned listen_bgp_port; /* Listening BGP socket should use this port (0 is default) */
|
||||
u32 listen_bgp_flags; /* Listening BGP socket should use these flags */
|
||||
const char *rpki_state_dir; /* File path to save Router Keys for RPKI */
|
||||
unsigned proto_default_debug; /* Default protocol debug mask */
|
||||
unsigned proto_default_mrtdump; /* Default protocol mrtdump mask */
|
||||
struct timeformat tf_route; /* Time format for 'show route' */
|
||||
|
@ -39,12 +39,15 @@ AC_SUBST(runtimedir)
|
||||
if test "$enable_debug" = yes ; then
|
||||
CONFIG_FILE="bird.conf"
|
||||
CONTROL_SOCKET="bird.ctl"
|
||||
RPKI_STATE_DIR="rpki"
|
||||
else
|
||||
CONFIG_FILE="\$(sysconfdir)/bird.conf"
|
||||
CONTROL_SOCKET="$runtimedir/bird.ctl"
|
||||
RPKI_STATE_DIR="\$(localstatedir)/rpki"
|
||||
fi
|
||||
AC_SUBST(CONFIG_FILE)
|
||||
AC_SUBST(CONTROL_SOCKET)
|
||||
AC_SUBST(RPKI_STATE_DIR)
|
||||
|
||||
AC_SEARCH_LIBS(clock_gettime, [c rt posix4], ,
|
||||
AC_MSG_ERROR([[Function clock_gettime not available.]]))
|
||||
|
@ -457,7 +457,10 @@ password_item_params:
|
||||
| ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
|
||||
;
|
||||
|
||||
/* Overwrite RPKI State Dir for BGPSEC Router Keys */
|
||||
|
||||
CF_ADDTO(conf, rpki_state_dir)
|
||||
rpki_state_dir: RPKI STATE DIR text ';' { new_config->rpki_state_dir = $4; }
|
||||
|
||||
/* Core commands */
|
||||
CF_CLI_HELP(SHOW, ..., [[Show status information]])
|
||||
|
@ -24,7 +24,7 @@ rpki_check_unused_hostname(void)
|
||||
CF_DECLS
|
||||
|
||||
CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, SSH, ENCRYPTION, USER,
|
||||
RETRY, REFRESH, EXPIRE)
|
||||
RETRY, REFRESH, EXPIRE, STATE, DIR)
|
||||
|
||||
CF_GRAMMAR
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#undef LOCAL_DEBUG
|
||||
|
||||
@ -142,6 +143,17 @@ struct pdu_error {
|
||||
uint8_t rest[];
|
||||
};
|
||||
|
||||
struct pdu_router_key {
|
||||
uint8_t ver;
|
||||
uint8_t type;
|
||||
uint8_t flags;
|
||||
uint8_t zero;
|
||||
uint32_t len;
|
||||
uint8_t ski[RPKI_SKI_SIZE];
|
||||
uint32_t asn;
|
||||
uint8_t spki[RPKI_SPKI_SIZE];
|
||||
};
|
||||
|
||||
struct pdu_reset_query {
|
||||
uint8_t ver;
|
||||
uint8_t type;
|
||||
@ -328,6 +340,12 @@ rpki_pdu_body_to_host_byte_order(void *pdu)
|
||||
}
|
||||
|
||||
case ROUTER_KEY:
|
||||
{
|
||||
struct pdu_router_key *rk = pdu;
|
||||
rk->asn = ntohl(rk->asn);
|
||||
break;
|
||||
}
|
||||
|
||||
case SERIAL_QUERY:
|
||||
case RESET_QUERY:
|
||||
case CACHE_RESPONSE:
|
||||
@ -373,6 +391,16 @@ rpki_log_packet(struct rpki_cache *cache, const void *pdu, const size_t len, con
|
||||
break;
|
||||
}
|
||||
|
||||
case ROUTER_KEY:
|
||||
{
|
||||
const struct pdu_router_key *rk = pdu;
|
||||
bsnprintf(detail, sizeof(detail), "(AS%u %02x", rk->asn, rk->ski[0]);
|
||||
for (const u8 *x = &rk->ski[1]; x < &rk->ski[RPKI_SKI_SIZE]; x++)
|
||||
bsnprintf(detail+strlen(detail), sizeof(detail)-strlen(detail), ":%02x", *x);
|
||||
bsnprintf(detail+strlen(detail), sizeof(detail)-strlen(detail), ")");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
*detail = '\0';
|
||||
}
|
||||
@ -741,6 +769,43 @@ rpki_handle_prefix_pdu(struct rpki_cache *cache, const void *pdu)
|
||||
return RPKI_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
rpki_handle_router_key_pdu(struct rpki_cache *cache, const struct pdu_router_key *pdu)
|
||||
{
|
||||
char file_name[4096]; /* PATH_MAX? */
|
||||
char ski_hex[41];
|
||||
const char *state_dir = config->rpki_state_dir;
|
||||
int i;
|
||||
int fd = -1;
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
bsnprintf(ski_hex + i*2, sizeof(ski_hex) - i*2, "%02X", pdu->ski[i]);
|
||||
|
||||
/* Check buffer size */
|
||||
size_t req_size = strlen(state_dir) + 2*sizeof(pdu->ski) + 2 + strlen(RPKI_ROUTER_KEY_EXT);
|
||||
if (req_size >= sizeof(file_name))
|
||||
{
|
||||
CACHE_TRACE(D_EVENTS, cache, "Buffer too small for %s/%u.%s" RPKI_ROUTER_KEY_EXT, state_dir, pdu->asn, ski_hex);
|
||||
return;
|
||||
}
|
||||
|
||||
bsnprintf(file_name, sizeof(file_name), "%s/%u.%s" RPKI_ROUTER_KEY_EXT, state_dir, pdu->asn, ski_hex);
|
||||
|
||||
fd = open(file_name, O_WRONLY|O_CREAT, 0664);
|
||||
if (fd < 0)
|
||||
{
|
||||
CACHE_TRACE(D_EVENTS, cache, "Cannot open file %s for write router key", file_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (write(fd, pdu->spki, RPKI_SPKI_SIZE) < 0)
|
||||
CACHE_TRACE(D_EVENTS, cache, "Cannot write into %s", file_name);
|
||||
else
|
||||
CACHE_TRACE(D_EVENTS, cache, "Wrote router key into file %s", file_name);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static uint
|
||||
rpki_check_interval(struct rpki_cache *cache, const char *(check_fn)(uint), uint interval)
|
||||
{
|
||||
@ -837,6 +902,10 @@ rpki_rx_packet(struct rpki_cache *cache, void *pdu, uint len)
|
||||
rpki_handle_prefix_pdu(cache, pdu);
|
||||
break;
|
||||
|
||||
case ROUTER_KEY:
|
||||
rpki_handle_router_key_pdu(cache, pdu);
|
||||
break;
|
||||
|
||||
case END_OF_DATA:
|
||||
rpki_handle_end_of_data_pdu(cache, pdu);
|
||||
break;
|
||||
@ -853,7 +922,6 @@ rpki_rx_packet(struct rpki_cache *cache, void *pdu, uint len)
|
||||
rpki_handle_error_pdu(cache, pdu);
|
||||
break;
|
||||
|
||||
case ROUTER_KEY:
|
||||
default:
|
||||
CACHE_TRACE(D_PACKETS, cache, "Received unsupported type of RPKI PDU: %u", type);
|
||||
};
|
||||
|
@ -32,6 +32,10 @@
|
||||
#define RPKI_MIN_VERSION 0
|
||||
#define RPKI_MAX_VERSION 1
|
||||
|
||||
#define RPKI_SKI_SIZE 20
|
||||
#define RPKI_SPKI_SIZE 91
|
||||
#define RPKI_ROUTER_KEY_EXT ".key"
|
||||
|
||||
/*
|
||||
* Used in parsing of configuration file
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user