Changeset 267


Ignore:
Timestamp:
Dec 21, 2009, 10:48:41 AM (15 years ago)
Author:
george
Message:
  • Upraveno: Nově přepracován systém generování značkovacích pravidel mangle firewallu. Pro snížení počtu pravidel procházených při značkování packetu, jsou adresy rozdělovány do podskupin. Díky tomu je snížen rozptyl mezi nejmenším a nejvyšším početem procházených pravidel.
  • Upraveno: Přepracovány funkce pro práci s IP adresami typu IPv4. Přehledněji zpracováno jako třída.
  • Přidáno: Tabulka v databázi pro persistentní přiřazení Id čísla podsítě pro generování pravidel mangle firewallu.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/config.sample.php

    r251 r267  
    5050   'InetInterface' => 'ether0',
    5151   'ConnectTimeout' => 5,
     52   'MangleRuleSubgroupMinPrefix' => 28,
    5253  ), 
    5354);
  • trunk/global.php

    r247 r267  
    1010include('config.php');
    1111include('database.php');
    12 include('error.php');
     12//include('error.php');
    1313include_once('code.php');
    1414$Database = new Database($Config['Database']['Host'], $Config['Database']['User'], $Config['Database']['Password'], $Config['Database']['Database']);
     
    233233}
    234234
    235 function ToVpnIp($Host)
    236 {
    237   if($Host['external_ip'] == '')
    238   {
    239     $Parts = explode('.', $Host['IP']);
    240     return('172.16.'.$Parts[2].'.'.$Parts[3]);
    241   } else
    242   {
    243     return($Host['external_ip']);
    244   }
    245 }
    246 
    247235function TimeToMysqlDateTime($Time)
    248236{
     
    264252}
    265253
    266 function ToCzfreeIp($Host)
    267 {
    268   $Parts = explode('.', $Host['external_ip']);
    269   if($Host['name'] == 'CENTRALA') return('10.144.1.1');
    270     else return('10.144.200.'.$Parts[3]);
    271 }
    272 
    273254function HumanDate($Time)
    274255{
     
    280261
    281262// Zobrazení číselný seznamu stránek
    282 function PagesList($URL,$Page,$TotalCount,$CountPerPage)
    283 {
    284   $Count = ceil($TotalCount/$CountPerPage);
     263function PagesList($URL, $Page, $TotalCount, $CountPerPage)
     264{
     265  $Count = ceil($TotalCount / $CountPerPage);
    285266  $Around = 10;
    286267  $Result = '';
     
    328309  $RemoteAddr = GetRemoteAddress();
    329310  $RemoteAddr = explode('.', $RemoteAddr);
    330   return(!(($RemoteAddr[0] == 192) and ($RemoteAddr[1] == 168)));
     311  return(!(($RemoteAddr[0] == 10) and ($RemoteAddr[1] == 145)));
    331312}
    332313
     
    351332}
    352333
    353 function IPv4ToInt32($IP)
    354 {
    355   $Parts = explode('.', $IP);
    356   return(($Parts[0] << 24) | ($Parts[1] << 16) | ($Parts[2] << 8) | $Parts[3]);
    357 }
    358 
    359 function Int32ToIPv4($Value)
    360 {
    361   return(implode('.', array(($Value >> 24) & 255, ($Value >> 16) & 255, ($Value >> 8) & 255, ($Value & 255))));
    362 }
    363 
    364 function CIDRToAddressRange($Subnet, $Mask)
    365 {
    366   $SubnetBinary = IPv4ToInt32($Subnet);
    367   $Hostmask = (1 << (32 - $Mask)) - 1;
    368   $Netmask = 0xffffffff ^ $Hostmask;
    369   $From = $SubnetBinary & $Netmask;
    370   $To = $From + $Hostmask;
    371   return(array('From' => Int32ToIPv4($From), 'To' => Int32ToIPv4($To)));
    372 }
    373 
    374 function IsAddressInSubnet($Address, $Subnet, $Mask)
    375 {
    376   $AddressBinary = IPv4ToInt32($Address);
    377   $SubnetBinary = IPv4ToInt32($Subnet);
    378   $Netmask = 0xffffffff ^ ((1 << (32 - $Mask)) - 1);
    379   if(($AddressBinary & $Netmask) == ($SubnetBinary & $Netmask)) return(true);
    380     else return(false);
    381 }
    382 
    383334function RouterOSIdent($Name)
    384335{
     
    391342function NotBlank($Text)
    392343{
    393   if($Text == '') return('&nbsp'); else return($Text);
     344  if($Text == '') return('&nbsp');
     345    else return($Text);
    394346}
    395347
  • trunk/system/generators/common.php

    r266 r267  
    11<?php
     2
     3include_once('../../network_address.php');
    24
    35function GetMarkByComment($Comment)
     
    1719}
    1820
     21function GetSubgroupByRange($AddressRange)
     22{
     23  global $Database;
     24 
     25  $DbResult = $Database->query('SELECT `Id` FROM `NetworkMangleSubgroup` WHERE `AddressRange`="'.$AddressRange.'"');
     26  if($DbResult->num_rows > 0)
     27  {
     28    $DbRow = $DbResult->fetch_assoc();
     29    return($DbRow['Id']);
     30  } else
     31  {
     32    $DbResult = $Database->query('INSERT INTO `NetworkMangleSubgroup` (`AddressRange`) VALUES ("'.$AddressRange.'")');
     33    return($Database->insert_id);
     34  }
     35}
     36
     37function InsertToAddressTree(&$Tree, $Address, $Name, $InterSubnets = false)
     38{
     39  global $Config;
     40 
     41  $Found = false;
     42  foreach($Tree['Items'] as $Index => $Node)
     43  {
     44    if($Node['Address']->Contain($Address))
     45    {
     46      InsertToAddressTree($Tree['Items'][$Index], $Address, $Name, true);
     47      $Found = true;
     48    }
     49  }
     50  if($Found == false)
     51  {
     52    if($InterSubnets and ($Tree['Address']->Prefix < $Config['MainRouter']['MangleRuleSubgroupMinPrefix']) and
     53    ($Address->Prefix > ($Tree['Address']->Prefix + 1)))
     54    {
     55      $NewAddress = new NetworkAddressIPv4();
     56      $NewAddress->Address = $Address->Address;
     57      $NewAddress->ChangePrefix($Tree['Address']->Prefix + 1);
     58      //echo('InsertToTree('.$NewAddress->AddressToString().'/'.$NewAddress->Prefix.')'."\n");
     59      $Tree['Items'][] = array('Address' => $NewAddress, 'Name' => $Name, 'Items' => array());
     60      InsertToAddressTree($Tree['Items'][count($Tree['Items']) - 1], $Address, $Name, true);
     61    } else
     62    {
     63     
     64      $NewNode = array('Address' => $Address, 'Name' => $Name, 'Items' => array());
     65     
     66      // Should be existed items placed under new node?
     67      $Found = false;
     68      foreach($Tree['Items'] as $Index => $Node)
     69      {
     70        if(($Node['Address']->Address == $NewNode['Address']->Address) and
     71        ($Node['Address']->Prefix == $NewNode['Address']->Prefix)) $Found = true;       
     72       
     73        //echo($Index.',');
     74        if($Address->Contain($Node['Address']))
     75        {
     76          $NewNode['Items'][] = $Node;
     77          unset($Tree['Items'][$Index]);
     78        }
     79      }
     80      if($Found == false) $Tree['Items'][] = $NewNode;     
     81    }
     82  }
     83}
     84
     85function ShowSubnetNode($Node, $Indent = 0)
     86{
     87  echo(str_repeat('  ', $Indent).$Node['Address']->AddressToString().'/'.$Node['Address']->Prefix.' '.$Node['Name']."\n");
     88  foreach($Node['Items'] as $Index => $Item)
     89  {
     90    ShowSubnetNode($Item, $Indent + 1);
     91  } 
     92}
     93
     94/*
     95function Test()
     96{
     97  $SubnetTree = array('Address' => new NetworkAddressIPv4(), 'Items' => array());
     98
     99  $NewAddress = new NetworkAddressIPv4();
     100  $NewAddress->AddressFromString('10.145.64.0');
     101  $NewAddress->Prefix = 24;
     102  InsertToAddressTree($SubnetTree, $NewAddress);
     103  $NewAddress = new NetworkAddressIPv4();
     104  $NewAddress->AddressFromString('10.145.64.0');
     105  $NewAddress->Prefix = 29;
     106  InsertToAddressTree($SubnetTree, $NewAddress);
     107  $NewAddress = new NetworkAddressIPv4();
     108  $NewAddress->AddressFromString('10.145.65.0');
     109  $NewAddress->Prefix = 24;
     110  InsertToAddressTree($SubnetTree, $NewAddress);
     111  $NewAddress = new NetworkAddressIPv4();
     112  $NewAddress->AddressFromString('10.145.65.156');
     113  $NewAddress->Prefix = 32;
     114  InsertToAddressTree($SubnetTree, $NewAddress);
     115  $NewAddress = new NetworkAddressIPv4();
     116  $NewAddress->AddressFromString('10.145.64.0');
     117  $NewAddress->Prefix = 20;
     118  InsertToAddressTree($SubnetTree, $NewAddress);
     119
     120
     121  ShowSubnetNode($SubnetTree);
     122  die();
     123}
     124*/
     125
    19126?>
  • trunk/system/generators/firewall_mangle.php

    r266 r267  
    1616$Routerboard->Debug = true;
    1717
    18 $Finance = &$System->Modules['Finance'];
    19 $Finance->LoadMonthParameters(0);
    20 
    2118$InetInterface = $Config['MainRouter']['InetInterface'];
    2219
    23 $ItemsMangle = array();
    2420
    25 // Root of tree and main limit
    26 $ItemsFirewall[] = array('chain' => 'forward', 'out-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-out', 'comment' => 'main-out');
    27 $ItemsFirewall[] = array('chain' => 'forward', 'in-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-in', 'comment' => 'main-in');
     21// Generate address tree
     22$AddressTree = array('Address' => new NetworkAddressIPv4(), 'Name' => 'main', 'Items' => array());
    2823
    2924// Divide rules by subnet number
    30 $DbResult = $Database->query('SELECT `Id`, `Name`, `AddressRange`, `Mask` FROM `NetworkSubnet`');
     25$DbResult = $Database->query('SELECT `Id`, `Name`, `AddressRange`, `Mask` FROM `NetworkSubnet` WHERE Member=0');
    3126while($Subnet = $DbResult->fetch_assoc())
    3227{
    33   $SubnetParts = explode('.', $Subnet['AddressRange']);
    34   $SubnetNumber = $SubnetParts[2];
    35   $ItemsFirewall[] = array('chain' => 'inet-out', 'src-address' => $Subnet['AddressRange'].'/'.$Subnet['Mask'], 'out-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-out-'.$SubnetNumber, 'comment' => 'subnet-'.RouterOSIdent($Subnet['Name']).'-out');
    36   $ItemsFirewall[] = array('chain' => 'inet-in', 'dst-address' => $Subnet['AddressRange'].'/'.$Subnet['Mask'], 'in-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-in-'.$SubnetNumber, 'comment' => 'subnet-'.RouterOSIdent($Subnet['Name']).'-in');
     28  $NewAddress = new NetworkAddressIPv4();
     29  $NewAddress->AddressFromString($Subnet['AddressRange']);
     30  $NewAddress->Prefix = $Subnet['Mask'];
     31  InsertToAddressTree($AddressTree, $NewAddress, 'subnet-'.RouterOSIdent($Subnet['Name']));
    3732}
    38 
    39 // Slow free internet
    40 $PacketMark = GetMarkByComment('free-out');
    41 $ItemsFirewall[] = array('chain' => 'inet-out', 'out-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'comment' => 'free-out', 'passthrough' => 'no');
    42 $PacketMark = GetMarkByComment('free-in');
    43 $ItemsFirewall[] = array('chain' => 'inet-in', 'in-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'comment' => 'free-in', 'passthrough' => 'no');
    4433
    4534// Process users
     
    4938  $Member['Name'] = RouterOSIdent($Member['Name'].'-'.$Member['Id'] );
    5039  echo('Uživatel '.$Member['Name'].': ');
    51 
    52   $DbResult2 = $Database->select('NetworkDevice', 'COUNT(*)', 'Used = 1 AND Member='.$Member['Id']);
    53   $Row = $DbResult2->fetch_row();
    54   $HostCount = $Row[0];
    5540
    5641  $DbResult2 = $Database->select('NetworkDevice', '*', '`Used` = 1 AND `Member` = '.$Member['Id']);
     
    6449      $Name = RouterOSIdent($Name);
    6550      echo($Name.', ');
    66       $IPParts = explode('.', $Interface['LocalIP']);
    67       $Subnet = $IPParts[2];
    68       $PacketMark = GetMarkByComment($Name.'-out');
    69       $ItemsFirewall[] = array('chain' => 'inet-out-'.$Subnet, 'src-address' => $Interface['LocalIP'], 'out-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Name.'-out');
    70       $PacketMark = GetMarkByComment($Name.'-in');
    71       $ItemsFirewall[] = array('chain' => 'inet-in-'.$Subnet, 'dst-address' => $Interface['LocalIP'], 'in-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Name.'-in');
     51      $NewAddress = new NetworkAddressIPv4();
     52      $NewAddress->AddressFromString($Interface['LocalIP']);
     53      $NewAddress->Prefix = 32;
     54      InsertToAddressTree($AddressTree, $NewAddress, $Name);
    7255    }
    7356  }
     
    7861    $Subnet['Name'] = RouterOSIdent('subnet-'.$Subnet['Name']);
    7962    echo($Subnet['Name'].', ');
    80     $IPParts = explode('.', $Subnet['AddressRange']);
    81     $SubnetNumber = $IPParts[2];
    82     $PacketMark = GetMarkByComment($Subnet['Name'].'-out');
    83     $ItemsFirewall[] = array('chain' => 'inet-out-'.$SubnetNumber, 'src-address' => $Subnet['AddressRange'].'/'.$Subnet['Mask'], 'out-interface' =>  $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Subnet['Name'].'-out');
    84     $PacketMark = GetMarkByComment($Subnet['Name'].'-in');
    85     $ItemsFirewall[] = array('chain' => 'inet-in-'.$SubnetNumber, 'dst-address' => $Subnet['AddressRange'].'/'.$Subnet['Mask'], 'in-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Subnet['Name'].'-in');
     63    $NewAddress = new NetworkAddressIPv4();
     64    $NewAddress->AddressFromString($Subnet['AddressRange']);
     65    $NewAddress->Prefix = $Subnet['Mask'];
     66    InsertToAddressTree($AddressTree, $NewAddress, $Subnet['Name']);
    8667  }
    8768  echo("\n");
    8869}
    8970
    90 //print_r($ItemsFirewall);
    91 $Routerboard->ListUpdate($PathFirewall, array('chain', 'dst-address', 'in-interface', 'action', 'new-packet-mark', 'passthrough', 'comment', 'out-interface', 'src-address', 'jump-target'), $ItemsFirewall, array(), true);
     71ShowSubnetNode($AddressTree);
     72
     73function ProcessNode($Node)
     74{
     75  global $InetInterface, $ItemsFirewall;
     76 
     77  foreach($Node['Items'] as $Index => $Item)
     78  {
     79    if(count($Item['Items']) == 0)
     80    {
     81      // Hosts
     82      $ParentSubnetId = GetSubgroupByRange($Node['Address']->AddressToString().'/'.$Node['Address']->Prefix);
     83      $PacketMark = GetMarkByComment($Item['Name'].'-out');
     84      $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-out', 'src-address' => $Item['Address']->AddressToString().'/'.$Item['Address']->Prefix, 'out-interface' =>  $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Item['Name'].'-out');
     85      $PacketMark = GetMarkByComment($Item['Name'].'-in');
     86      $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-in', 'dst-address' => $Item['Address']->AddressToString().'/'.$Item['Address']->Prefix, 'in-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'passthrough' => 'no', 'comment' => $Item['Name'].'-in');
     87    } else
     88    {
     89      // Subnets
     90      $ParentSubnetId = GetSubgroupByRange($Node['Address']->AddressToString().'/'.$Node['Address']->Prefix);
     91      $SubnetId = GetSubgroupByRange($Item['Address']->AddressToString().'/'.$Item['Address']->Prefix);
     92      $PacketMark = GetMarkByComment($Item['Name'].'-out');
     93     
     94      $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-out', 'src-address' => $Item['Address']->AddressToString().'/'.$Item['Address']->Prefix, 'out-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-'.$SubnetId.'-out', 'comment' => $Item['Name'].'-out');   
     95      $ItemsFirewall[] = array('chain' => 'inet-'.$ParentSubnetId.'-in', 'dst-address' => $Item['Address']->AddressToString().'/'.$Item['Address']->Prefix, 'in-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-'.$SubnetId.'-in', 'comment' => $Item['Name'].'-in');   
     96     
     97      ProcessNode($Item);     
     98    }   
     99  }
     100}
     101
     102// Generate firewall rules
     103$ItemsFirewall = array();
     104
     105// Root of tree and main limit
     106$ItemsFirewall[] = array('chain' => 'forward', 'out-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-1-out', 'comment' => 'main-out');
     107$ItemsFirewall[] = array('chain' => 'forward', 'in-interface' => $InetInterface, 'action' => 'jump', 'jump-target' => 'inet-1-in', 'comment' => 'main-in');
     108
     109ProcessNode($AddressTree);
     110
     111// Slow free internet
     112$PacketMark = GetMarkByComment('free-out');
     113$ItemsFirewall[] = array('chain' => 'inet-1-out', 'out-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'comment' => 'free-out', 'passthrough' => 'no');
     114$PacketMark = GetMarkByComment('free-in');
     115$ItemsFirewall[] = array('chain' => 'inet-1-in', 'in-interface' => $InetInterface, 'action' => 'mark-packet', 'new-packet-mark' => $PacketMark, 'comment' => 'free-in', 'passthrough' => 'no');
     116
     117
     118print_r($ItemsFirewall);
     119//$Routerboard->ListUpdate($PathFirewall, array('chain', 'dst-address', 'in-interface', 'action', 'new-packet-mark', 'passthrough', 'comment', 'out-interface', 'src-address', 'jump-target'), $ItemsFirewall, array(), true);
    92120
    93121?>
Note: See TracChangeset for help on using the changeset viewer.