Contents

ROS 控制网络访问

Contents

问题

在ROS里面有一个儿童访问功能,通过设置就可以控制每一个设备的上网时间,原理自然是设置防火墙,在设定时间端就把所有的网络drop掉。简单有效而且功能足够强大,因为所有的网络必须通过ROS主路由进行外网访问。但是在设定了不同的网关后,这个网络访问功能就会失效,原因是流量通过目标网关用masquarade的方式伪装了,这样ROS就不会认为这是来自于设限设备。 /router.png

解决方案

解决方案就是在防火墙生效的时候,自动把目标网关取消(DhcpOptionSet重制),恢复到默认ROS网关,这样就会继续接管这个设备的限制,具体代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
    # Get all the devices under "XXX" user
    :local kcUser "xxx";
    :foreach kcDevice in=[/ip kid-control device find where user=$kcUser] do={
        :local macAddress [/ip kid-control device get $kcDevice mac-address ];

        :local kcLease [/ip dhcp-server lease find where mac-address=$macAddress];
        :local ipAddress [/ip dhcp-server lease get $kcLease address];
        :local activeAddress [/ip dhcp-server lease get $kcLease active-address];
        :local deviceName [/ip dhcp-server lease get $kcLease comment];

        :if ([:len $activeAddress] > 0) do={
            :local firewallFilter  [/ip firewall filter find where chain="kid-control" and src-address=$activeAddress];

            # check if the firewall is enable now, which is configured under ip/kid-control 
            :if ([:len $firewallFilter] > 0) do={
                :local DhcpOptionSet "$[/ip dhcp-server lease get $kcLease dhcp-option-set]";
                :put ("Rejected by kidcontrolProxy: $deviceName:$activeAddress@$macAddress's OptionSet is \\"$DhcpOptionSet\\"");

                # Change the dhcp-option-set to empty if the firewall is enabled
                # Which will make the device to use the default gateway
                # So that the device's traffic will be controlled by ip/kid-control's firewall
                # otherwise, this device will go through the Proxy server so the ip/kid-control's firewall will not work
                :if ([:len $DhcpOptionSet] > 0) do={
                    /ip dhcp-server lease set $kcLease dhcp-option-set=;
                    :log warn ("Rejected by kidcontrolProxy: $deviceName:$activeAddress@$macAddress's OptionSet was \\"$DhcpOptionSet\\", now changed to: \\"$[/ip dhcp-server lease get $kcLease dhcp-option-set]\\"");
                }

            } else={
                :local DhcpOptionSet "$[/ip dhcp-server lease get $kcLease dhcp-option-set]";
                :put ("No kidcontrolProxy enabled: $deviceName:$activeAddress@$macAddress's OptionSet is \\"$DhcpOptionSet\\"");

                # if the ip/kid-control is not enabled, then the device should go through the Proxy server
                :local enableProxy [:pick $deviceName ([:len $deviceName]-3) [:len $deviceName]];
                
                # Using the (P) in the devicename to rollback the dhcp-option-set
                :if ($enableProxy = "(P)" and [:len $DhcpOptionSet] = 0) do={
                    :put ("kidcontrolProxy change to PROXY");
                    /ip dhcp-server lease set $kcLease dhcp-option-set="PROXY";
                    :log warn ("No kidcontrolProxy enabled: $deviceName:$activeAddress@$macAddress's OptionSet was \\"$DhcpOptionSet\\", now changed to: \\"$[/ip dhcp-server lease get $kcLease dhcp-option-set]\\"");
                    
                } 
                :if ($enableProxy != "(P)" and [:len $DhcpOptionSet] > 0) do={
                    :put ("kidcontrolProxy change to NULL");
                    /ip dhcp-server lease set $kcLease dhcp-option-set=;
                    :log warn ("No kidcontrolProxy enabled: $deviceName:$activeAddress@$macAddress's OptionSet was \\"$DhcpOptionSet\\", now changed to: \\"$[/ip dhcp-server lease get $kcLease dhcp-option-set]\\"");
                }
            }   
            
        } else={
            :local DhcpOptionSet [/ip dhcp-server lease get $kcLease dhcp-option-set];
            :put ("kidcontrolProxy Device is not active: $deviceName:$ipAddress@$macAddress's OptionSet was \\"$DhcpOptionSet\\"");
        }
    }
}