非公開な Azure Blob Storage を外部からセキュアにアクセスさせる

ちょっとややこしいタイトルだな...:sweat_smile:


# はじめに

とあるところから「SharePoint や OneDrive を使わずにファイル共有したいんだが」と相談がありました。相談事をまとめると以下のとおりです。


## とあるところからの相談事

- 社外に持ち出す PC 向けにファイルを共有したい
    - この PC は用途の都合で、Azure AD にデバイス参加できず
- 社外に持ち出す PC での SharePoint、OneDrive の利用は禁止している
    - Blob Storage を使わせようと想定だが、現在は条件付きアクセスの条件に一致していないためアクセスできず
- VPN 接続せずに、インターネット経由でアクセスさせたい (できれば)
- Azure AD でのユーザー認証はマスト
- Azure AD Premium ライセンスは保持している (ユーザーに割り当て済み)


## 相談事を解決するためには

次に、相談事を解決するためのアイデアを出してみます。

- **ブラウザーでアクセスしてもらう**
    - ユーザー負担がほぼない
- **Blob Storage をプライベートなリソースとする**
    - 使わせたいって言ってたから
- **Azure AD 認証を必要とする通信経路として**、以下の 2 点がが挙げられる
    - 仮想ネットワークに Point to Site (OpenVPN プロトコル＋Azure AD 認証) で VPN 接続 [^1] [^2] して、アクセスさせる
    - **Azure AD Application Proxy [^3] を経由してアクセスさせる**

といったかんじでアイデアが浮かびました。できれば VPN 接続は避けたいということなので、上記の**太字なところ**で実現させようと思います。


# 環境を構築する

それでは、ひとつずつ構築していきます。

## Azure Blob Storage をプライベートなリソースにする

Blob Storage へのアクセスをプライベートな環境からのみとする構成にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/bf9b95e3-9f6f-6799-f93c-5de1ed3d6d91.png)


### 静的 Web サイトを有効にする

今回は、以下のドキュメントを参考に Storage Account を作成し、静的 Web サイト [^4] を有効にして、`$web` コンテナー配下でファイルを共有します。

[参考：Azure Storage で静的 Web サイトをホストする](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-static-website-how-to?WT.mc_id=AZ-MVP-5003113&tabs=azure-portal)

静的 Web サイトの有効が完了すると、エンドポイント URL が発行されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/dc3973e1-fb0c-6a38-3f57-38b1b3b15bb8.png)


### パブリックなエンドポイントを遮断する

[作成した Storage Account] > [ネットワーク] を開き、[ファイアウォールと仮想ネットワーク] タブを開いて、インターネット経由からのアクセスをすべて遮断 (接続を許可しない) します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/43f5dd70-bce5-7c83-26aa-cd9b8e943691.png)

こうすることで、Azure ポータル、[Azure Storage Explorer](https://docs.microsoft.com/ja-jp/azure/vs-azure-tools-storage-manage-with-storage-explorer?WT.mc_id=AZ-MVP-5003113)、ブラウザーなどでインターネット経由でコンテナー「`$web`」にアクセスすると以下のようにアクセスできないことが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/217716a0-6e2c-3d67-a874-40c50c2d8b48.png)


### Private Endpoint を作成する

インターネットを経由せずにプライベートな環境から Storage Account にアクセスできるようにします。
これには、Private Link (Private Endpoint) [^5] を使用します。以下のドキュメントの手順に従って作成します。

[参考：チュートリアル:Azure プライベート エンドポイントを使用してストレージ アカウントに接続する](https://docs.microsoft.com/ja-jp/azure/private-link/tutorial-private-endpoint-storage-portal?WT.mc_id=AZ-MVP-5003113#create-storage-account-with-a-private-endpoint)

これから作成する Private Endpoint はふたつ。ひとつは「コンテンツを閲覧する」ためのもの、もうひとつは「コンテンツを操作する」ためのものです。

それぞれの Private Endpoint を作成する際に指定する「対象サブリソース」で、以下のように前者 (コンテンツ閲覧用) は「web」、後者 (コンテンツ操作用) は「blob」を選択します。作成した Private Endpoint には Private IP アドレスが割り当てられます。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/3f608bee-8f43-a5d6-0d17-6a2f03da95e8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/538d9370-f915-52d0-11ca-8848e2f36f4c.png)

それぞれにアクセスするために、事前に FQDN を Private Endpoint の Private IP アドレスに名前解決できるようにしておく必要があります。この時点では動作確認を目的とするため、接続元の仮想マシンの hosts ファイルで名前解決して、正常にアクセスできることを確認します。

「web」のエンドポイントへは、ブラウザーを開き、Storage Account 静的 Web サイトを有効にした時の URL を指定してアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/ecf36d0f-48d5-3b03-046c-9e80c397c7ba.png)

「blob」のエンドポイントへは、Azure Storage Explorer を開き、「接続文字列」を指定してアクセスします。
※「接続文字列」は、Azure ポータルで、[作成した Storage Account] > [アクセスキー] を選択し、[key1] または [key2] の [接続文字列] の値をコピーして指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/24ffebe1-bfae-f058-361d-cca0de97c9b4.png)


## 外部から Azure AD Application Proxy を経由してアクセスさせる

Azure AD Premium ライセンスをお持ちで、外部からプライベートなリソース (Web アプリケーション) をアクセスさせたいのであれば、ぜひこの「Azure AD Application Proxy」の導入をご検討していただきたいです。外部からプライベートなリソースにアクセスさせるために VPN を構築しないとなーと考えがちですが、この方法のほうがとてもカンタンに実現できます。


### Azure AD Application Proxy とは

外部から社内環境 (プライベートな環境) にある Web アプリケーションにセキュアにアクセスできるようにする Azure AD Premium の機能です。この機能は、Azure 上の「Azure AD Application Proxy Service」と社内環境にある (構築する)「Azure AD Application Proxy Connector」を組み合わせて実現させます。[^6]


### インターネット経由でプライベートなリソースへアクセスする手順

今回は、前述した Private Endpoint 経由で Storage 静的 Web サイトにアクセスさせます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/8abc22a5-9bee-bb9d-c386-58fb9ce6fc81.png)

今回の環境でのアクセスする順番は以下のとおりとなります。

1. あらかじめ生成された外部 URL にアクセスしたユーザーは、Azure AD のサインインページにリダイレクトされます。
2. サインインが成功すると、Azure AD は、ブラウザーにトークンを返します。
3. ブラウザーは、受け取ったトークンを Azure AD Application Proxy Service に送信します。Azure AD Application Proxy Service は受け取ったトークンから UPN と SPN を取得し、社内環境に構築した Azure AD Application Proxy Connector に渡します。
4. Azure AD Application Proxy Connector は社内環境内の Web アプリケーションにリクエストを送信します。
5. Web アプリケーションのレスポンスは Azure AD Application Proxy Connector に返され、
6. そして Azure AD Application Proxy Service を介して、ユーザーに返されます。


### Windows Server VM を作成し、Azure AD Application Proxy Connector をインストールする

Windows Server 2012 R2 以上の仮想マシン (Public IP アドレスを関連付けて) を作成し、Azure AD Application Proxy Connector をインストールします。以下のドキュメントを参考にして構築していきます。

[参考：チュートリアル:Azure Active Directory のアプリケーション プロキシを使用してリモート アクセスするためのオンプレミス アプリケーションを追加する](https://docs.microsoft.com/ja-jp/azure/active-directory/app-proxy/application-proxy-add-on-premises-application?WT.mc_id=AZ-MVP-5003113)


#### TLS 1.2 を有効にする

Azure AD Application Proxy Connector をインストールには、Windows Server で TLS 1.2 を有効にする必要があります。そのためには、前述のドキュメントに記載されているレジストリキーを設定して再起動します。

```
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
```


#### アウトバウンド ポートを開く

Azure AD Application Proxy Connector は、**アウトバウンド TCP 443 と TCP 80 の通信**を行います (これ以外の通信は行わない)。よって、NSG 送信セキュリティ規則に 2 つの通信を許可します。必要に応じて、Windows ファイアウォールにも設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/756a043d-6edb-c5d9-da04-ca2949d61efb.png)


#### 名前解決しておく

事前に Storage Account 静的 Web サイトの FQDN を Private Endpoint の Private IP アドレスに名前解決できるようにしておく必要があります。コネクタをインストールする仮想マシンの hosts ファイルで名前解決しておけばよろしいかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/ecf36d0f-48d5-3b03-046c-9e80c397c7ba.png)


#### コネクタをインストールする

以下のドキュメントの手順に従って、Azure AD Application Proxy Connector をインストールします。

[参考：チュートリアル:Azure Active Directory のアプリケーション プロキシを使用してリモート アクセスするためのオンプレミス アプリケーションを追加する > コネクタのインストールと登録](https://docs.microsoft.com/ja-jp/azure/active-directory/app-proxy/application-proxy-add-on-premises-application?WT.mc_id=AZ-MVP-5003113#install-and-register-a-connector)

しばらくすると、Azure ポータルでコネクタがアクティブになったことが確認できます。以下のドキュメントの手順に従って操作します。

[参考：チュートリアル:Azure Active Directory のアプリケーション プロキシを使用してリモート アクセスするためのオンプレミス アプリケーションを追加する > コネクタが正しくインストールおよび登録されていることを確認する](https://docs.microsoft.com/ja-jp/azure/active-directory/app-proxy/application-proxy-add-on-premises-application?WT.mc_id=AZ-MVP-5003113#verify-the-connector-installed-and-registered-correctly)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/4e7830c4-b257-bc5e-0a97-c285ab109481.png)


#### Azure AD テナントにアプリケーションを登録する

ここでは、Azure AD テナントに先に作成した Storage Account 静的 Web サイトを登録します。以下のドキュメントの手順に従って操作していきます。

[参考：チュートリアル:Azure Active Directory のアプリケーション プロキシを使用してリモート アクセスするためのオンプレミス アプリケーションを追加する > オンプレミス アプリを Azure AD に追加する](https://docs.microsoft.com/ja-jp/azure/active-directory/app-proxy/application-proxy-add-on-premises-application?WT.mc_id=AZ-MVP-5003113#add-an-on-premises-app-to-azure-ad)

Azure ポータルで、[Azure AD] > [エンタープライズ アプリケーション] を開き、上部の [新しいアプリケーション] をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/0a97658c-5003-9f60-5490-30dd5db1091f.png)

「Azure AD ギャラリーの参照 (プレビュー)」が開きます。
上部の [独自のアプリケーションの作成] をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/9c93ab52-4b29-4876-c4bb-c2264d99578d.png)

「独自のオンプレミスのアプリケーションの追加」が開きます。
前述のドキュメントの手順 5 と手順 6 を参考に情報を入力していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/be9ef3ad-27f2-d66c-5c8c-f3dee28b347a.png)

アプリケーションの登録後、プロパティを確認しましょう。
[ホームページ URL] は、ユーザーが外部から Storage Account 静的 Web サイトにアクセスするための URL です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/02244318-7552-f2bc-375a-a13aefbf28f6.png)

Storage Account 静的 Web サイトを利用するユーザーを限定したい場合は、[ユーザーの割り当てが必要ですか] で「はい」を選択して保存し、[ユーザーとグループ] にユーザーまたはグループを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/36e185df-5d85-6ae8-1ec3-7bd260db8798.png)


# 動作確認

外部からプライベートな Storage 静的 Web サイトにアクセスしてみます。
アクセス先の URL は、Azure ポータルで、[Azure AD] > [エンタープライズ アプリケーション] を開き、[今回登録したアプリケーション] > [アプリケーション プロキシ] の [外部 URL] で確認できます。これをコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/fb38b9ca-f56c-d8fe-5d66-cb815d32a0ec.png)

ブラウザーで「外部 URL」にアクセスすると、サインインページが表示されます。利用許可されたユーザーの資格情報を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/b321e5c1-39bc-25ee-e48b-c698bd296aa9.png)

サインイン後、社内環境で確認したページが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/416b6da4-d5fa-bee2-9ae6-2244bcedfa30.png)

このように、外部からプライベートなリソースにアクセスできました。ブラウザーだけでアクセスできるため、ユーザーにはほぼ負担なく利用することができます。環境構築もカンタンにできました。


[^1]: [P2S OpenVPN プロトコル接続用の Azure Active Directory テナントを作成する](https://docs.microsoft.com/ja-jp/azure/vpn-gateway/openvpn-azure-ad-tenant?WT.mc_id=AZ-MVP-5003113)
[^2]: [Azure Active Directory 認証: P2S OpenVPN プロトコル接続用に VPN クライアントを構成する](https://docs.microsoft.com/ja-jp/azure/vpn-gateway/openvpn-azure-ad-client?WT.mc_id=AZ-MVP-5003113)
[^3]: [Azure AD アプリケーション プロキシからのオンプレミス アプリケーションへのリモート アクセス](https://docs.microsoft.com/ja-jp/azure/active-directory/manage-apps/application-proxy?WT.mc_id=AZ-MVP-5003113)
[^4]: [Azure Storage での静的 Web サイト ホスティング](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-static-website?WT.mc_id=AZ-MVP-5003113)
[^5]: [Azure Storage のプライベート エンドポイントを使用する](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-private-endpoints?WT.mc_id=AZ-MVP-5003113)
[^6]: [Azure AD アプリケーション プロキシからのオンプレミス アプリケーションへのリモート アクセス](https://docs.microsoft.com/ja-jp/azure/active-directory/manage-apps/application-proxy?WT.mc_id=AZ-MVP-5003113)