BitcoinのP2Pネットワークに参加するノードは、起動時に他のピアを探し接続することでネットワークに参加する。現在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が、BitcoinのP2Pネットワークからターゲットとなるフルノードを分離する攻撃で、BGBハイジャックなどのルーティング操作を必要としないため攻撃が検知されづらい。
ASマップとは?
ASとはautonomous systemの略。インターネットは小さなネットワークが集まって構成されていて、この小さなネットワーク1つ1つがASで、1つ以上のネットワークオペレーター(ISPや大企業)のコントロール下にあるIPのルーティングプレフィックスの集合。小さなといってもISPなどの比較的大きなネットワークではある。これらのASにふられるグローバルで一意な番号がAS番号(ASN)でBGPのルーティングの際に使用されている。IPが属するAS番号についてはAutonomous System Lookup (AS / ASN / IP) | HackerTarget.comとかで確認できる。
そして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がマップファイルを作成するスクリプトを公開しているので、それを利用するのが早い。
リポジトリ内に、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マップファイルを以下の手順で作成できるみたい(一時的だけどそれなりにディスクスペースが必要)。
$python3 ./download_dumps.py
を実行し最新のRIPEダンプをダウンロードする。ダウンロードしたデータはdumps
フォルダに格納されている。ちなみに、全データ(圧縮されて約2.8GB)ダウンロードするのに少し時間がかかる。- 続いて
$sh ./quagga_parse.sh
を実行し、dumps
フォルダ内のダンプファイルを読み込み、人が読める形式にしてpaths
フォルダ内に格納する(圧縮されて約9.8GB)。 python3 ./quagga_aggregate.py
を実行するとpaths
フォルダ内のデータを読み込み、パスを集約し、すべてのIPプレフィックスをASNパスの共通サフィックスの最初の要素に割り当てる。結果prefix_asns.out
というファイルが生成される。- 1つ上のフォルダにある
../buildmap.p
に`prefix_asns.out
を与えて実行する。
ただ、実行しようとすると、3のマッピングの処理中に期待したASNのサフィックスが見つからずにエラーが発生する。RIPEダンプの1つが404で取得できていないのが原因なのか?不明。