Changeset 870


Ignore:
Timestamp:
Apr 3, 2020, 12:30:49 AM (4 years ago)
Author:
chronos
Message:
  • Added: IPv6 mangle firewall configuration.
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Application/UpdateTrace.php

    r869 r870  
    21022102        "VALUES (NULL , 'Omezení rychlosti', ".$DbRow['Id'].", '".$ActionId."', '1');");
    21032103  }
     2104}
     2105
     2106function UpdateTo870($Manager)
     2107{
     2108  $Manager->Execute('ALTER TABLE `NetworkSubnet`ADD COLUMN `MaskIPv6` INT(11) NOT NULL AFTER `AddressRangeIPv6`;');
     2109  $Manager->Execute('UPDATE `NetworkSubnet` SET `MaskIPv6`=64 WHERE `AddressRangeIPv6` != ""');
     2110  $Manager->Execute('UPDATE `NetworkSubnet` SET `AddressRangeIPv6` = REPLACE(`AddressRangeIPv6`, "/64", "")');
    21042111}
    21052112
     
    22032210      862 => array('Revision' => 867, 'Function' => 'UpdateTo867'),
    22042211      867 => array('Revision' => 869, 'Function' => 'UpdateTo869'),
     2212      869 => array('Revision' => 870, 'Function' => 'UpdateTo870'),
    22052213    ));
    22062214  }
  • trunk/Application/Version.php

    r869 r870  
    11<?php
    22
    3 $Revision = 869; // Subversion revision
    4 $DatabaseRevision = 869; // SQL structure revision
    5 $ReleaseTime = strtotime('2020-03-31');
     3$Revision = 870; // Subversion revision
     4$DatabaseRevision = 870; // SQL structure revision
     5$ReleaseTime = strtotime('2020-04-03');
  • trunk/Modules/Network/Network.php

    r869 r870  
    268268        'ExtMask' => array('Type' => 'String', 'Caption' => 'Vnější prefix', 'Default' => ''),
    269269        'AddressRangeIPv6' => array('Type' => 'String', 'Caption' => 'Rozsah adres IPv6', 'Default' => ''),
     270        'MaskIPv6' => array('Type' => 'Integer', 'Caption' => 'Prefix IPv6', 'Default' => ''),
    270271        'Configure' => array('Type' => 'Boolean', 'Caption' => 'Nastavovat', 'Default' => ''),
    271272        'Interfaces' => array('Type' => 'TNetworkSubnetInterfaceList', 'Caption' => 'Rozhraní', 'Default' => ''),
  • trunk/Modules/NetworkConfigRouterOS/Generators/Common.php

    r790 r870  
    3333}
    3434
    35 function InsertToAddressTree(&$Tree, $Address, $Name, $InterSubnets = false, $ForceMark = false)
     35function InsertToAddressTreeIPv4(&$Tree, $Address, $Name, $InterSubnets = false, $ForceMark = false)
    3636{
    3737  global $Config;
     
    4242    if($Node['Address']->Contain($Address))
    4343    {
    44       InsertToAddressTree($Tree['Items'][$Index], $Address, $Name, true);
     44      InsertToAddressTreeIPv4($Tree['Items'][$Index], $Address, $Name, true);
    4545      $Found = true;
    4646    }
     
    5454      $NewAddress->Address = $Address->Address;
    5555      $NewAddress->ChangePrefix($Tree['Address']->Prefix + 1);
    56       //echo('InsertToTree('.$NewAddress->AddressToString().'/'.$NewAddress->Prefix.')'."\n");
    5756      $Tree['Items'][] = array('Address' => $NewAddress, 'Name' => $Name, 'Items' => array(), 'ForceMark' => false);
    58       InsertToAddressTree($Tree['Items'][count($Tree['Items']) - 1], $Address, $Name, true);
     57      InsertToAddressTreeIPv4($Tree['Items'][count($Tree['Items']) - 1], $Address, $Name, true);
    5958    } else
    6059    {
    61 
    6260      $NewNode = array('Address' => $Address, 'Name' => $Name, 'Items' => array(), 'ForceMark' => $ForceMark);
    6361
     
    6967        ($Node['Address']->Prefix == $NewNode['Address']->Prefix)) $Found = true;
    7068
    71         //echo($Index.',');
     69        if($Address->Contain($Node['Address']))
     70        {
     71          $NewNode['Items'][] = $Node;
     72          unset($Tree['Items'][$Index]);
     73        }
     74      }
     75      if($Found == false) $Tree['Items'][] = $NewNode;
     76    }
     77  }
     78}
     79
     80function InsertToAddressTreeIPv6(&$Tree, $Address, $Name, $InterSubnets = false, $ForceMark = false)
     81{
     82  global $Config;
     83
     84  $Found = false;
     85  foreach($Tree['Items'] as $Index => $Node)
     86  {
     87    if($Node['Address']->Contain($Address))
     88    {
     89      InsertToAddressTreeIPv6($Tree['Items'][$Index], $Address, $Name, true);
     90      $Found = true;
     91    }
     92  }
     93  if($Found == false)
     94  {
     95    if($InterSubnets and ($Tree['Address']->Prefix < $Config['MainRouter']['MangleRuleSubgroupMinPrefix']) and
     96    ($Address->Prefix > ($Tree['Address']->Prefix + 1)))
     97    {
     98      $NewAddress = new NetworkAddressIPv6();
     99      $NewAddress->Address = $Address->Address;
     100      $NewAddress->ChangePrefix($Tree['Address']->Prefix + 1);
     101      $Tree['Items'][] = array('Address' => $NewAddress, 'Name' => $Name, 'Items' => array(), 'ForceMark' => false);
     102      InsertToAddressTreeIPv6($Tree['Items'][count($Tree['Items']) - 1], $Address, $Name, true);
     103    } else
     104    {
     105      $NewNode = array('Address' => $Address, 'Name' => $Name, 'Items' => array(), 'ForceMark' => $ForceMark);
     106
     107      // Should be existed items placed under new node?
     108      $Found = false;
     109      foreach($Tree['Items'] as $Index => $Node)
     110      {
     111        if(($Node['Address']->Address == $NewNode['Address']->Address) and
     112        ($Node['Address']->Prefix == $NewNode['Address']->Prefix)) $Found = true;
     113
    72114        if($Address->Contain($Node['Address']))
    73115        {
     
    89131  }
    90132}
    91 
    92 /*
    93 function Test()
    94 {
    95   $SubnetTree = array('Address' => new NetworkAddressIPv4(), 'Items' => array());
    96 
    97   $NewAddress = new NetworkAddressIPv4();
    98   $NewAddress->AddressFromString('10.145.64.0');
    99   $NewAddress->Prefix = 24;
    100   InsertToAddressTree($SubnetTree, $NewAddress);
    101   $NewAddress = new NetworkAddressIPv4();
    102   $NewAddress->AddressFromString('10.145.64.0');
    103   $NewAddress->Prefix = 29;
    104   InsertToAddressTree($SubnetTree, $NewAddress);
    105   $NewAddress = new NetworkAddressIPv4();
    106   $NewAddress->AddressFromString('10.145.65.0');
    107   $NewAddress->Prefix = 24;
    108   InsertToAddressTree($SubnetTree, $NewAddress);
    109   $NewAddress = new NetworkAddressIPv4();
    110   $NewAddress->AddressFromString('10.145.65.156');
    111   $NewAddress->Prefix = 32;
    112   InsertToAddressTree($SubnetTree, $NewAddress);
    113   $NewAddress = new NetworkAddressIPv4();
    114   $NewAddress->AddressFromString('10.145.64.0');
    115   $NewAddress->Prefix = 20;
    116   InsertToAddressTree($SubnetTree, $NewAddress);
    117 
    118 
    119   ShowSubnetNode($SubnetTree);
    120   die();
    121 }
    122 */
  • trunk/Modules/NetworkConfigRouterOS/Generators/FirewallMangle.php

    r811 r870  
    4949  function Run()
    5050  {
     51    $this->RunIPv4();
     52    $this->RunIPv6();
     53  }
     54
     55  function RunIPv4()
     56  {
    5157    global $ItemsFirewall;
    52    
     58
    5359    $PathFirewall = array('ip', 'firewall', 'mangle');
    5460
     
    6167    $InetInterface = $this->System->Config['MainRouter']['InetInterface'];
    6268
    63 
    6469    // Generate address tree
    6570    $AddressTree = array('Address' => new NetworkAddressIPv4(), 'Name' => 'main', 'Items' => array(), 'ForceMark' => false);
     
    7277      $NewAddress->AddressFromString($Subnet['AddressRange']);
    7378      $NewAddress->Prefix = $Subnet['Mask'];
    74       InsertToAddressTree($AddressTree, $NewAddress, 'subnet-'.RouterOSIdent($Subnet['Name']));
     79      InsertToAddressTreeIPv4($AddressTree, $NewAddress, 'subnet-'.RouterOSIdent($Subnet['Name']));
    7580    }
    7681
     
    96101          $NewAddress = new NetworkAddressIPv4();
    97102          $NewAddress->AddressFromString($Interface['LocalIP']);
    98           $NewAddress->Prefix = 32;
    99           InsertToAddressTree($AddressTree, $NewAddress, $Name);
     103          $NewAddress->Prefix = IPV4_BIT_WIDTH;
     104          InsertToAddressTreeIPv4($AddressTree, $NewAddress, $Name);
    100105        }
    101106      }
    102107
    103       $DbResult2 = $this->Database->select('NetworkSubnet', '*', '`Member`='.$Member['Id']);
     108      $DbResult2 = $this->Database->select('NetworkSubnet', '*', '(`Member`='.$Member['Id'].') AND (AddressRange != "")');
    104109      while($Subnet = $DbResult2->fetch_assoc())
    105110      {
     
    112117        else $ForceMark = false;
    113118        echo($ForceMark.', ');
    114         InsertToAddressTree($AddressTree, $NewAddress, $Subnet['Name'], false, $ForceMark);
     119        InsertToAddressTreeIPv4($AddressTree, $NewAddress, $Subnet['Name'], false, $ForceMark);
    115120      }
    116121      echo("\n");
     
    143148    $Routerboard->ListUpdate($PathFirewall, array('chain', 'dst-address', 'in-interface', 'action', 'new-packet-mark', 'passthrough', 'comment', 'out-interface', 'src-address', 'jump-target'), $ItemsFirewall, array(), true);
    144149  }
     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  }
    145250}
  • trunk/Packages/Common/Common.php

    r869 r870  
    2121include_once(dirname(__FILE__).'/Process.php');
    2222include_once(dirname(__FILE__).'/Generics.php');
     23include_once(dirname(__FILE__).'/BigInt.php');
     24include_once(dirname(__FILE__).'/Int128.php');
    2325
    2426class PackageCommon
  • trunk/Packages/Common/NetworkAddress.php

    r746 r870  
    11<?php
     2
     3define('IPV4_BIT_WIDTH', 32);
    24
    35class NetworkAddressIPv4
     
    1416  function GetNetMask()
    1517  {
    16     return(0xffffffff ^ ((1 << (32 - $this->Prefix)) - 1));
     18    return(((1 << IPV4_BIT_WIDTH) - 1) ^ ((1 << (IPV4_BIT_WIDTH - $this->Prefix)) - 1));
    1719  }
    1820
     
    3234    $From = new NetworkAddressIPv4();
    3335    $From->Address = $this->Address;
    34     $From->Prefix = 32;
     36    $From->Prefix = IPV4_BIT_WIDTH;
    3537    $HostMask = 0xffffffff ^ $this->GetNetMask();
    3638    $To = new NetworkAddressIPv4();
    3739    $To->Address = $From->Address + $HostMask;
    38     $To->Prefix = 32;
     40    $To->Prefix = IPV4_BIT_WIDTH;
    3941    return(array('From' => $From, 'To' => $To));
    4042  }
     
    4345  {
    4446    $this->Prefix = $NewPrefix;
    45     if($this->Prefix > 32) $this->Prefix = 32;
     47    if($this->Prefix > IPV4_BIT_WIDTH) $this->Prefix = IPV4_BIT_WIDTH;
    4648    if($this->Prefix < 0) $this->Prefix = 0;
    4749    $this->Address = $this->Address & $this->GetNetMask();
     
    5355    if(($this->Prefix < $Address->Prefix) and (($Address->Address & $UpperNetmask) == ($this->Address & $UpperNetmask))) $Result = true;
    5456      else $Result = false;
    55     //echo($Address->AddressToString().'/'.$Address->Prefix.' in '.$this->AddressToString().'/'.$this->Prefix.' '.$Result."\n");
    5657    return($Result);
    5758  }
    5859}
     60
     61define('IPV6_BIT_WIDTH', 128);
    5962
    6063class NetworkAddressIPv6
     
    6972  }
    7073
     74  function GetNetMask()
     75  {
     76    return(Int128Xor(Int128Sub(Int128Shl(IntToInt128(1), IntToInt128(IPV6_BIT_WIDTH)), IntToInt128(1)),
     77      Int128Sub(Int128Shl(IntToInt128(1), IntToInt128(IPV6_BIT_WIDTH - $this->Prefix)), IntToInt128(1))));
     78  }
     79
    7180  function AddressToString()
    7281  {
     
    7786  {
    7887    $this->Address = inet_pton($Value);
     88  }
     89
     90  function ChangePrefix($NewPrefix)
     91  {
     92    $this->Prefix = $NewPrefix;
     93    if($this->Prefix > IPV6_BIT_WIDTH) $this->Prefix = IPV6_BIT_WIDTH;
     94    if($this->Prefix < 0) $this->Prefix = 0;
     95    $this->Address = Int128And($this->Address, $this->GetNetMask());
    7996  }
    8097
     
    107124  }
    108125
     126  function Contain($Address)
     127  {
     128    $UpperNetmask = $this->GetNetMask();
     129    if(($this->Prefix < $Address->Prefix) and ((Int128Equal(Int128And($Address->Address, $UpperNetmask), Int128And($this->Address, $UpperNetmask))))) $Result = true;
     130      else $Result = false;
     131    return($Result);
     132  }
    109133}
Note: See TracChangeset for help on using the changeset viewer.