以下の内容はhttps://uncaughtexception.hatenablog.com/entry/2025/06/30/045335より取得しました。


Azure Cloud Shellを全力でセキュアにしてみる、のその後

これの続き。

uncaughtexception.hatenablog.com

1. リソース構成/必須Azureロールの訂正

前のエントリーでは、リソース構成とロール割り当てについて、

初期設定時は最低限、
・ 4種類のリソースが同じリソースグループ内にある
・ リソースグループと4種類のリソース、それぞれにReaderロールがある
というリソース構成/ロール割り当てが必須。

と書いた。

けどこれは👇のCloud Shellの設定用UIから設定する場合の話。

あくまで、この設定用UIがリソースを検索するために必要な構成/ロール。

REST APIで直接設定する場合は、リソース構成は自由だし、(設定だけなら)Readerロールすらいらなかった。
ただし実行時はストレージアカウントに対するReader and Data Accessロールが必要。

👆の設定用UIでリソースを選んだ後、どういうリクエストが飛ぶかを調べたら、

https://management.azure.com/providers/Microsoft.Portal/userSettings/cloudconsole?api-version=2023-02-01-preview

というエンドポイントに👇のようなJSONをHTTPでPUTしていて、JSONの中に必要なリソースのIDが書かれていた。

HTTP PUTしているJSON

{
  "properties": {
    "preferredOsType": "linux",
    "preferredLocation": "southeastasia",
    "storageProfile": {
      "storageAccountResourceId": "/subscriptions/.../resourceGroups/.../providers/Microsoft.Storage/storageAccounts/...",
      "fileShareName": "...",
      "diskSizeInGB": 5
    },
    "terminalSettings": {
      "fontSize": "medium",
      "fontStyle": "monospace"
    },
    "vnetSettings": {
      "networkProfileResourceId": "/subscriptions/.../resourceGroups/.../providers/Microsoft.Network/networkProfiles/...",
      "relayNamespaceResourceId": "/subscriptions/.../resourceGroups/.../providers/Microsoft.Relay/namespaces/...",
      "isolatedStorageProfile": {
        "storageAccountResourceId": "/subscriptions/.../resourceGroups/.../providers/Microsoft.Storage/storageAccounts/...",
        "fileShareName": "...",
        "diskSizeInGB": 5
      },
      "location": "japaneast"
    },
    "userSubscription": "...",
    "sessionType": "Mounted",
    "networkType": "Isolated",
    "preferredShellType": "bash"
  }
}

設定スクリプト

どこに何しているかがわかれば、あとはそれを実行するスクリプトを作るだけ。

az login
SUBSCRIPTION_ID=$(az account show --query "id" --output tsv)
# Azure RelayとNetwork Profileについては、ReaderロールもなくCLIで取ってくることができないので、リソースIDはべた書き
AZURERELAY_ID=/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/.../providers/Microsoft.Relay/namespaces/...
NETPROFILE_ID=/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/.../providers/Microsoft.Network/networkProfiles/...

# ストレージアカウントは閲覧可能なので、CLIで取ってきてもリソースIDはべた書きでも、どっちでもよし。
# CLIで取ってくる場合のコマンドやフィルタ条件 (--query "[0].id") は適宜修正
STORAGEACCOUNT_ID=$(az storage account list --query "[0].id" --output tsv)
STORAGEACCOUNT_SHARENAME=...
# 実行
az rest \
  --method put \
  --url "https://management.azure.com/providers/Microsoft.Portal/userSettings/cloudconsole?api-version=2023-02-01-preview" \
  --body "
      {
        \"properties\": {
          \"preferredOsType\": \"linux\",
          \"preferredLocation\": \"southeastasia\",
          \"storageProfile\": {
            \"storageAccountResourceId\": \"${STORAGEACCOUNT_ID}\",
            \"fileShareName\": \"${STORAGEACCOUNT_SHARENAME}\",
            \"diskSizeInGB\":5
          },
          \"terminalSettings\": {
            \"fontSize\": \"medium\",
            \"fontStyle\":\"monospace\"
          },
          \"vnetSettings\": {
            \"networkProfileResourceId\": \"${NETPROFILE_ID}\",
            \"relayNamespaceResourceId\": \"${AZURERELAY_ID}\",
            \"isolatedStorageProfile\": {
              \"storageAccountResourceId\": \"${STORAGEACCOUNT_ID}\",
              \"fileShareName\": \"${STORAGEACCOUNT_SHARENAME}\",
              \"diskSizeInGB\": 5
            },
            \"location\": \"japaneast\"
          },
          \"userSubscription\": \"${SUBSCRIPTION_ID}\",
          \"sessionType\": \"Mounted\",
          \"networkType\": \"Isolated\",
          \"preferredShellType\": \"bash\"
        }
      }"

使い方例

ふんわりとした使い方イメージ。

  1. 管理者が以下のリソースを準備する
    • VNETやAzure Relayなど共通で必要なリソース
    • Cloud Shell利用者ごとに、ストレージアカウントとファイル共有の準備とストレージアカウントのReader and Data Accessロールの付与をする
  2. 👆のスクリプトのリソースIDの箇所とファイル共有名等を修正して、利用者に「これを実行して」と配布する
  3. 利用者はローカル環境で受け取ったスクリプトを実行する

利用者が次にCloud Shellを開いた時は、設定が聞いてVNETに接続しているはず。

2. Azure Relayのネットワーク制限

デフォルトだと、Azure Relayのネットワークは、パブリックアクセスが全解放されている。

クライアントのIPアドレスが絞れるなら、IPアドレス制限をした方がいい。

ちなみに、ブラウザーとAzure Relayの間のやり取りでは、servicebus.windows.netドメインのホストにWebSocket接続をしている。
VNET接続の場合は専用のAzure Relayリソース、VNETなしの場合も共用のAzure Relayリソースが使われている。

なので、会社のネットワークなどのFirewall/Proxyあたりで、このドメイン全体をブロックされるとCloud Shellは動かないので注意。

コチラからは以上です。




以上の内容はhttps://uncaughtexception.hatenablog.com/entry/2025/06/30/045335より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14