Develop with pleasure!

福岡でCloudとかBlockchainとか。

Bitcoin Core 0.20.0でASマップを使ったピア選択を有効にする

BitcoinP2Pネットワークに参加するノードは、起動時に他のピアを探し接続することでネットワークに参加する。現在Bitcoin Coreでは8つのアウトバウンドピア(ブロックリレー専用のものがさらに2つある)に接続するようになっているが、ピアを選択する際にピアのIPアドレスの先頭が異なるものを選択するようになっている。

この/16プレフィックスルールは、ISPの多くがプレフィックスの異なる範囲のIPアドレスを多数持っておらず、ユーザーが期待するIPアドレスを入手するのが困難であるため、攻撃者がプレイフィックスの異なるIPを取得するのが難しいという仮定に基づいている。

ところが、クラウドの登場で巨大なIPの範囲を持つISPが登場するようになり、ユーザーが異なるプレフィックスのIPを取得するのが以前より簡単になってしまった。そのため、IPのプレフィックスの代わりに、AS番号を使用しAS番号の異なるピアに接続するようピア選択を改良したのが0.20.0で導入されたASマップ。ただまだ実験的な機能であるとし、デフォルトは従来の/16プレフィックスルールのまま。

このASマップによるピア選択がサポートされると、2019年に発表されたErbus攻撃↓のような攻撃への対策にも繋がる。

https://erebus-attack.comp.nus.edu.sg/

Erbus攻撃は悪意あるISPが、BitcoinP2Pネットワークからターゲットとなるフルノードを分離する攻撃で、BGBハイジャックなどのルーティング操作を必要としないため攻撃が検知されづらい。

ASマップとは?

ASとはautonomous systemの略。インターネットは小さなネットワークが集まって構成されていて、この小さなネットワーク1つ1つがASで、1つ以上のネットワークオペレーター(ISPや大企業)のコントロール下にあるIPのルーティングプレフィックスの集合。小さなといってもISPなどの比較的大きなネットワークではある。これらのASにふられるグローバルで一意な番号がAS番号(ASN)でBGPのルーティングの際に使用されている。IPが属するAS番号についてはASN Lookup Tool | UltraToolsとかで確認できる。

そしてIPがどのASに属するかをマッピングしたものがASマップ。ちなみにASマップを利用せずにBitcoin Coreをmainnetで起動したところ、アウトバウンドピアのAS番号は↓だった。

AS16509, AMAZON-02, US
AS24940, HETZNER-AS, DE
AS6327, SHAW, CA
AS5588, GTSCE GTS Central Europe / Antel Germany, CZ
AS16276, OVH, FR
AS23470, RELIABLESITE, US
AS60781, LEASEWEB-NL-AMS-01 Netherlands, NL
AS16509, AMAZON-02, US

AWSっぽいAS16509のみAS番号が重複していた。AS間のIP分散は均一ではないため、/16プレフィックスルールを8つのアウトバウンドピアの選択に使うと2つの大きなASからの接続が発生する可能性があると言われていて、その通りになっている。

ASマップを利用する

Bitcoin Core 0.20.0で接続するアウトバウンドピアの選択にASマップを利用する場合、-asmapオプションを使ってIP -> ASNのマッピングファイルを指定する。

$ bitcoind -daemon -asmap

と起動すると(bitcoin.conf内で指定するのでもOK)、Bitcoinディレクトリ内のip_asn.mapという名前のファイルを探しにいく。別のファイル名やパスを指定したい場合は-asmap=<ファイルパス>を指定すればいい。

ASマップの用意

ip_asn.mapファイルは提供されていないので、自分で用意する必要がある。ASマップを作成する方法としては、各ユーザーがそれぞれルーターダンプを使って独自に作成するか、今後Bitcoin Coreのリリースと一緒に配布される?ようになるかもしれない。

現状、コア開発者の@sipaがマップファイルを作成するスクリプトを公開しているので、それを利用するのが早い。

https://github.com/sipa/asmap

リポジトリ内に、demo.mapという名前のファイルがあるので、これをip_asn.mapにリネームして-asmapオプションを付けてbitcoindを起動すればいい。

起動して接続されたアウトバウンドピアのAS番号を確認すると↓

AS42116, ERTH-NCHLN-AS, RU
AS50297, INFIUM, UA
AS8758, IWAY, CH
AS14061, DIGITALOCEAN-ASN, US
AS12876, Online SAS, FR
AS3223, VOXILITY, GB
AS63949, LINODE-AP Linode, LLC, US
AS44395, ORG-UL31-RIPE, AM
AS24904, KWAOO K-NET SARL, FR
AS6830, LIBERTYGLOBAL Liberty Global (formerly UPC Broadband Holding, aka AORTA), AT

AS番号が重複するピアは無くなった。

独自にASマップを作成する場合

remote_dumpsディレクトリには、現時点のBGPのルーティング情報をダウンロードし、マッピングファイルを作成するスクリプトが提供されているので、そのスクリプトを使ってASマップファイルを準備することもできるもよう。

事前に以下のセットアップを行い↓

$ cd remote_dumps
$ sudo ./setup.sh

↑の準備は一度やればOK。続いて、ASマップファイルを以下の手順で作成できるみたい(一時的だけどそれなりにディスクスペースが必要)。

  1. $python3 ./download_dumps.pyを実行し最新のRIPEダンプをダウンロードする。ダウンロードしたデータはdumpsフォルダに格納されている。ちなみに、全データ(圧縮されて約2.8GB)ダウンロードするのに少し時間がかかる。
  2. 続いて$sh ./quagga_parse.shを実行し、dumpsフォルダ内のダンプファイルを読み込み、人が読める形式にしてpathsフォルダ内に格納する(圧縮されて約9.8GB)。
  3. python3 ./quagga_aggregate.pyを実行するとpathsフォルダ内のデータを読み込み、パスを集約し、すべてのIPプレフィックスをASNパスの共通サフィックスの最初の要素に割り当てる。結果prefix_asns.outというファイルが生成される。
  4. 1つ上のフォルダにある../buildmap.p`prefix_asns.outを与えて実行する。

ただ、実行しようとすると、3のマッピングの処理中に期待したASNのサフィックスが見つからずにエラーが発生する。RIPEダンプの1つが404で取得できていないのが原因なのか?不明。

所感

  • 現状デフォルトの/16プレフィックスルールでもASの重複はそんなに無いが、ASマップによる選択を有効にすることで、確実に接続ピアのASが重複しないことが保証される。
  • アウトバウンドピアは自身がブロックやトランザクションをアナウンスするのに使用するため、異なるASのピアに対して送る方がネットワーク的には好ましい?
  • 頻度は高くなくてもいいけど、ASマップファイルの定期的な配布や、更新も必要。