mcpField
R
routeros-hotspot

routeros-hotspot

github.com/tikociクラウド・DevOps8346 回インストール5 日前に更新
リポジトリ

routeros-hotspot について

ネットワーク管理者やエージェント向けのRouterOSホットスポット設定スキルです。キャプティブポータル、DHCP Option 114、証明書、認証と設定上の注意点を扱います。

主な機能

  1. 01ホットスポットのインスタンスとプロファイル設定
  2. 02DHCP Option 114の設定
  3. 03HTTPS証明書とログインページの設定
  4. 04IPおよびHTTPのウォールドガーデン管理
  5. 05RADIUSとIPv4の制約の説明

活用シーン

  1. 01HTTPSゲストログインポータルの導入
  2. 02クライアントへのキャプティブポータルURI通知
  3. 03外部認証ホストへのアクセス許可
  4. 04ホットスポットとRADIUS設定の調査

MCP 対応

READMEでは、RouterOSのコマンドツリー確認とドキュメントページ取得にrosetta MCPサーバーを利用できると説明されています。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tikoci/routeros-skills --skill routeros-hotspot

インストール後、Claude Code で/routeros-hotspotを入力して読み込まれたか確認します。

同梱ファイルreferences/radius-client.mdreferences/template-variables.md

詳細

RouterOS Hotspot

Hotspot チェーンの仕組み

Hotspot のトラフィックインターセプトは、通常のファイアウォールの input/forward チェーンよりも先に実行されます。これが、最も重要なポイントです。

  • /ip/hotspot はブリッジまたはインターフェースにバインドされ、そのインターフェース上のすべてのトラフィックが最初に Hotspot チェーンに入ります
  • Hotspot インターフェースからの TCP 80/443 をブロックするファイアウォールルールを設定しても、キャプティブポータルのログインページはブロックされません。ファイアウォールが確認する前に Hotspot が処理するためです
  • RouterOS は動的なファイアウォールルール(hs-unauth、hs-auth チェーン)を自動的に挿入します。これらの Hotspot 管理ルールを手動で作成、削除、または妨害しないでください

よくある間違い: セキュリティ上の問題を「修正」するために、bridge-hotspot からのポート 443 を DROP するルールを追加すると、HTTPS ログインページが気付かれないまま機能しなくなります。

Hotspot プロファイル

/ip/hotspot/profile/add \
  name=my-profile \
  hotspot-address=10.20.0.1 \
  login-by=https,mac,http-pap \
  mac-auth-mode=mac-as-username-and-password \
  dns-name=login.example.com \
  ssl-certificate=login.example.com.crt_0 \
  nas-port-type=ethernet \
  use-radius=yes \
  radius-accounting=yes \
  html-directory-override=hotspot-files

主なプロパティ:

  • ssl-certificate= — インポート後の名前を指定します(RouterOS はインポートした証明書名に _0 を付加します)
  • nas-port-type= — 有線 Hotspot には ethernet、無線 Hotspot には wireless-ieee-802-11-g を使用します
  • html-directory-override= — ルーターのファイルシステム上のフォルダー名と完全に一致させる必要があります
  • login-by=https — ログインページを HTTPS で提供します。同じ証明書を使用して www-ssl サービスを有効にする必要があります
  • use-radius=yes — 設定すると、ローカルの /ip/hotspot/user エントリーは無視されます。追加しても効果はありません

Hotspot インスタンス

/ip/hotspot/add \
  name=hotspot1 \
  interface=bridge-hotspot \
  profile=my-profile \
  address-pool=pool-hotspot \
  addresses-per-mac=2 \
  idle-timeout=5m \
  keepalive-timeout=none \
  disabled=no

注: keepalive-timeout=none は keepalive を無効にします。keepalive-timeout=0 は無効な値であり、無視されます。

注: RouterOS Hotspot は NAT に依存しており、IPv4 のみに対応しています。Hotspot サブシステムは IPv6 クライアントをサポートしていません。

DHCP オプション 114 — キャプティブポータル API(RFC 8910)

オプション 114(2020 年に標準化、RFC 8910)は、キャプティブポータルの URI をクライアントに通知します。LLM のトレーニングデータでは十分に取り上げられていません。

# force=yes is REQUIRED — without it, clients whose DHCP Parameter Request
# List does not include code 114 (e.g. iOS, Android) silently skip the option
/ip/dhcp-server/option/add \
  name=captive-portal \
  code=114 \
  force=yes \
  value="'https://login.example.com/api'"

/ip/dhcp-server/option/sets/add \
  name=captive-portal-set \
  options=captive-portal

/ip/dhcp-server/set my-dhcp-server dhcp-option-set=captive-portal-set

オプション値の構文: 外側は二重引用符、内側は一重引用符です — "'https://...'"。内側の引用符がないと、オプションは文字列 URI ではなくバイナリデータとして送信されます。

api.json のタイミング: RouterOS が hotspot/api.json を作成するのは、Hotspot の有効化時ではなく、最初のクライアント CAPPORT プローブの後です。最初のクライアントが接続した後、これを html-directory-override フォルダーに移動します。

# Handles both flash/ and non-flash storage layouts
:local srcPath "hotspot/api.json"
:local dstPath "hotspot-files/api.json"
:if ([:len [/file find name="flash"]] > 0) do={
  :set srcPath "flash/hotspot/api.json"
  :set dstPath "flash/hotspot-files/api.json"
}
:if ([:len [/file find name=$srcPath]] > 0) do={
  /file set [find name=$srcPath] name=$dstPath
} else={
  :log warning "api.json not yet created — run after first client CAPPORT probe"
}

Walled Garden

追加と削除を冪等にするため、一貫した comment= タグを使用します。タグがないと、スクリプトを繰り返し実行するたびにエントリーが重複して蓄積されます。

# Remove only our entries, not manually-added ones
/ip/hotspot/walled-garden/ip/remove [find comment="my-wg"]

/ip/hotspot/walled-garden/ip/add dst-host=example.com   action=accept comment="my-wg"
/ip/hotspot/walled-garden/ip/add dst-host=*.example.com action=accept comment="my-wg"

IP と HTTP の Walled Garden:

  • /ip/hotspot/walled-garden/ip — 宛先ホストをレイヤー 3 で照合し、認証前に適用されます。HTTPS の宛先にはこちらを使用します
  • /ip/hotspot/walled-garden — レイヤー 7 の URL パターン照合を行い、HTTP が必要です。HTTPS では機能しません

SSL 証明書に関する注意

Hotspot プロファイルでは ssl-certificate=name.crt_0 を指定します(RouterOS はインポート時に _0 を付加します)。同じ証明書を使用して www-ssl を有効にします。

/ip/service/set www-ssl disabled=no certificate=login.example.com.crt_0 tls-version=only-1.2

簡単なインポート方法:

/certificate import file-name=login.example.com.crt passphrase=""
/certificate import file-name=login.example.com.key passphrase=""
# After import, the certificate appears as login.example.com.crt_0

外部キャプティブポータル — HTML テンプレート変数

RouterOS は、html-directory-override 配下のファイルを配信する前に、サーバー側で $(variable) を置換します。これらは JavaScript 変数ではありません。ブラウザーがページを受け取る前に値が設定されます。

外部キャプティブポータルの設定では、通常 login.html、alogin.html、status.html を上書きします。サーブレットページの完全な一覧、POST フィールド、RADIUS パススルー変数、多言語対応の target= の仕組み、HTTP レスポンス制御の構文については、references/template-variables.md を参照してください。

ログイン POST エンドポイントには $(link-login-only) を使用し、元の宛先を dst で渡します。また、URL やクエリ文字列に値を埋め込む場合は、必ず $(link-orig-esc)、$(mac-esc)、$(username-esc) などのエスケープ済みの形式を選んでください。値に &、=、?、# が含まれると、エスケープされていない形式では解析に失敗したり、インジェクションの経路が生じたりする可能性があります。

条件構文(サーバー側で処理され、JavaScript ではありません):

$(if logged-in == "yes")
  <a href="$(link-logout)">Logout</a>
$(else)
  <form action="$(link-login-only)" method="post">...</form>
$(endif)

演算子:存在判定($(if VAR))、==、!=。また、$(elif ...) も使用できます。算術演算や文字列演算のネストには対応していません。

外部キャプティブポータル向けの汎用的な login.html パターン:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="pragma" content="no-cache">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  <script src='https://auth.example.com/snippets/router-os/redirect'></script>
</head>
<body>
  <div id="entryPoint">Redirecting...</div>
  <script>
    window.addEventListener('load', function () {
      ExternalAuth_redirect(
        '$(server-name)', '$(mac-esc)', '$(link-login-only)',
        '$(link-orig-esc)', '$(error-orig)', '$(logged-in)', '$(ip)'
      );
    });
  </script>
</body>
</html>

外部プロバイダーがユーザーを認証し、username、password、dst の POST フィールドを付けてブラウザーを $(link-login-only) にリダイレクトします。RouterOS はローカルデータベースまたは RADIUS で検証し、認証クッキーを発行して、dst にリダイレクトします。

ウォールドガーデンには、外部認証ホスト(および CDN/アセットの各ホスト)を含める必要があります。含めない場合、未認証のブラウザーは手順 2 のリダイレクトスクリプトにアクセスできません。

LLM によくある誤り

誤り正しい動作
ホットスポットインターフェイスからの TCP 443 を DROP するホットスポットチェーンはファイアウォールより前に実行されるため、HTTPS ログインページが機能しなくなります
キープアライブを無効にするために keepalive-timeout=0 を指定するkeepalive-timeout=none を使用します
内側のシングルクォートなしでオプション 114 の value= を指定する"'https://...'" のように、外側はダブルクォート、内側はシングルクォートにする必要があります
オプション 114 に force=yes を指定しないDHCP PRL にないオプションは iOS/Android が黙って無視します
use-radius=yes のときに /ip/hotspot/user を追加するRADIUS が有効な場合、ローカルユーザーは使用されません
/ip/hotspot/walled-garden で HTTPS ドメインにワイルドカードを使うHTTPS には /ip/hotspot/walled-garden/ip を使用します(レイヤー 3 での一致)
IPv6 を使用するデュアルスタックネットワークでホットスポットを使うホットスポットは IPv4 のみ対応で、IPv6 はサポートされていません
$(link-login) を JavaScript 変数として扱うJS ではなく、RouterOS によるサーバー側置換です
$(link-orig)/$(mac)/$(username) を別の URL に埋め込む-esc 形式を使用します。エスケープされていない形式は &、=、? で解析に失敗したり、インジェクションを可能にしたりすることがあります
PCC/複数ルーティングテーブルを使用してホットスポットを構成するホットスポットはデフォルトのルーティングテーブルのみを使用します。WAN を分割する構成では、ホットスポットトラフィックに明示的な /ip route rule が必要です

追加リソース

関連スキル:

  • routeros-fundamentals — RouterOS CLI 構文、REST API、スクリプトの基礎
  • routeros-certificates(バックログ) — 証明書チェーンの完全な処理パターン

MCP ツール:

  • rosetta MCP サーバー — /tool/ping、/ip/hotspot コマンドツリーの調査(routeros_search、routeros_get_page)

MikroTik のドキュメント:

RADIUS 統合

RADIUS クライアント設定パターンについては、references/radius-client.md を参照してください。

コメント