今日はかなり地味な話題ですが、ライトニングノード運営者が困る可能性のあるDoS攻撃対策として提案されているStateless Invoicesというものを解説します。

問題:インボイス発行にはデータ保管が伴う

ライトニング上の支払いは基本的には送金を受け取る側のノードがインボイスを生成するところから始まります。インボイスの生成に使用したプリイメージ(秘密データ)は実際にビットコインが送られてきた際にそれを受け取るのに必要なため、インボイスの生成にはデータ保管が伴います。(さもなくば受け取ることができず、生成した意味がない)

インボイスの期限が切れた後は受け取る予定がないので削除しても問題ありません。別の話題にはなりますが、送金や中継があるたびに当該チャネルの「過去のステート(状態)」が生まれ、相手による不正なチャネル閉鎖を防ぐセキュリティモデル上、チャネルを閉じるまでこれを削除できないのもLNノードのデータ保管問題の1つです。

そこでLNノードに対する1つのDoS攻撃ベクトルとして、短時間に非常に大きな数のインボイスをリクエストすることで相手のノードに膨大な量のデータを保管させるというものが考えられます。こうしてストレージの余裕が全くなくなってしまうと、新たなインボイスの発行が妨害されたり、ノード自体の動作の不安定化につながります。

アプリケーションのバックエンドとして通常利用する分には、アプリケーション自体にインボイスを短期間に大量生成するユーザー対策を施せば良いでしょう。しかし、DoS攻撃と実際の利用者の区別がつきにくいケース(例えば日付が変わると同時に「サトシタイム」が始まってみんなが一斉に10 satsもらうインボイスを発行するなど)があったり、そもそも対策の実装が手間でライトニングの導入を面倒にしてしまうので、インボイス発行時のデータ保管を発行ノードではなく送金者に任せる方法が提案されました。これがStateless Invoicesです。

STATELESS INVOICESの仕組み

ライトニング慣れしている読者の皆さんは疑問に思うでしょう。「最初からプリイメージをユーザーに渡してしまうと、ライトニングのトラストレス性が損なわれるのではないか」と。でも大丈夫です。なぜなら、Stateless Invoicesではインボイス自体にプリイメージではなく「プリイメージの導出に使うパラメータ」を盛り込むからです。

具体的に見ていきましょう。

まず、支払いを受け付けたいノードが使い捨てのランダムなpayment_secretを生成します。次にノード秘密鍵、このpayment_secret、受け取りたい金額、コミットするインボイス内容(除くpreimage_hash)をまとめてハッシュし、今回使用するプリイメージを生成します。最後にこのプリイメージのハッシュを使ってpayment_secretを含む先程の金額・内容のインボイスを発行します。

送金者にこのインボイスを渡した後、インボイス発行ノードはこれらのデータを破棄しても問題ありません。

実際に送金が行われるとき、送金者はペイメントとともにカスタムTLVレコード(特殊な添付メッセージのようなもの)でpayment_secretとインボイスの内容を添えて送金します。インボイスを発行したノードまでペイメントとこのデータが到達すると、支払いを受け付けるノードはこのデータと秘密鍵を使ってプリイメージを復元でき、インボイスの内容とペイメントが合致する(確かに自分が発行したインボイスである)ことを確認できます。

これによって、インボイスを発行したあとデータを保管することなく、実際に送金を受け取る際にデータを復元することができるようになります。

課題:中継ノードも対応が必要

今日このテーマを選んだのは、EclairというLNノード実装がStateless Invoicesに対応したからです。しかし、実際に利用する上では送金経路上の全てのノードがStateless Invoicesに使うカスタムTLVメッセージを理解している必要があります。

Stateless Invoicesでは前述の通り送金者がインボイスに含まれるoption_payment_metadataというデータをカスタムTLVレコードとして送金に添付する必要があります。また、中継ノードがいる場合はその中継ノードもこれを次のノードへと伝えなければいけませんが、自身が理解しないTLVレコードは転送しないのが既定であるため、中継ノードもStateless Invoicesを理解していなければ宛先がプリイメージの復元に必要な情報を受け取れず、送金が失敗してしまいます。

幸い、中継ノードに必要なのは「そのカスタムTLVレコードは転送するべき」ということだけであり、自身がStateless Invoicesの発行や送金に対応する必要はないので、対応コストは低いでしょう。

それまではたとえStateless Invoicesを使っていても、宛先が直接チャネルを張っている相手でなければ成功確率が著しく低い状況になると思います。もちろん、将来的にStateless Invoicesが普及するとも限らないのも大変難しいところです。

まとめ

・LNノードのデータ保管問題の1つに、発行したインボイスに対応するプリイメージを期限まで保管する必要性がある

・対策しなければ、これを悪用してDoS攻撃に使われる可能性もある

・Stateless Invoicesはインボイスに含めたデータを使って、宛先ノードがプリイメージを保管することなく支払いを受け取った際に復元する方法

・復元に必要なデータを送金に合わせて送る必要があるため、中継ノードもそのデータの転送に対応する必要がある