検索
連載

【Azure】App ServiceでIPv6でもリッスンできるようにするTech TIPS

日本国内でIPv6に接続しているユーザーの割合は50%を超えるという。これほど多いのなら、WebサイトもIPv6で受信できるようにしたい、という運用担当者も多いだろう。そこでAzureの「App Service」でIPv6での受信を有効化する手順やその注意点を説明する。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「Tech TIPS」のインデックス

連載目次

Azure App ServiceでIPv6でもリッスンできるようにする

対象:Azure App Service


 Googleの統計によれば、日本国内からGoogleのサービスに「IPv6」に接続しているユーザーの割合は、2025年4月下旬で52.25%とのことだ。半数以上がIPv6で通信できるというのは、意外に多いと思った人も多いだろう。

 これほど多いのなら、たとえIPv4が枯渇しておらず、いまだ実用的だとしても、Webサイト側はIPv6でもIPv4でも受信できるようにしたい、という人も多いと思う。

 Azureの「App Service」でも、まだプレビューながらIPv6での受信に対応している。そこで本Tech TIPSでは、IPv6での受信を有効化する手順とその注意点について説明する。

 前述の通り、IPv6での受信機能はまだプレビュー段階なので、Productionスロットすなわち運用中のライブサイトに適用するのはあまり望ましくない。また今後、仕様が変わる可能性もある点には留意していただきたい。

 今回取り扱うのは、App Serviceがクライアントからのリクエストを受信するときのリッスンIPアドレスである。App Serviceのインスタンスが送信する際のソースIPアドレスは対象外なので注意していただきたい。

AzureポータルでApp ServiceのIPv6での受信を有効化する

 IPv6に関する設定をする前に、App Serviceのデフォルトドメイン(既定のドメイン)の名前解決がどのようになっているか確認してみよう。

 Windows OS標準の「nslookup」コマンドを以下のように実行すると、最終的な解決先のIPアドレスが表示される。

IPv6の有効化前に調べたApp Serviceのデフォルトドメインの名前解決
IPv6の有効化前に調べたApp Serviceのデフォルトドメインの名前解決
この画面内にあるドメイン名(FQDN)やIPアドレスは、いずれも筆者がデプロイしたApp Serviceのものであり、別の環境では異なる名前/アドレスになることが多いだろう。nslookupコマンドの使い方については、Tech TIPS「DNSトラブル解決の定番、nslookupの基本的な使い方(社内ネットワーク編)」を参照していただきたい。

 IPv6での受信を有効化していない、すなわちIPv4のみ受信する場合、App Serviceのデフォルトドメインは次のように名前解決される。

  1. 1つ目のCNAMEレコード: <サブドメイン1>.sip.azurewebsites.windows.net
  2. 2つ目のCNAMEレコード: <サブドメイン2>.japaneast.cloudapp.azure.com
  3. Aレコード: <IPv4アドレス>

 さて、IPv6での受信を有効化してみよう。Azureポータルでは、以下のように[設定]−[構成]−[受信IPモード]で[IPv4とIPv6]を選択し、[保存]ボタンを押す。このとき、アプリが再起動(再デプロイ)されて一時的に応答が途絶するので注意しよう。

App Serviceの受信IPアドレスにIPv6を追加する(1/2)
App Serviceの受信IPアドレスにIPv6を追加する(1/2)
App Serviceの受信IPアドレスにIPv6を追加する(2/2)
App Serviceの受信IPアドレスにIPv6を追加する(2/2)

 上記の設定後、十数分〜数十分ほど待って名前解決の変更が広くインターネットに伝搬してから、再び前出のnslookupコマンドを実行してみよう。今度はIPv4だけではなくIPv6のアドレスも解決されるはずだ。

IPv6での受信を有効化してから調べたApp Serviceのデフォルトドメインの名前解決
IPv6での受信を有効化してから調べたApp Serviceのデフォルトドメインの名前解決

 以後、IPv6が優先されるクライアントデバイスから対象のApp Serviceにアクセスすると、IPv6で通信できるようになる。

 IPv6での受信の有効化後、App Serviceのデフォルトドメインは次のように名前解決される。

  1. CNAMEレコード: <サブドメイン>.sip-v4andv6.azurewebsites.windows.net
  2. Aレコード: <IPv4アドレス>、AAAAレコード: <IPv6アドレス>

 筆者が試した限り、IPv4アドレスはIPv6での受信の有効化前と後で変化しなかった。

App Serviceのデプロイ時にIPv6での受信を有効化する

 App ServiceをデプロイするためのリソーステンプレートでIPv6での受信を有効化するには、「Microsoft.Web/sites」というリソースの「properties.ipMode」に「IPv4AndIPv6」という値を設定する。

// リソース生成: App Serviceのサイト本体
resource webApp 'Microsoft.Web/sites@ 2024-04-01' = {
  name: '<Webサイト名>'
  location: location
  properties: {
    ipMode: 'IPv4AndIPv6'
    /* ……他のプロパティ設定…… */
  }
}

【Bicep】IPv6での受信を有効化したApp Serviceを生成する
レファレンス: Microsoft.Web/sites

Azure CLIで既存のApp ServiceのIPv6での受信を有効化する

 Azure CLIでIPv6での受信を有効化するには、以下のように「az resource update」コマンドを実行する。

az resource update -g <リソースグループ名> -n <リソース名> --resource-type "Microsoft.Web/sites" --set properties.ipMode="IPv4AndIPv6"

【Azure CLI】既存のApp ServiceでIPv6での受信を有効化する
レファレンス: az resource update

 IPv6での受信を無効化する場合は、上記コマンドラインの「IPv4AndIPv6」を「IPv4」に置き換えて実行すればよい。

【注意】カスタムドメインの名前解決にAレコードを使っている場合はAAAAレコードを手動で追加する

 カスタムドメインを使用しているApp Serviceであっても、それをCNAMEレコードで名前解決をしているなら、IPv6での受信を有効化するだけで、IPv6でも名前解決されるようになる。そのため、DNSのレコードを修正する必要はない。

 一方、カスタムドメインをAレコードで名前解決している場合、手動でAAAAレコードを追加してIPv6でも解決できるようにする必要がある。これを忘れると、カスタムドメインでは引き続きIPv4でしかアクセスできないので注意が必要だ。

【注意】ソースIPアドレスでアクセス制限している場合はIPv6アドレスも追加する

 App Serviceへのアクセスを特定拠点のソースIPアドレスで制限していて、かつその拠点がIPv6でも通信できる場合、各拠点のIPv6アドレス範囲も許可/禁止リストに加える必要がある。

 App Service標準のアクセス制限機能は、Azureポータルの[設定]−[ネットワーク]−[受信トラフィックの構成]−[公衆ネットワーク アクセス]で設定できる。ここが「アクセス制限なしで有効」以外の場合は、何らかの制限がかかっているはずなので注意が必要だ。

 また、Tech TIPS「【Azure】App Service on LinuxでディレクトリごとにクライアントIP制限を実装する方法と注意点(NGINX編)」で説明している方法でソースIPアドレス制限を実装している場合も、同様にIPv6アドレスを許可/禁止リストに加える必要がある。

【参考】App Service上のPHPで接続元のソースIPアドレスを表示する

 参考までに、PHPスタックが選択されているApp Serviceで、接続元のソースIPアドレスを表示するページのリストを以下に記す。

<?php
  $clientIPHeaders = [
    'HTTP_X_AZURE_CLIENTIP', // Azure Front Doorなどが追加するヘッダ
    'HTTP_X_CLIENT_IP', // Azure App Serviceなどが追加するヘッダ
    'REMOTE_ADDR', // 直近のリモートIPアドレスが格納される一般的なヘッダ
  ];

  $results =  '(不明)'; // 表示するIPアドレスの初期値

  foreach ($clientIPHeaders as $header) {
    // $_SERVERから各リクエストヘッダの値を取得
    $clientIP = filter_input(INPUT_SERVER, $header, FILTER_VALIDATE_REGEXP, [
        'options' => [ 'regexp' => '/^[a-fA-F\d\.:\[\]]+$/' ]
    ]);

    // IPv6アドレスをくくる「[]」を削除
    $clientIP = str_replace('[', '', (string)$clientIP);
    $clientIP = str_replace(']', '', (string)$clientIP);

    // IPアドレスとして検証。プライベートIPと予約済みIPは除外
    $clientIP = filter_var((string)$clientIP, FILTER_VALIDATE_IP, [
      'flags' => FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE
    ]);

    // 有意なIPアドレスなら確定
    if (!empty($clientIP)) {
      $results = $clientIP;
      break;
    }
  }
?>
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>接続元IPアドレス(ソースIP)</title>
  </head>
  <body>
    <main>
      <h1>接続元IPアドレス(ソースIP)</h1>
      <p><b><?= $results ?></b></p>
    </main>
  </body>
</html>

【PHP】接続元のソースIPアドレスを表示するページのリスト

 これをPHPファイルに書き込んでApp Serviceにアップロードした後、Wi-Fiとプロキシを一時的に「オフ」にしたスマートフォンから開いてみよう。IPv6での受信を有効化しているApp Serviceの場合、以下の画面のようにIPv6アドレスが表示されることが多いはずだ。

上記のPHPコードによって表示されたIPv6のソースIPアドレス(例)
上記のPHPコードによって表示されたIPv6のソースIPアドレス(例)

■関連リンク


「Tech TIPS」のインデックス

Tech TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.