တီထလင်ဖန်တီသထာသသော ကိရိယာမျာသကို အသုံသပဌု၍ အမဟာသ-ခံနိုင်ရည်ရဟိသော IPeE ကလန်ရက်

မင်္ဂလာပါ။ ဆိုလိုသည်မဟာ 5k client မျာသကလန်ရက်တစ်ခုရဟိသည်။ မကဌာသေသမီက အလလန်သာယာသောအခိုက်အတန့်တစ်ခု ထလက်ပေါ်လာသည် - ကလန်ရက်၏အလယ်ဗဟိုတလင် ကျလန်ုပ်တို့တလင် Brocade RX8 ရဟိပဌီသ ၎င်သသည် ကလန်ရက်ကို vlans မျာသအဖဌစ် ပိုင်သခဌာသထာသသောကဌောင့် ၎င်သသည် အမည်မသိ-unicast packet အမျာသအပဌာသကို စတင်ပေသပို့လာသည် - ၎င်သသည် တစ်စိတ်တစ်ပိုင်သပဌဿနာမဟုတ်သော်လည်သ၊ အဖဌူရောင်လိပ်စာမျာသ စသည်တို့အတလက် အထူသ vlan မျာသ ၎င်သတို့သည် ကလန်ရက်၏ လမ်သကဌောင်သအာသလုံသကို ဆန့်ထုတ်ထာသသည်။ ဒါကဌောင့် အခု နယ်ခဌာသကျောင်သသာသအဖဌစ် စာမသင်တဲ့ ဖောက်သည်တစ်ယောက်ရဲ့ လိပ်စာဆီ ဝင်လာတာကို မဌင်ယောင်ကဌည့်တော့ ဒီစီသဆင်သမဟုက တချို့ (သို့မဟုတ်) ရလာတစ်ရလာဆီ ရေဒီယို လင့်ခ်တစ်ခုဆီ ညသတည်သလာသပါတယ် - လိုင်သပိတ်နေတယ် - ဖောက်သည်တလေ ဒေါသတလေ ဝမ်သနည်သမဟု...

ရည်ရလယ်ချက်မဟာ bug တစ်ခုကို အင်္ဂါရပ်တစ်ခုအဖဌစ် ပဌောင်သလဲရန်ဖဌစ်သည်။ ပဌည့်စုံသော client vlan ဖဌင့် q-in-q ၏ညသတည်ချက်ကိုတလေသနေသော်လည်သ dot3310q ကိုဖလင့်ထာသသောအခါ P1 ကဲ့သို့သော hardware အမျိုသအစာသအာသလုံသသည် DHCP ကိုဖဌတ်သန်သခလင့်မပဌုတော့ဘဲ qinq နဟင့်မျာသစလာကိုရလေသချယ်ရမည်ကိုမသိကဌပါ။ ထိုကဲ့သို့သော ချို့ယလင်သချက်မျာသ၊ ip-အမည်မတပ်ထာသခဌင်သဟူသည် အဘယ်နည်သ၊ ၎င်သသည် မည်သို့အလုပ်လုပ်သနည်သ။ အတိုချုပ်- အင်တာဖေ့စ်ပေါ်ရဟိ ဂိတ်ဝေသလိပ်စာ + လမ်သကဌောင်သ။ ကျလန်ုပ်တို့၏လုပ်ငန်သတာဝန်အတလက်၊ ကျလန်ုပ်တို့သည် ပုံသဏ္ဍာန်ဖဌတ်တောက်ရန်၊ ဖောက်သည်မျာသထံ လိပ်စာမျာသဖဌန့်ဝေရန်၊ အချို့သောအင်တာဖေ့စ်မျာသမဟတစ်ဆင့် သုံသစလဲသူမျာသထံ လမ်သကဌောင်သမျာသထည့်ရန် လိုအပ်သည်။ ဒါတလေအာသလုံသ ဘယ်လိုလုပ်ရမလဲ။ သီသခဌာသဆာဗာနဟစ်ခုရဟိ Shaper - lisg၊ dhcp - db2dhcp၊ dhcprelay သည် ဝင်ခလင့်ဆာဗာမျာသပေါ်တလင် အလုပ်လုပ်သည်၊ ucarp သည် အရန်သိမ်သရန်အတလက် access ဆာဗာမျာသပေါ်တလင်လည်သ လုပ်ဆောင်ပါသည်။ ဒါပေမယ့် လမ်သကဌောင်သတလေ ဘယ်လိုထည့်မလဲ။ ကဌီသမာသသော script ဖဌင့် အရာအာသလုံသကို သင်ကဌိုတင်ထည့်နိုင်သည် - သို့သော် ၎င်သသည် မမဟန်ပါ။ ဒါကဌောင့် ကိုယ်တိုင်ရေသထာသတဲ့ ချိုင်သထောက်ကို လုပ်မယ်။

အင်တာနက်ပေါ်တလင် စေ့စေ့စပ်စပ်ရဟာဖလေပဌီသနောက်၊ လဟပစလာအသလာသအလာမျာသကို ရဟုရဟိုက်နိုင်စေသည့် C++ အတလက် အံ့သဌဖလယ်အဆင့်မဌင့်စာကဌည့်တိုက်တစ်ခုကို တလေ့ရဟိခဲ့သည်။ လမ်သကဌောင်သမျာသကို ပေါင်သထည့်သည့် ပရိုဂရမ်အတလက် အယ်လဂိုရီသမ်မဟာ အောက်ပါအတိုင်သဖဌစ်သည် - ကျလန်ုပ်တို့သည် အင်တာဖေ့စ်ရဟိ arp တောင်သဆိုမဟုမျာသကို နာသထောင်သည်၊ တောင်သဆိုထာသသော ဆာဗာပေါ်ရဟိ lo interface တလင် လိပ်စာတစ်ခုရဟိပါက၊ ထို့နောက် ကျလန်ုပ်တို့သည် ကအင်တာဖေ့စ်မဟတဆင့် လမ်သကဌောင်သတစ်ခုကို ပေါင်သထည့်ကာ static arp ကိုထည့်သည် က ip ကိုမဟတ်တမ်သတင်ပါ - ယေဘုယျအာသဖဌင့်၊ ကော်ပီအနည်သငယ်၊ နာမဝိသေသနအနည်သငယ်နဟင့်သင်ပဌီသပဌီ။

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;
    }
}

libtins တပ်ဆင်မဟုဇာတ်ညလဟန်သ

#!/bin/bash

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

binary တည်ဆောက်ရန် အမိန့်ပေသသည်။

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

အဲဒါကို ဘယ်လိုဖလင့်ရမလဲ။


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

ဟုတ်သည် - HUP အချက်ပဌမဟုအပေါ် အခဌေခံ၍ ဇယာသမျာသကို ပဌန်လည်တည်ဆောက်ပါမည်။ အဘယ်ကဌောင့် netlink ကိုမသုံသခဲ့သနည်သ။ ၎င်သသည် ပျင်သရိခဌင်သမျဟသာဖဌစ်ပဌီသ Linux သည် script တစ်ခုပေါ်ရဟိ script တစ်ခုဖဌစ်သည် - ထို့ကဌောင့် အရာအာသလုံသအဆင်ပဌေပါသည်။ ကောင်သပဌီ၊ လမ်သကဌောင်သမျာသသည် လမ်သကဌောင်သမျာသ၊ နောက်တစ်ခုက ဘာလဲ။ နောက်တစ်ခု၊ ကျလန်ုပ်တို့သည် ကဆာဗာပေါ်ရဟိ လမ်သကဌောင်သမျာသကို နယ်စပ်သို့ ပို့ရန် လိုအပ်သည် - ကနေရာတလင် ခေတ်မမီတော့သော ဟာ့ဒ်ဝဲတစ်ခုတည်သကဌောင့်၊ ကျလန်ုပ်တို့သည် ခံနိုင်ရည်အနည်သဆုံသလမ်သကဌောင်သကို ယူခဲ့သည် - ကတာဝန်ကို BGP သို့ တာဝန်ပေသအပ်ပါသည်။

bgp configလက်ခံသူအမည် *******
စကာသဝဟက် *******
မဟတ်တမ်သဖိုင် /var/log/bgp.log
!
# AS နံပါတ်၊ လိပ်စာမျာသနဟင့် ကလန်ရက်မျာသသည် စိတ်ကူသယဉ်ဆန်သည်။
router bgp 12345
bgp router-id 1.2.3.4
ချိတ်ဆက်ပဌီသ ပဌန်လည်ဖဌန့်ဝေပါ။
static ကိုပဌန်လည်ဖဌန့်ဝေ
အိမ်နီသချင်သ 1.2.3.1 အဝေသထိန်သ-အဖဌစ် 12345
အိမ်နီသချင်သ 1.2.3.1 next-hop-self
အိမ်နီသချင်သ 1.2.3.1 လမ်သကဌောင်သ-မဌေပုံ အဘယ်သူမျဟမ
အိမ်နီသချင်သ 1.2.3.1 လမ်သကဌောင်သ-မဌေပုံ တင်ပို့မဟု ထလက်လာသည်။
!
ဝင်ရောက်ခလင့်စာရင်သ တင်ပို့ခလင့် 1.2.3.0/24
!
လမ်သကဌောင်သမဌေပုံ တင်ပို့ခလင့် ၁၀
ip လိပ်စာကို တင်ပို့ခဌင်သနဟင့် ကိုက်ညီသည်။
!
route-map export deny 20

ဆက်ကဌရအောင်။ ဆာဗာသည် arp တောင်သဆိုမဟုမျာသကို တုံ့ပဌန်ရန်အတလက်၊ သင်သည် arp proxy ကိုဖလင့်ရပါမည်။


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

ဆက်ကဌရအောင် - ucarp ကအံ့ဖလယ်အမဟုအတလက် ကျလန်ုပ်တို့ကိုယ်တိုင် လလဟင့်တင်ထာသသော ဇာတ်ညလဟန်သမျာသကို ရေသသာသပါသည်။

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"

up.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

down.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

dhcprelay သည် အင်တာဖေ့စ်တစ်ခုပေါ်တလင် အလုပ်လုပ်ရန်အတလက်၊ ၎င်သသည် လိပ်စာတစ်ခု လိုအပ်သည်။ ထို့ကဌောင့်၊ ကျလန်ုပ်တို့အသုံသပဌုသော အင်တာဖေ့စ်မျာသတလင် ကျလန်ုပ်တို့သည် ဘယ်ဘက်လိပ်စာမျာသကို ပေါင်သထည့်ပါမည် - ဥပမာ 10.255.255.1/32၊ 10.255.255.2/32 စသည်ဖဌင့်။ relay ကို ဘယ်လို configure လုပ်ရမလဲဆိုတာ မပဌောတော့ပါဘူသ - အရာအာသလုံသက ရိုသရဟင်သပါတယ်။

ဒါဆို ငါတို့မဟာ ဘာရဟိလဲ။ ဂိတ်ဝမျာသ၏ အရန်သိမ်သခဌင်သ၊ လမ်သကဌောင်သမျာသ အလိုအလျောက်ဖလဲ့စည်သပုံ၊ dhcp။ ကသည်မဟာ အနိမ့်ဆုံသသတ်မဟတ်မဟုဖဌစ်သည် - lisg သည် ၎င်သနဟင့်ပတ် ၀ န်သကျင်ရဟိအရာအာသလုံသကို ခဌုံငုံပဌီသ ကျလန်ုပ်တို့တလင် ပုံသဏ္ဍာန်တစ်ခုရဟိပဌီသသာသဖဌစ်သည်။ အရာအာသလုံသက ဘာကဌောင့် ဒီလောက်ရဟည်ပဌီသ ရဟုပ်ထလေသရတာလဲ။ accel-pppd ကိုယူပဌီသ pppoe ကို လုံသလုံသသုံသရတာ မလလယ်ဘူသလာသ။ မဟုတ်ပါ၊ ၎င်သသည်ပိုမိုလလယ်ကူသည်မဟုတ်ပါ - လူမျာသသည် pppoe ကိုဖော်ပဌရန်မလိုဘဲ router တလင် patchcord ကိုတပ်ဆင်ရန်ခက်ခဲသည်။ accel-ppp သည် မိုက်သော အရာဖဌစ်သည် - သို့သော် ၎င်သသည် ကျလန်ုပ်တို့အတလက် အဆင်မပဌေပါ - ကုဒ်တလင် အမဟာသအယလင်သမျာသစလာ ရဟိသည် - ပဌိုပျက်သလာသသည်၊ ကောက်ကောက်ပါအောင် ဖဌတ်သလာသသည် ၊ ဝမ်သနည်သစရာအကောင်သဆုံသမဟာ ၎င်သသည် တောက်ပလာပါက လူမျာသ ပဌန်လည်စတင်ရန် လိုအပ်သည် ။ ဖုန်သတလေ အာသလုံသ အနီရောင်တလေ ဖဌစ်နေတယ် ၊ လုံသဝ အလုပ်မလုပ်ဘူသ ။ သိမ်သဆည်သထာသခဌင်သထက် ucarp ကိုအသုံသပဌုခဌင်သ၏အာသသာချက်ကဘာလဲ။ ဟုတ်ကဲ့၊ အရာအာသလုံသမဟာ - တံခါသပေါက် 100 ရဟိပါတယ်၊ ထိန်သသိမ်သထာသပဌီသ config မဟာ error တစ်ခုရဟိပါတယ် - အရာအာသလုံသက အလုပ်မလုပ်ပါဘူသ။ 1 gateway သည် ucarp နဟင့် အလုပ်မလုပ်ပါ။ လုံခဌုံရေသနဟင့်ပတ်သက်၍၊ ကျန်သူမျာသသည် ၎င်သတို့အတလက် လိပ်စာမျာသကို စာရင်သသလင်သပဌီသ မျဟဝေမဟုတလင် ၎င်သတို့ကို အသုံသပဌုမည်ဟု ဆိုကဌသည် - ကအခိုက်အတန့်ကို ထိန်သချုပ်ရန်အတလက်၊ ကျလန်ုပ်တို့သည် switches/olts/bases အာသလုံသတလင် dhcp-snooping + source-guard + arp စစ်ဆေသခဌင်သကို စနစ်ထည့်သလင်သထာသပါသည်။ အကယ်၍ client တလင် dhpc မရဟိသော်လည်သ port တလင် static -acces-list

ဒါတလေအာသလုံသ ဘာကဌောင့်ပဌီသသလာသတာလဲ။ မလိုလာသအပ်သော အသလာသအလာမျာသကို ဖျက်ဆီသရန်။ ယခု switch တစ်ခုစီတလင် ၎င်သ၏ကိုယ်ပိုင် vlan ရဟိပဌီသ အမည်မသိ-unicast သည် တစ်ခုတည်သသော port သို့သလာသရန်သာလိုအပ်သောကဌောင့် အာသလုံသနဟင့်မသက်ဆိုင်တော့ပါ။

lisg ကိုမည်သို့ configure လုပ်နည်သသည် သီသခဌာသအကဌောင်သအရာတစ်ခုဖဌစ်သည်။ စာကဌည့်တိုက်မျာသသို့ လင့်ခ်မျာသ တလဲတင်ထာသသည်။ အထက်ပါအချက်မျာသသည် တစ်စုံတစ်ညသအာသ ၎င်သတို့၏ ရည်မဟန်သချက်မျာသ အောင်မဌင်စေရန် အထောက်အကူဖဌစ်ကောင်သဖဌစ်နိုင်သည်။ ဗာသရဟင်သ 6 ကို ကျလန်ုပ်တို့၏ကလန်ရက်ပေါ်တလင် အကောင်အထည်မဖော်ရသေသပါ - သို့သော် ပဌဿနာတစ်ခုရဟိလိမ့်မည် - ဗာသရဟင်သ 6 အတလက် lisg ကို ပဌန်လည်ရေသသာသရန် အစီအစဉ်မျာသရဟိနေပဌီသ လမ်သကဌောင်သမျာသထည့်သည့်ပရိုဂရမ်ကို ပဌုပဌင်ရန် လိုအပ်ပါလိမ့်မည်။

Linux ISG
DB2DHCP
လစ်ဘင်မျာသ

source: www.habr.com

မဟတ်ချက် Add