Эта новая логика гораздо понятнее и логичнее: сначала firewall принимает правила с нужными вам параметрами и в нужном количестве, а последнее правило — отклонить всё подряд. Моя домашняя настройка для контроля, могут ли дети пользоваться интернетом из любого места:
Я определил основные SSID для меня и жены, ТВ и устройств детей: MAIN, TV, KID1MOB, KID2MOB, KID1LAP, KID2LAP. MAIN с надёжным паролем, остальные — простым 12345678.
Добавил фильтры в wireless / access-list:
accept: mac:from_tv interface:TV
reject: interface:TV
accept: mac:kids_mobile interface:KID1MOB time:08-21
reject: interface:KID1MOB
и так далее...
То есть каждое устройство привязано к своему wifi-ssid, остальное отклоняется.
Добавил планировщик, срабатывающий каждые 5 минут:
/tool fetch url="https://user:pass@mywebpage.com/net/io.json"
/system script run dev
io.json выглядит так:
{"kid1mob":false,"kid1lap":false,"kid2mob":false,"kid2lap":false,"tv":true}
И написал скрипт с названием dev:
{
:local check [/file get io.json contents]; # в переменной удалены кавычки из json, получается вроде kid1mob:false
:local kid1mob_j [:pick $check ([:find $check "kid1mob" -1]+9)]; # ищем позицию "kid1mob" и берем символ через 9 позиций (t или f)
:local kid2mob_j [:pick $check ([:find $check "kid2mob" -1)+9)];
:local kid1lap_j [:pick $check ([:find $check "kid1lap" -1)+9)];
:local kid2lap_j [:pick $check ([:find $check "kid2lap" -1)+9)];
:local tv_j [:pick $check ([:find $check "tv" -1)+4)];
:local kid1mob_i [/interface get kid1mob disabled]; # переменная true, если интерфейс отключён
:local kid2mob_i [/interface get kid2mob disabled];
:local kid1lap_i [/interface get kid1lap disabled];
:local kid2lap_i [/interface get kid2lap disabled];
:local tv_i [/interface get TV disabled];
:if ( $kid1mob_j="t" && $kid1mob_i=true) do={/interface/wifiwave2/enable kid1mob}
:if ( $kid1mob_j="f" && $kid1mob_i=false) do={/interface/wifiwave2/disable kid1mob}
:if ( $kid1lap_j="t" && $kid1lap_i=true) do={/interface/wifiwave2/enable kid1lap}
:if ( $kid1lap_j="f" && $kid1lap_i=false) do={/interface/wifiwave2/disable kid1lap}
:if ( $kid2mob_j="t" && $kid2mob_i=true) do={/interface/wifiwave2/enable kid2mob}
:if ( $kid2mob_j="f" && $kid2mob_i=false) do={/interface/wifiwave2/disable kid2mob}
:if ( $kid2lap_j="t" && $kid2lap_i=true) do={/interface/wifiwave2/enable kid2lap}
:if ( $kid2lap_j="f" && $kid2lap_i=false) do={/interface/wifiwave2/disable kid2lap}
:if ( $tv_j="t" && $tv_i=true) do={/interface/wifiwave2/enable TV}
:if ( $tv_j="f" && $tv_i=false) do={/interface/wifiwave2/disable TV}
};
Почему так много проверок? Потому что если включать уже включённый WiFi, интерфейс всё равно переключается с выкл/вкл, а это не очень удобно.
Простая PHP-страница на моём хостинге, которая генерирует файл io.json:
index.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Internet access</title>
<meta>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body class="d-flex flex-column ng-cloak">
<div class="container py-2"><div class="row"><div class="col"><h2 class="font-weight-light">Internet</h2>
Настройте доступ в интернет
<?php
$json_file="io.json";
$kid1mob=$kid1lap=$kid2mob=$kid2lap=$tv=0;
$file = file_get_contents($json_file);
$json = json_decode($file, true);
$kid1mob=$json['kid1mob']!="" ;
$kid1lap=$json['kid1lap']!="" ;
$kid2mob=$json['kid2mob']!="" ;
$kid2lap=$json['kid2lap']!="" ;
$tv=$json['tv']!="" ;
?>
<form method="post" action="submit.php">
<div class="form-check form-switch"><input class="form-check-input" type="checkbox" role="switch" id="kid1mob" name="kid1mob" <?php if($kid1mob)echo "checked"; ?> /><label class="form-check-label" for="kid1mob">Мобильный у ребенка 1 может пользоваться интернетом</label></div>
<div class="form-check form-switch"><input class="form-check-input" type="checkbox" role="switch" id="kid1lap" name="kid1lap" <?php if($kid1lap)echo "checked"; ?> /><label class="form-check-label" for="kid1lap">Ноутбук у ребенка 1 может пользоваться интернетом</label></div>
<div class="form-check form-switch"><input class="form-check-input" type="checkbox" role="switch" id="kid2mob" name="kid2mob" <?php if($kid2mob)echo "checked"; ?> /><label class="form-check-label" for="kid2mob">Мобильный у ребенка 2 может пользоваться интернетом</label></div>
<div class="form-check form-switch"><input class="form-check-input" type="checkbox" role="switch" id="kid2lap" name="kid2lap" <?php if($kid2lap)echo "checked"; ?> /><label class="form-check-label" for="kid2lap">Ноутбук у ребенка 2 может пользоваться интернетом</label></div>
<div class="form-check form-switch"><input class="form-check-input" type="checkbox" role="switch" id="tv" name="tv" <?php if($tv)echo "checked"; ?> /><label class="form-check-label" for="tv">ТВ может пользоваться интернетом</label></div>
<div class="d-grid gap-2 col-6 mx-auto"><button class="btn btn-primary" type="submit">Применить</button></div>
</form></div></div></div></body></html>
И добавил action-скрипт submit.php:
<?php
$json_file="io.json";
$json=['kid1mob' => 0, 'kid1lap' => 0, 'kid2mob' => 0, 'kid2lap' => 0, 'tv' => 0 ];
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
$json=[
'kid1mob' => $_POST["kid1mob"]!="",
'kid1lap' => $_POST["kid1lap"]!="",
'kid2mob' => $_POST["kid2mob"]!="",
'kid2lap' => $_POST["kid2lap"]!="",
'tv' => $_POST["tv"] !=""
];
file_put_contents($json_file, json_encode($json));
}
?>
<!DOCTYPE html>
<html lang="en">
<meta http-equiv="Refresh" content="0; url='https://mywebpage.com/net'" />
<head></head><body></body></html>
Вот и всё, теперь мы с женой можем из любого места включать и отключать доступ в интернет каждому ребёнку и устройству через простую веб-страницу, страница защищена паролем через cPanel.