RPKI is a hierarchical Public Key Infrastructure(PKI) that binds Internet Number Resources(INRs) such as Autonomous System Numbers(ASNs) and IP addresses to public keys via certificates. RPKI allows INR holder(certificate holder) to allocate certain IP prefix to their customers via issuing resource certificates(RCs) and authorizing an ASN to announce certain IP prefixes via issuing ROAs, and all of these RPKI objects are published in RPKI repository.
As the bridge between inter-domain routing system and RPKI repository, RPKI Relying Party(RP) is designed to assist BGP Speakers in synchronization of RPKI objects, validation of certificate chain, cache management and transmission of Validated ROA Payloads(VRPs).
RPSTIR2 is a kind of RP software written in GO, which based on design idea of RPSTIR, provides all the standard functions mentioned above. RPSTIR2 also supports more RPKI-related protocols and optimizes performance.
RPSTIR2 is capable of running on CentOS7(64bit)/Ubuntu18(64bit) or higher.
OpenSSL version must be 1.1.1b or higher, and "enable-rfc3779" needs to be set when compiling OpenSSL.
$ wget --no-verbose --inet4-only https://www.openssl.org/source/openssl-1.1.1f.tar.gz
$ tar xzvf openssl-1.1.1f.tar.gz
$ cd openssl-1.1.1f
$ ./config shared enable-rfc3779
$ make
$ make install
$ echo "export PATH=/usr/local/ssl/bin:$PATH" >> /root/.bashrc
$ source /root/.bashrc
You can download and install MySQL from https://dev.mysql.com/downloads/ according to your platform. MySQL version must be 8 or higher and should support JSON. You should login in MySQL as root, and create user accounts and database of RPSTIR2.
CREATE USER 'rpstir2'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Rpstir-123';
CREATE USER 'rpstir2'@'%' IDENTIFIED WITH mysql_native_password BY 'Rpstir-123';
flush privileges;
CREATE DATABASE rpstir2;
GRANT ALL PRIVILEGES ON rpstir2.* TO 'rpstir2'@'localhost' with grant option;
GRANT ALL PRIVILEGES ON rpstir2.* TO 'rpstir2'@'%' with grant option;
flush privileges;
Note: You also can use docker to run MySQL, and make sure that the time zone of docker is the same as that of the host.
If you plan to compile the program by yourself, you need to install a version of Golang higher than 1.17. Otherwise you don't need to install it.
Before installing RPSTIR2, you should create directories in advance, one of which is for program and the other is for the cache data. you can modify the shell, and change "conf/project.conf".
Directory | Path |
---|---|
programDir | /root/rpki/rpstir2 |
dataDir | /root/rpki/data |
$ mkdir -p /root/rpki/ /root/rpki/rpstir2 /root/rpki/data /root/rpki/data/rrdprepo /root/rpki/data/rsyncrepo /root/rpki/data/tal
$ cd /root/rpki/
$ git clone https://github.com/bgpsecurity/rpstir2.git
$ cd /root/rpki/rpstir2/bin
$ chmod +x *
$ cp /root/rpki/rpstir2/build/tal/* /root/rpki/data/tal/
You can modify configuration parameters of programDir, dataDir, mysql, and port in configuration file(/root/rpki/rpstir2/conf/project.conf).
The RPSTIR2 must be started first, you can check for errors by looking at the log files in ./log/ directory.
You can check the log files in ./log/ to see whether the program is started successfully.
$ cd /root/rpki/rpstir2/bin
$./rpstir2.sh start
$ cd /root/rpki/rpstir2/bin
$./rpstir2.sh stop
This command is used to initialize or reset the database. Please check the log files in ./log/ to see if the execution is successful.
$ cd /root/rpki/rpstir2/bin
$./rpstir2.sh start
$./rpstir2.sh init
You can use crontab to perform scheduled synchronization tasks. Then RPSTIR2 will download RPKI objects, and complete the subsequent validation procedure according to the schedule you set.
$ crontab -e
10 */4 * * * cd /root/rpki/rpstir2/bin/;./rpstir2.sh crontab
Note: The RPSTIR2 service must start first.
You can download RPKI objects with rsync or RRDP protocol, and complete the subsequent validation procedure.
$ cd /root/rpki/rpstir2/bin
$ ./rpstir2.sh sync
Because rsync and RRDP take long time to run, they are executed in the background. So you need a command to determine if the synchronization and validation process is complete.
$ cd /root/rpki/rpstir2/bin
$ ./rpstir2.sh state | jq .
When you get the following JSON message, if "isRunning" is "true", it means that sync and validation are still running; if it is "false", sync and validation complete. At this time, the router can obtain rpki data through RTR port.
{
"result": "ok",
"msg": "",
"data": {
"startTime": "2020-01-01 01:01:01 CST",
"isRunning": "false",
"runningState": "idle"
}
}
Note: jq can format JSON for output
You can get results of synchronization and validation. It shows the valid, warning and invalid number of cer, roa, mft and crl respectively.
$ cd /root/rpki/rpstir2/bin
$./rpstir2.sh results | jq .
{
"cerResult": {
"fileType": "cer",
"validCount": 16920,
"warningCount": 0,
"invalidCount": 6
},
"crlResult": {
"fileType": "crl",
"validCount": 16916,
"warningCount": 0,
"invalidCount": 51
},
"mftResult": {
"fileType": "mft",
"validCount": 16914,
"warningCount": 0,
"invalidCount": 71
},
"roaResult": {
"fileType": "roa",
"validCount": 31779,
"warningCount": 0,
"invalidCount": 288
}
}
You can get all valid roas after sync.
$ cd /root/rpki/rpstir2/bin
$./rpstir2.sh exportroas | jq .
[
{
"repo": "rpki.afrinic.net",
"rir": "AFRINIC",
"maxLength": 20,
"addressPrefix": "102.128.144/20",
"asn": 328210
},
{
"repo": "rpki.afrinic.net",
"rir": "AFRINIC",
"maxLength": 24,
"addressPrefix": "102.128.144/20",
"asn": 328210
},
....
You can parse cer/mft/crl/roa/sig/asa file.
$ cd /root/rpki/rpstir2/bin
$./rpstir2.sh parse ../doc/checklist.sig | jq .
{
"data": {
"signerInfoModel": {
"messageDigest": "BD32690504277FE2D1CCEF127174F0ACA0A1785170452C472BE631839425400D",
"signingTime": "2021-02-10T14:50:25Z",
"contentType": "1.3.6.1.4.1.41948.49",
"digestAlgorithm": "sha256",
"version": 3
},
"eeCertModel": {
"eeCertEnd": 1279,
"eeCertStart": 224,
"crldpModel": {
"critical": false,
"crldps": [
"rsync://chloe.sobornost.net/rpki/RIPE-nljobsnijders/LMq8Kl3LkWGqticaaLl6IAGSsJ4.crl"
]
},
"cerIpAddressModel": {
"critical": false,
"cerIpAddresses": null
},
"siaModel": {
"critical": false,
"signedObject": "",
"caRepository": "",
"rpkiNotify": "",
"rpkiManifest": ""
},
"issuerAll": "CN=2ccabc2a5dcb9161aab6271a68b97a200192b09e",
"subjectAll": "CN=EE",
"isCa": false,
"version": 3,
"digestAlgorithm": "SHA256-RSA",
"sn": "9",
"notBefore": "2021-02-10T22:50:10+08:00",
"notAfter": "2022-02-10T22:50:10+08:00",
"keyUsageModel": {
"keyUsageValue": "Digital Signature",
"critical": true,
"keyUsage": 1
},
"extKeyUsages": [],
"basicConstraintsValid": false
},
"aiaModel": {
"critical": false,
"caIssuers": "rsync://rpki.ripe.net/repository/DEFAULT/LMq8Kl3LkWGqticaaLl6IAGSsJ4.cer"
},
"version": 0,
"ski": "41ca827f3de666e9f7323f3059f6a7bb8b671175",
"aki": "2ccabc2a5dcb9161aab6271a68b97a200192b09e",
"filePath": "",
"fileName": "checklist.sig",
"fileHash": "fe44eb4ef1e389c1879f000f31485bac43e3c51a66040337625aa887a20d9556",
"rpkiSignedChecklist": {
"fileHashModels": [
{
"hash": "9516dd64be7c1725b9fca117120e58e8d842a5206873399b3ddffc91c4b6acf0",
"file": "b42_ipv6_loa.png"
},
{
"hash": "0ae1394722005cd92f4c6aa024d5d6b3e2e67d629f11720d9478a633a117a1c7",
"file": "b42_service_definition.json"
}
],
"digestAlgorithm": "2.16.840.1.101.3.4.2.1",
"cerIpAddresses": [
{
"addressPrefixRange": "",
"rangeEnd": "",
"rangeStart": "",
"max": "",
"min": "",
"addressPrefix": "2001:67c:208c::/48",
"addressFamily": 2
}
]
},
"eContentType": "1.3.6.1.4.1.41948.49"
},
"msg": "",
"result": "ok"
}
$ cd /root/rpki/rpstir2/bin
$./rpstir2.sh parse ../doc/AS211321.asa | jq .
{
"data": {
"signerInfoModel": {
"messageDigest": "C7388599A2D43808F7BB13A0D095FFCFBBA880AE850C2699F67B764538E66CA0",
"signingTime": "2021-11-11T11:19:00Z",
"contentType": "1.2.840.113549.1.9.16.1.49",
"digestAlgorithm": "sha256",
"version": 3
},
"eeCertModel": {
"eeCertEnd": 1308,
"eeCertStart": 102,
"crldpModel": {
"critical": false,
"crldps": [
"rsync://rsync.accept.krill.cloud/repo/accept/0/7088BE00CA85327CA016C9074ED007C3FA919991.crl"
]
},
"cerIpAddressModel": {
"critical": false,
"cerIpAddresses": null
},
"siaModel": {
"critical": false,
"signedObject": "rsync://rsync.accept.krill.cloud/repo/accept/0/AS211321.asa",
"caRepository": "",
"rpkiNotify": "",
"rpkiManifest": ""
},
"issuerAll": "CN=7088be00ca85327ca016c9074ed007c3fa919991",
"subjectAll": "CN=37CA1DDE4D094734AB3B048269E12FDDAEAA691B",
"isCa": false,
"version": 3,
"digestAlgorithm": "SHA256-RSA",
"sn": "2de71e5b974c86a28d6bb3c1e1b4ece5091f12c",
"notBefore": "2021-11-11T19:14:00+08:00",
"notAfter": "2022-11-10T19:19:00+08:00",
"keyUsageModel": {
"keyUsageValue": "Digital Signature",
"critical": true,
"keyUsage": 1
},
"extKeyUsages": [],
"basicConstraintsValid": false
},
"siaModel": {
"critical": false,
"signedObject": "rsync://rsync.accept.krill.cloud/repo/accept/0/AS211321.asa",
"caRepository": "",
"rpkiNotify": "",
"rpkiManifest": ""
},
"aiaModel": {
"critical": false,
"caIssuers": "rsync://localcert.ripe.net/repository/DEFAULT/cIi-AMqFMnygFskHTtAHw_qRmZE.cer"
},
"version": 0,
"ski": "37ca1dde4d094734ab3b048269e12fddaeaa691b",
"aki": "7088be00ca85327ca016c9074ed007c3fa919991",
"filePath": "",
"fileName": "AS211321.asa",
"fileHash": "e2f896d37de277e93309ef52f01fe3131b762b1383e86cd7933887ad7eaf1257",
"asProviderAttestations": [
{
"ProviderAsIds": [
{
"addressFamilyIdentifier": "",
"providerAsId": 65000
},
{
"addressFamilyIdentifier": "0x0001",
"providerAsId": 65001
},
{
"addressFamilyIdentifier": "0x0002",
"providerAsId": 65002
}
],
"customerAsId": 211321
}
],
"eContentType": "1.2.840.113549.1.9.16.1.49"
},
"msg": "",
"result": "ok"
}
You can compile the program by yourself if you have installed GoLang.
$ cd /root/rpki/rpstir2/bin
$./rpstir2.sh rebuild
$ cd /root/rpki/rpstir2/bin
$./rpstir2.sh help
Please open an issue on our GitHub page or mail to shaoqing@zdns.cn with any problems or bugs you encounter.