AWS は最近、Amazon Managed Blockchain と Amazon CloudWatch 間の新しい統合の提供を開始しました。メンバー認証局 (CA)、Hyperledger Fabric ピアノード、およびチェーンコードでのアクティビティなど、ブロックチェーンネットワークでの重要なアクティビティを示す詳細なログを利用できるようになりました。
この投稿では、これらの新機能を使用して、分散型アプリのブロックチェーンアクティビティを追跡する方法を示します。また、Amazon CloudWatch でアラームを作成してブロックチェーンのアクティビティを通知する方法についても説明します。
Amazon Managed Blockchain でロギングを有効化する
始める前に、Amazon CloudWatch Logs でログを有効にして、ブロックチェーンネットワークと Fabric クライアントをセットアップします。詳細については、CloudWatch Logs を使用したブロックチェーンアクティビティのモニタリングを参照してください。
ロギングを有効にできる場所は 2 つあります。メンバーをブロックチェーンネットワークに追加すると、メンバーの認証局 (CA) サービスへのログオンを有効にするオプションが利用できるようになります。次のスクリーンショットを参照してください。
ロギングオプションのいずれかを有効にすると、/aws/managedblockchain/<NetworkID>/<MemberID>
という名前のロググループが作成されます。CA ロギングを有効にすると、ca
というこのグループの下にログストリームが表示されます。このログストリームには、CA に関連するすべてのアクティビティの詳細なログが含まれています。
ピアノードを作成するときにロギングを有効にすることもできます。ノード上のすべてのアクティビティを表示する詳細なログ (ピアノードログ) またはチェーンコードによって作成されたログを有効にするオプションがあります。次のスクリーンショットを参照してください。
チェーンコードログは、ビジネスワークフローにおける重要なアクティビティを追跡するのに役立ちます。CA およびピアノードのログは、Fabric コンポーネント間の複雑なインタラクションのトラブルシューティングに役立ち、特定のワークロードに関する洞察を得ることができます。
チェーンコードにログメッセージを追加する
チェーンコードログ機能は、ビジネスワークフローにおける重要なアクティビティを追跡するのに特に役立ちます。この投稿では、ログを使用して、適切なアクセス許可を持つユーザーのみがチェーンコードの呼び出しを実行できることを確認し、ユーザーが不正なアクセスを試みたときにアラートを発生させる方法を示します。これらの機能をテストし、CloudWatch アラームを有効にして、不正アクセス試行について通知するには、ネットワークに次のコードをデプロイします。/home/ec2-user/permissions-example/index.js
の Fabric クライアントのホームフォルダに次のコードを保存します。
/////////////////////////////////////////////////////////
// ROLE-BASED ACCESS CONTROL EXAMPLE
//
// 次のチェーンコードは、未承認のクライアントが
//チェーンコードメソッドを呼び出すことを防止する方法を示しています。
/////////////////////////////////////////////////////////
'use strict';
const shim = require('fabric-shim');
/////////////////////////////////////////////////////////
// requireRole
//
// このメソッドは、呼び出し元のクライアントが
//指定されたロールを持っていない場合にエラーを表示させます。
/////////////////////////////////////////////////////////
async function requireRole(stub, role) {
const ClientIdentity = shim.ClientIdentity;
let cid = new ClientIdentity(stub);
if (!cid.assertAttributeValue('role', role))
throw new Error(`Unauthorized access: ${role} required`);
}
let Chaincode = class {
async Init(stub) {
console.info('============= Init called =============');
return shim.success();
}
async Invoke(stub) {
console.info('============= Invoke called =============');
// ensure client has admin role before proceeding
try {
await requireRole(stub, 'admin');
} catch(err) {
// log failed access attempt and return
console.error("Error during Invoke: ", err);
return shim.error(err.message || err);
}
// クライアントには期待されるロールがあるため、続行します
console.info('SUCCESS!')
return shim.success();
}
}
shim.start(new Chaincode());
また、次の依存関係宣言を /home/ec2-user/permissions-example/package.json
に保存する必要があります。
{
"name": "permissions",
"version": "0.1",
"description": "Chaincode for testing user permissions",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"dependencies": {
"fabric-shim": "^1.2.4"
}
}
チェーンコードをデプロイおよびテストする
チェーンコードをデプロイして、呼び出しが想定どおりにアクセス許可テストに失敗するかどうかをテストします。
[ec2-user@ip-XXX-XX-XX-XXX ~]$ docker exec cli peer chaincode install -n perms -v 0.1 -l node -p /opt/home/permissions-example
2020-02-26 02:19:51.499 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2020-02-26 02:19:51.499 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2020-02-26 02:19:51.500 UTC Container Computing WriteFolderToTarPackage -> INFO 003 rootDirectory = /opt/home/permissions-example
2020-02-26 02:19:51.505 UTC [chaincodeCmd] install -> INFO 004 Installed remotely response:<status:200 payload:"OK" >
[ec2-user@ip-XXX-XX-XX-XXX ~]$ docker exec cli peer chaincode instantiate -o $ORDERER -C mychannel -n perms -v 0.1 -l node -c '{"Args": ["init"]}' --cafile /opt/home/managedblockchain-tls-chain.pem --tls
2020-02-26 02:20:03.558 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2020-02-26 02:20:03.558 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
[ec2-user@ip-XXX-XX-XX-XXX ~]$ docker exec cli peer chaincode query -C mychannel -n perms -c '{"Args": ["invoke"]}' -o $ORDERER --cafile /opt/home/managedblockchain-tls-chain.pem --tls
Error: endorsement failure during query. response: status:500 message:"transaction returned with failure: Unauthorized access: admin required"
すべてが想定どおりに進むと、前述のコード例のように、チェーンコードにアクセス許可エラーが表示されます。これは、ロール属性がまだ割り当てられていないデフォルトの Fabric クライアント ID を使用してチェーンコードを呼び出したためです。
必要なアクセス許可を持つ新しいクライアント ID を生成する
この次のステップでは、適切なロール属性を持つクライアント証明書とキーを生成します。この投稿では単純なパスワードを使用しています。ご自身の環境では、一意で安全なパスワードを使用してください。次のコマンドと結果の出力を参照してください。
[ec2-user@ip-XXX-XX-XX-XXX ~]$ fabric-ca-client register --id.name superuser --id.affiliation member1 --tls.certfiles /home/ec2-user/managedblockchain-tls-chain.pem --id.type user --id.secret Password123 --id.attrs "role=admin:ecert"
2020/02/26 02:31:00 [INFO] Configuration file location: /home/ec2-user/.fabric-ca-client/fabric-ca-client-config.yaml
2020/02/26 02:31:00 [INFO] TLS Enabled
2020/02/26 02:31:00 [INFO] TLS Enabled
Password: Password123
[ec2-user@ip-XXX-XX-XX-XXX ~]$ fabric-ca-client enroll -u https://superuser:Password123@$CASERVICEENDPOINT --tls.certfiles /home/ec2-user/managedblockchain-tls-chain.pem -M /home/ec2-user/superuser-msp
2020/02/26 02:35:04 [INFO] TLS Enabled
2020/02/26 02:35:04 [INFO] generating key: &{A:ecdsa S:256}
2020/02/26 02:35:04 [INFO] encoded CSR
2020/02/26 02:35:04 [INFO] Stored client certificate at /home/ec2-user/superuser-msp/signcerts/cert.pem
2020/02/26 02:35:04 [INFO] Stored root CA certificate at /home/ec2-user/superuser-msp/cacerts/ca-m-sercxjlv7zdg5pjn76hwx6iahu-n-qcid77fovbeideo2wyuvvomdpa-managedblockchain-us-east-1-amazonaws-com-30002.pem
[ec2-user@ip-XXX-XX-XX-XXX ~]$ cp -r admin-msp/admincerts/ superuser-msp
ID を作成したら、別の ID から中間証明書をコピーして、新しい証明書にチェーンコード操作で使用される必要なすべての情報が含まれていることを確認します。
これで、この新しい ID を使用してチェーンコードを呼び出し、それがアクセス許可チェックに合格したかどうかを確認できます。環境変数の CORE_PEER_MSPCONFIGPATH
のデフォルト設定を上書きして、Fabric クライアントがデフォルトの代わりに新しい証明書をクライアント ID として使用するようにします。次のコマンドを参照してください。
[ec2-user@ip-XXX-XX-XX-XXX ~]$ docker exec -e "CORE_PEER_MSPCONFIGPATH=/opt/home/superuser-msp" cli peer chaincode query -C mychannel -n perms -c '{"Args": ["invoke"]}' -o $ORDERER --cafile /opt/home/managedblockchain-tls-chain.pem --tls
CloudWatch ログ内に、SUCCESS!
のデバッグ出力が表示されます。
CloudWatch アラームを設定する
最後のステップとして、権限のないユーザーがチェーンコードを呼び出そうとするたびに CloudWatch アラームを設定できます。これを行うには、[Amazon CloudWatch Logs の新しいデザインを試す] を選択して、新しい CloudWatch インターフェイスを必ず有効にしてください。
- CloudWatch Logs コンソールで、[ロググループを表示] を選択します。
- ブロックチェーンメンバーのロググループを選択します。
- [メトリクスフィルター] タブで、[メトリクスフィルターの作成] を選択します。
- フィルターパターンを定義し、チェーンコードのログストリームの例でテストします。
- フィルターが機能することを確認したら、[次へ] を選択します。
- 次の情報を指定します。
- フィルター名。
- このフィルターがグループ化されている名前空間。
- メトリクス名 (これはフィルター名と同じにすることができます)。
- メトリクス値として値
1
- デフォルト値として値
0
。
- [次へ] を選択し、[メトリクスフィルターの作成] を選択します。
メトリクスフィルターのリストに戻ると、作成したフィルターが表示されています。
- 新しいフィルターを選択し、[アラームの作成] を選択します。
- すべての不正アクセス試行の通知を受け取るには、次のとおり設定します。
- 統計の最小値を選択します。
- 期間を 5 分のままにします。
- しきい値は静的なままにします。
- アラーム状態を 0 より大きい値に設定します。
- [次へ] を選択します。
- [アラーム状態トリガー] で、[アラーム状態] を選択します。
- [新しいトピックの作成] を選択します。
- トピック名と通知用のメールアドレスを入力します。
- [トピックの作成] を選択します。
アラームに名前を付けるよう求めるプロンプトが表示されます。
- 名前を入力し、[次へ] を選択します。
- [アラームの作成] を選択します。
- 受信したメールの確認リンクを選択します。
その後、不正なチェーンコード呼び出しのプロセスを繰り返し、通知が電子メールで受信されることを確認できます。
まとめ
この投稿では、ブロックチェーンネットワークで CloudWatch Logs を有効にし、ネットワークにチェーンコードをデプロイし、チェーンコードログを使用して不正アクセスを監視する方法を示しました。また、ネットワークユーザーの追加の証明書属性を生成する方法と、ワークロードにおいて特定の重要な条件が発生したときに自動的にアラートを出すように CloudWatch アラームを設定する方法も学びました。Amazon Managed Blockchain での構築の経験と、質問や機能のリクエストをコメントセクションにぜひお寄せください。
著者について
Carl Youngblood は、アマゾン ウェブ サービスのブロックチェーンソリューションアーキテクトです。