LNDの利用するMacaroonsとは
ライトニングノードのメジャーな実装のひとつにLNDがあるのですが、LNDは外部アプリと連携するためのAPIが標準搭載されていることもあり、LNDをウォレットの実態として利用するようなモバイルウォレットアプリなどが登場しています。
ライトニングノードは仕組み上オンチェーンの秘密鍵を保有しており、ある意味ホットウォレットと捉えることもできます。そうなると、リモートから不正にアクセスされてしまうのでは、とセキュリティが気になりますね。
今回は、LNDで外部アプリと連携する際に使用されている認証と認可メカニズムである「Macaroons」について解説します。
背景
LNDは外部アプリと連携するためにgRPC APIを公開することができます。ですが、単純にAPIを公開すると世界中の誰とも分からない人からアクセスされてしまいますので別途ファイアウォール的なセキュリティで守る必要があります。このへんは、2016年夏ごろに課題視されていたようです。
このGitHub Issueによると、認証方式としてPassword Hash方式、Macaroons方式の2つが提案されていたようです。
Password Hash方式
いわゆるパスワードで守る方式です。とてもシンプルなことが強みでもあり弱みでもあります。API命令ごとにサトシ数量指定に制約を課す、といった柔軟な制御はできません。
Macaroons方式
とても柔軟な制御ができますが、先進的で採用事例に乏しいです。
ウォレット形式ですら独自方式を採用しているLNDです。こういった場合、いかにも後者を採用しそうですね。はたして2017年1月、Lightning LabsはMacaroonsを導入する方針だと表明し、同年8月には実装しました。
Macaroonsとは?
Macaroonsは、分散システムでの認証と認可に使用される柔軟性の高いトークンベースの方法で、Googleを含む著者陣が2014年に公開した研究論文がオリジナルです。
Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in the Cloud
Macaroonsは、いわばHMACチェーンといった構造をしています。
HMACというのはHash Based Message Authentication Codeのことで、認証及び改ざん検出に使われる暗号技術のひとつです。普通のSHA256といったハッシュ関数だとデータだけが入力であるのに対し、HMACではデータと秘密鍵とが入力になります。
ハッシュ値 = SHA256(データ)
HMAC値=HMAC(秘密鍵, データ)
HMAC自体にはデータの暗号化機能はないのですが、改ざんを検知することができます。例えば、気心の知れているとある2人がデータを安全に(途中で改ざんされずに)やりとりしたいという状況を考えます。この2人は秘密鍵(あるいはパスワード)を事前に共有しておきます。
データを送付する際に、データそのものとそのHMAC値(タグといったりします)とをセットにして送ります。秘密鍵を共有している受信者は、受け取ったデータと秘密鍵からHMACを計算し、受け取ったタグと一致するかを検証することでデータが改ざんされていないかを確認できます。
さて、Macaroonsでは、こうしたHMACを重ねてAPI認証用のトークンを構成します。この重ねる感じがお菓子のマカロンを感じるからのネーミングなんでしょうか。ところで、API認証には昔からCookieというものが利用されてきました。お菓子繋がりでちょっとお洒落ですね。
にしても、ライトニングネットワークでのオニオンルーティングといい、プライバシーテックは重ねるものばかりです。
ちょっと横道にそれましたが、HMACを重ねるとはどういうことでしょうか。
Macaroonsでは権限の制限をトークンに課して新たなトークンを再生成することを可能としています。
例えば、なんでもできちゃうAdminトークンを最初につくり、それにこのトークンを利用できるのはIP=192.168.1.1なクライアントだけだよ、という制限を付けることができます。
まず、適当な乱数R、秘密鍵Sを用意します。これを使ってAdminトークンを生成します。
H1 = HMAC(S, R)
Adminトークン = { R, H1 }
次に、IP制限C (IP=192.168.1.1)をつけます
H2 = HMAC(H1, C)
IP制限トークン = { R, C, H2 }
このように一つ前の層のHMAC値を新たな層での秘密鍵として利用し、HMACを計算します。秘密鍵を知っている主体だけがこのHMACの連なりを順に辿ることで検証できます。
HMACを重ねるという技により、アクセス制御のための条件付き委任が実現できました。
IP制限トークンを受け取ったユーザーは、元のAdminトークンに戻すことができない点がポイントですね。
LNDにおけるMacaroonsの利用
Macaroonsは、アクセス制御のための条件付き委任を可能にする、拡張可能なデータ構造を持っています。LNDは特に次の点を評価しmacaroons方式を採用したとのことです。
- 柔軟性: Macaroonsは、権限の委任や制限に関して非常に柔軟性があります。これにより、LNDは、必要な権限だけを持つmacaroonsを生成できます。
- セキュリティ: Macaroonsは、暗号化技術を使用しており、安全性が高いとされています。これにより、攻撃者が不正なアクセスを試みても、アクセスが制限されます。
- 簡素化: Macaroonsは、APIキーのようなシンプルな概念を維持しつつ、柔軟性とセキュリティを提供します。これにより、開発者は簡単に扱うことができます。
これにより、LNDユーザーは、異なる権限レベルでAPIへのアクセスを制御できます。LNDでは、デフォルトで3つのmacaroonsが生成されます。
- Admin Macaroon: 管理者権限を持つmacaroonで、LNDノードの全ての機能へアクセスできます。
- Invoice Macaroon: 請求書(インボイス)に関連する機能に限定されたアクセス権を持ちます。これにより、ユーザーは新しい請求書を作成したり、既存の請求書のステータスを確認することができます。
- Read-only Macaroon: LNDノードの情報を読み取るだけができる権限を持ちます。これにより、ユーザーはノードやチャネルの状態を確認し、取引履歴を参照することができますが、送金や請求書の作成など、書き込み操作はできません。
これらのうち適切なものをアプリに提供することで、アプリはLNDノードを与えられた権限の範囲で操作できます。例えば、Zeusウォレットですと、Admin Macaroonが必要です。
また、LNDでは現状次の2つの制約をmacaroonに付加することができます。
- 有効期限: いつまでAPIを利用できるか、という時間制約ですね。
- IP制限: API呼び出し元クライアントのIPに制限をかけることができます。
まとめ
有効期限やIP制限をつけるだけなら、ノードを設置するインフラ側のセキュリティで実現できるんじゃないの、という疑問が湧いてきます。また、3つのmacaroonsにしても実際にはAdmin Macaroonばかりが利用されています。
おそらく、これらはmacaroonsの本来目指したユースケースなのではなく、LNDが初期実装としてなんとなく実装してみた、というのが実情だと思います。
論文では、分散システムにおける"assertion"爆発を解決するんだ、というモチベーションが語られています。ライトニングネットワークも分散システムではあるのですが、今の実装はあくまで1つのノードとそれにアクセスするアプリとの単純なサーバークライアント間での通信に適用したに過ぎません。
本来原著者らが考えていたメリットとは違うところにメリットが見いだされて実装されたのだとしたら、それはそれで面白い話ですね。
著者による論文発表の様子がYoutubeにあがっていました。分散システムの話など深堀りされたい方はこちらの視聴にチャレンジしてみてもいいかもです。
次の記事
読者になる
一緒に新しい世界を探求していきましょう。

ディスカッション