Cibiyar sadarwa ta IPEE mai jurewa kuskure ta amfani da ingantattun kayan aikin

Sannu. Wannan yana nufin akwai hanyar sadarwa na abokan ciniki 5k. Kwanan nan wani lokaci mai ban sha'awa bai zo ba - a tsakiyar cibiyar sadarwar muna da Brocade RX8 kuma ya fara aika da fakitin Unicast da yawa da ba a sani ba, tun da an raba hanyar sadarwa zuwa vlans - wannan ba matsala ba ce, AMMA akwai. vlans na musamman don farar adireshi, da sauransu. kuma an miƙe su a duk sassan hanyar sadarwa. Don haka yanzu ka yi tunanin shigowar kwarara zuwa adireshin abokin ciniki wanda ba ya karatu a matsayin dalibin kan iyaka kuma wannan kwararar ta tashi zuwa hanyar haɗin rediyo zuwa wasu (ko duka) ƙauyen - tashar ta toshe - abokan cinikin sun fusata - bakin ciki ...

Manufar ita ce a juya kwaro zuwa sifa. Ina tunani a cikin hanyar q-in-q tare da cikakken abokin ciniki vlan, amma duk nau'ikan kayan aiki kamar P3310, lokacin da aka kunna dot1q, yana daina barin DHCP ta hanyar, suma ba su san yadda ake zaɓar qinq da yawa ba. irin wadannan matsaloli. Menene ip-unnambered kuma ta yaya yake aiki? A taƙaice sosai: adireshin ƙofa + hanya akan hanyar sadarwa. Don aikinmu, muna buƙatar: yanke mai siffa, rarraba adireshi ga abokan ciniki, ƙara hanyoyi zuwa abokan ciniki ta wasu musaya. Yadda za a yi duk wannan? Shaper - lisg, dhcp - db2dhcp akan sabobin masu zaman kansu guda biyu, dhcprelay yana gudana akan sabar shiga, ucarp kuma yana gudana akan sabar shiga - don madadin. Amma yadda za a ƙara hanyoyi? Kuna iya ƙara komai a gaba tare da babban rubutun - amma wannan ba gaskiya bane. Don haka za mu yi kullun da aka rubuta da kansa.

Bayan cikakken bincike akan Intanet, na sami babban ɗakin karatu na C++ mai ban sha'awa, wanda ke ba ku damar ɓata zirga-zirga da kyau. Algorithm na shirin da ke ƙara hanyoyi shine kamar haka - muna sauraron buƙatun arp akan mahaɗin, idan muna da adireshi akan lo interface akan uwar garken da aka nema, to sai mu ƙara hanya ta wannan hanyar sadarwa kuma mu ƙara arp a tsaye. rikodin zuwa wannan ip - gabaɗaya, ƴan kwafi-pastes, ɗan siffa kuma kun gama

Sources na 'router'

#include <stdio.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>

#include <tins/tins.h>
#include <map>
#include <iostream>
#include <functional>
#include <sstream>

using std::cout;
using std::endl;
using std::map;
using std::bind;
using std::string;
using std::stringstream;

using namespace Tins;

class arp_monitor {
public:
    void run(Sniffer &sniffer);
    void reroute();
    void makegws();
    string iface;
    map <string, string> gws;
private:
    bool callback(const PDU &pdu);
    map <string, string> route_map;
    map <string, string> mac_map;
    map <IPv4Address, HWAddress<6>> addresses;
};

void  arp_monitor::makegws() {
    struct ifaddrs *ifAddrStruct = NULL;
    struct ifaddrs *ifa = NULL;
    void *tmpAddrPtr = NULL;
    gws.clear();
    getifaddrs(&ifAddrStruct);
    for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
        if (!ifa->ifa_addr) {
            continue;
        }
        string ifName = ifa->ifa_name;
        if (ifName == "lo") {
            char addressBuffer[INET_ADDRSTRLEN];
            if (ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4
                // is a valid IP4 Address
                tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
                inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
            } else if (ifa->ifa_addr->sa_family == AF_INET6) { // check it is IP6
                // is a valid IP6 Address
                tmpAddrPtr = &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr;
                inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
            } else {
                continue;
            }
            gws[addressBuffer] = addressBuffer;
            cout << "GW " << addressBuffer << " is added" << endl;
        }
    }
    if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct);
}

void arp_monitor::run(Sniffer &sniffer) {
    cout << "RUNNED" << endl;
    sniffer.sniff_loop(
            bind(
                    &arp_monitor::callback,
                    this,
                    std::placeholders::_1
            )
    );
}

void arp_monitor::reroute() {
    cout << "REROUTING" << endl;
    map<string, string>::iterator it;
    for ( it = route_map.begin(); it != route_map.end(); it++ ) {
        if (this->gws.count(it->second) && !this->gws.count(it->second)) {
            string cmd = "ip route replace ";
            cmd += it->first;
            cmd += " dev " + this->iface;
            cmd += " src " + it->second;
            cmd += " proto static";
            cout << cmd << std::endl;
            cout << "REROUTE " << it->first << " SRC " << it->second << endl;
            system(cmd.c_str());
            cmd = "arp -s ";
            cmd += it->first;
            cmd += " ";
            cmd += mac_map[it->first];
            cout << cmd << endl;
            system(cmd.c_str());

        }
    }
    for ( it = gws.begin(); it != gws.end(); it++ ) {
	string cmd = "arping -U -s ";
	cmd += it->first;
	cmd += " -I ";
	cmd += this->iface;
	cmd += " -b -c 1 ";
	cmd += it->first;
        system(cmd.c_str());
    }
    cout << "REROUTED" << endl;
}

bool arp_monitor::callback(const PDU &pdu) {
    // Retrieve the ARP layer
    const ARP &arp = pdu.rfind_pdu<ARP>();

    if (arp.opcode() == ARP::REQUEST) {
	
        string target = arp.target_ip_addr().to_string();
        string sender = arp.sender_ip_addr().to_string();
        this->route_map[sender] = target;
        this->mac_map[sender] = arp.sender_hw_addr().to_string();
        cout << "save sender " << sender << ":" << this->mac_map[sender] << " want taregt " << target << endl;
        if (this->gws.count(target) && !this->gws.count(sender)) {
            string cmd = "ip route replace ";
            cmd += sender;
            cmd += " dev " + this->iface;
            cmd += " src " + target;
            cmd += " proto static";
//            cout << cmd << std::endl;
/*            cout << "ARP REQUEST FROM " << arp.sender_ip_addr()
                 << " for address " << arp.target_ip_addr()
                 << " sender hw address " << arp.sender_hw_addr() << std::endl
                 << " run cmd: " << cmd << endl;*/
            system(cmd.c_str());
            cmd = "arp -s ";
            cmd += arp.sender_ip_addr().to_string();
            cmd += " ";
            cmd += arp.sender_hw_addr().to_string();
            cout << cmd << endl;
            system(cmd.c_str());
        }
    }
    return true;
}

arp_monitor monitor;
void reroute(int signum) {
    monitor.makegws();
    monitor.reroute();
}

int main(int argc, char *argv[]) {
    string test;
    cout << sizeof(string) << endl;

    if (argc != 2) {
        cout << "Usage: " << *argv << " <interface>" << endl;
        return 1;
    }
    signal(SIGHUP, reroute);
    monitor.iface = argv[1];
    // Sniffer configuration
    SnifferConfiguration config;
    config.set_promisc_mode(true);
    config.set_filter("arp");

    monitor.makegws();

    try {
        // Sniff on the provided interface in promiscuous mode
        Sniffer sniffer(argv[1], config);

        // Only capture arp packets
        monitor.run(sniffer);
    }
    catch (std::exception &ex) {
        std::cerr << "Error: " << ex.what() << std::endl;
    }
}

rubutun shigarwa na libtins

#!/bin/bash

git clone https://github.com/mfontanini/libtins.git
cd libtins
mkdir build
cd build
cmake ../
make
make install
ldconfig

Umurnin gina binary

g++ main.cpp -o arp-rt -O3 -std=c++11 -lpthread -ltins

Yadda za a kaddamar da shi?


start-stop-daemon --start --exec  /opt/ipoe/arp-routes/arp-rt -b -m -p /opt/ipoe/arp-routes/daemons/eth0.800.pid -- eth0.800

Ee - zai sake gina teburin bisa siginar HUP. Me yasa baku amfani da netlink? Lalaci ne kawai kuma Linux rubutun ne akan rubutun - don haka komai yana da kyau. To, hanyoyi hanyoyi ne, me zai biyo baya? Bayan haka, muna buƙatar aika hanyoyin da ke kan wannan uwar garken zuwa kan iyaka - a nan, saboda kayan aikin da suka gabata, mun ɗauki hanyar mafi ƙarancin juriya - mun sanya wannan aikin ga BGP.

bgp configsunan masauki *******
kalmar sirri *******
log fayil /var/log/bgp.log
!
Lambar # AS, adireshi da cibiyoyin sadarwa na almara ne
na'ura mai ba da hanya tsakanin hanyoyin sadarwa bgp 12345
bgp na'ura mai ba da hanya tsakanin hanyoyin sadarwa-id 1.2.3.4
sake rarraba haɗa
sake rarraba a tsaye
makwabta 1.2.3.1 nesa-kamar 12345
maƙwabcin 1.2.3.1 na gaba-hop-kai
maƙwabci 1.2.3.1 taswirar hanya babu kowa a ciki
makwabta 1.2.3.1 hanya-taswirar fitarwa fita
!
Izinin fitarwa-jerin shiga 1.2.3.0/24
!
Izinin fitar da taswirar hanya 10
daidaita ip address fitarwa
!
hana fitar da taswirar hanya 20

Mu ci gaba. Domin uwar garken ya amsa buƙatun arp, dole ne ku kunna wakili na arp.


echo 1 > /proc/sys/net/ipv4/conf/eth0.800/proxy_arp

Mu ci gaba - ucarp. Mun rubuta rubutun ƙaddamarwa don wannan abin al'ajabi da kanmu.

Misalin gudu daya daemon


start-stop-daemon --start --exec  /usr/sbin/ucarp -b -m -p /opt/ipoe/ucarp-gen2/daemons/$iface.$vhid.$virtualaddr.pid -- --interface=eth0.800 --srcip=1.2.3.4 --vhid=1 --pass=carpasword --addr=10.10.10.1 --upscript=/opt/ipoe/ucarp-gen2/up.sh --downscript=/opt/ipoe/ucarp-gen2/down.sh -z -k 10 -P --xparam="10.10.10.0/24"

sama.sh


#!/bin/bash

iface=$1
addr=$2
gw=$3

vlan=`echo $1 | sed "s/eth0.//"`


ip ad ad $addr/32 dev lo
ip ro add blackhole $gw
echo 1 > /proc/sys/net/ipv4/conf/$iface/proxy_arp

killall -9 dhcrelay
/etc/init.d/dhcrelay zap
/etc/init.d/dhcrelay start


killall -HUP arp-rt

kasa.sh


#!/bin/bash

iface=$1
addr=$2
gw=$3

ip ad d $addr/32 dev lo
ip ro de blackhole $gw
echo 0 > /proc/sys/net/ipv4/conf/$iface/proxy_arp


killall -9 dhcrelay
/etc/init.d/dhcrelay zap
/etc/init.d/dhcrelay start

Domin dhcprelay yayi aiki akan mu'amala, yana buƙatar adireshi. Don haka, akan hanyoyin sadarwa da muke amfani da su za mu ƙara adiresoshin hagu - misali 10.255.255.1/32, 10.255.255.2/32, da sauransu. Ba zan gaya muku yadda ake saita gudun ba da sanda ba - komai yana da sauki.

To me muke da shi? Ajiyayyen hanyoyin ƙofofin, daidaitawar hanyoyin atomatik, dhcp. Wannan shine mafi ƙarancin saiti - lisg kuma yana nannade duk abin da ke kewaye da shi kuma mun riga mun sami mai siffa. Me yasa komai yayi tsayi da rudani? Shin bai fi sauƙi ba don ɗaukar accel-pppd da amfani da pppoe gaba ɗaya? A'a, ba shi da sauƙi - mutane ba za su iya shigar da patchcord cikin na'ura mai ba da hanya tsakanin hanyoyin sadarwa ba, ban da pppoe. accel-ppp abu ne mai sanyi - amma bai yi mana aiki ba - akwai kurakurai da yawa a cikin lambar - yana rugujewa, yana yanke karkace, kuma abin bakin ciki shine idan ya haskaka - to mutane suna buƙatar sake kunnawa. komai - wayoyin suna ja - bai yi aiki ba kwata-kwata. Menene amfanin amfani da ucarp maimakon kiyayewa? Ee, a cikin komai - akwai ƙofofin 100, masu kiyayewa da kuskure ɗaya a cikin saitin - komai baya aiki. ƙofa 1 baya aiki tare da ucarp. Game da tsaro, sun ce masu hagu za su yi rajistar adireshi don kansu kuma za su yi amfani da su a kan rabon - don sarrafa wannan lokacin, mun kafa dhcp-snooping + source-guard + arp dubawa a kan duk switches/olts/bases. Idan abokin ciniki bashi da dhpc amma a tsaye - jerin hanyoyin shiga a tashar jiragen ruwa.

Me yasa aka yi duk wannan? Don lalata zirga-zirga maras so. Yanzu kowane canji yana da nasa vlan kuma ba a sani ba-unicast ba ya zama mai ban tsoro, tun da yake kawai yana buƙatar zuwa tashar jiragen ruwa ɗaya kuma ba duka ba ... To, illa masu illa sune daidaitattun kayan aiki na kayan aiki, mafi girman inganci a rarraba sararin adireshin.

Yadda ake saita lisg wani batu ne daban. Ana haɗe hanyoyin haɗi zuwa ɗakunan karatu. Wataƙila abin da ke sama zai taimaka wa wani wajen cimma burinsa. Har yanzu ba a aiwatar da sigar 6 akan hanyar sadarwar mu ba - amma za a sami matsala - akwai shirye-shiryen sake rubuta lisg don sigar 6, kuma zai zama dole a gyara shirin da ke ƙara hanyoyin.

Linux ISG
Saukewa: DB2DHCP
Libtin

source: www.habr.com

Add a comment