news 2026/9/19 1:48:12

RouterOS家庭网络内容过滤实战:从DNS黑洞到L7三层拦截

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RouterOS家庭网络内容过滤实战:从DNS黑洞到L7三层拦截

孩子在浏览器里点开一个链接,页面加载完之前又迅速切走,你走近时只看到一片纯白的标签页。这个场景很多家长都经历过。我之前也试过在电脑上装各种家长控制软件,结果要么被卸载得干干净净,要么换一个浏览器就能绕过,最后真正解决问题的,是在路由器层面动手。今天要说的就是基于 RouterOS 的家庭网络内容过滤方案,不依赖任何终端软件,只需要在网关设备上做几层配置。

1. 为什么路由层面拦截是家长的“最佳落点”

1.1 终端上装软件,为什么总漏

先说说我踩过的坑。电脑装管家类软件或家长控制软件,最大的问题是:软件运行在孩子使用的设备上,孩子对这台设备有完全的控制权。只要知道怎么退出进程、怎么绕过自启、换一个绿色版浏览器,规则就等于摆设。就算软件做得再隐蔽,设备的账号权限掌握在孩子手里,破除只是时间问题。

而平板、手机这类移动设备更麻烦,每个平台都要单独装一套管理端,有时候还要注册家庭共享账号,孩子改了 Apple ID 密码或者把系统恢复出厂,所有配置全部归零。更崩溃的是智能电视、游戏机、学习机这类设备,很多根本装不了第三方管控软件。所以终端的拦截方案,天然就漏掉一大片。

1.2 RouterOS 当网关,天然做到“统一扫黑”

RouterOS 是 MikroTik 路由器上跑的网络操作系统,也因为常用它做软路由,所以被很多人当作高级路由器的代名词。它和普通家用路由器最大的区别是:所有流量都从它这里过,而且你能在流量的不同处理阶段插手。这就决定了,只要把限制规则做在路由器上,全家设备一视同仁。

孩子设备开机、连 WiFi、发请求,无论是什么品牌的手机、平板、笔记本,流量都必须经过路由器。终端上的家长控制软件可以不装、可以卸载,但想绕过路由器,除非换一个网络环境,否则很难。等于在家庭网络入口处修了一道闸门,所有设备和所有请求,都从这道闸门过。

1.3 三层拦截框架:先知道自己要做什么

RouterOS 的内容过滤不是一个功能,而是一套组合拳。我后来把方案固定成三个层面:

  • DNS 层:域名解析阶段直接让坏域名“查不到”,这是性价比最高的一层。
  • L7 内容层:通过正则匹配流量特征,把漏网的域名和关键词拦掉。
  • 防火墙层:基于地址列表、MAC 和设备 IP,做丢弃、拦截和时间段控制。

这三个层面解决的问题不一样。DNS 层负责把绝大多数不良站点提前消灭在解析阶段;L7 层负责兜底那些绕过 DNS 的流量;防火墙层管的是设备和时间维度,让规则只在孩子设备上生效、在规定时间段内生效。这篇文章我按这个顺序一步步讲完整。

2. 搭建前先理清网络拓扑:RouterOS 放在哪个位置才拦得住

2.1 三种常见放法,选一种适合你的

RouterOS 不是买来插上就完事,你得先决定它在家庭网络里扮演什么角色。

第一种:RouterOS 做主路由。光猫改桥接,RouterOS 直接拨号上网,家里所有设备都在它下面。这是最彻底、效果最好的方案,所有流量必经 RouterOS,所有规则天然覆盖全家。缺点是如果光猫是运营商定制版,改桥接需要找运营商问清楚。

第二种:RouterOS 做二级路由器。运营商光猫继续当主路由,把 RouterOS 的 WAN 口接在主路由的 LAN 口下,孩子的所有设备接到 RouterOS 的 LAN 口。这种改动最小,路由器设置出错也不会影响全家网络,但会多一层 NAT。

第三种:RouterOS 做旁路网关。如果主路由不好动,还可以把 RouterOS 设置成旁路由模式,LAN 口和主路由在同一网段,比如主路由是 192.168.1.1,RouterOS 设成 192.168.1.2,需要管控的设备把网关和 DNS 手动改成 192.168.1.2。优点是现有网络完全不动,缺点是只对手动指定了网关的设备生效。

我个人建议,家里动手能力强、路由设备也支持的话,直接上第一种;如果只是临时改造,第三种的“旁路模式”最实用,后面我会给旁路模式单独提几条注意事项。

2.2 最容易被忽略的基础工程:让所有设备都走路由器解析

无论哪种拓扑,都必须保证设备的 DNS 请求到 RouterOS 上来。因为第一道拦截线就是 DNS,设备如果绕开了路由器自带的 DNS,后面的域名黑名单就全失效了。

典型的基础配置是这样的:

/ip address add address=192.168.8.1/24 interface=bridge_lan /ip dhcp-server setup /ip dns set servers=119.29.29.29,223.5.5.5 allow-remote-requests=yes

allow-remote-requests=yes这一条最关键。它允许局域网设备向 RouterOS 发起 DNS 查询,否则路由器不会响应来自 LAN 的 53 端口请求。

DHCP 服务也要把下发的 DNS 地址指到 RouterOS 自己的 LAN IP 上。这样设备拿到 IP 后,DNS 天然指向路由器,后续规则才能覆盖到。

2.3 旁路模式的两个附加条件

如果你选了旁路模式,有两个坑必须先排掉。第一,主路由的 DHCP 下发的网关和 DNS 要改成旁路由的 IP,否则设备不会把流量交给 RouterOS;第二,如果主路由开启了 DHCP 冲突检测、或者开启了 DHCP 防护,这些功能会干扰旁路由工作,建议在主路由上把相应开关关掉,或者改用手动指定孩子设备的网关和 DNS。

旁路模式下还有个隐藏问题:因为设备的默认网关是主路由,RouterOS 有可能只收到 DNS 流量,但收不到完整的上网流量,这会导致后面基于 IP 和地址列表的过滤规则失效。所以旁路模式最稳的组合是“手动指定设备的 DNS 到 RouterOS + 把设备的网关也手动指定到 RouterOS”,让管控设备在逻辑上跟着 RouterOS 走。

3. 第一道拦截线:DNS 黑洞,把坏域名“提前蒸发”

3.1 思路并不复杂:让域名解析到一个假地址

大多数不良网站在电脑上出现,第一步都是域名解析。你输入一个域名,系统去问 DNS:这个域名对应哪个 IP?DNS 回答后,浏览器才去连接那个 IP。

RouterOS 的做法就是把黑名单域名的解析结果直接“掉包”。对局域网设备来说,这些域名也会返回一个 IP,但返回的是一个不会到达任何真实服务器的黑洞地址。设备连过去必然是失败,效果上等于“域名被封了”。

典型的黑洞地址可以用一个不会和正常内网冲突的保留地址,比如 10.255.255.254。我在实际配置里用的是:

/ip dns static add name=www.bad-example.com address=10.255.255.254 comment=ban

添加之后,任何一个通过 RouterOS 做 DNS 解析的设备,查询www.bad-example.com都会得到10.255.255.254。这一步完成后,即使流量本身是加密的 HTTPS,也照样被拦住,因为 HTTPS 连接发起前也得先做 DNS 解析,解析失败后面全免谈。

3.2 黑洞 IP 也要配一条防火墙兜底

有人测试时会说:解析的确变成了 10.255.255.254,但浏览器转圈转很久才报错。这个问题就是因为黑洞地址是真实存在的,设备真的去尝试建立 TCP 连接了,一直等到超时才放弃。

解决办法是加一条防火墙规则,把发往黑洞地址的流量直接丢掉或拒绝。我习惯用reject,这样客户端立刻就能收到网络不可达的提示,浏览器会马上显示无法访问,而不是傻等几秒钟。

/ip firewall address-list add list=blackhole address=10.255.255.254 /ip firewall filter add chain=forward dst-address=10.255.255.254 action=reject reject-with=icmp-admin-prohibited log=yes log-prefix=blackhole

加了这条规则后,设备一旦尝试连接黑洞 IP,RouterOS 会直接用 ICMP 消息回复“此操作被禁止”,浏览器响应速度飞快。

3.3 批量灌入黑名单:手工不是长久之计

一个域名一个域名去/ip dns static add也能用,但维护成本太高。实际管理的做法是批量导入。

我的做法是在一台内网服务器上维护一个文本文件,里面每一行格式都是一条 RouterOS 命令:

/ip dns static add name=bad1.com address=10.255.255.254 comment=ban /ip dns static add name=bad2.com address=10.255.255.254 comment=ban

第三方域名黑名单来源很多,可以用脚本清洗后统一加comment=ban。然后把文件放到 RouterOS 能访问的 HTTP 服务上。RouterOS 上用两条命令就能完成更新:

/tool fetch url="http://192.168.1.10/blacklist.rsc" dst-path=blacklist.rsc /import file-name=blacklist.rsc

关键问题在于重复导入会产生重复条目,所以每次导入前要把旧的 ban 条目清掉:

/ip dns static remove [find where comment="ban"] /import file-name=blacklist.rsc

这个清旧再导入的过程,用一个/system script包起来,再用/system scheduler定时每天凌晨执行一次,黑名单就能自动保持更新。配合夜里的低峰期,既不影响家人上网,又能保证第二天规则是最新的。

3.4 为什么只靠 DNS 不够

DNS 拦截虽然高效,但它管不住两种流量。

第一种是“不走路由器 DNS”的流量。孩子设备如果手动把 DNS 改成 114.114.114.114、223.5.5.5 这类公共 DNS,域名解析请求就不经过 RouterOS,第一道线直接失效。第二种是客户端和 DNS 服务器之间的“加密 DNS”功能。部分想开小差的设备,会在系统设置里开启自带的安全 DNS,然后域名解析请求就变成加密流量了,普通路由器也看不懂它到底查询了什么域名。

这两类漏网情况,第一道 DNS 线完全束手无策。所以我会在后面第四部分专门讲 L7 层面的兜底,再在后面第六部分讲怎么从防火墙层面强制 DNS 必须走路由器。

4. 第二道拦截线:L7 内容过滤与 HTTPS SNI 识别

4.1 Layer7 是怎么“看”一条连接的

RouterOS 的 layer7-protocol 功能,简单来说就是给每个 TCP 连接的前几个数据包做“预检”,用正则表达式匹配载荷内容。如果匹配,这个连接就被打上特定标记,后续防火墙可以针对这个标记做动作。

这和我们平时说的“防火墙”不在一个层面。传统防火墙只看 IP、端口、协议,属于“网络层”;L7 是深入到数据内容的“应用层”检测。对应到实际场景,孩子访问http://www.bad-example.com/page.html,HTTP 请求头里会带着完整的域名和路径,L7 正则能在明文流量里直接抓到特征。

所以我给 L7 的定位是:DNS 层没拦住、或者域名没进黑名单的情况下,L7 仍然能根据流量内容完成拦截,算第二道保险。

4.2 一个实际可用的 L7 正则案例

定义 L7 规则很简单:

/ip firewall layer7-protocol add name=block-bad regexp="^.+(bad-example\\.com|example-bad\\.org).*"

然后在防火墙规则里引用它:

/ip firewall filter add chain=forward src-address-list=children protocol=tcp dst-port=80,443 layer7-protocol=block-bad action=drop log=yes log-prefix=l7-block

这里做了两件值得注意的事。第一,加了src-address-list=children,让规则只对孩子设备生效,避免误伤成年人的正常上网;第二,限制了protocol=tcp dst-port=80,443,因为 L7 匹配需要消耗 CPU,限制端口后能显著减小性能压力。

正则本身不要写太长,RouterOS 对 L7 正则有性能上限,一条规则里塞上几十个关键词,设备 CPU 会明显升高。我的习惯是一条 L7 规则只针对一小类站点,宁可多建几条规则,也不要写“万能大正则”。

4.3 HTTPS 加密后,SNI 过滤能做什么

现在的网站越来越多上了 HTTPS,HTTP 层的内容被 TLS 加密,L7 正则看不到 URL 路径了。但 TLS 握手的第一个包(ClientHello)里有一个字段叫 SNI,里面明文包含了客户端要连接的域名。

换句话说,虽然我看不到你访问的具体文章页面,但我知道你连接的是哪个域名。靠这个字段,就能在 TLS 握手阶段把连接掐掉。

RouterOS 上可以做类似的 SNI 匹配,正则写法大概是:

/ip firewall layer7-protocol add name=tls-sni-block regexp="^\\x16\\x03.*(bad-example\\.com|example-bad\\.org)" /ip firewall filter add chain=forward src-address-list=children protocol=tcp dst-port=443 layer7-protocol=tls-sni-block action=drop log=yes log-prefix=sni-block

正则里的\x16\x03是 TLS ClientHello 的开头标志,后面的.*(域名)才是真正要匹配的目标。

我必须提醒:这条规则会让 RouterOS 去检查每一个到 443 端口的 TCP 流,如果路由器本身性能一般,全家设备都跑 443 流量时 CPU 可能会飙高。因此这条规则同样要绑src-address-list=children,只对需要管控的孩子设备开启。我在实际部署中只用它覆盖孩子的常用设备,绝不对整网开启。

4.4 L7 也是有限制的

L7 正则不是万能的。RouterOS 的 L7 只能匹配流的前几个数据包,如果连接建立后内容才发生变化,它看不见;如果负载里没有任何文本特征而是纯二进制,正则也很难匹配。另外正则匹配错误带来的误杀通常比漏过更麻烦。我见过有人用“sex”这类单词做正则,结果把很多正常讨论人体健康、或是教育科普类的网站全部拦了,搞得家里鸡飞狗跳。

所以 L7 在家庭场景里的定位只能是“补充手段”,主拦截还是要靠 DNS 黑名单这种确定性强的规则。

5. 第三道拦截线:address-list、MAC 绑定与上网时间自动切换

5.1 先把设备分好组:address-list 的真正用法

家庭网络里最容易被忽视的是“规则作用对象”。很多父母从网上找到一条过滤规则,加进 RouterOS 后,发现全家人的网络都变得乱七八糟,原因就是规则没有限定设备。

RouterOS 里有一个非常好用的对象管理工具:地址列表(address-list)。它相当于一个动态分组,你可以把孩子的设备 IP 加进children列表,把大人设备加进parents列表,然后防火墙规则只需要写src-address-list=children,后续不管孩子设备换到哪个 WiFi 网段,规则都自动生效。

添加成员的命令:

/ip firewall address-list add list=children address=192.168.8.50 add list=parents address=192.168.8.2

这个分组思路要在一开始就设计好。后面所有 DNS 过滤、L7 过滤、时间控制规则,统一引用children这个列表,逻辑非常干净。

5.2 用 DHCP 静态租约把规则钉死

孩子的设备 IP 如果经常变,地址列表就形同虚设。所以需要给孩子的设备绑定固定 IP,RouterOS 里叫做 DHCP 静态租约。

先看当前设备拿到的 IP 和 MAC:

/ip dhcp-server lease print

找到孩子设备对应的那条记录,然后把它转成静态租约:

/ip dhcp-server lease make-static [find where mac-address=XX:XX:XX:XX:XX:XX]

之后这台设备每次连网都会拿到同一个 IP。这样children地址列表里的 IP 就是稳定的,防火墙规则也就稳定了。

用 MAC 地址直接做规则的思路也有,但注意如果你的 RouterOS 是旁路模式、或者中间有 NAT 设备,MAC 地址在跨三层时会被替换,规则就不准了。相比之下,DHCP 静态租约配合 IP 地址列表是最稳的方案。

5.3 定时规则:到点断网比“看见孩子关不掉”更有效

内容过滤只解决“能不能访问”,上网时长是另一回事。RouterOS 防火墙规则自带time参数,可以直接按时间段匹配。

我的典型配置是晚上十点到第二天早上七点,孩子设备断网:

/ip firewall filter add chain=forward src-address-list=children action=drop time=22:00:00-23:59:59 comment="night block part1" add chain=forward src-address-list=children action=drop time=00:00:00-07:00:00 comment="night block part2"

时间范围跨午夜的时候,我建议还是拆成两条规则写,避免不同版本 RouterOS 对跨午夜时间段的解析不一致。这两条规则放在防火墙 filter 规则列表的最前面,并且不在前面放任何针对children的放行规则,否则会被提前放行。

除了断网,还可以用调度脚本实现更精细的“作业模式”。比如下午四点到六点是学习时间,只允许访问学习类域名,其他全部拒绝。可以先在/system scheduler里建一个脚本任务,到点自动往children列表里临时加入一个“学习期”状态,由一条防火墙规则读取这个状态来放行或拦截。脚本本身不难,关键是规则顺序别搞混,RouterOS 的 firewall filter 是按顺序从上到下匹配的,第一条命中的规则生效,后面的不再看。

6. 上线前的验证与日常排障:确认规则真的在拦

6.1 三步验证法:nslookup、防火墙计数器、浏览器实测

配置完成不能拍拍手就完事,至少要做三轮验证。

第一轮,验证 DNS 解析。在设备上执行:

nslookup www.bad-example.com

如果返回结果是 10.255.255.254,说明 DNS 层的黑洞规则生效;如果返回的是真实 IP,说明设备没有走 RouterOS 的 DNS。此时先检查设备的 DNS 设置,再检查 RouterOS 的allow-remote-requests是否开启。

第二轮,验证防火墙规则有没有被命中。在 RouterOS 上:

/ip firewall filter print stats

注意观察黑名单相关规则的packets计数。如果访问过程中 packets 在上涨,说明规则被触发了。如果一直是 0,要么规则顺序不对,要么流量类型不匹配。

第三轮,浏览器实测。在孩子设备上打开被屏蔽的域名,正确的表现是:页面立即报“无法访问此网站”或者“连接已重置”,而不是等待十几秒后超时。能迅速失败,说明 reject 兜底规则也在正常工作。

6.2 日志里如何看到“试探行为”

RouterOS 的日志体系虽然不如商业上网行为管理设备那么华丽,但也足够用。只要在防火墙规则里加了log=yes log-prefix=blackhole,每次命中规则就会产生一条日志。

查看方式:

/log print

在输出中筛选blackholel7-blocksni-block这些关键词,就能看到哪些域名被拦截、来自哪个源 IP。这个信息量其实已经很大了,不需要额外安装任何流量审计插件。

我个人的做法是只保留拦截日志,不记录完整的上网历史。拦截日志能告诉我“孩子今天有哪些不该有的访问企图”,但又不会一步步记录他去过哪些正常网站,给孩子留一点空间。

6.3 常见漏网原因和对策

设备绕过了路由器 DNS。这是最常见的问题。孩子如果手动把 IP 设置里的 DNS 改成公共 DNS,第一道线就失效。要在防火墙里加一条“DNS 锁定”规则:允许孩子设备访问 RouterOS 自己的 53 端口,但禁止孩子设备访问其他任何 53 端口。

/ip firewall filter add chain=forward src-address-list=children dst-address=192.168.8.1 protocol=udp dst-port=53 action=accept add chain=forward src-address-list=children protocol=udp dst-port=53 action=drop add chain=forward src-address-list=children protocol=tcp dst-port=53 action=drop

注意顺序:先放行到路由器 DNS 的请求,再丢弃其他 DNS 请求。这样孩子设备就算手动填了公共 DNS,请求也会在路由器上被丢掉。

IPv6 没管。如果家里开了 IPv6,而 RouterOS 只配了 IPv4 防火墙规则,孩子设备很可能通过 IPv6 绕过所有 IPv4 层面的封堵。我建议在规则没有完全覆盖 IPv6 之前,先关闭孩子设备的 IPv6,或者在 RouterOS 的 IPv6 防火墙里复制一套同样的规则。

孩子用手机流量上网。这种情况路由层面管不到,只能靠运营商侧的管理功能或者手机系统自带的家庭控制。RouterOS 能覆盖的是家庭 WiFi 和有线网络,不是全世界。

7. 维护半年后我才明白的几件事

这套方案上线之后,不是一劳永逸。用下来的体会是:黑名单更新频率,比规则本身更重要。我刚开始时把所有精力都放在研究正则和防火墙语法上,后来发现真正起长期作用的,是那个每晚自动拉取黑名单、清旧条目、再导入的脚本。网站列表每天都在变,不更新就会慢慢失效。

第二点体会是“规则宜精不宜多”。RouterOS 功能太强,很容易陷入“越配越复杂”的陷阱。我见过有人给一台家庭用软路由搞了上百条防火墙规则,最后自己都分不清哪条先哪条后,一次误配置把全家网络搞瘫。实战中,DNS 黑名单 + 孩子设备分组 + 时间断网这三样东西已经能覆盖 90% 的诉求,L7 和 SNI 过滤属于锦上添花。

第三点,不要试图把路由器变成监控工具。我知道有些家长想知道孩子浏览了全部内容,但从家庭关系的角度,这种监控一旦被孩子发现,反弹会非常严重。我现在的做法是只保留拦截日志,不看全部访问记录。保证安全的同时,也保留最基本的信任。

最后提醒一句很重要的:RouterOS 是一台路由器,不是一个万能的安全盒子。如果孩子设备本身的系统有漏洞、或者被安装了恶意软件,路由器层面只管住流量,管不住终端上的问题。所以设备系统的自动更新、账户权限管理这些基本功,一样都不能丢。路由器上的这些过滤规则,只是家庭网络防护体系里的一道闸门,不是唯一一道。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 1:46:03

电子政务运维经费测算:从资产台账到财政评审的完整路径

简介:深圳市电子政务项目运行维护经费指导意见(2007年发布)是一份供有关部门编制电子政务运维预算时参照的官方标准文件,旨在规范运维经费测算与申报流程。包内共1个PDF文件,大小约70KB,完整收录了《深圳市…

作者头像 李华
网站建设 2026/9/19 1:40:52

MCP、Skill、Plugin 别再混用:Agent 扩展的三层选型与协作

上周有个做后端的哥们儿在群里问,他想让手里的 agent 能查公司内部接口文档,顺带按团队规范生成代码。有人让他写 MCP,有人说写个 Skill 就够了,还有人直接甩了篇 Plugin 开发教程过来。三份文档他都看了,结果比看之前…

作者头像 李华
网站建设 2026/9/19 1:39:47

Windows下Maven环境变量配置与mvn命令不被识别排查指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 1:37:55

轮式机器人直线控制:陀螺仪+PID航向闭环实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华