【実務・中級編】 プローブ要求(Probe Request)のプライバシーとランダムMAC – 家庭用ネットワーク・IoT・モバイル通信実践ガイド

Wi-Fiプローブ要求の裏側:MACアドレスランダム化がもたらすインフラ運用の現実とプライバシー保護の技術的アプローチ

こんにちは。現場の泥臭いパケット解析から最新のWi-Fi規格まで、電波と格闘し続けているシニアネットワークエンジニアです。

オフィス、カフェ、あるいは街を歩いているとき、私たちのスマートフォンやノートPCは、目に見えないところで絶えず周囲の無線アクセスポイント(AP)と対話を繰り広げています。「おーい、前につながったあのAPは近くにないか?」と。この、接続先を血眼になって探すデバイスの叫び声こそが、今回深掘りする「プローブ要求(Probe Request)」です。

近年、このプローブ要求をめぐるプライバシー保護の動きは、インフラエンジニアの頭を悩ませる大きな変革期を迎えています。iOSやAndroid、さらにはWindowsに至るまで、端末が発信するMACアドレスを常に偽装する「MACアドレスランダム化(MAC Randomization)」が標準装備されたからです。

今回は、このプローブ要求のパケットレベルでの挙動、プライバシー保護のメカニズム、そして動的MACアドレスが飛び交う現代において、私たちインフラエンジニアやWeb・位置情報サービス開発者が直面する課題と実践的な対処法について、現場の知見を交えて徹底解説します。

—

1. プローブ要求(Probe Request)の基本メカニズム

Wi-Fiの接続プロセスにおいて、デバイス(STA)がAPを見つける方法には大きく分けて2つあります。APが定期的に発信するビーコン(Beacon)を受動的に待つ「パッシブスキャン」と、デバイス側から積極的に周囲へ呼びかける「アクティブスキャン」です。プローブ要求は後者で使われます。

アクティブスキャンの通信シーケンス

デバイスが移動し、現在接続中の電波が弱まったり、スリープから復帰したりした際、デバイスは以下のようなシーケンスで周囲のAPを探索します。

[デバイス (STA)]                         [アクセスポイント (AP)]
      |                                           |
      | --- (1) プローブ要求 (Probe Request) ---->|  ※特定のSSIDを指定 または ブロードキャスト
      |                                           |
      |<-- (2) プローブ応答 (Probe Response) -----|  ※対応可能なSSIDやケイパビリティを返答
      |                                           |

1. プローブ要求(Probe Request)の送出:
デバイスは管理フレーム(Management Frame)の一つであるプローブ要求を空中線に向けてブロードキャスト(またはユニキャスト)します。このフレームの中には、デバイスが過去に接続したことのあるSSIDのリスト(Preferred Network List: PNL)や、対応している無線規格(Wi-Fi 4/5/6/7など)のレート情報が含まれています。
2. プローブ応答(Probe Response)の返信:
要求を受け取ったAPは、自らがそのSSIDをサポートしていれば、プローブ応答を返します。これにより、デバイスは周囲にどのようなAPが存在し、どのチャネルで稼働しているかを把握します。

—

2. MACアドレスランダム化の技術仕様とプライバシーリスク

かつて、すべてのネットワークカード(NIC)には、IEEEが管理する固有のOUI(Organizationally Unique Identifier)を含む、世界で唯一のMACアドレス(BSSID/STA MAC)がハードコーディングされていました。

この静的なMACアドレスは、ネットワーク管理において非常に都合が良いものでした。しかし、ユーザーのプライバシーの観点からは致命的な欠陥となります。街中の店舗や公共スペースに設置された複数のWi-Fiセンサー(パケットスニッファ)が、この固有MACアドレスを数メートルおきにキャッチすることで、「特定のデバイス(=特定の個人)が、何時何分にどの店舗の前を通り過ぎ、どこに滞在したか」という移動経路(トラッキング)が丸裸にされてしまうのです。

ランダム化の仕組み

こうしたプライバシー侵害を防ぐため、近年の主要なOSでは、Wi-Fiスキャン時に本来のハードウェアMACアドレス(Burned-In Address: BIA)ではなく、一時的に生成したランダムなMACアドレスを使用する機能がデフォルトで有効になっています。

  • ローカル管理アドレス(Locally Administered Address)の利用:

ランダム生成されたMACアドレスの第2オクテットの最下位から2ビット目(U/Lビット)は「1」に設定され、グローバルにユニークなIEEE割り当てではないことが明示されます。

  • ローテーションのタイミング:

OSや設定によって異なりますが、特定のSSIDに接続していない状態(スキャン中)では数分おき、あるいはネットワークごとに異なるランダムMACを割り当てることで、長期的な追跡を困難にしています。

—

3. インフラ運用・開発現場への影響とトラブルシューティング

この「MACアドレスがころころ変わる」仕様は、セキュリティとプライバシーの観点では大正解ですが、ネットワークインフラの運用者や、位置情報・マーケティング系のWeb APIを構築するエンジニアにとっては、頭の痛い問題を引き起こします。

よくある現場のトラブル

1. MACアドレス認証(MACファイヤーウォール)の崩壊:
社内ネットワークやホテル・学校などのゲストWi-Fiで、「特定のMACアドレスのみを許可する」という古典的なアクセス制御を行っている場合、ユーザーが勝手にMACアドレスを変えるため、突如としてネットワークから切断されるトラブルが多発します。
2. 位置情報アナリティクス・動線分析の精度低下:
商業施設などでプローブ要求をパケットキャプチャし、「今日のユニーク来場者数」を算出しているシステムでは、1人のユーザーが複数のランダムMACをばら撒くため、来場者数が実際よりも何倍も多く水増しされて計測されてしまいます。
3. 固定IP(DHCPリザーベーション)の破綻:
「このプリンターには常にこのIPを割り当てる」といった運用をMACアドレスベースで行っている場合、デバイス側がランダムMACを使用するように設定されていると、接続のたびにIPが変わって印刷できなくなる現象が起きます。

—

4. 実務で役立つ設定とコード例

ここからは、このランダムMACやプローブ要求の挙動を考慮したシステム構築・デバッグの現場で役立つ実用的なアプローチを、具体的なコードや設定例を交えて紹介します。

① ネットワーク管理者向け:MACアドレスランダム化の無効化(ポリシー制御)

企業ネットワーク(特に802.1X認証やエンタープライズWi-Fi)において、セキュリティ担保やデバイス管理の観点からランダムMACを禁止したい場合、MDM(Mobile Device Management)等でプロファイル配信を行い、特定のSSIDに対して「プライベートWi-Fiアドレス(ランダムMAC)」を無効化する設定を行います。

iOS/iPadOS向けの構成プロファイル(.mobileconfig)の抜粋例を以下に示します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <!-- 企業用Wi-Fiネットワークの設定ペイロード -->
            <key>PayloadType</key>
            <string>com.apple.wifi.managed</string>
            <key>PayloadIdentifier</key>
            <string>com.example.corporate.wifi</string>
            <key>PayloadUUID</key>
            <string>A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>SSID_STR</key>
            <string>Corporate-Secure-Wi-Fi</string>
            <key>AutoJoin</key>
            <true/>
            <key>EncryptionType</key>
            <string>WPA2</string>
            <!-- プライベートMACアドレス(ランダム化)を無効化し、ハードウェアMACの使用を強制する -->
            <key>DisableAssociationMACRandomization</key>
            <true/>
        </dict>
    </array>
    <key>PayloadIdentifier</key>
    <string>com.example.profile.wifi-policy</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>F6E5D4C3-B2A1-9F8E-7D6C-5B4A3F2E1D0C</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

② 開発者向け:プローブ要求を模したシミュレーション・テストスクリプト(Python)

例えば、IoTゲートウェイやWi-Fi位置情報連携APIのバックエンドを開発している際、様々なMACアドレスパターンや不正なプローブ要求に対するAPIの耐性をテストしたい場合があるでしょう。

以下は、Pythonの requests ライブラリを用いて、ランダムに生成したMACアドレス(ローカル管理アドレスのビットパターンを含む)をヘッダーに付与し、APIサーバーへデバイスの状態を送信するテスト用のスクリプト例です。

import random
import requests
import json
import time

def generate_random_mac():
    """
    プライバシー保護を意識したランダムMACアドレスを生成する関数。
    IEEE 802の規約に基づき、ローカル管理アドレス(U/Lビットを1)として生成。
    """
    # 第1バイトの最下位から2ビット目を1にする (例: 0x02, 0x06, 0x0A, 0x0E など)
    first_byte = random.choice([0x02, 0x06, 0x0A, 0x0E])
    mac_bytes = [first_byte] + [random.randint(0x00, 0xFF) for _ in range(5)]
    return ":".join(f"{b:02x}" for b in mac_bytes)

def simulate_device_probe_api():
    """
    Wi-Fiスキャナーやエッジルーターから送信されるプローブ情報を模した
    Web APIへのPOSTリクエスト送信スクリプト
    """
    api_endpoint = "https://api.example.internal/v1/wifi/telemetry"
    
    # テスト用にダミーのデバイス情報を構築
    payload = {
        "timestamp": int(time.time()),
        "ap_bssid": "aa:bb:cc:dd:ee:ff",
        "rssi": random.randint(-85, -45),
        "probed_ssid": "Corporate-Guest-Wi-Fi",
        "client_mac": generate_random_mac() # ランダム化されたMACアドレスをシミュレート
    }
    
    headers = {
        "Content-Type": "application/json",
        "X-API-Key": "your-internal-service-secret-key"
    }
    
    try:
        # バックエンドのインgestion APIへデータを送信
        response = requests.post(api_endpoint, data=json.dumps(payload), headers=headers, timeout=5)
        
        if response.status_code == 200:
            print(f"[SUCCESS] MAC: {payload['client_mac']} のプログデータを正常に処理しました。")
        else:
            print(f"[WARNING] サーバーからの予期せぬ応答: {response.status_code} - {response.text}")
            
    except requests.exceptions.RequestException as e:
        print(f"[ERROR] API通信エラーが発生しました: {e}")

if __name__ == "__main__":
    print("--- Wi-Fiプローブ要求・ランダムMACシミュレーション開始 ---")
    # 連続して数回テストリクエストを送信
    for i in range(3):
        simulate_device_probe_api()
        time.sleep(1)

③ 運用者向け:パケットキャプチャによるプローブ要求のデバッグ(tshark)

現場で「本当にデバイスがランダムMACでプローブを飛ばしているか」「意図したSSIDを要求しているか」を調べるには、無線インターフェースをモニターモードにして tshark(WiresharkのCUI版)でキャプチャするのが最も確実です。

以下のコマンドは、無線インターフェース wlan0 を特定のチャネル(例: チャネル6)に固定し、プローブ要求フレーム(フレームサブタイプ: subtype probe-req)のみをフィルタリングしてリアルタイムにコンソールへ出力する実践的なコマンドです。

# 事前に無線インターフェースをモニターモードに変更しておく必要があります
# 例: sudo ip link set wlan0 down && sudo iw wlan0 set monitor control && sudo ip link set wlan0 up

tshark -i wlan0 \
  -Y "wlan.fc.type_subtype == 0x04" \
  -T fields \
  -e frame.time \
  -e wlan.sa \
  -e wlan.ssid \
  -e wlan_mgt.ds.current_channel

【出力の見方のTips】

  • wlan.sa(Source Address)に表示されるMACアドレスの第2文字に注目してください。2, 6, a, e といった文字が含まれている場合、それは見事にMACアドレスがランダム化されている証拠です。
  • wlan.ssid が空白になっている場合、それは特定のSSID名を指定せず、周囲すべてのAPをリストアップさせるためのワイルドカード・プローブ要求です。

—

まとめ

プローブ要求とMACアドレスランダム化の進化は、エンドユーザーのプライバシーを守る上で不可欠な技術的防衛策です。しかし、それに依存したネットワーク設計やレガシーな認証方式を採用しているインフラ、あるいは単純なMACアドレスベースのトラッキングを前提としたWebサービスや分析ツールは、根本的な設計変更を迫られています。

現場のエンジニアとして私たちが取るべきアプローチは、「MACアドレスが変わるという前提(Zero Trustな無線空間)」に立ち返り、認証にはIEEE 802.1XやWPA3-Enterprise、あるいは適切なWeb認証(Captive Portal)を組み合わせることです。

電波の飛び交う空間のルールを正しく理解し、堅牢でプライバシーに配慮したネットワーク・インフラを一緒に築き上げていきましょう。現場からは以上です!

コメント

タイトルとURLをコピーしました