воскресенье, 25 марта 2012 г.

Деление работающей сети на вланы

Здравствуйте, хочу поделиться процессом который происходит сейчас у меня. Работаю у не большого провайдера. Используем Docsis 2.0 и переходим на оптику. Сам переход был спонтанным (резко перестало хватать скорости абонентам, плюс не большая, но конкуренция). Закупили оборудования, используем порядка 90 штук DES-1228ME, DES-3200-10 на уровне доступа и три штуки DGS-3627G для агрегации и три штуки DES-3200-28F в помощь DGS-3627G (банально не хватило оптических портов). Маршрутизатором используем Mikrotik. Как принято, наверно, у многих небольших провайдеров, сначала чтоб работало, потом документация, потом допиливание сети до полностью рабочего состояния. Так и у нас, купили оборудование, протянули оптику, подключили все друг к другу, DHCP исправно выдает адреса, IP-MAC-Port Binding на портах доступа. Началось все хорошо, клиенты просто рекой потянулись, все работает, но как и предполагалось началось… После достижения определенной массы абонентов начались тормоза (у нас это примерно наступило когда в сети было порядка 600 хостов). Ну делить, так делить. 


Для начала нужен план, он, вроде как, у меня созрел. Да, забыл еще упомянуть, что предстоит переход на публичные IP и получение своей AS.

ПЛАН
1. Собрать информацию о коммутаторах доступа, портах, IP-MAC-Port Binding на этих портах.
2. Собрать информацию об узлах агрегации (какой коммутатор уровня доступа к какому порту подключен).
3. Логически разбить сеть на более мелкие подсети (у нас пока сеть с маской 255.255.248.0) 
4. Изменить конфигурацию маршрутизатора
5. Изменить соответствующие правила в шейпере маршрутизатора.
6. Изменить конфигурации всех коммутаторов.
7. Отказаться от IP-MAC-Port Binding на портах доступа и использовать Option82 DHCP сервера.

Вроде всё. 

Пункты 4,5,6 должны быть исполнены одновременно, дабы не останавливать работу сети или её части. 

Для решения первого пункта написал два скрипта на PHP и использовал MySQL. Все действие происходит на Ubuntu 11.04. Дополнительные пакеты: snmp и php5-snmp. Устанавливаются через sudo apt-get install snmp и sudo apt-get install php5-snmp.

Создадим базу IPM в MySQL, я сделал это с помощью phpmyadmin. В базе всего две таблицы одна для коммутаторов, вторая для связок IP-MAC-Port Binding. 

Для коммутаторов.

CREATE TABLE
`comutator` (
`id` INT(5) NOT NULL ,
`ip` CHAR(15) NOT NULL,
`mac` CHAR(30) NOT NULL,
`model` CHAR(20) NOT NULL,
`adress` CHAR(50) NOT NULL,
PRIMARY KEY(`id`,`ip`,`mac`)
)


В этой таблице: id — номер коммутатора, ip — его IP адрес, mac — его MAC адрес, model — модель коммутатора(нужно будет позже) и adress — это адрес установки (слава богу прописали это в system name коммутатора) 

Для связок IP-MAC-Port Binding.

CREATE TABLE
`ipmcli` (
`idcom` INT(5) NOT NULL,
`ipcl` CHAR(15) NOT NULL,
`maccl` CHAR(30) NOT NULL,
`port` CHAR(3) NOT NULL,
PRIMARY KEY(`ipcl`,`maccl`,`port`)

)


Для этой таблицы значение полей следующее — idcom — номер коммутатора (берется из первой таблицы), ipcl — IP адрес клиента, maccl — MAC адрес клиентского компьютера, ну и port — порт куда подключен абонент.

Первый скрипт, пробегает по диапазону IP адресов коммутаторов (заранее известен) и вытаскивает нужную информацию.

#!/usr/bin/php
<?php
$db_host = "localhost";
$db_user = "ВАШ ПОЛЬЗОВАТЕЛЬ";
$db_pass = "ВАШ ПАРОЛЬ";
$db_name = "ipm";
$id = 0;
$conn = mysql_connect($db_host, $db_user, $db_pass) or die(mysql_error());
mysql_select_db($db_name);

for ($pi = 1; $pi < 100; $pi++)
{
$ModelType = '';
$ip = "xxx.xxx.xxx.".$pi; //ВАША СЕТЬ КОММУТАТОРОВ
$rcomm = 'public';
$sysDescr = snmpget($ip, $rcomm, ".1.3.6.1.2.1.1.1.0",100000);//Модель коммутатора
$macDescr[0] = snmpget($ip, $rcomm, "iso.3.6.1.2.1.2.2.1.6.1",100000);//МAC адрес коммутатора
$macDescr[1] = eregi_replace("Hex-STRING: ","",$macDescr[0]);
$sysName[0] = snmpget($ip, $rcomm, "iso.3.6.1.2.1.1.5.0",100000);//Имя коммотатора
$sysName[1] = eregi_replace("STRING: ","",$sysName[0]);

// Определяем тип модели

if (stripos($sysDescr, 'DES-1228/ME') !== false)
{
$ModelType = 'DES-1228ME';
}
if (stripos($sysDescr, 'DES-3627G') !== false)
{
$ModelType = 'DES-3627G';
}
if (stripos($sysDescr, 'DES-3200-28F') !== false)
{
$ModelType = 'DES-3200-28F';
}
if (stripos($sysDescr, 'DES-3200-10') !== false)
{
$ModelType = 'DES-3200-10';
}
mysql_query("insert ignore into comutator (id,ip,mac, model, adress) values ('".($id=$id+1)."','".$ip."','".$macDescr[1]."','".$ModelType."',".$sysName[1].")"); //ложим в базу
}
mysql_close($conn);
?>


Второй скрипт из каждого коммутатора вытаскивает нужную информацию.

#!/usr/bin/php
<?php
$db_host = "localhost";
$db_user = "ВАШ ПОЛЬЗОВАТЕЛЬ";
$db_pass = "ВАШ ПАРОЛЬ";
$db_name = "ipm";
$conn = mysql_connect($db_host, $db_user, $db_pass) or die(mysql_error());
mysql_select_db($db_name);
$result = mysql_query("SELECT * FROM `comutator` WHERE 1") or die("Invalid query: " . mysql_error());
echo"\n";
while ($row = mysql_fetch_array($result)) {

$ip=$row['ip'];
$rcomm='public';

// список IP в таблице IMP
$ip_imp = str_ireplace('IpAddress: ', '',($swIMBip = @snmpwalk($ip, $rcomm, ".1.3.6.1.4.1.171.12.23.4.1.1.1",1000000)));
// список MAC в таблице IMP
$mac_imp = str_ireplace(' ', '', (str_ireplace('Hex-STRING: ', '',($swIMBmac = @snmpwalk($ip, $rcomm, ".1.3.6.1.4.1.171.12.23.4.1.1.2",1000000)))));

foreach( $mac_imp as $key => $value)
{
//echo "$key = $value \n";
$value =str_ireplace('STRING:', '', $value)."\n";
$value =str_ireplace('"', '', $value)."\n";
if(strlen($value)<12)
{
$mac_imp[$key]=strToHex($value);
}
}

$swIMBports = @snmpwalk($ip, $rcomm, ".1.3.6.1.4.1.171.12.23.4.1.1.4",1000000);


count($ip_imp);
for ($arr_count=0;$arr_count<count($ip_imp);$arr_count++)
{

//Определение порта в IMP

$imb_port = str_ireplace('Hex-STRING: ', '', $swIMBports[$arr_count])."\n";
$imb_port = str_ireplace('00 00 00 00', '', $imb_port)."\n";
$imb_port = str_ireplace(' ', '', $imb_port)."\n";
$imb_port = decbin(hexdec($imb_port))."\n";


while (strlen($imb_port) <= 32)$imb_port = "0" . $imb_port;

$imb_ports = "";

for ($w = 0; $w < strlen($imb_port); $w++)
{

if ($imb_port[$w] == "1")
{
$imb_ports .= ( $w + 1 );
if ($w < strripos($imb_port, '1')) $imb_ports .= ", ";
}
}

$results = mysql_query("INSERT IGNORE INTO ipmcli (idcom,ipcl,maccl,port) values ('".$row['id']."','".$ip_imp[$arr_count]."','".$mac_imp[$arr_count]."','".$imb_ports."') ") or die("Invalid query: " . mysql_error());;

}
}
}
mysql_close($conn);
?>


В итоге во второй таблице получаем что, кто и к какому порту подключен.

Вместо заключения.

Прошу сильно за литературное изложение не пинать, за реализацию сего — можно, дабы пришло понимание как правильно все делается и работает.

Спасибо за внимание, надеюсь продолжить публиковать небольшие статейки, как я справлялся с этой проблемой. Осталось еще шесть пунктов.

Комментариев нет:

Отправить комментарий