የተሻሻሉ መሳሪያዎችን በመጠቀም ስህተትን የሚቋቋም የአይፒኢ አውታረ መረብ

ሀሎ. ይህ ማለት የ 5k ደንበኞች አውታረመረብ አለ. በቅርብ ጊዜ በጣም ደስ የማይል ጊዜ መጣ - በአውታረ መረቡ መሃል ላይ ብሮኬድ RX8 አለን እና ብዙ ያልታወቁ የዩኒካስት ፓኬቶችን መላክ ጀመረ ፣ ምክንያቱም አውታረ መረቡ ወደ vlans የተከፋፈለ ስለሆነ - ይህ በከፊል ችግር አይደለም ፣ ግን አሉ ልዩ vlans ለ ነጭ አድራሻዎች, ወዘተ. እና በሁሉም የኔትወርክ አቅጣጫዎች ተዘርግተዋል. እና አሁን እንደ ድንበር ተማሪ ለማይማር ደንበኛ ወደ አድራሻው እንደሚመጣ አስቡት እና ይህ ፍሰት ወደ አንዳንድ (ወይም ሁሉም) መንደር ወደ ራዲዮ ሊንክ ይበርራል - ቻናሉ ተዘጋግቷል - ደንበኞቹ ተናደዋል - ሀዘን...

ግቡ ስህተትን ወደ ባህሪ መለወጥ ነው። እኔ ሙሉ ባለ ሙሉ ደንበኛ vlan ጋር q-in-q አቅጣጫ እያሰብኩ ነበር, ነገር ግን እንደ P3310 ያሉ ሃርድዌር ሁሉም ዓይነት, dot1q ሲነቃ DHCP መፍቀድ ያቆማል, እነሱ ደግሞ qinq እና ብዙ መምረጥ እንዴት አያውቁም. እንደዚህ አይነት ወጥመዶች. ip-ያልተሰየመ ምንድን ነው እና እንዴት ነው የሚሰራው? በጣም ባጭሩ፡ መግቢያ በር አድራሻ + በበይነገጽ ላይ መንገድ። ለተግባራችን, እኛ ያስፈልገናል: ቅርጽ ሰጪውን መቁረጥ, አድራሻዎችን ለደንበኞች ማሰራጨት, በተወሰኑ መገናኛዎች በኩል ለደንበኞች መስመሮችን መጨመር. ይህን ሁሉ እንዴት ማድረግ ይቻላል? ሻፐር - lisg, dhcp - db2dhcp በሁለት ገለልተኛ አገልጋዮች ላይ, dhcprelay በመዳረሻ አገልጋዮች ላይ ይሰራል, ucarp እንዲሁ በመዳረሻ አገልጋዮች ላይ ይሰራል - ለመጠባበቂያ. ግን መንገዶችን እንዴት መጨመር ይቻላል? ሁሉንም ነገር በትልቅ ስክሪፕት አስቀድመው ማከል ይችላሉ - ግን ይህ እውነት አይደለም. ስለዚህ በእራስዎ የተጻፈ ክራች እንሰራለን.

በበይነመረቡ ላይ ጥልቅ ፍለጋ ካደረግኩ በኋላ ለ C++ ግሩም የሆነ ከፍተኛ ደረጃ ላይብረሪ አገኘሁ፣ ይህም ትራፊክን በሚያምር ሁኔታ ለማሽተት ያስችላል። መንገዶችን የሚጨምር የፕሮግራሙ አልጎሪዝም እንደሚከተለው ነው - በበይነገጹ ላይ የአርፕ ጥያቄዎችን እናዳምጣለን ፣ በተጠየቀው አገልጋይ ላይ በሎ በይነገጽ ላይ አድራሻ ካለን ፣ ከዚያ በዚህ በይነገጽ በኩል መንገድ እንጨምራለን እና የማይንቀሳቀስ አርፕ እንጨምራለን ። ወደዚህ ip ይመዝገቡ - በአጠቃላይ ፣ ጥቂት ቅጂዎች ፣ ትንሽ ቅጽል እና ጨርሰዋል

የ'ራውተር' ምንጮች

#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

ሁለትዮሽ ለመገንባት ትእዛዝ

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 አልተጠቀምክም? ስንፍና ብቻ ነው እና ሊኑክስ በስክሪፕት ላይ ያለ ስክሪፕት ነው - ስለዚህ ሁሉም ነገር ደህና ነው። ደህና፣ መንገዶች መንገዶች ናቸው፣ ቀጥሎ ምን አለ? በመቀጠል በዚህ አገልጋይ ላይ ያሉትን መንገዶች ወደ ድንበር መላክ አለብን - እዚህ ፣ በተመሳሳይ ጊዜ ያለፈበት ሃርድዌር ምክንያት ፣ አነስተኛውን የመቋቋም መንገድ ወስደናል - ይህንን ተግባር ለ BGP መደብን።

bgp ውቅርየአስተናጋጅ ስም *******
የይለፍ ቃል *******
የምዝግብ ማስታወሻ ፋይል /var/log/bgp.log
!
# AS ቁጥር፣ አድራሻዎች እና ኔትወርኮች ምናባዊ ናቸው።
ራውተር bgp 12345
bgp ራውተር-መታወቂያ 1.2.3.4
እንደገና ማሰራጨት ተገናኝቷል
የማይንቀሳቀስ እንደገና ማሰራጨት።
ጎረቤት 1.2.3.1 ሩቅ-እንደ 12345
ጎረቤት 1.2.3.1 ቀጣይ-ሆፕ-ራስ
ጎረቤት 1.2.3.1 መስመር ካርታ የለም
ጎረቤት 1.2.3.1 መስመር-ካርታ ወደ ውጭ መላክ
!
የመዳረሻ ዝርዝር ወደ ውጭ መላክ ፈቃድ 1.2.3.0/24
!
የመንገድ ካርታ ወደ ውጪ መላክ ፈቃድ 10
ግጥሚያ ip አድራሻ ወደ ውጭ መላክ
!
የመንገድ ካርታ ወደ ውጪ መላክ ውድቅ 20

እንቀጥል። አገልጋዩ ለአርፕ ጥያቄዎች ምላሽ እንዲሰጥ የአርፕ ፕሮክሲውን ማንቃት አለቦት።


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

እንቀጥል - ucarp. ለዚህ ተአምር የማስጀመሪያ ስክሪፕቶችን እራሳችን እንጽፋለን።

አንድ ዴሞን የማሄድ ምሳሌ


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"

ወደ ላይ.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

ታች.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, ወዘተ. ማስተላለፊያውን እንዴት እንደሚያዋቅሩ አልነግርዎትም - ሁሉም ነገር ቀላል ነው.

ታዲያ ምን አለን? የመተላለፊያ መንገዶች መጠባበቂያ፣ የመንገዶች ራስ-ማዋቀር፣ dcp. ይህ ዝቅተኛው ስብስብ ነው - ሊስግ ሁሉንም ነገር በዙሪያው ያጠቃልላል እና እኛ ቀድሞውኑ ሼር አለን. ለምንድነው ሁሉም ነገር በጣም ረጅም እና ውስብስብ የሆነው? accel-ppd ን መውሰድ እና በአጠቃላይ pppoe መጠቀም ቀላል አይደለም? አይ፣ ቀላል አይደለም - ሰዎች ፓtchኮርድን ወደ ራውተር መግጠም አይችሉም፣ ፒፖን ሳይጨምር። accel-ppp አሪፍ ነገር ነው - ግን ለኛ አልሰራም - በኮዱ ውስጥ ብዙ ስህተቶች አሉ - ይፈርሳል፣ በጥሞና ይቆርጣል፣ እና በጣም የሚያሳዝነው ነገር ከደመቀ - ከዚያ ሰዎች እንደገና መጫን አለባቸው። ሁሉም ነገር - ስልኮቹ ቀይ ናቸው - ምንም አልሰራም. ከማቆየት ይልቅ ዩካርፕን መጠቀም ጥቅሙ ምንድነው? አዎን, በሁሉም ነገር - 100 መግቢያዎች, የመጠባበቂያ እና አንድ ስህተት በማዋቀር ውስጥ - ሁሉም ነገር አይሰራም. 1 ጌትዌይ ከ ucarp ጋር አይሰራም። ከደህንነት ጋር በተያያዘ፣ ግራዎቹ ለራሳቸው አድራሻዎችን ይመዘግባሉ እና በአክሲዮኑ ላይ ይጠቀማሉ ይላሉ - ይህንን አፍታ ለመቆጣጠር በሁሉም ማብሪያ / olts/bases ላይ dhcp-snooping + Source-Guard + arp ፍተሻ አዘጋጅተናል። ደንበኛው dhpc ከሌለው ግን የማይንቀሳቀስ - የመዳረሻ ዝርዝር በወደቡ ላይ።

ይህ ሁሉ የሆነው ለምንድነው? ያልተፈለገ ትራፊክ ለማጥፋት. አሁን እያንዳንዱ ማብሪያ / ማጥፊያ የራሱ vlan አለው እና ያልታወቀ-ዩኒካስት ከአሁን በኋላ አስፈሪ አይደለም, ምክንያቱም ወደ አንድ ወደብ ብቻ መሄድ ስለሚያስፈልገው እና ​​ለሁሉም አይደለም ... ደህና, የጎንዮሽ ጉዳቶች ደረጃውን የጠበቀ የመሳሪያ ውቅር, የአድራሻ ቦታን በመመደብ የበለጠ ውጤታማነት ነው.

lisgን እንዴት ማዋቀር እንደሚቻል የተለየ ርዕስ ነው። ወደ ቤተመጻሕፍት የሚወስዱ አገናኞች ተያይዘዋል። ምናልባት ከላይ ያለው አንድ ሰው ግባቸውን ለማሳካት ይረዳዋል። ስሪት 6 በእኛ አውታረመረብ ላይ ገና አልተተገበረም - ግን ችግር ይኖራል - ለ 6 ስሪት lisg እንደገና ለመፃፍ እቅድ ተይዟል, እና መስመሮችን የሚጨምር ፕሮግራም ማስተካከል አስፈላጊ ይሆናል.

ሊኑክስ አይኤስጂ
DB2DHCP
ሊብቲንስ

ምንጭ: hab.com

አስተያየት ያክሉ