2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BGP経路検証を支えるRPKI — Krill × Routinator によるROA発行と検証

Last updated at Posted at 2025-11-02

はじめに

最近、RPKIが気になっている。とあるISPのインターンでRPKIの話題が出たのがきっかけだ。そのときは軽い説明程度で、「へ〜、ほうほう」とおもっただけなのだが、BGP関連の話で頻繁に登場するため、これはきちんと理解しておくべき技術なのではないかと感じた。

そこで本記事では、CML ( Cisco Modeling Labs ) を用いたミニチュアRPKI環境の構築と動作確認を通じて、RPKIの理解を深めることを目的とする。具体的には、NLnet Labsが提供するKrill(子CA)とRoutinator(RPKI Validator)を構築し、実際にROAを発行して、BGPルータ上で「経路の正当性がどのように判定されるのか」を確認する。

最終的に、「ROAを発行するとBGPの経路選択にどのような変化が起きるのか」を目で見て確認するところまでを目標とする。

image.png

背景 - 経路ハイジャック

経路ハイジャック ( BGPハイジャック ) は、インターネットの通信経路を偽装して、他人のネットワーク宛てのデータを横取りしたり遮断したりするものです。

実際にどのように経路ハイジャックが起きるのかを、以下の構成図で簡単に説明します。

構成としては、AS1、AS2、AS3、AS4の4つのASがある状態で、各ASは隣接ASとピアを張っている状態です。そして、AS3は「10.0.0.0/16」というアドレス範囲を保有しており、AS2やAS1に対して「このネットワークは自分のものです」とBGPを使って経路情報を広報しています。インターネットではBGPの情報をもとにルータが最適な経路を判断するため、AS1から10.0.0.0/16宛ての通信はAS2を経由してAS3へ届きます。

スクリーンショット 2025-11-02 14.55.07.png

しかし、悪意を持ったAS4が「10.0.0.0/16は自分のネットワークだ」と嘘の経路情報を広報します。すると、AS1はAS4とも直接接続しているため、AS4からの情報を受け取ります。BGPはASパスが短い/またはパス属性によりAS4経由が優先される場合があります。これにより、AS4は通信を盗み見たり、改ざんしたり、最悪の場合はすべて破棄することも可能となります。

スクリーンショット 2025-11-02 14.55.11.png

ここで登場するのが RPKI ( Resource Public Key Infrastructure ) です。
AS3が「10.0.0.0/16はAS3が正当な発信元である」という内容の ROAを発行していれば、AS1やAS2は経路情報を受け取る際にRPKIデータベースを参照し、「この経路の発信元ASは正しいか?」を検証します。
AS4の虚偽経路はこの検証で失敗し、「無効 ( invalid ) 」と判定されるため、AS1はAS4からの経路を採用しません。
結果として、AS1は正当なAS3の経路のみを維持し、不正な経路ハイジャックを防ぐことができます。

スクリーンショット 2025-11-02 14.55.17.png

RPKI ( Resource Public Key Infrastructure ) とは

ここでは、前述で登場した RPKIについて、もう少し詳しく説明します。
RPKIは、IPアドレスやAS番号といったインターネット上のリソースに対して「誰が正当な所有者であるかを証明」し、その情報をもとに BGP の経路広報が正しいかどうかを検証できる仕組みです。

大まかな流れとしては、

  1. 組織が自分のプレフィックスに対してROAを作成

  2. CAがそのROAを受け取り、リポジトリに登録

  3. 各ネットワークのROAキャッシュサーバがROAを同期・検証

  4. 検証済みROA ( VRP ) をキャッシュサーバに保持

  5. BGPルータがキャッシュを参照して経路の正当性を判定

といった流れになります。

スクリーンショット 2025-11-02 17.20.38.png

以降では、各用語について触れていきます。

CA ( Certificate Authority:認証局 )

RPKI の基盤を支えているのが CA です。
各地域インターネットレジストリ ( RIR:APNIC、ARIN、RIPE NCCなど ) は、自身が割り当てたリソースに対して リソース証明書 ( Resource Certificate ) を発行します。
組織 ( LIRやISP ) はその証明書を使って、「自分が正当に管理しているプレフィックスである」ことを第三者に証明できます。

たとえば:

  • RIPE NCCが組織Aに 203.0.113.0/24 を割り当てる。
  • 組織AはRIPE NCCからCA証明書を受け取る。
  • その証明書により、「このプレフィックスの正当な管理者はAである」と証明可能になる

ROA ( Route Origin Authorization )

ROAは、「どのAS番号がどのプレフィックスをBGPで広報してよいか」を定義する情報です。
リソース証明書をもとに作成され、RPKIシステム全体の要となる存在です。

ROA
Prefix: 203.0.113.0/24  
Origin-AS: 64500  
MaxLength: 24

このROAは、「AS64500が203.0.113.0/24を広報することは正当である」という意味を持ちます。
一方で、他のAS ( 例:AS64501 ) が同じプレフィックスを広報した場合、その経路は「無効 ( invalid ) 」として判定されます。

ROAは発行組織自身が署名し、RPKIリポジトリに公開されます。
世界中のネットワーク機器はこのリポジトリを参照し、受け取ったBGP経路情報が正しいかどうかを照合します。

ROAキャッシュサーバ

ルータが直接RPKIデータをダウンロードして検証するのは非効率であり、スケーラビリティにも課題があります。
そのため、各ネットワークでは ROAキャッシュサーバ ( RPKI Validator ) を用意し、リポジトリから定期的にROA情報を取得・検証して整形した結果をルータへ配信します。

ルータはこのキャッシュサーバと通信する際に、RTRプロトコル ( RPKI to Router Protocol:RFC 6810 / RFC 8210 ) を使用します。
RTRは軽量なプロトコルであり、ルータが最新の検証状態 ( Valid / Invalid / NotFound ) をリアルタイムで受け取れる仕組みを提供します。

検証構成

ここでは、検証構成について説明します。
( ↓論理構成図 )
スクリーンショット 2025-11-03 19.12.25.png

( ↓CML構成図 )
スクリーンショット 2025-11-02 22.48.45.png

■ 親CA ( NLnet Labs RPKI Testbed )

NLnet LabsのRPKI Testbedは「親CA ( Parent CA ) 」として機能し、子CAであるKrillにリソース証明書を委任します。
この構成では、AS60000に対して「192.168.0.0/24」を認可するROAが発行されます。


■ 子CAおよびRPKIバリデータ ( Ubuntuサーバ上 )

Ubuntuサーバ上には、以下の2つの主要コンポーネントが動作している。

  • Krill ( Child CA )
    親CAからの委任を受け、AS60000向けのROAを発行する。

  • Routinator ( ROAs Validator )
    KrillからROAを取得・検証し、VRP ( Validated ROA Payloads ) を生成。
    生成したVRPを RPKI-RTRプロトコル を通じてルータに配布し、ルータが経路の正当性を判断できるようにする。


■ BGPネットワーク

右側は CML 2.8 ( Cisco Modeling Labs ) 上のBGPネットワーク環境で、3台の仮想ルータが接続されている。

ルータ AS番号 機能 経路広告
iol-0 AS10000 検証対象ルータ。Routinatorと接続し、受信経路をRPKIで検証する。
iol-1 AS50000 不正な経路 ( 192.168.0.0/24 )を広告。 無効経路 ( Valid )
iol-2 AS60000 正しいな経路 ( 192.168.0.0/24 ) を広告。 正常経路 ( Invalid )

■ 目標:経路検証の結果

ルータ iol-0 は、Routinatorから取得したVRPに基づいて経路を検証する。
その結果:

  • AS50000の経路 ( 192.168.0.0/24 ) → 不正 ( Invalid )
  • AS60000の経路 ( 192.168.0.0/24 ) → 正しい ( Valid )

サーバ構築

Krillの構築 & セットアップ

以下のドキュメントに従い、Krillをインストールします。

Krillの導入
sudo apt update

sudo apt install \
  ca-certificates \
  curl \
  gnupg \
  lsb-release

curl -fsSL https://packages.nlnetlabs.nl/aptkey.asc | sudo gpg --dearmor -o /usr/share/keyrings/nlnetlabs-archive-keyring.gpg

echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nlnetlabs-archive-keyring.gpg] https://packages.nlnetlabs.nl/linux/ubuntu \
$(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/nlnetlabs.list > /dev/null

sudo apt update
sudo apt install krill

次に、/etc/krill.confを編集し、外部からWebUIにアクセス可能にします。デフォルトでは、127.0.0.1からしかアクセスできない。

sudo vim /etc/krill.conf
ip "0.0.0.0" <=を追加

/etc/krill.confを編集後は、krillをリスタートします。

sudo systemctl restart krill

krillがうまく動作していれば、ブラウザからhttps://<Ubuntu IP>:3000にアクセスすることで以下のWebUIが表示される。

スクリーンショット 2025-11-02 23.09.44.png

ここからはWebUIで設定を行なっていく。パスワードは、/etc/krill.conf内のadmin_tokenに記載されている。以下のコマンドで確認可能。

sudo grep -i "admin_token = " /etc/krill.conf 

パスワードを入力すると、以下の画面に移行します。ここでは、親CA ( NLnet Labs RPKI Testbed ) とやり取りを行う、子CAを作成します。子CAの名前は適当で良いです。

スクリーンショット 2025-11-02 23.15.40.png

CAを作成すると、以下の画面に移行します。

スクリーンショット 2025-11-02 23.19.09.png

まず、親CAのリポジトリに接続する設定を行います。子CAのWebUIのRepository=>Add a repository を押下します。そして、Publisher Requestをコピーします。

スクリーンショット 2025-11-02 23.32.09.png

次は、https://testbed.krill.cloud/ui/testbed/remove にアクセスし、Register Publisherに子CAでコピーしたPublisher Requestを貼り付けます。そして、Register publisherを押下します。

スクリーンショット 2025-11-02 23.34.39.png

すると、レスポンスが表示されるので、これをコピーします。

スクリーンショット 2025-11-02 23.36.45.png

子CAのWebUIに戻り、Repository Responseに貼り付けてConfirmを押下します。

スクリーンショット 2025-11-02 23.39.18.png

設定がうまくいくと、以下のような画面になります。

スクリーンショット 2025-11-02 23.43.08.png

次に、親CA ( NLnet Labs RPKI Testbed ) に作成した子CAを登録します。流れはリポジトリの時と同様です。まず子CAのWebUIのParents=>Add an additional parent を押下します。そして、Child Requestをコピーします。

スクリーンショット 2025-11-02 23.51.26.png

次は、https://testbed.krill.cloud/ui/testbed/remove にアクセスし、Register CAに子CAでコピーしたChild Requestを貼り付けます。また、ASN ResourcesIPv4 Resourcesを設定します。今回は雑にAS0-655350.0.0.0/0と設定し、REgister child CAを押下します。

スクリーンショット 2025-11-02 23.55.45.png

すると、レスポンスが表示されるので、これをコピーします。
スクリーンショット 2025-11-02 23.55.56.png

子CAのWebUIに戻り、Parent Responseに貼り付けてConfirmを押下します。また、名前はNLnet_Labs_RPKI_Testbedとしています。

スクリーンショット 2025-11-03 0.11.56.png

設定がうまくいくと、以下のような画面になります。

スクリーンショット 2025-11-03 0.12.32.png

以上がKrillのセットアップとなり、これでROAを作成可能になります。

Routinatorの構築 & セットアップ

Krillと同様に以下のドキュメントに従い、Routinatorをインストールします。

Routinatorの導入
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nlnetlabs-archive-keyring.gpg] https://packages.nlnetlabs.nl/linux/ubuntu \
$(lsb_release -cs)-proposed main" | sudo tee /etc/apt/sources.list.d/nlnetlabs-proposed.list > /dev/null

sudo apt update

sudo apt install routinator

次に、/etc/routinator/routinator.confを編集し、外部からアクセス可能にします。デフォルトでは、127.0.0.1からしかアクセスできない。

sudo vim /etc/routinator/routinator.conf

# rtr-listen = ["127.0.0.1:3323"]
rtr-listen = ["0.0.0.0:3323"]
# http-listen = ["127.0.0.1:8323"]
http-listen = ["0.0.0.0:8323"]                                

Routinatorは、デフォルトだとインターネット上の経路情報を検証するために必要なRPKI ( Resource Public Key Infrastructure ) データを取得する際、5つの地域インターネットレジストリ ( RIR ) ——AFRINIC、APNIC、ARIN、LACNIC、RIPE NCC——が提供するトラストアンカーロケータ ( TAL ) に接続します。
このTALは、それぞれのRIRが運用するトラストアンカー証明書 ( 信頼の起点となる証明書 ) への“案内役”として機能し、RoutinatorがRPKI全体の認証情報 ( ROAやマニフェストなど ) を検出・検証するための出発点を提供するものです。今回は、NLnet Labs RPKI Testbedが提供するTALを使用するため、設定を変更する必要があります。

具体的には以下のオプションをつけた状態で起動させます。

sudo routinator --tal=nlnetlabs-testbed --no-rir-tals --config /etc/routinator/routinator.conf server

routinatorがうまく動作していれば、ブラウザからhttp://<Ubuntu IP>:8323にアクセスすることで以下のWebUIが表示されます。

スクリーンショット 2025-11-03 0.41.20.png

また、MetricsにNLNETLABS-TESTBEDの情報が表示されるようになります。

スクリーンショット 2025-11-03 1.07.00.png

以上がRoutinatorのセットアップとなり、これで子CAで作成したROAを参照することが可能になります。

ルータ設定

次はルータの設定です。

iol0
en
conf t

int e0/0
description TO-Ubuntu-Server
ip add 100.0.0.1 255.255.255.252
no shut

int e0/1
ip add 10.0.0.1 255.255.255.252
no shut

int e0/2
ip add 20.0.0.1 255.255.255.252
no shut

exit

router bgp 10000
neighbor 10.0.0.2 remote-as 50000
neighbor 20.0.0.2 remote-as 60000
bgp rpki server tcp 100.0.0.2 port 3323 refresh 60
iol1
en
conf t

int e0/1
ip add 10.0.0.2 255.255.255.252
no shut

int lo0
ip add 192.168.0.254 255.255.255.0

exit

access-list 1 permit 192.168.0.0 0.0.0.255
route-map AS10000-OUT permit 10
match ip address 1
set metric 10

exit

router bgp 50000
bgp router-id 1.1.1.1
neighbor 10.0.0.1 remote-as 10000
neighbor 10.0.0.1 route-map AS10000-OUT out
network 192.168.0.0 mask 255.255.255.0
address
iol2
en 
conf t

int e0/2
ip add 20.0.0.2 255.255.255.252
no shut

int lo0
ip add 192.168.0.254 255.255.255.0

exit

access-list 1 permit 192.168.0.0 0.0.0.255
route-map AS10000-OUT permit 10
match ip address 1
set metric 20

exit

router bgp 60000
bgp router-id 2.2.2.2
neighbor 20.0.0.1 remote-as 10000
neighbor 20.0.0.1 route-map AS10000-OUT out
network 192.168.0.0 mask 255.255.255.0

以上の設定を無事に完了すると、iol0がiol1とio02とピアを張れていることがわかります。

iol0
show ip bgp summary

スクリーンショット 2025-11-03 2.38.42.png

また、不正経路の方がMEDの値が小さいので、BGPテーブルを確認すると192.168.0.0/24のネクストホップが10.0.0.2となっていることがわかります。さらに、ROAが確認できないため、Not foundになっていることがわかります。

スクリーンショット 2025-11-03 5.59.46.png

ROAの作成

ここからは、ROA作成していきます。
ROAの作成は子CAのWebUIから作成可能です。ROAs => Add ROAを押下します。

スクリーンショット 2025-11-03 3.55.58.png

今回は、AS60000からの経路広告を正しい経路としたいので、ASN60000Prefix192.168.0.0/24Max Length24とします。

スクリーンショット 2025-11-03 3.59.27.png

無事に作成できると以下のように、作成したROAが表示されます。

スクリーンショット 2025-11-03 4.01.32.png

Routinatorで確認すると以下のようにVRPが表示されるようになります。

スクリーンショット 2025-11-03 6.03.40.png

確認

ROAの作成が完了したので、どのように変わったかを確認します。
iol0でshow ip bgpを行うと以下のような結果が返ってきます。先ほどとは、異なりAS60000から広告された経路情報を採用していることがわかります。また、先ほどまではNot foundでしたが、ROAを作成したことで経路情報にvalidとinvalidが表示されています。

スクリーンショット 2025-11-03 4.05.31.png

おわりに

本検証では、CML上でKrillとRoutinatorを構築し、RPKIの基本的な動作を確認しました。
具体的には、

  • 親CA ( NLnet Labs RPKI Testbed ) と子CA ( Krill ) の連携設定

  • 子CAによるROA ( Route Origin Authorization ) の発行

  • RoutinatorによるROAの取得・検証 ( VRP生成 )

  • ルータ ( iol0 ) によるRPKI-RTRプロトコルを用いた経路検証

という流れを構築・動作確認しました。

検証の結果、RPKIに基づくROAの有無で経路選択が変化することを確認できました。
ROAが存在しない場合はNotFoundとして扱われ、不正な経路が選択される可能性があるが、ROAを発行するとRoutinatorがVRPとしてルータに配布し、BGP経路がValid/Invalidに分類され、正しい経路 ( Valid ) が選択されることを確認しました。

参考文献

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?