routeros-hotspot について
ネットワーク管理者やエージェント向けのRouterOSホットスポット設定スキルです。キャプティブポータル、DHCP Option 114、証明書、認証と設定上の注意点を扱います。
主な機能
- 01ホットスポットのインスタンスとプロファイル設定
- 02DHCP Option 114の設定
- 03HTTPS証明書とログインページの設定
- 04IPおよびHTTPのウォールドガーデン管理
- 05RADIUSとIPv4の制約の説明
活用シーン
- 01HTTPSゲストログインポータルの導入
- 02クライアントへのキャプティブポータルURI通知
- 03外部認証ホストへのアクセス許可
- 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 ツール:
rosettaMCP サーバー —/tool/ping、/ip/hotspotコマンドツリーの調査(routeros_search、routeros_get_page)
MikroTik のドキュメント:
- HotSpot — 公式リファレンス
- DHCP Server — オプション 114 の設定
RADIUS 統合
RADIUS クライアント設定パターンについては、references/radius-client.md を参照してください。