同一リージョン内ではVirtual MachineからのアクセスはStorage AccountにプライベートIPアドレスとして見える


結論

Virtual MachineからStorage Accountにアクセスしたときに
Storage AccountからVirtual MachineのIPアドレスがどう見えるか。

 ・リージョン内:プライベートIPアドレス
 ・リージョン外:グローバルIPアドレス

はじめに

2018年頃の話です。
システムを設計する中でStorage Accountをセキュアに運用するために
特定のVirtual Machineからの通信のみ許可する方法を検討しました。

当時まだAzureを使い始めたばかりでサービスエンドポイントのことも知ってはいたけどよく理解できてなかったため
Storage Accountのファイアウォール機能でVirtual MachineのグローバルIPアドレスを許可することで実現しようと考えました。

東西Blob問題

ところが実際に検証してみるとグローバルIPアドレスを許可したVirtual MachineからStorage Accountにアクセスできません。
さんざん調査した(当時調査スキルも低かった)けどよくわからなかったので、MSサポートに問い合わせました。
するとペアリージョン内の通信はプライベートIPアドレスが利用される、とのことでした。

※結論に書いてあることにお気づきかもしれませんが、サポートの回答が若干間違っています。
 ペアリージョン内であればグローバルIPアドレスが利用されます。
 あくまでも同一リージョン内に限ってプライベートIPアドレスが利用されます。

しかしファイアウォールのIPアドレス制限機能ではプライベートIPアドレスを指定するとエラーになります。

そこで当時は仕方なくBlobを西日本リージョンで作成することでこの問題を回避しました。
我々はこれを東西Blob問題と呼びました。

いや今考えればサービスエンドポイント使えばよかったってだけの話なんですけどね。若気の至りでした。

今も仕様は変わっていないのか

2年ほど経った2020年6月現在でも同じ仕様なのかが気になったので実機で検証してみました。

準備

用意するAzureリソースは以下3つです。
あとStorage Accountのログを確認するためにAzure Storage Explorerをインストールしておきます。

 ・Virtual Machine (Linux) @ japaneast
 ・Storage Account @ japaneast
 ・Storage Account @ japanwest

次にStorage Account側からVirtual MachineのIPアドレスがどう見えるかを確認するために
Storage Accountの診断ログを有効化しましょう。

「ログ記録」の各項目にチェックを入れて「保存」します。
※今回はアップロードのログだけを拾っての検証だったので
「書き込み」にだけチェックを入れていればもう少しログが見やすかったかなと後から後悔しました。
こうすることでそのStorage Accountに$logsというコンテナが作られてそこにアクセスログが出力されていくようになります。

ていうかStorage Accountの診断ログってLog Analyticsに転送できないんですね・・・。
$logsの中は時間ごとにフォルダが分かれてさらにその中でもファイルが分かれます。
しかも厄介なことに実際のアクセスとログが出力されるのにタイムラグがあります。5分くらい?
なので自分のアクセスしたログを特定するのがちょっと大変です。

検証

では実際にVirtual MachineからBlobをアップロードしてみましょう。
今回はLinuxVMにAzurePowershellをインストールして検証しました。

まずは同一リージョンである東日本リージョンのBlobにファイルをアップロードします。

$Context =  New-AzStorageContext -StorageAccountName "junbostoragejapaneast" -StorageAccountKey "qD7XA+jf7aaC1XDIZfU+17zep43eZYcx55JLg/DeQ1QkF9GsYPooOKrSRqvDhZjZVOUGcAm/ANf+8bIvkuBC6w=="
$Context | Set-AzStorageBlobContent -Container "test" -File "./uploadfromlinux"

次に西日本リージョンのBlobにファイルをアップロードします。

$Context =  New-AzStorageContext -StorageAccountName "junbowest" -StorageAccountKey "iuEEaX0klgWB2yD1ari/uuJjtR8hW7wSZuw/CqmV2PJPyAywOAVfGrJ7RQpavBe41YpMUY8YkObL7xa0BkWbig=="
$Context | Set-AzStorageBlobContent -Container "test" -File "./uploadfromlinux"

さて、それぞれのBlobでVirtual MachineのIPアドレスがどう見えているかをアクセスログで確認しましょう。
ちなみにプライベートIPアドレス、グローバルIPアドレスは以下の通りです。

まずは同一リージョン(東日本リージョン)のログです。

1.0;2020-06-09T15:46:33.1132205Z;PutBlob;Success;201;6;6;authenticated;junbostoragejapaneast;junbostoragejapaneast;blob;"https://junbostoragejapaneast.blob.core.windows.net:443/test/uploadfromlinux?timeout=300";"/junbostoragejapaneast/test/uploadfromlinux";79fbb3f3-f01e-0041-4075-3e0b11000000;0;10.8.0.4:43572;2019-02-02;558;4;362;0;4;"XJWX88gkWQfqcaidnTnQjg==";"XJWX88gkWQfqcaidnTnQjg==";""0x8D80C8C48E9C438"";Tuesday, 09-Jun-20 15:46:33 GMT;;"AzurePowershell/v1.0.0 DataMovement/1.2.0.0 Azure-Storage/11.1.1 (.NET Core; Unix 3.10.0.693)";;"Azure-Storage-PowerShell-4ad0ed95-59d5-4e6e-8751-d50bf84f4989"

見づらいので情報を絞りましょう。

・・・;PutBlob;・・・;"/junbostoragejapaneast/test/uploadfromlinux";・・・;10.8.0.4:43572;・・・

10.8.0.4とプライベートIPアドレスに見えてますね。

次に西日本リージョンのログです。

・・;PutBlob;・・・;"/junbowest/test/uploadfromlinux";・・・;13.78.88.247:60016;・・・

13,78.88.247とグローバルIPアドレスに見えてますね。

さいごに

今ではサービスエンドポイントだけでなくプライベートエンドポイントもGAされ、
Storage AccountでVMのグローバルIPアドレスでの制御をするシーンは少ないでしょう。

 ・サービスエンドポイントやプライベートエンドポイントが対応していないPaaSでIPアドレス制御したい
 ・アクセス元として別テナントのAzureVMを許可したい

こんなときに同じリージョン内での通信ではIPアドレスがプライベートかもしれない、というのを頭の片隅に置いておくと、
トラブルシュートの際に役に立つかもしれません。