• Stars
    star
    283
  • Rank 140,671 (Top 3 %)
  • Language
    Go
  • License
    BSD 3-Clause "New...
  • Created over 5 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The RPKI-to-Router server used at Cloudflare

GoRTR

Build Status GoDoc GitHub release (latest by date)

GoRTR is an open-source implementation of RPKI to Router protocol (RFC 6810) using the the Go Programming Language.

  • /lib contains a library to create your own server and client.
  • /prefixfile contains the structure of a JSON export file and signing capabilities.
  • /cmd/gortr/gortr.go is a simple implementation that fetches a list and offers it to a router.
  • /cmd/rtrdump/rtrdump.go allows copying the PDUs sent by a RTR server as a JSON file.
  • /cmd/rtrmon/rtrmon.go compare and monitor two RTR servers (using RTR and/or JSON), outputs diff and Prometheus metrics.

Disclaimer

This software comes with no warranty.

In the field

Cloudflare

Cloudflare operates 200+ GoRTR globally. They provide redundancy in at the PoP level. This provides increased reliability by computing a unique prefix list and providing a secure distribution of the file over its CDN before being sent to the routers.

GoRTR also powers the public RTR server available on rtr.rpki.cloudflare.com on port 8282 and 8283 for SSH (rpki/rpki)


Telia

Telia has deployed RPKI and uses GoRTR connected with OctoRPKI and rpki-client to distribute the ROAs to its routers. Instances of the RTR servers handle around 250 sessions each.


NTT

NTT has deployed OpenBSD's rpki-client together with GoRTR to facilitate rejecting RPKI Invalid BGP route announcements towards it's Global IP Network (AS 2914). More information is available here.


GTT

GTT deployed GoRTR along with OctoRPKI. The setup currently provides 400+ RTR sessions to their routers for filtering RPKI invalids.


Cogent

Cogent deployed GoRTR and OctoRPKI at the end of May 2020. 8 validators feed approximately 2500 routers.


Router vendors also used this software to develop their implementations.

Do you use this tool at scale? Let us know!

Features of the server

  • Refreshes a JSON list of prefixes (from either Cloudflare or a RIPE Validator)
  • Prometheus metrics
  • Lightweight
  • TLS
  • SSH
  • Signature verification and expiration control

Features of the extractor

  • Generate a list of prefixes sent via RTR (similar to Cloudflare JSON input, or RIPE RPKI Validator)
  • Lightweight
  • TLS
  • SSH

Features of the API

  • Protocol v0 of RFC6810
  • Protocol v1 of RFC8210
  • Event-driven API
  • TLS
  • SSH

To start developing

You need a working Go environment (1.10 or newer). This project also uses Go Modules.

$ git clone [email protected]:cloudflare/gortr.git && cd gortr
$ go build cmd/gortr/gortr.go

With Docker

If you do not want to use Docker, please go to the next section.

If you have Docker, you can start GoRTR with docker run -ti -p 8082:8082 cloudflare/gortr. The containers contain Cloudflare's public signing key and an testing ECDSA private key for the SSH server.

It will automatically download Cloudflare's prefix list and use the public key to validate it.

You can now use any CLI attributes as long as they are after the image name:

$ docker run -ti -p 8083:8083 cloudflare/gortr -bind :8083

If you want to build your own image of GoRTR:

$ docker build -t mygortr -f Dockerfile.gortr.prod .
$ docker run -ti mygortr -h

It will download the code from GitHub and compile it with Go and also generate an ECDSA key for SSH.

Please note: if you plan to use SSH with Cloudflare's default container (cloudflare/gortr), replace the key private.pem since it is a testing key that has been published. An example is given below:

$ docker run -ti -v $PWD/mynewkey.pem:/private.pem cloudflare/gortr -ssh.bind :8083

Install it

There are a few solutions to install it.

Go can directly fetch it from the source

$ go get github.com/cloudflare/gortr/cmd/gortr

Copy cf.pub to your local directory if you want to use Cloudflare's signed JSON file.

You can use the Makefile (by default it will be compiled for Linux, add GOOS=darwin for Mac)

$ make dist-key build-gortr

The compiled file will be in /dist.

Or you can use a package (or binary) file from the Releases page:

$ sudo dpkg -i gortr[...].deb
$ sudo systemctl start gortr

If you want to sign your list of prefixes, generate an ECDSA key. Then generate the public key to be used in GoRTR. You will have to setup your validator to use this key or have another tool to sign the JSON file before passing it to GoRTR.

$ openssl ecparam -genkey -name prime256v1 -noout -outform pem > private.pem
$ openssl ec -in private.pem -pubout -outform pem > public.pem

Run it

Once you have a binary:

$ ./gortr -tls.bind 127.0.0.1:8282

Make sure cf.pub is in the current directory. Or pass -verify.key=path/to/cf.pub

Package it

If you want to package it (deb/rpm), you can use the pre-built docker-compose file.

$ docker-compose -f docker-compose-pkg.yml up

You can find both files in the dist/ directory.

Usage with a proxy

This was tested with a basic Squid proxy. The User-Agent header is passed in the CONNECT.

You have to export the following two variables in order for GoRTR to use the proxy.

export HTTP_PROXY=schema://host:port
export HTTPS_PROXY=schema://host:port

With SSL

You can run GoRTR and listen for TLS connections only (just pass -bind "").

First, you will have to create a SSL certificate.

$ openssl ecparam -genkey -name prime256v1 -noout -outform pem > private.pem
$ openssl req -new -x509 -key private.pem -out server.pem

Then, you have to run

$ ./gortr -ssh.bind :8282 -tls.key private.pem -tls.cert server.pem

With SSH

You can run GoRTR and listen for SSH connections only (just pass -bind "").

You will have to create an ECDSA key. You can use the following command:

$ openssl ecparam -genkey -name prime256v1 -noout -outform pem > private.pem

Then you can start:

$ ./gortr -ssh.bind :8282 -ssh.key private.pem -bind ""

By default, there is no authentication.

You can use password and key authentication:

For example, to configure user rpki and password rpki:

$ ./gortr -ssh.bind :8282 -ssh.key private.pem -ssh.method.password=true -ssh.auth.user rpki -ssh.auth.password rpki -bind ""

And to configure a bypass for every SSH key:

$ ./gortr -ssh.bind :8282 -ssh.key private.pem -ssh.method.key=true -ssh.auth.key.bypass=true -bind ""

Configure filters and overrides (SLURM)

GoRTR supports SLURM configuration files (RFC8416).

Create a json file (slurm.json):

{
    "slurmVersion": 1,
    "validationOutputFilters": {
     "prefixFilters": [
       {
        "prefix": "10.0.0.0/8",
        "comment": "Everything inside will be removed"
       },
       {
        "asn": 65001,
       },
       {
        "asn": 65002,
        "prefix": "192.168.0.0/24",
       },
     ],
     "bgpsecFilters": []
    },
    "locallyAddedAssertions": {
     "prefixAssertions": [
       {
        "asn": 65001,
        "prefix": "2001:db8::/32",
        "maxPrefixLength": 48,
        "comment": "Manual add"
       }
     ],
     "bgpsecAssertions": [
     ]
    }
  }

When starting GoRTR, add the -slurm ./slurm.json argument.

The log should display something similar to the following:

INFO[0001] Slurm filtering: 112214 kept, 159 removed, 1 asserted
INFO[0002] New update (112215 uniques, 112215 total prefixes).

For instance, if the original JSON fetched contains the ROA: 10.0.0.0/24-24 AS65001, it will be removed.

The JSON exported by GoRTR will contain the overrides and the file can be signed again. Others GoRTR can be configured to fetch the ROAs from the filtering GoRTR: the operator manages one SLURM file on a leader GoRTR.

Debug the content

You can check the content provided over RTR with rtrdump tool

$ ./rtrdump -connect 127.0.0.1:8282 -file debug.json

You can also fetch the re-generated JSON from the -export.path endpoint (default: http://localhost:8080/rpki.json)

Data sources

Use your own validator, as long as the JSON source follows the following schema:

{
  "roas": [
    {
      "prefix": "10.0.0.0/24",
      "maxLength": 24,
      "asn": "AS65001"
    },
    ...
  ]
}
  • Cloudflare (list curated, signed, compressed and cached in +160 PoPs)
  • Third-party JSON formatted VRP exports:
    • NTT (based on OpenBSD's rpki-client)
    • RIPE (based on RIPE NCC's RPKI Cache Validator)

To use a data source that do not contain signatures or validity information, pass: -verify=false -checktime=false

Note: for boolean flags, it requires the equal sign

Cloudflare's prefix list removes duplicates and entries that are not routed on the Internet (>/24 IPv4 and >/48 IPv6).

By default, the session ID will be randomly generated. The serial will start at zero.

You can define a serial to start with the following way:

  • the JSON must contain a serial field in metadata; and
  • the flag -useserial must be set to 1 or 2

When flag is set to 1, every change of file will increment the serial regardless of the current serial field. Make sure the refresh rate of GoRTR is more frequent than the refresh rate of the JSON.

When flag is set to 2, GoRTR will set the value of the serial in the JSON. If an ID is missed or not updated, it will cause discrepancies on the client.

Configurations

Compatibility matrix

A simple comparison between software and devices. Implementations on versions may vary.

Device/software Plaintext TLS SSH Notes
RTRdump Yes Yes Yes
RTRlib Yes No Yes Only SSH key
Juniper Yes No No
Cisco Yes No Yes Only SSH password
Nokia SR OS Yes No No Since 9.0.R1(2010)
Arista Yes No No
FRRouting Yes No Yes Only SSH key
Bird2 Yes No Yes Only SSH key
Quagga Yes No No

Configure on Juniper

Configure a session to the RTR server (assuming it runs on 192.168.1.100:8282)

louis@router> show configuration routing-options validation
group TEST-RPKI {
    session 192.168.1.100 {
        port 8282;
    }
}

Add policies to validate or invalidate prefixes

louis@router> show configuration policy-options policy-statement STATEMENT-EXAMPLE
term RPKI-TEST-VAL {
    from {
        protocol bgp;
        validation-database valid;
    }
    then {
        validation-state valid;
        next term;
    }
}
term RPKI-TEST-INV {
    from {
        protocol bgp;
        validation-database invalid;
    }
    then {
        validation-state invalid;
        reject;
    }
}

Display status of the session to the RTR server.

louis@router> show validation session 192.168.1.100 detail
Session 192.168.1.100, State: up, Session index: 1
  Group: TEST-RPKI, Preference: 100
  Port: 8282
  Refresh time: 300s
  Hold time: 600s
  Record Life time: 3600s
  Serial (Full Update): 1
  Serial (Incremental Update): 1
    Session flaps: 2
    Session uptime: 00:25:07
    Last PDU received: 00:04:50
    IPv4 prefix count: 46478
    IPv6 prefix count: 8216

Show content of the database (list the PDUs)

louis@router> show validation database brief
RV database for instance master

Prefix                 Origin-AS Session                                 State   Mismatch
1.0.0.0/24-24              13335 192.168.1.100                           valid
1.1.1.0/24-24              13335 192.168.1.100                           valid

Configure on Cisco

You may want to use the option to do SSH-based connection.

On Cisco, you can have only one RTR server per IP.

To configure a session for 192.168.1.100:8282: Replace 65001 by the configured ASN:

router bgp 65001
 rpki server 192.168.1.100
  transport tcp port 8282
 !
!

For an SSH session, you will also have to configure router bgp 65001 rpki server 192.168.1.100 password xxx where xxx is the password. Some experimentations showed you have to configure the username/password first, otherwise it will not accept the port.

router bgp 65001
 rpki server 192.168.1.100
  username rpki
  transport ssh port 8282
 !
!
ssh client tcp-window-scale 14
ssh timeout 120

The last two SSH statements solved an issue causing the connection to break before receiving all the PDUs (TCP window full problem).

To visualize the state of the session:

RP/0/RP0/CPU0:ios#sh bgp rpki server 192.168.1.100

RPKI Cache-Server 192.168.1.100
  Transport: SSH port 8282
  Connect state: ESTAB
  Conn attempts: 1
  Total byte RX: 1726892
  Total byte TX: 452
  Last reset
    Timest: Apr 05 01:19:32 (04:26:58 ago)
    Reason: protocol error
SSH information
  Username: rpki
  Password: *****
  SSH PID: 18576
RPKI-RTR protocol information
  Serial number: 15
  Cache nonce: 0x0
  Protocol state: DATA_END
  Refresh  time: 600 seconds
  Response time: 30 seconds
  Purge time: 60 seconds
  Protocol exchange
    ROAs announced:  67358 IPv4   11754 IPv6
    ROAs withdrawn:     80 IPv4      34 IPv6
    Error Reports :      0 sent       0 rcvd
  Last protocol error
    Reason: response timeout
    Detail: response timeout while in DATA_START state

To visualize the accepted PDUs:

RP/0/RP0/CPU0:ios#sh bgp rpki table

  Network               Maxlen          Origin-AS         Server
  1.0.0.0/24            24              13335             192.168.1.100
  1.1.1.0/24            24              13335             192.168.1.100

Configure on Arista

router bgp <asn>
   rpki cache <name>
      host <ipv4|ipv6|hostname> [vrf <vrfname>] [port <1-65535>] # default port is 323
      local-interface <interface>
      preference <1-10>                    # the lower the value, the more preferred
                                           # default is 5
      refresh-interval <1-86400 seconds>   # default is 3600
      expire-interval <600-172800 seconds> # default is 7200
      retry-interval <1-7200 seconds>      # default is 600

If multiple caches are configured, the preference controls the priority.
Caches which are more preferred will be connected to first, if they are not reachable then connections will be attempted to less preferred caches.
If caches have the same preference value, they will all be connected to and the ROAs that are synced from them will be merged together.

To visualize the state of the session:

show bgp rpki cache [<name>]
show bgp rpki cache counters [errors]
show bgp rpki roa summary

To visualize the accepted PDUs:

show bgp rpki roa (ipv4|ipv6) [prefix]

Configure on Nokia SR OS

/configure router "management" # or "Base" for in-band
    origin-validation {
        rpki-session 172.65.0.2 {
            admin-state enable
            description "rtr.rpki.cloudflare.com"
            port 8282
        }
    }

See this NANOG 67 presentation for context

To check the state:

A:admin@IXPRouter# show router "management" origin-validation rpki-session detail 

===============================================================================
RPKI Session Information
===============================================================================
IP Address         : 172.65.0.2
Description        : rtr.rpki.cloudflare.com
-------------------------------------------------------------------------------
Port               : 8282               Oper State         : established
Uptime             : 0d 00:29:07        Flaps              : 0
Active IPv4 Records: 327768             Active IPv6 Records: 67796
Admin State        : Up                 Local Address      : n/a
Hold Time          : 600                Refresh Time       : 300
Stale Route Time   : 3600               Connect Retry      : 120
Serial ID          : 1                  Session ID         : 9944
===============================================================================
No. of Sessions    : 1
===============================================================================

License

Licensed under the BSD 3 License.

More Repositories

1

quiche

🥧 Savoury implementation of the QUIC transport protocol and HTTP/3
Rust
8,654
star
2

cfssl

CFSSL: Cloudflare's PKI and TLS toolkit
Go
8,049
star
3

cloudflared

Cloudflare Tunnel client (formerly Argo Tunnel)
Go
5,870
star
4

boringtun

Userspace WireGuard® Implementation in Rust
Rust
5,768
star
5

workerd

The JavaScript / Wasm runtime that powers Cloudflare Workers
C++
5,699
star
6

flan

A pretty sweet vulnerability scanner
Python
3,910
star
7

miniflare

🔥 Fully-local simulator for Cloudflare Workers. For the latest version, see https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare.
TypeScript
3,656
star
8

wrangler-legacy

🤠 Home to Wrangler v1 (deprecated)
Rust
3,233
star
9

cloudflare-docs

Cloudflare’s documentation
CSS
2,578
star
10

tableflip

Graceful process restarts in Go
Go
2,549
star
11

workers-rs

Write Cloudflare Workers in 100% Rust via WebAssembly
Rust
2,182
star
12

workers-sdk

⛅️ Home to Wrangler, the CLI for Cloudflare Workers®
TypeScript
2,047
star
13

wildebeest

Wildebeest is an ActivityPub and Mastodon-compatible server
TypeScript
2,026
star
14

gokey

A simple vaultless password manager in Go
Go
1,836
star
15

ebpf_exporter

Prometheus exporter for custom eBPF metrics
C
1,639
star
16

lol-html

Low output latency streaming HTML parser/rewriter with CSS selector-based API
Rust
1,388
star
17

redoctober

Go server for two-man rule style file encryption and decryption.
Go
1,373
star
18

cf-ui

💎 Cloudflare UI Framework
JavaScript
1,297
star
19

sslconfig

Cloudflare's Internet facing SSL configuration
1,287
star
20

cloudflare-go

Go library for the Cloudflare v4 API
Go
1,246
star
21

foundations

Cloudflare's Rust service foundations library.
Rust
1,163
star
22

hellogopher

Hellogopher: "just clone and make" your conventional Go project
Makefile
1,153
star
23

production-saas

(WIP) Example SaaS application built in public on the Cloudflare stack!
TypeScript
1,099
star
24

bpftools

BPF Tools - packet analyst toolkit
Python
1,087
star
25

cloudflare-blog

Cloudflare Blog code samples
C
1,065
star
26

wrangler-action

🧙‍♀️ easily deploy cloudflare workers applications using wrangler and github actions
TypeScript
993
star
27

templates

A collection of starter templates and examples for Cloudflare Workers and Pages
JavaScript
979
star
28

circl

CIRCL: Cloudflare Interoperable Reusable Cryptographic Library
Go
970
star
29

wirefilter

An execution engine for Wireshark-like filters
Rust
913
star
30

pingora

A library for building fast, reliable and evolvable network services.
Rust
896
star
31

cf-terraforming

A command line utility to facilitate terraforming your existing Cloudflare resources.
Go
859
star
32

next-on-pages

CLI to build and develop Next.js apps for Cloudflare Pages
TypeScript
845
star
33

utahfs

UtahFS is an encrypted storage system that provides a user-friendly FUSE drive backed by cloud storage.
Go
805
star
34

workers-chat-demo

JavaScript
779
star
35

pint

Prometheus rule linter/validator
Go
772
star
36

Stout

A reliable static website deploy tool
Go
749
star
37

goflow

The high-scalability sFlow/NetFlow/IPFIX collector used internally at Cloudflare.
Go
729
star
38

unsee

Alert dashboard for Prometheus Alertmanager
Go
710
star
39

terraform-provider-cloudflare

Cloudflare Terraform Provider
Go
704
star
40

mitmengine

A MITM (monster-in-the-middle) detection tool. Used to build MALCOLM:
Go
690
star
41

workers-graphql-server

🔥Lightning-fast, globally distributed Apollo GraphQL server, deployed at the edge using Cloudflare Workers
JavaScript
635
star
42

react-gateway

Render React DOM into a new context (aka "Portal")
JavaScript
569
star
43

xdpcap

tcpdump like XDP packet capture
Go
567
star
44

cloudflare-php

PHP library for the Cloudflare v4 API
PHP
566
star
45

ahocorasick

A Golang implementation of the Aho-Corasick string matching algorithm
Go
541
star
46

lua-resty-logger-socket

Raw-socket-based Logger Library for Nginx (based on ngx_lua)
Perl
477
star
47

nginx-google-oauth

Lua module to add Google OAuth to nginx
Lua
425
star
48

gokeyless

Go implementation of the keyless protocol
Go
420
star
49

worker-typescript-template

ʕ •́؈•̀) TypeScript template for Cloudflare Workers
TypeScript
416
star
50

golibs

Various small golang libraries
Go
402
star
51

stpyv8

Python 3 and JavaScript interoperability. Successor To PyV8 (https://github.com/flier/pyv8)
C++
388
star
52

sandbox

Simple Linux seccomp rules without writing any code
C
385
star
53

mmap-sync

Rust library for concurrent data access, using memory-mapped files, zero-copy deserialization, and wait-free synchronization.
Rust
380
star
54

speedtest

Component to perform network speed tests against Cloudflare's edge network
JavaScript
371
star
55

mmproxy

mmproxy, the magical PROXY protocol gateway
C
370
star
56

pages-action

JavaScript
355
star
57

rustwasm-worker-template

A template for kick starting a Cloudflare Worker project using workers-rs. Write your Cloudflare Worker entirely in Rust!
Rust
350
star
58

workers-types

TypeScript type definitions for authoring Cloudflare Workers.
TypeScript
350
star
59

cobweb

COBOL to WebAssembly compiler
COBOL
345
star
60

cloudflare-ingress-controller

A Kubernetes ingress controller for Cloudflare's Argo Tunnels
Go
344
star
61

lua-resty-cookie

Lua library for HTTP cookie manipulations for OpenResty/ngx_lua
Perl
340
star
62

svg-hush

Make it safe to serve untrusted SVG files
Rust
333
star
63

boring

BoringSSL bindings for the Rust programming language.
Rust
330
star
64

node-cloudflare

Node.js API for Client API
JavaScript
319
star
65

cfweb3

JavaScript
309
star
66

workerskv.gui

(WIP) A cross-platform Desktop application for exploring Workers KV Namespace data
Svelte
307
star
67

JSON.is

Open-source documentation for common JSON formats.
JavaScript
302
star
68

sqlalchemy-clickhouse

Python
299
star
69

cloudflare.github.io

Cloudflare ❤️ Open Source
CSS
298
star
70

json-schema-tools

Packages for working with JSON Schema and JSON Hyper-Schema
JavaScript
296
star
71

chatgpt-plugin

Build ChatGPT plugins with Cloudflare's Developer Platform 🤖
JavaScript
290
star
72

tls-tris

crypto/tls, now with 100% more 1.3. THE API IS NOT STABLE AND DOCUMENTATION IS NOT GUARANTEED.
Go
283
star
73

react-modal2

💭 Simple modal component for React.
JavaScript
279
star
74

doom-wasm

Chocolate Doom WebAssembly port with WebSockets support
C
273
star
75

keyless

Cloudflare's Keyless SSL Server Reference Implementation
C
272
star
76

isbgpsafeyet.com

Is BGP safe yet?
HTML
262
star
77

go

Go with Cloudflare experimental patches
Go
260
star
78

dog

Durable Object Groups
TypeScript
255
star
79

kv-asset-handler

Routes requests to KV assets
TypeScript
244
star
80

mod_cloudflare

C
243
star
81

tubular

BSD socket API on steroids
C
242
star
82

semver_bash

Semantic Versioning in Bash
Shell
238
star
83

cloudflare-rs

Rust library for the Cloudflare v4 API
Rust
236
star
84

cfssl_trust

CFSSL's CA trust store repository
Go
226
star
85

doca

A CLI tool that scaffolds API documentation based on JSON HyperSchemas.
JavaScript
224
star
86

pmtud

Path MTU daemon - broadcast lost ICMP packets on ECMP networks
C
218
star
87

alertmanager2es

Receives HTTP webhook notifications from AlertManager and inserts them into an Elasticsearch index for searching and analysis
Go
218
star
88

itty-router-openapi

OpenAPI 3 and 3.1 schema generator and validator for Cloudflare Workers
TypeScript
218
star
89

origin-ca-issuer

Go
216
star
90

worker-template-router

JavaScript
216
star
91

cloudflare-docs-engine

A documentation engine built on Gatsby, powering Cloudflare’s docs https://github.com/cloudflare/cloudflare-docs
JavaScript
215
star
92

python-worker-hello-world

Python hello world for Cloudflare Workers
JavaScript
209
star
93

saffron

The cron parser powering Cron Triggers on Cloudflare Workers
Rust
207
star
94

Cloudflare-WordPress

A Cloudflare plugin for WordPress
PHP
204
star
95

certmgr

Automated certificate management using a CFSSL CA.
Go
202
star
96

collapsify

Collapsify inlines all the resources of a page into a single document
JavaScript
200
star
97

worker-speedtest-template

JavaScript
195
star
98

har-sanitizer

TypeScript
192
star
99

zkp-ecdsa

Proves knowledge of an ECDSA-P256 signature under one of many public keys that are stored in a list.
TypeScript
187
star
100

shellflip

Graceful process restarts in Rust
Rust
183
star