Run an RPKI-RTR server in the cloud for 12 cents a year


RFC8210 defines the operation of RPKI-RTR. In a nutshell, the protocol defines a method for an RPKI cache to send RPKI prefix origin data and router keys to routers. Those routers are then able to adjust their policy based on updates received from the cache. i.e. if a new prefix is signed, that signed data is picked up in the cache, and sent to all its peer routers. Those routers may decide to increase the local preference for valid signed prefixes, drop invalids, or any other policy the operator chooses.

GCP free tier

Google provides numerous free products up to a certain tier. In this specific case we can use the F1-micro instance which gives:

  • 0.2 vCPU
  • 0.6GB RAM
  • 30GB HDD
  • 1GB Network Egress

While the above may seem small, it’s all we need.


I needed a server that was extremely efficient to run on the above specs, so I decided to just write my own. It’s called rpkirtr because I can’t be bothered to think of a better name.

Cloudflare publishes an updated list of currently signed prefixes. rpkirtr downloads the list every 15 minutes and converts is to RPKI-RTR format ready to send to peers. The server itself will accept connections from any router over IPv4 or IPv6.

The configuration, like update time and where the list comes from, is currently baked into the app itself. I may move that out into a config.ini file if there is any interest. The app itself could also be extended to eventually get RPKIs directly from each registry, but that would require more resources so I may do that as a separate project.

I’ve been using this myself for roughly 6 months. Memory used is always less than 100MB, usually less than 50MB. I have three bird clients connected to collect RPKI stats for bgp4_table and bgp6_table.

Just clone the repo, go build, and run. Set it up a systemd service if you plan to keep it running at all times.

GCP config

Create your free F1-micro instance as normal. You’ll need to be able to get to the instance from remote so reserve a static external IP address and assign it to your F1 instance. This is the address you’ll have your routers connect to.

Log into the Google Cloud Console, go into Compute Engine, and set up a new firewall rule allowing ingress traffic to port 8282, the RPKI-RTR default port.

Google gives 1GB of egress traffic for free. Depending on the amount of routers you have, and the speed of updates, you could go over this tier. My own setup goes just over this amount and I currently get charged 1 cent a month. Hence I pay a total of 12c a year for this. I would recommend going into GCP billing, selecting ‘Budgets & alerts’ and setting up both notifications and limits. This is to ensure that if you suddenly have a large amount of traffic exiting your VM, you don’t get a shocker of a bill. I’ve personally set my threshold to $1 a month and to immidiately alert me if I breach 50% of that in a month. I’ve yet to be alerted.

bird config

You’ll need bird2 minimum to support RPKI. The configuration to connect to rpkirtr is very simple:

## ROAs ##
roa4 table roa_v4;
roa6 table roa_v6;

protocol rpki gcp {
  roa4 { table roa_v4; };
  roa6 { table roa_v6; };
  remote "x.x.x.x" port 8282;
  retry keep 90;
  refresh keep 900;
  expire keep 172800;

Once connected, you can view the session like so:

bird> show protocols all gcp
Name       Proto      Table      State  Since         Info
gcp        RPKI       ---        up     19:41:31.026  Established
  Cache server:     x.x.x.x:8282
  Status:           Established
  Transport:        Unprotected over TCP
  Protocol version: 1
  Session ID:       39
  Serial number:    1957
  Last update:      before 868.209 s
  Refresh timer   : 31.790/900
  Retry timer     : ---
  Expire timer    : 171931.790/172800
  Channel roa4
    State:          UP
    Table:          roa_v4
    Preference:     100
    Input filter:   ACCEPT
    Output filter:  REJECT
    Routes:         111063 imported, 0 exported, 106080 preferred
    Route change stats:     received   rejected   filtered    ignored   accepted
      Import updates:         111068          0          0          0     111068
      Import withdraws:            5          0        ---          0          5
      Export updates:              0          0          0        ---          0
      Export withdraws:            0        ---        ---        ---          0
  Channel roa6
    State:          UP
    Table:          roa_v6
    Preference:     100
    Input filter:   ACCEPT
    Output filter:  REJECT
    Routes:         18345 imported, 0 exported, 17421 preferred
    Route change stats:     received   rejected   filtered    ignored   accepted
      Import updates:          18345          0          0          0      18345
      Import withdraws:            0          0        ---          0          0
      Export updates:              0          0          0        ---          0
      Export withdraws:            0        ---        ---        ---          0

In the case above, I have 111063 IPv4 record and 18345 IPv6 records.

Note that my rpkirtr only supports version 1 of the protocol. I do not support version 0. Config-wise you’ll need to ensure your router supports version 1 and then you should be good.

Wrap up

As noted, the amount of routers you’re sending updates to could tip you over the 1c a month threshold, but even with 10s of routers the cost is not going to be higher than about 5c a month. Pretty cheap for an RPKI-RTR set up :)

Google only gives you a single instance for free. But there is nothing stopping you from using a free tier from another provider and setting up a backup rpkirtr server there.

Feel free to send me pull requests on my repo if you see any big issues. I have some more ideas but as it’s been rock solid for months I’ve just left it as is for now.