【Azure】App Service on LinuxにBASIC認証を実装する方法と注意点Tech TIPS

AzureのWeb/アプリケーションサービス「App Service」で、サイトコンテンツへのアクセスをユーザー認証で制限したい場合、互換性維持のため「BASIC認証」を採用したいこともあるのではないだろうか? Azureポータルからはできなくとも、各種設定ファイルを直接修正すれば実現可能だ。その手順と注意点を説明する。

» 2025年02月26日 05時00分 公開
[島田広道デジタルアドバンテージ]
「Tech TIPS」のインデックス

連載目次

Azure App Service on LinuxのNGINXをカスタマイズ

対象:Azure App Service on Linux(NGINX内蔵)

 AzureのWeb/アプリケーションサーバ「App Service」は、「Microsoft Entra ID」などのIDサービスを使ったユーザー認証に標準で対応している。

 しかし、レンタルサーバなどで運用されていたネットサービスをApp Serviceに移植するといった場合には、昔ながらのBASIC認証もApp Serviceにそのまま移したい、ということもあるのではないだろうか?(もちろんセキュリティの観点では、より強靱なIDサービスの方が望ましいのだが)。

 実は、App Serviceの内蔵Webサーバの設定を変更すると、BASIC認証を実装することが可能だ。本Tech TIPSでは、その手順と注意点を説明する。

 対象は、App Service on Linux内蔵のNGINXとする(App Service on WindowsのIISや、古いApp Service on LinuxのApacheについては対象外)。またNGINXの設定変更の手順については、Tech TIPS「【Azure】App ServiceのWebサーバ『NGINX』をカスタマイズする方法」を参照していただきたい。

 App ServiceのランタイムスタックはPHP 8.3としている。その他のスタックではスタートアップスクリプト(後述)の名称や内容が異なる、といった違いがあるので注意していただきたい。

 以下で説明している作業には、Linuxのシェルでコマンドを実行できる環境が必要だ。WSL(Windows Subsystem for Linux)あるいはHyper-Vやクラウド上のLinux VMなどを用意していただきたい。

手順1――認証情報をファイルに保存する「htpasswd」コマンドを準備する

 まずは、BASIC認証のユーザー名とパスワードをファイルに保存するためのコマンド「htpasswd」を実行できるようにする。

 作業用のLinux環境のシェルで次のコマンドラインを実行してみる。

which htpasswd

 htpasswdのフルパスが表示されたら、htpasswdは実行できる。

 そうではなく、「no htpasswd in ~」と表示されたり、あるいは何も表示されなかったりした場合は、以下の手順でhtpasswdを明示的にインストールする必要がある。

●Ubuntuを含むDebian系ディストリビューションの場合

 以下のように「apt-get」コマンドで「apache2-utils」パッケージをインストールする。

sudo apt-get install -y apache2-utils

●AlmaLinuxを含むRed Hat Enterprise Linux系ディストリビューションの場合

 以下のように「dnf」コマンドで「httpd-tools」パッケージをインストールする。

sudo dnf install -y httpd-tools

●App Service on Linuxの場合

 Tech TIPS「【Azure】App Service on LinuxにSSHで接続する方法と注意点(WebSSH編)」のように、App Service on LinuxにSSHで接続し、そこでhtpasswdコマンドをインストールして実行することも可能だ。

 執筆時点でApp Service on LinuxのOSは「Debian 11」(開発コード名「Bullseye」)相当なので、インストールには前述のapt-getコマンドを利用すればよい。ただsudoコマンドは不要だ(実行するとエラーになる)。

apt-get install -y apache2-utils

 ただ、App Serviceを再起動したり再デプロイしたりすると、コンテナごと初期化されるため、htpasswdコマンドが実行できない状態に戻ってしまうことには注意してほしい。なるべく、安定したLinux環境を別途用意して、こうした作業に利用する方がよいだろう。

手順2――htpasswdコマンドで認証情報ファイルを作成する

 htpasswdコマンドを実行できるようにしたら、BASIC認証のための認証情報ファイルを作成する(NGINXはこのファイルを読み込んで、ユーザーの認証に利用する)。

 認証情報ファイルを作成するには、以下のように「-c」オプションを付けてhtpasswdコマンドを実行する。

htpasswd -c <認証情報ファイルの名前> <ユーザー名>

 <認証情報ファイルの名前>には、「.htpasswd」あるいは「.htpasswd-<用途>」というようなファイルを指定することが多いようだ。もちろん、必要ならフルパスで指定すること。

 <ユーザー名>には、BASIC認証のダイアログの「ユーザー名」欄に記入してもらうテキストを指定する。

 上記のコマンドラインを実行するとパスワードが問い合わされるので、確認も含めて2回、パスワードを入力する。正しく作成できると、以下の画面のようになるはずだ。

htpasswdコマンドでBASIC認証向けの認証情報ファイルを新規作成する htpasswdコマンドでBASIC認証向けの認証情報ファイルを新規作成する

 既存の認証情報ファイルが存在し、そこに新たなユーザー名とパスワードの組み合わせを追記するなら、「-c」オプションを指定せずにhtpasswdコマンドを実行すればよい。

htpasswd <認証情報ファイルの名前> <ユーザー名>

 <認証情報ファイルの名前>の末尾に新たな認証情報が追記されるはずだ。

手順3――作成した認証情報ファイルをApp Serviceの[/home/]ディレクトリ以下に配置する

 作成した認証情報ファイル(ここでは[.htpasswd]とする)は、App Serviceの[/home/]ディレクトリ以下に配置する。他のディレクトリに配置すると、App Serviceの再起動時(コンテナの再デプロイ時)に消失してしまうので注意すること。

 [.htpasswd]ファイルはFTPなどでローカルPCからアップロードしてもよいし、リポジトリ内に配置してデプロイしてもよい。

 配置した[.htpasswd]ファイルのフルパスはメモしておく。後でNGINXの設定ファイルに記述する必要があるからだ。

手順4――特定のディレクトリでBASIC認証を有効にする

 ほとんどのサイトコンテンツは無制限にアクセス可能な一方で、特定のWebアプリだけはユーザーを限定したい、といった場合、そのWebアプリのある特定ディレクトリだけにBASIC認証を設定することが多い。

 そのような場合、App ServiceではNGINXの設定ファイルの一つ[/etc/nginx/sites-available/default]を以下のように修正するとよいだろう(直接修正せず、前出のTech TIPSで説明しているように、[/home/]ディレクトリ以下に修正済みの[sites-available/default]ファイルを配置し、そこへシンボリックリンクを張ること)。

server {
<前略>

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /html/;
    }

    # ----- 以下を挿入 -----
    # 管理専用の「/kanrishanoheya」ディレクトリ以下に、BASIC認証を強制する
    location ~ ^/kanrishanoheya/ {
        # 認証ダイアログに表示されるメッセージを指定
        auth_basic "Authorization Required";
        # 認証情報ファイルのフルパスを指定
        auth_basic_user_file "/home/auth/.htpasswd";

        # 必要なら他の設定をここに挿入
    }
    # -----挿入終わり -----

    # Disable .git directory
    location ~ /\.git {
        deny all;
        access_log off;
        log_not_found off;
    }

<後略>
}

[sites-available/default]を書き換えて特定ディレクトリのみBASIC認証を有効にする

 修正したら、設定ファイルを検証してからNGINXに読み込ませる。

nginx -t
nginx -s reload

 この後、Webブラウザで対象ディレクトリ以下のパスを開き、認証ダイアログが表示され、[.htpasswd]ファイルに指定したユーザー名/パスワードで認証に成功するかどうかを試してみよう。その他のコンテンツについても、従来と同じく認証なしでアクセスできることも確認した方がよい。

 成功したら、前出のTech TIPSで説明しているように、スタートアップスクリプトに[sites-available/default]ファイルの差し替えを設定する。

【注意】サイト全体でBASIC認証を有効化するなら各種プローブなどを除外すべき

 特定ディレクトリではなくサイト全体に対してBASIC認証を有効化することも可能だ。ただし、App Serviceに対する動作確認用アクセスについては、BASIC認証から外す必要がある。

 その1つは「Always On(常時接続)」と呼ばれる機能のプローブ(調査のためのアクセス)だ。AzureポータルのApp Serviceの[設定]-[構成]-[常時接続]を「オン」にすると、App Serviceには、クライアントIPアドレス「127.0.0.1」「::1」からHTTPで定期的に「/」(ルート)へのGETリクエストが送信される。それに対してHTTPステータスコード「200 OK」を返さないと、そのWebアプリはやがてアンロードされてしまう。その後のアクセスでは、Webアプリの再ロードの分だけ応答(レスポンス)が遅くなってしまう。

 「/」にBASIC認証をかけている場合、その認証情報を知らないプローブに対して、App Serviceは「401 Unauthorized」を返す。結果として、しばしばWebアプリがアンロードされ、性能低下を招いてしまう。

 もう1つは「正常性チェック」のプローブである。AzureポータルのApp Serviceの[監視]-[正常性チェック]-[正常性チェック]タブ-[有効にする]ラジオボタンを選択している場合、そこで指定している「正常性プローブパス」に対して定期的にリクエストが送信される。これに対して200~299のHTTPステータスコードを返さないと、そのインスタンスは異常と見なされて切り離されてしまう。

 正常性プローブパスにBASIC認証をかけている場合、インスタンスが減って性能が下がってしまう。

 そこで、以下のようにNGINXの2つの設定ファイルを追加/修正することで、「/」と正常性プローブパスをBASIC認証から除外し、認証なしでアクセスできるようにする。

# map.conf: default.confで参照する変数をmapディレクティブで定義する

# Always On(常時接続)のプローブかどうかを判定する
map $http_user_agent $always_on_ua {
    default     0;
    "AlwaysOn"  1; # User-Agentを確認
}
map $remote_addr $always_on_ua_ip {
    default     0;
    127.0.0.1   $always_on_ua; # クライアントIPアドレスを確認
    ::1         $always_on_ua; # クライアントIPアドレスを確認   
}
map $request_uri $always_on_ua_ip_uri { # URI
    default 0;
    "/"     $always_on_ua_ip; # URI(パス)を確認
}

# BASIC認証を外すかどうかをURI(パス)で判定する
map $request_uri $no_auth_basic {
    default                 0;
    "/health_check.html"    1; # 正常性チェック
    "/favicon.ico"          1; # ファビコン
    "/"                     $always_on_ua_ip; # Always On
}

# auth_basicディレクティブの引数を確定する
map $no_auth_basic $auth_basic_str_off {
    default "Authentication required"; # realmの文字列
    1       off; # BASIC認証を外す
}

サイト全体でBASIC認証を有効化するために[conf.d/map.conf]を新規追加する
正常性プローブパスは「/health_check.html」としている。
※NGINXのレファレンス: map

server {
    #proxy_cache cache;
    #proxy_cache_valid 200 1s;
    listen 8080;
    listen [::]:8080;
    root /home/site/wwwroot;
    index  index.php index.html index.htm;
    server_name  example.com www.example.com
    port_in_redirect off;

    # ---------- 以下を挿入 ----------
    # 正しいクライアントIPアドレスを取得するための設定(詳細は別記事で解説)
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    set_real_ip_from 169.254.0.0/16;

    # 【サイト全体】認証ダイアログに表示されるメッセージを指定
    auth_basic $auth_basic_str_off;
    # 【サイト全体】認証情報ファイルのフルパスを指定
    auth_basic_user_file "/home/auth/.htpasswd";

    # Always On(常時接続)のプローブなら、アクセスを許可する
    if ($always_on_ua_ip_uri) { return 200; }
    # ---------- 挿入終わり ----------

    location / {            
        index  index.php index.html index.htm hostingstart.html;
    }

<後略>
}

サイト全体でBASIC認証を有効化するために[sites-available/default]を書き換える
※NGINXのレファレンス: real_ip_header/real_ip_recursive/set_real_ip_fromauth_basic/auth_basic_user_fileif/return

 スタートアップスクリプト[/home/startup.sh]には、以下のように[sites-available/default][conf.d/map.conf]それぞれのシンボリックリンク作成を記述する必要がある。

#!/usr/bin/env bash

# 設定ファイルを変更または差し替える
ln -snf /home/custom/etc/nginx/sites-available/default /etc/nginx/sites-available/default
ln -snf /home/custom/etc/nginx/conf.d/map.conf /etc/nginx/conf.d/map.conf

# NGINXに設定ファイルを再度読み込ませる
nginx -s reload

スタートアップスクリプト[/home/startup.sh]の例

 たとえAlways Onや正常性チェックを無効化している場合でも、あらかじめ正常性プローブパスを決めておいて、それらのパスをBASIC認証から外しておくことをお勧めする。そうしないと、この問題を失念したまま、これらの機能を有効化したら性能が下がってしまった、という事態を招きかねないからだ。

■関連リンク

「Tech TIPS」のインデックス

Tech TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

Windows Server Insider 記事ランキング

本日月間

注目のテーマ

4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。