اصلاحی ٹولز کا استعمال کرتے ہوئے غلطی برداشت کرنے والا IPeE نیٹ ورک

ہیلو. اس کا مطلب ہے کہ 5k کلائنٹس کا نیٹ ورک ہے۔ حال ہی میں ایک بہت ہی خوشگوار لمحہ آیا - نیٹ ورک کے بیچ میں ہمارے پاس ایک بروکیڈ RX8 ہے اور اس نے بہت سارے نامعلوم-یونیکاسٹ پیکٹ بھیجنا شروع کردیئے ہیں، چونکہ نیٹ ورک کو vlans میں تقسیم کیا گیا ہے - یہ جزوی طور پر کوئی مسئلہ نہیں ہے، لیکن وہاں موجود ہیں۔ سفید پتوں وغیرہ کے لیے خصوصی vlans اور وہ نیٹ ورک کی تمام سمتوں میں پھیلے ہوئے ہیں۔ تو اب تصور کریں کہ ایک ایسے کلائنٹ کے ایڈریس پر آنے والے بہاؤ کا جو سرحدی طالب علم کے طور پر نہیں پڑھ رہا ہے اور یہ بہاؤ کسی (یا تمام) گاؤں کے ریڈیو لنک کی طرف اڑتا ہے - چینل بند ہے - کلائنٹ ناراض ہیں - اداسی...

مقصد ایک بگ کو فیچر میں تبدیل کرنا ہے۔ میں ایک مکمل کلائنٹ ولان کے ساتھ q-in-q کی سمت میں سوچ رہا تھا، لیکن P3310 جیسے تمام قسم کے ہارڈ ویئر، جب dot1q فعال ہو جاتا ہے، DHCP کو جانے دینا بند کر دیتا ہے، وہ یہ بھی نہیں جانتے کہ کس طرح منتخب کرنا ہے اور بہت سے اس قسم کے نقصانات. ip-unnambered کیا ہے اور یہ کیسے کام کرتا ہے؟ بہت مختصر طور پر: انٹرفیس پر گیٹ وے ایڈریس + روٹ۔ اپنے کام کے لیے، ہمیں یہ کرنے کی ضرورت ہے: شیپر کو کاٹنا، کلائنٹس کو پتے تقسیم کرنا، مخصوص انٹرفیس کے ذریعے کلائنٹس کے لیے راستے شامل کرنا۔ یہ سب کیسے کریں؟ شیپر - lisg، dhcp - db2dhcp دو آزاد سرورز پر، dhcprelay رسائی سرورز پر چلتا ہے، ucarp بھی رسائی سرورز پر چلتا ہے - بیک اپ کے لیے۔ لیکن راستے کیسے شامل کریں؟ آپ ایک بڑی اسکرپٹ کے ساتھ سب کچھ پہلے سے شامل کر سکتے ہیں - لیکن یہ سچ نہیں ہے۔ تو ہم خود لکھی ہوئی بیساکھی بنائیں گے۔

انٹرنیٹ پر مکمل تلاش کے بعد، مجھے C++ کے لیے ایک شاندار اعلیٰ سطحی لائبریری ملی، جو آپ کو ٹریفک کو خوبصورتی سے سونگھنے کی اجازت دیتی ہے۔ روٹس کو شامل کرنے والے پروگرام کا الگورتھم مندرجہ ذیل ہے - ہم انٹرفیس پر آر پی کی درخواستوں کو سنتے ہیں، اگر ہمارے پاس سرور پر لو انٹرفیس پر کوئی ایڈریس ہے جس کی درخواست کی گئی ہے، تو ہم اس انٹرفیس کے ذریعے ایک روٹ شامل کرتے ہیں اور ایک جامد آر پی شامل کرتے ہیں۔ اس آئی پی پر ریکارڈ کریں - عام طور پر، چند کاپی پیسٹ، تھوڑی سی صفت اور آپ نے کام کر لیا۔

'راؤٹر' کے ذرائع

#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 سگنل کی بنیاد پر میزیں دوبارہ بنائے گا۔ آپ نے نیٹ لنک کیوں نہیں استعمال کیا؟ یہ صرف سستی ہے اور لینکس ایک اسکرپٹ پر ایک اسکرپٹ ہے - لہذا سب کچھ ٹھیک ہے۔ ٹھیک ہے، راستے راستے ہیں، آگے کیا ہے؟ اس کے بعد، ہمیں اس سرور پر موجود راستوں کو بارڈر پر بھیجنے کی ضرورت ہے - یہاں، اسی پرانے ہارڈ ویئر کی وجہ سے، ہم نے کم سے کم مزاحمت کا راستہ اختیار کیا - ہم نے یہ کام BGP کو سونپا۔

bgp تشکیلمیزبان کا نام *******
پاس ورڈ *******
لاگ فائل /var/log/bgp.log
!
# AS نمبر، پتے اور نیٹ ورک فرضی ہیں۔
راؤٹر bgp 12345
bgp راؤٹر آئی ڈی 1.2.3.4
منسلک دوبارہ تقسیم کریں
جامد کو دوبارہ تقسیم کریں۔
پڑوسی 1.2.3.1 remote-as 12345
پڑوسی 1.2.3.1 Next-hop-self
پڑوسی 1.2.3.1 روٹ میپ کوئی نہیں
پڑوسی 1.2.3.1 روٹ میپ ایکسپورٹ آؤٹ
!
رسائی کی فہرست برآمد کی اجازت 1.2.3.0/24
!
روٹ میپ ایکسپورٹ پرمٹ 10
آئی پی ایڈریس ایکسپورٹ سے میچ کریں۔
!
روٹ میپ ایکسپورٹ سے انکار 20

آئیے جاری رکھیں۔ سرور کے لیے arp کی درخواستوں کا جواب دینے کے لیے، آپ کو arp پراکسی کو فعال کرنا چاہیے۔


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"

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، وغیرہ۔ میں آپ کو یہ نہیں بتاؤں گا کہ ریلے کو کیسے ترتیب دیا جائے - سب کچھ آسان ہے۔

تو ہمارے پاس کیا ہے؟ گیٹ ویز کا بیک اپ، راستوں کی آٹو کنفیگریشن، ڈی ایچ سی پی۔ یہ کم از کم سیٹ ہے - lisg بھی اپنے ارد گرد ہر چیز کو لپیٹتا ہے اور ہمارے پاس پہلے سے ہی ایک شیپر موجود ہے۔ سب کچھ اتنا طویل اور الجھا ہوا کیوں ہے؟ کیا accel-pppd لینا اور pppoe کو مکمل طور پر استعمال کرنا آسان نہیں ہے؟ نہیں، یہ آسان نہیں ہے - لوگ مشکل سے پیچ کورڈ کو راؤٹر میں فٹ کر سکتے ہیں، pppoe کا ذکر نہیں کرنا۔ accel-ppp ایک اچھی چیز ہے - لیکن اس نے ہمارے لئے کام نہیں کیا - کوڈ میں بہت ساری غلطیاں ہیں - یہ ٹوٹ جاتا ہے، یہ ٹیڑھی سے کاٹتا ہے، اور سب سے افسوسناک بات یہ ہے کہ اگر یہ چمکتا ہے - تو لوگوں کو دوبارہ لوڈ کرنے کی ضرورت ہے سب کچھ - فون سرخ ہیں - اس نے بالکل کام نہیں کیا۔ Keepalived کے بجائے ucarp استعمال کرنے کا کیا فائدہ ہے؟ جی ہاں، ہر چیز میں - 100 گیٹ ویز ہیں، کیپ لیویڈ اور کنفیگریشن میں ایک ایرر - سب کچھ کام نہیں کرتا۔ 1 گیٹ وے ucarp کے ساتھ کام نہیں کرتا ہے۔ سیکورٹی کے بارے میں، ان کا کہنا ہے کہ بائیں والے اپنے لیے پتے رجسٹر کریں گے اور انہیں شیئر پر استعمال کریں گے - اس لمحے کو کنٹرول کرنے کے لیے، ہم نے تمام سوئچز/olts/بیسز پر dhcp-snooping + source-guard + arp معائنہ قائم کیا ہے۔ اگر کلائنٹ کے پاس ڈی ایچ پی سی نہیں ہے لیکن جامد ہے - پورٹ پر رسائی کی فہرست۔

یہ سب کیوں کیا گیا؟ ناپسندیدہ ٹریفک کو تباہ کرنے کے لیے۔ اب ہر سوئچ کا اپنا vlan ہے اور نامعلوم-unicast اب کوئی خوفناک نہیں ہے، کیونکہ اسے صرف ایک بندرگاہ پر جانے کی ضرورت ہے اور سب کو نہیں... ٹھیک ہے، ضمنی اثرات ایک معیاری آلات کی تشکیل ہیں، ایڈریس کی جگہ مختص کرنے میں زیادہ کارکردگی۔

lisg کو ترتیب دینے کا طریقہ ایک الگ موضوع ہے۔ لائبریریوں کے لنکس منسلک ہیں۔ شاید مندرجہ بالا کسی کو ان کے مقاصد کو حاصل کرنے میں مدد ملے گی. ہمارے نیٹ ورک پر ابھی تک ورژن 6 نافذ نہیں کیا جا رہا ہے - لیکن ایک مسئلہ ہو گا - ورژن 6 کے لیے lisg کو دوبارہ لکھنے کے منصوبے ہیں، اور اس پروگرام کو درست کرنا ضروری ہو گا جو روٹس کو شامل کرتا ہے۔

لینکس آئی ایس جی
DB2DHCP
لبٹنز

ماخذ: www.habr.com

نیا تبصرہ شامل کریں