App Serviceに対して設定できるアクセス制限方法と設定手順
はじめに
Microsoft Azure Techのカレンダー | Advent Calendar 2022 - Qiita 19日目の記事です。
App Serviceは様々な方法のアクセス制限を提供しています。
本記事では下記のシナリオにおいて利用可能なアクセス制限方法と設定手順を紹介します。
- IPアドレスベースでアクセスを制限する
- Azure上の仮想ネットワークからのアクセスのみ許可する
- オンプレミス環境からのアクセスのみ許可する
- インターネットからのアクセスのうち、認証を通った場合のみアクセスを許可する
IPアドレスベースでアクセスを制限する
使用するリソース:App Serviceのアクセス制限機能
App Serviceのアクセス制限機能
App Serviceでは、アクセス制限を設定することでIPアドレスによるアクセス制限を行うことができます。
アクセス制限の設定により、優先度で順序付けした許可リストまたは拒否のリストを定義できます。このリストは、アプリへのネットワーク アクセスを制御します。 リストには、IP アドレスまたは Azure Virtual Network のサブネットを含めることができます。
Azure App Service のアクセス制限 - Azure App Service | Microsoft Learn
【手順】
1 . Azure portalから、App Serviceにアクセスし、左メニューの「ネットワーク」>「アクセス制限」を選択する
2 . 「規則の追加」からソースの設定で「IPv4」を選択し、IPアドレスブロックに該当のIPアドレスを入力し「規則の追加」を押下
ここまでの設定でIPアドレスベースのアクセス制限が構成できます。
【挙動】
【補足】
- IPアドレスでの制限以外にも、「仮想ネットワーク」「サービスタグ」が選択できます(後述します)
- 仮想ネットワーク:
- 指定した仮想ネットワークのサブネットからのアクセスのみ許可/拒否する
- https://learn.microsoft.com/ja-jp/azure/app-service/app-service-ip-restrictions#set-a-service-endpoint-based-rule
- サービスタグ:
- 特定のAzureサービスからのアクセスのみ許可/拒否する
- https://learn.microsoft.com/ja-jp/azure/app-service/app-service-ip-restrictions#set-a-service-tag-based-rule
Azure上の仮想ネットワークからのアクセスのみ許可する
使用するリソース:App Serviceのアクセス制限機能、Private Endpoint
App Serviceのアクセス制限機能(サービスエンドポイント)
サービスエンドポイントを利用したアクセス制限について紹介します。
イメージとしては下記のようになります。
【手順】
1 . Azure portalから、App Serviceにアクセスし、左メニューの「ネットワーク」>「アクセス制限」を選択する
2 . 「規則の追加」からソースの設定で「仮想ネットワーク」を選択し、サブネットまで入力後「規則の追加」を押下
ここまでの設定で仮想ネットワークからのアクセス制限が構成できます。
【挙動】
【補足】
上記のアクセス制限を構成すると、制限対象の仮想ネットワーク側に、サービスエンドポイントが自動で構成されます。
サービスエンドポイントとは
仮想ネットワーク (VNet) サービス エンドポイントでは、Azure のバックボーン ネットワーク上で最適化されたルートを介して、Azure サービスに安全に直接接続できます。 エンドポイントを使用することで、重要な Azure サービス リソースへのアクセスを仮想ネットワークのみに限定することができます。
プライベートエンドポイント
プライベートエンドポイントを利用したアクセス制限について紹介します。
イメージとしては下記のようになります。
【手順】
前提として、ある仮想ネットワークのサブネット上に仮想マシンが構成されている状態で、ここからプライベートエンドポイントを構成していきます。
1 . Azure portalから、App Serviceにアクセスし、左メニューの「ネットワーク」>「プライベートエンドポイント」を選択する
2 . 「追加」から対象のApp Serviceへのアクセスを許可するサブネットを入力後「OK」を押下
ここまでの設定で仮想ネットワークからのアクセス制限が構成できます。
【挙動】
【補足】
プライベートエンドポイント作成時の、「プライベートDNSゾーンと統合する」について
プライベートエンドポイントを利用する際、アクセス対象(今回でいうAppService)の名前解決を行うためにプライベートDNSゾーンが必要です。
Azure PortalからプライベートDNSゾーンを見てみると、リソースに対してどんなプライベートIPアドレスが振られているか確認することができます。
名前解決を行うフローの詳細は下記ご参照ください。
Azure プライベート エンドポイントの DNS 構成 | Microsoft Learn
仮想ネットワークに接続されたデバイスの確認
仮想ネットワークの「接続デバイス」から、接続されているデバイスを確認できます。
今回追加したプライベートエンドポイントもここから参照できます。
(ちょっと脱線)サービスエンドポイントとプライベートエンドポイントの違い
App Serviceへのアクセスを限られたネットワーク(仮想ネットワーク)に限定する方法として、サービスエンドポイントとプライベートエンドポイントを使う方法を紹介しました。
どちらも同様の機能を提供しているサービスエンドポイントとプライベートエンドポイントについて、両者の違いとそれぞれのユースケースを紹介します。
サービスエンドポイント
【アクセス制限方法】
-
サブネットのルートテーブルの書き換えで制御する
- ex: AppServiceとの通信に使用するプロトコル・ポートの制限をルートテーブルに追加する(Microsoft.Webのサービスエンドポイントを作成した場合)
-
- 上記のルートテーブルの変更はAzure Portalからは参照できず、内部的な上位のルートテーブルに適応される
【アクセス制限が可能な領域】
-
仮想ネットワークのサブネット
- ピアリング先仮想ネットワークやオンプレからのアクセスは出来ない
-
特定のサービス(AppService/SQLServerなど)単位でアクセス制限を行う
【利用料】
- 無料で使用可能
【ユースケース】
- あるサブネットのみからのアクセスを許可したい場合
- 追加のコストをかけずにアクセス制限したい場合
プライベートエンドポイント
【アクセス制限方法】
- 指定したサブネット内にネットワークインターフェースを用意し、プライベートIP アドレスを割り当てることで制御する(割り当てられたプライベートIPアドレスからでしかアクセスを許可しない)
- 用意されたネットワークインタフェース=プライベートエンドポイント
- プライベートエンドポイントを名前解決するためのDNS設定が必要
【アクセス制限が可能な領域】
【利用料】
有料(価格 - Azure Private Link | Microsoft Azure)
【ユースケース】
- オンプレミス環境からのアクセスを許可したい場合
- あるサービスの中でも、特定のリソースのみアクセスを許可したい場合(ex: SQLServer1は許可したいが、SQLServer2は拒否したい)
- サービスエンドポイントが提供していないリソースへのアクセス制限をしたい場合
- 下記サービスエンドポイントが提供しているリソース(Azure 仮想ネットワーク サービス エンドポイント | Microsoft Learn)
- 下記サービスエンドポイントが提供しているリソース(Azure 仮想ネットワーク サービス エンドポイント | Microsoft Learn)
オンプレミス環境からのアクセスのみ許可する
使用するリソース:ExpressRoute
ExpressRoute
ExpressRouteを使って、オンプレミスのネットワークとAzure上の仮想ネットワークを接続することができます。
Azure ExpressRoute: 接続モデル | Microsoft Learn
ExpressRouteの概要や利点は下記ドキュメントをご参照ください。
Azure ExpressRoute の概要プライベート接続を介して接続する | Microsoft Learn
【手順】
ここではドキュメントの紹介のみさせていただきます。
クイックスタート: ExpressRoute を使った回線の作成と変更 - Azure portal | Microsoft Learn
チュートリアル:ExpressRoute 回線のピアリングの構成 - Azure portal | Microsoft Learn
チュートリアル: Azure portal を使用して ExpressRoute の仮想ネットワーク ゲートウェイを構成する | Microsoft Learn
インターネットからのアクセスのうち、認証を通った場合のみアクセスを許可する
使用するリソース:AzureAD、クライアント証明書、IDaabS等の外部認証サービス
AzureAD
App Service認証機能を使って、App Serviceに到達する前にAzure ADログインを求めることができます。
イメージとしては下記のようになります。
Azure AD 認証を構成する - Azure App Service | Microsoft Learn
【手順】
1 . Azure portalから、App Serviceにアクセスし、左メニューの「認証」>「ID プロバイダーを追加」を選択する
2 . 「ID プロバイダー」でMicrosoftを選択し、「追加」を押下
ここまでの設定でAzureADを使ったアクセス制限が構成できます。
【挙動】
【補足】
IDプロバイダー追加時の設定について
「IDプロバイダー」はMicrosoft以外に、下記からも選択可能です。
認証されていない要求
「IDプロバイダー」で選択したサインインに失敗した要求に対して、どのステータスコートを返却するかの設定です。
クライアント証明書
AppServiseでは、クライアント要求が TLS/SSL を経由するときにクライアント証明書を要求し、その証明書をアプリ上で検証することでアクセスを制限することができます。
【手順】
1 . Azure portalから、App Serviceにアクセスし、左メニューの「構成」>「全般設定」を選択する
2 . 「着信クライアント証明書」で「必須」を選択し保存する
ここまでの設定で、クライアントがAppServiceにアクセスしてきた際に、証明書を求めることができます。
3 . アプリコードで証明書を検証し、アクセスを制限する
アクセスを制限するには、要求した証明書をアプリで検証する必要があります。
Node.jsのサンプルを紹介します。
import { NextFunction, Request, Response } from 'express';
import { pki, md, asn1 } from 'node-forge';
export class AuthorizationHandler {
public static authorizeClientCertificate(req: Request, res: Response, next: NextFunction): void {
try {
// Get header
const header = req.get('X-ARR-ClientCert');
if (!header) throw new Error('UNAUTHORIZED');
// Convert from PEM to pki.CERT
const pem = `-----BEGIN CERTIFICATE-----${header}-----END CERTIFICATE-----`;
const incomingCert: pki.Certificate = pki.certificateFromPem(pem);
// Validate certificate thumbprint
const fingerPrint = md.sha1.create().update(asn1.toDer(pki.certificateToAsn1(incomingCert)).getBytes()).digest().toHex();
if (fingerPrint.toLowerCase() !== 'abcdef1234567890abcdef1234567890abcdef12') throw new Error('UNAUTHORIZED');
// Validate time validity
const currentDate = new Date();
if (currentDate < incomingCert.validity.notBefore || currentDate > incomingCert.validity.notAfter) throw new Error('UNAUTHORIZED');
// Validate issuer
if (incomingCert.issuer.hash.toLowerCase() !== 'abcdef1234567890abcdef1234567890abcdef12') throw new Error('UNAUTHORIZED');
// Validate subject
if (incomingCert.subject.hash.toLowerCase() !== 'abcdef1234567890abcdef1234567890abcdef12') throw new Error('UNAUTHORIZED');
next();
} catch (e) {
if (e instanceof Error && e.message === 'UNAUTHORIZED') {
res.status(401).send();
} else {
next(e);
}
}
}
}
Node.jsの場合、X-ARR-ClientCert
ヘッダーに要求した証明書(base64エンコードPEM文字列)が入ります。
それをnode-forge
で証明書オブジェクトに変換して、検証を行います。
Node.js以外のサンプルコートは下記に記載があるので、ご参考までに紹介いたします。
TLS 相互認証の構成 - Azure App Service | Microsoft Learn
【挙動】
- AppServiceにアクセスする
IDaaS等の外部認証サービス
ここでは詳細な手順は割愛しますが、外部のIDaaSを利用する方法もございます。
その場合、アプリ上でトークン取得や認証サイトへのリダイレクトを行う必要があります。
大まかな流れとしては下記のようになります。
詳細は、IDaaSの一例であるAuth0のドキュメントを下記に紹介いたしますので、ご参照ください。
その他のアクセス制限方法
さらに高度なアクセス制限については、下記ドキュメントをご参照ください。
Azure App Service のアクセス制限 - Azure App Service | Microsoft Learn
最後に
AppServiceで利用できる様々なアクセス制限方法を紹介しました。
アクセス制御は安全なウェブサイトを構築するうえで欠かせない仕組みであるため、要件に合った方法を選定していただければと思います。
安全なウェブサイトの作り方 - 1.11 アクセス制御や認可制御の欠落:IPA 独立行政法人 情報処理推進機構
参考
Azure App Service のアクセス制限 - Azure App Service | Microsoft Learn
Azure 仮想ネットワーク サービス エンドポイント | Microsoft Learn
プライベート エンドポイントとは - Azure Private Link | Microsoft Learn
Azure Private Link サービスとは | Microsoft Learn
Azure プライベート エンドポイントの DNS 構成 | Microsoft Learn
Virtual network integration of Azure services for network isolation | Microsoft Learn