mcpField
R
routeros-hotspot

routeros-hotspot

github.com/tikoci云与 DevOps8346 次安装5 天前更新
代码仓库

关于 routeros-hotspot

面向 RouterOS 网络管理员与 Agent 的热点配置参考,讲解认证门户、DHCP Captive Portal API、证书和访客网络放行规则。内容聚焦容易配置错误的行为与排查要点。

主要功能

  1. 01配置热点实例与配置文件
  2. 02设置 DHCP Option 114
  3. 03配置 HTTPS 证书与登录页
  4. 04管理 IP 与 HTTP 放行规则
  5. 05说明 RADIUS 与 IPv4 限制

适用场景

  1. 01部署带 HTTPS 的访客登录门户
  2. 02向客户端通告 Captive Portal 地址
  3. 03为外部认证站点配置网络放行
  4. 04排查热点与 RADIUS 配置问题

MCP 相关

README 提及 rosetta MCP 服务,可用于检查 RouterOS 命令树并查询相关页面。

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/routeros-hotspot确认已加载。

附带文件references/radius-client.mdreferences/template-variables.md

详细介绍

RouterOS 热点

热点链的工作方式

热点流量拦截发生在常规防火墙 input/forward 链之前。这是最重要的一点:

  • /ip/hotspot 绑定到网桥或接口——该接口上的所有流量都会先进入热点链
  • 防火墙规则中阻止来自热点接口的 TCP 80/443 流量,不会阻止强制门户登录页面——热点会在防火墙看到流量之前处理它
  • RouterOS 会自动注入动态防火墙规则(hs-unauth、hs-auth 链)——不要手动创建、删除或干扰这些由热点管理的规则

**常见错误:**为“修复安全漏洞”而添加一条阻止来自 bridge-hotspot 的 443 端口流量的 DROP 规则——这会导致 HTTPS 登录页面悄无声息地失效。

热点配置文件

/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= — 有线热点使用 ethernet,无线热点使用 wireless-ieee-802-11-g
  • html-directory-override= — 必须与路由器文件系统上的文件夹名称完全一致
  • login-by=https — 通过 HTTPS 提供登录页面;需要启用 www-ssl 服务,并使用同一证书
  • use-radius=yes — 启用后,本地 /ip/hotspot/user 条目会被绕过;添加这些条目不会产生任何效果

热点实例

/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 热点依赖 NAT,且仅支持 IPv4。热点子系统不支持 IPv6 客户端。

DHCP 选项 114 — 强制门户 API(RFC 8910)

选项 114(于 2020 年标准化,RFC 8910)会向客户端指示强制门户 URI。在大模型训练数据中,它的相关信息并不多见。

# 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 仅在第一个客户端 CAPPORT 探测后才创建 hotspot/api.json,而不是在启用热点时创建。第一个客户端连接后,将其移至 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"
}

围墙花园

使用一致的 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 围墙花园:

  • /ip/hotspot/walled-garden/ip — 根据目标主机进行第 3 层匹配,在身份验证前应用。用于 HTTPS 目标。
  • /ip/hotspot/walled-garden — 根据第 7 层 URL 模式进行匹配,需要 HTTP。对 HTTPS 不起作用。

SSL 证书说明

热点配置文件引用 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。完整的 servlet 页面列表、POST 字段、RADIUS 透传变量、多语言 target= 机制以及 HTTP 响应控制语法,请参阅 references/template-variables.md。

将 $(link-login-only) 用作登录 POST 端点,通过 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>

外部提供方对用户进行身份验证,然后将浏览器重定向回 $(link-login-only),并使用 username + password + dst POST 字段。RouterOS 会进行验证(本地数据库或 RADIUS),签发身份验证 Cookie,并重定向到 dst。

围墙花园必须包含外部身份验证主机(以及任何 CDN/资源主机)——否则,未通过身份验证的浏览器将无法访问步骤 2 中的重定向脚本。

LLM 常见错误

错误正确做法
从热点接口 DROP TCP 443热点链在防火墙之前运行——这会导致 HTTPS 登录页面无法使用
使用 keepalive-timeout=0 禁用 keepalive使用 keepalive-timeout=none
Option 114 的 value= 缺少内部单引号必须是 "'https://...'"——外部用双引号,内部用单引号
Option 114 未设置 force=yes如果选项不在 iOS/Android 的 DHCP PRL 中,系统会静默跳过该选项
在 use-radius=yes 时添加 /ip/hotspot/userRADIUS 启用时会绕过本地用户
在 /ip/hotspot/walled-garden 中使用通配符 HTTPS 域名HTTPS 使用 /ip/hotspot/walled-garden/ip(第 3 层匹配)
在包含 IPv6 的双栈网络上运行热点热点仅支持 IPv4——不支持 IPv6
将 $(link-login) 当作 JavaScript 变量这是 RouterOS 服务器端替换,而非 JS
将 $(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。

评论

支持 Markdown