source: trunk/Modules/NetworkConfigRouterOS/Generators/FirewallMangle.php@ 870

Last change on this file since 870 was 870, checked in by chronos, 5 years ago
  • Added: IPv6 mangle firewall configuration.
File size: 12.3 KB
Line 
1<?php
2
3class ConfigRouterOSFirewallMangle extends NetworkConfigItem
4{
5 function ProcessNode($Node)
6 {
7 global $InetInterface, $ItemsFirewall;
8
9 foreach($Node['Items'] as $Index => $Item)
10 {
11 if(count($Item['Items']) == 0)
12 {
13 // Hosts
14 $ParentSubnetId = GetSubgroupByRange($Node['Address']->AddressToString().'/'.$Node['Address']->Prefix);
15 $Address = $Item['Address']->AddressToString();
16 if($Item['Address']->Prefix != 32) $Address .= '/'.$Item['Address']->Prefix;
17
18 $PacketMark = GetMarkByComment($Item['Name'].'-out');
19 $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-out', 'src-address' => $Address, 'out-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Item['Name'].'-out');
20 $PacketMark = GetMarkByComment($Item['Name'].'-in');
21 $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-in', 'dst-address' => $Address, 'in-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Item['Name'].'-in');
22 } else
23 {
24 // Subnets
25 $ParentSubnetId = GetSubgroupByRange($Node['Address']->AddressToString().'/'.$Node['Address']->Prefix);
26 $SubnetId = GetSubgroupByRange($Item['Address']->AddressToString().'/'.$Item['Address']->Prefix);
27 $PacketMark = GetMarkByComment($Item['Name'].'-out');
28
29 $Address = $Item['Address']->AddressToString();
30 if($Item['Address']->Prefix != 32) $Address .= '/'.$Item['Address']->Prefix;
31
32 $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-out', 'src-address' => $Address, 'out-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-'.$SubnetId.'-out', 'comment' => $Item['Name'].'-out');
33 $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-in', 'dst-address' => $Address, 'in-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-'.$SubnetId.'-in', 'comment' => $Item['Name'].'-in');
34
35 $this->ProcessNode($Item);
36 }
37 }
38 if($Node['ForceMark'] == true)
39 {
40 // Mark member subnets
41 $ParentSubnetId = GetSubgroupByRange($Node['Address']->AddressToString().'/'.$Node['Address']->Prefix);
42 $PacketMark = GetMarkByComment($Node['Name'].'-out');
43 $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-out', 'src-address' => '', 'out-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Node['Name'].'-all-out');
44 $PacketMark = GetMarkByComment($Node['Name'].'-in');
45 $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-in', 'dst-address' => '', 'in-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Node['Name'].'-all-in');
46 }
47 }
48
49 function Run()
50 {
51 $this->RunIPv4();
52 $this->RunIPv6();
53 }
54
55 function RunIPv4()
56 {
57 global $ItemsFirewall;
58
59 $PathFirewall = array('ip', 'firewall', 'mangle');
60
61 $Routerboard = new Routerboard();
62 $Routerboard->UserName = $this->System->Config['MainRouter']['UserName'];
63 $Routerboard->Timeout = $this->System->Config['MainRouter']['ConnectTimeout'];
64 $Routerboard->HostName = $this->System->Config['MainRouter']['HostName'];
65 $Routerboard->Debug = true;
66
67 $InetInterface = $this->System->Config['MainRouter']['InetInterface'];
68
69 // Generate address tree
70 $AddressTree = array('Address' => new NetworkAddressIPv4(), 'Name' => 'main', 'Items' => array(), 'ForceMark' => false);
71
72 // Divide rules by subnet number
73 $DbResult = $this->System->Database->query('SELECT `Id`, `Name`, `AddressRange`, `Mask` FROM `NetworkSubnet` WHERE `Member` IS NULL');
74 while($Subnet = $DbResult->fetch_assoc())
75 {
76 $NewAddress = new NetworkAddressIPv4();
77 $NewAddress->AddressFromString($Subnet['AddressRange']);
78 $NewAddress->Prefix = $Subnet['Mask'];
79 InsertToAddressTreeIPv4($AddressTree, $NewAddress, 'subnet-'.RouterOSIdent($Subnet['Name']));
80 }
81
82 // Process users
83 $DbResult = $this->System->Database->query('SELECT `Member`.*, `Subject`.`Name` FROM `Member` '.
84 'LEFT JOIN `Subject` ON `Subject`.`Id` = `Member`.`Subject` '.
85 'WHERE `Member`.`Blocked` = 0');
86 while($Member = $DbResult->fetch_assoc())
87 {
88 $Member['Name'] = RouterOSIdent($Member['Name'].'-'.$Member['Id'] );
89 echo('Uživatel '.$Member['Name'].': ');
90
91 $DbResult2 = $this->System->Database->select('NetworkDevice', '*', '`Used` = 1 AND `Member` = '.$Member['Id']);
92 while($Device = $DbResult2->fetch_assoc())
93 {
94 $DbResult3 = $this->Database->select('NetworkInterface', '*', '`Device` = '.$Device['Id'].' AND `LocalIP` != ""');
95 while($Interface = $DbResult3->fetch_assoc())
96 {
97 $Name = $Device['Name'];
98 if($Interface['Name'] != '') $Name .= '-'.$Interface['Name'];
99 $Name = RouterOSIdent($Name);
100 echo($Name.', ');
101 $NewAddress = new NetworkAddressIPv4();
102 $NewAddress->AddressFromString($Interface['LocalIP']);
103 $NewAddress->Prefix = IPV4_BIT_WIDTH;
104 InsertToAddressTreeIPv4($AddressTree, $NewAddress, $Name);
105 }
106 }
107
108 $DbResult2 = $this->Database->select('NetworkSubnet', '*', '(`Member`='.$Member['Id'].') AND (AddressRange != "")');
109 while($Subnet = $DbResult2->fetch_assoc())
110 {
111 $Subnet['Name'] = RouterOSIdent('subnet-'.$Subnet['Name']);
112 echo($Subnet['Name'].', ');
113 $NewAddress = new NetworkAddressIPv4();
114 $NewAddress->AddressFromString($Subnet['AddressRange']);
115 $NewAddress->Prefix = $Subnet['Mask'];
116 if($Subnet['Member'] != 0) $ForceMark = true;
117 else $ForceMark = false;
118 echo($ForceMark.', ');
119 InsertToAddressTreeIPv4($AddressTree, $NewAddress, $Subnet['Name'], false, $ForceMark);
120 }
121 echo("\n");
122 }
123
124 ShowSubnetNode($AddressTree);
125
126 // Generate firewall rules
127 $ItemsFirewall = array();
128
129 // Root of tree and main limit
130 $ItemsFirewall[] = array('chain' => 'forward', 'out-interface' => $InetInterface, 'dst-address' => '!77.92.221.0/24', 'action' => 'jump', 'jump-target' => 'inet-1-out', 'comment' => 'main-out');
131 $ItemsFirewall[] = array('chain' => 'forward', 'in-interface' => $InetInterface, 'src-address' => '!77.92.221.0/24', 'action' => 'jump', 'jump-target' => 'inet-1-in', 'comment' => 'main-in');
132
133 $this->ProcessNode($AddressTree);
134
135 // Limited free internet
136 $PacketMark = GetMarkByComment('free-out');
137 $ItemsFirewall[] = array('chain' => 'inet-1-out', 'out-interface' => $InetInterface,
138 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'comment' => 'free-out', 'passthrough' => 'yes');
139 $PacketMark = GetMarkByComment('free-in');
140 $ItemsFirewall[] = array('chain' => 'inet-1-in', 'in-interface' => $InetInterface,
141 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'comment' => 'free-in', 'passthrough' => 'no');
142 // Unregistred clients add to address list
143 $ItemsFirewall[] = array('chain' => 'inet-1-out', 'out-interface' => $InetInterface, 'src-address' => '10.145.0.0/16',
144 'action' => 'add-src-to-address-list', 'address-list' => 'unregistred', 'address-list-timeout' => '1d',
145 'comment' => 'unregistred-clients');
146
147 //print_r($ItemsFirewall);
148 $Routerboard->ListUpdate($PathFirewall, array('chain', 'dst-address', 'in-interface', 'action', 'new-packet-mark', 'passthrough', 'comment', 'out-interface', 'src-address', 'jump-target'), $ItemsFirewall, array(), true);
149 }
150
151 function RunIPv6()
152 {
153 global $ItemsFirewall;
154
155 $PathFirewall = array('ipv6', 'firewall', 'mangle');
156
157 $Routerboard = new Routerboard();
158 $Routerboard->UserName = $this->System->Config['MainRouter']['UserName'];
159 $Routerboard->Timeout = $this->System->Config['MainRouter']['ConnectTimeout'];
160 $Routerboard->HostName = $this->System->Config['MainRouter']['HostName'];
161 $Routerboard->Debug = true;
162
163 $InetInterface = $this->System->Config['MainRouter']['InetInterface'];
164
165 // Generate address tree
166 $AddressTree = array('Address' => new NetworkAddressIPv4(), 'Name' => 'main', 'Items' => array(), 'ForceMark' => false);
167
168 // Divide rules by subnet number
169 $DbResult = $this->System->Database->query('SELECT `Id`, `Name`, `AddressRangeIPv6`, `MaskIPv6` FROM `NetworkSubnet` '.
170 'WHERE (`Member` IS NULL) AND (`AddressRangeIPv6` != "")');
171 while($Subnet = $DbResult->fetch_assoc())
172 {
173 $NewAddress = new NetworkAddressIPv6();
174 $NewAddress->AddressFromString($Subnet['AddressRangeIPv6']);
175 $NewAddress->Prefix = $Subnet['MaskIPv6'];
176 InsertToAddressTreeIPv6($AddressTree, $NewAddress, 'subnet-'.RouterOSIdent($Subnet['Name']));
177 }
178
179 // Process users
180 $DbResult = $this->System->Database->query('SELECT `Member`.*, `Subject`.`Name` FROM `Member` '.
181 'LEFT JOIN `Subject` ON `Subject`.`Id` = `Member`.`Subject` '.
182 'WHERE `Member`.`Blocked` = 0');
183 while($Member = $DbResult->fetch_assoc())
184 {
185 $Member['Name'] = RouterOSIdent($Member['Name'].'-'.$Member['Id'] );
186 echo('Uživatel '.$Member['Name'].': ');
187
188 $DbResult2 = $this->System->Database->select('NetworkDevice', '*', '`Used` = 1 AND `Member` = '.$Member['Id']);
189 while($Device = $DbResult2->fetch_assoc())
190 {
191 $DbResult3 = $this->Database->select('NetworkInterface', '*', '`Device` = '.$Device['Id'].' AND `IPv6` != ""');
192 while($Interface = $DbResult3->fetch_assoc())
193 {
194 $Name = $Device['Name'];
195 if($Interface['Name'] != '') $Name .= '-'.$Interface['Name'];
196 $Name = RouterOSIdent($Name);
197 echo($Name.', ');
198 $NewAddress = new NetworkAddressIPv6();
199 $NewAddress->AddressFromString($Interface['IPv6']);
200 $NewAddress->Prefix = IPV6_BIT_WIDTH;
201 InsertToAddressTreeIPv6($AddressTree, $NewAddress, $Name);
202 }
203 }
204
205 $DbResult2 = $this->Database->select('NetworkSubnet', '*', '(`Member`='.$Member['Id'].') AND (AddressRangeIPv6 != "")');
206 while($Subnet = $DbResult2->fetch_assoc())
207 {
208 $Subnet['Name'] = RouterOSIdent('subnet-'.$Subnet['Name']);
209 echo($Subnet['Name'].', ');
210 $NewAddress = new NetworkAddressIPv6();
211 $NewAddress->AddressFromString($Subnet['AddressRangeIPv6']);
212 $NewAddress->Prefix = $Subnet['MaskIPv6'];
213 if($Subnet['Member'] != 0) $ForceMark = true;
214 else $ForceMark = false;
215 echo($ForceMark.', ');
216 InsertToAddressTreeIPv6($AddressTree, $NewAddress, $Subnet['Name'], false, $ForceMark);
217 }
218 echo("\n");
219 }
220
221 ShowSubnetNode($AddressTree);
222
223 // Generate firewall rules
224 $ItemsFirewall = array();
225
226 // Root of tree and main limit
227 $ItemsFirewall[] = array('chain' => 'forward', 'out-interface' => $InetInterface, 'dst-address' => '!2a00:e580:244::/48',
228 'action' => 'jump', 'jump-target' => 'inet-1-out', 'comment' => 'main-out');
229 $ItemsFirewall[] = array('chain' => 'forward', 'in-interface' => $InetInterface, 'src-address' => '!2a00:e580:244::/48',
230 'action' => 'jump', 'jump-target' => 'inet-1-in', 'comment' => 'main-in');
231
232 $this->ProcessNode($AddressTree);
233
234 // Limited free internet
235 $PacketMark = GetMarkByComment('free-out');
236 $ItemsFirewall[] = array('chain' => 'inet-1-out', 'out-interface' => $InetInterface,
237 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'comment' => 'free-out', 'passthrough' => 'yes');
238 $PacketMark = GetMarkByComment('free-in');
239 $ItemsFirewall[] = array('chain' => 'inet-1-in', 'in-interface' => $InetInterface,
240 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'comment' => 'free-in', 'passthrough' => 'no');
241 // Unregistred clients add to address list
242 $ItemsFirewall[] = array('chain' => 'inet-1-out', 'out-interface' => $InetInterface, 'src-address' => '2a00:e580:244::/48',
243 'action' => 'add-src-to-address-list', 'address-list' => 'unregistred', 'address-list-timeout' => '1d',
244 'comment' => 'unregistred-clients');
245
246 //print_r($ItemsFirewall);
247 $Routerboard->ListUpdate($PathFirewall, array('chain', 'dst-address', 'in-interface', 'action', 'new-packet-mark',
248 'passthrough', 'comment', 'out-interface', 'src-address', 'jump-target'), $ItemsFirewall, array(), true);
249 }
250}
Note: See TracBrowser for help on using the repository browser.