مرحبا لذلك هناك شبكة من العملاء 5K. في الآونة الأخيرة ، ظهرت لحظة غير سعيدة - في وسط الشبكة ولدينا Brocade RX8 وبدأت في إرسال الكثير من الحزم المجهولة أحادية الإرسال ، نظرًا لأن الشبكة مقسمة إلى شبكات محلية ظاهرية - هذه ليست مشكلة جزئيًا ولكن هناك بعض الشبكات المحلية الخاصة للعناوين البيضاء ، إلخ. وتمتد في جميع اتجاهات الشبكة. لذا تخيل الآن تدفقًا واردًا على عنوان عميل لا يدرس كحدود ، وهذا الدفق يطير باتجاه وصلة الراديو لبعض القرى (وهكذا في كل شيء) - القناة مسدودة - العملاء شريرون - حزينون ...
المهمة هي تحويل الخطأ إلى ميزة. لقد فكرت في اتجاه q-in-q مع شبكة محلية ظاهرية كاملة للعميل ، ولكن جميع أنواع القطع من الحديد مثل P3310 عندما أقوم بتشغيل dot1q تتوقف عن اجتياز DHCP ، ما زالوا لا يعرفون كيف الانتقائية qinq والكثير من العكازات تحت الماء مثل ذلك. ما هو ip-unberbered وكيف يعمل؟ إذا لفترة وجيزة جدا - عنوان البوابة + الطريق على الواجهة. لمهمتنا ، نحتاج إلى: قص الصيغ ، توزيع العناوين على العملاء ، إضافة طرق للعملاء عبر واجهات محددة. كيف نفعل كل هذا؟ المشكل - lisg ، dhcp - db2dhcp على خادمين مستقلين ، يعمل dhcprelay على خوادم الوصول ، يعمل ucarp أيضًا على خوادم الوصول - للنسخ الاحتياطي. ولكن كيف تضيف طرق؟ يمكنك إضافة كل شيء في نص برمجي كبير مقدمًا - لكن هذا ليس صحيحًا. لذلك نحن سوف السياج عكاز عصامي.
بعد البحث بدقة على الإنترنت ، وجدت مكتبة رائعة رفيعة المستوى لـ c ++ تتيح لك شم حركة المرور بشكل جميل. فيما يلي خوارزمية البرنامج الذي يضيف المسارات - نستمع إلى طلبات واجهة ARP ، إذا كان لدينا عنوان خادم على واجهة lo التي نطلبها ، أضف المسار عبر هذه الواجهة وقم بإضافة إدخال ARP ثابت إلى عنوان 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; } }
الأمر لبناء الثنائي 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
!
# عدد من العنوان والعنوان والشبكة اخترع
جهاز التوجيه bgp 12345
bgp router-id 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
نواصل. لكي يستجيب الخادم لطلبات 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"
لكي يعمل dhcprelay على واجهة ، فإنه يحتاج إلى عنوان. لذلك ، على الواجهات التي نستخدمها ، سنضيف العناوين اليسرى - على سبيل المثال ، 10.255.255.1/32 ، 10.255.255.2/32 ، إلخ. لن أخبرك عن كيفية إعداد المرحلات - كل شيء بسيط هناك.
إذن ما لدينا. بوابات النسخ الاحتياطي ، طرق الضبط التلقائي ، DHCP. هذا هو الحد الأدنى من مجموعة - حتى هو ثمل على ذلك ولدينا بالفعل المشكل. لماذا كل شيء طويل وبارد؟ ليس من السهل أن تأخذ تسارع PPPD وعموما استخدام PPPOE؟ لا ، ليس الأمر أسهل - فالناس لا يكادون يتمكنون من تحزيم رقعة رقعة في جهاز التوجيه ، ناهيك عن pppoe. تعتبر ميزة التسريع - ppp شيءًا رائعًا - ولكنها لا تعمل من أجلنا - مجموعة من الأخطاء في الشفرة - إنها تدور وتقطع بشكل ملتوي ، والشيء المحزن هو أنه إذا تم تفتيحها ، فسيحتاج الناس إلى إعادة تشغيل كل شيء - الهواتف حمراء - بشكل عام ، لم تكن مناسبة. ما هو زائد استخدام ucarp بدلا من keepalived؟ نعم ، في كل شيء - هناك 100 بوابة ، keepalived وخطأ واحد في التكوين - لا يعمل كل شيء. 1 بوابة لا تعمل مع ucarp. فيما يتعلق بالأمان ، يقولون إن العناوين سيتم توزيعها على اليسار وسيتم استخدامها على الكرة - للتحكم في هذه اللحظة ، نقوم بتهيئة dhcp-snooping + source-guard + arp التفتيش على جميع المفاتيح / alt / قواعد. إذا لم يكن لدى العميل dhpc لكن احصائيات - قائمة acces على المنفذ.
لماذا تم كل هذا؟ لتدمير حركة المرور نحن لا نحب. الآن ، لدى كل مفتاح شبكة محلية ظاهرية خاصة به ولم يعد الخوف من الإرسال غير معروف ، حيث إنه يحتاج إلى الانتقال إلى منفذ واحد فقط وليس كل ذلك ... حسنًا ، الآثار الجانبية هي تكوين موحد للأجهزة وكفاءة عالية لتخصيص مساحة العنوان.
كيفية تكوين lisg هو موضوع منفصل. الروابط إلى المكتبات مرفقة. ربما شخص ما سوف يساعد أعلاه في تنفيذ مهامهم. لم نعرض بعد الإصدار 6 على شبكتنا - ولكن ستكون هناك مشكلة - هناك خطط لإعادة كتابة الإصدار السادس جيدًا ، وستحتاج إلى تعديل البرنامج الذي يضيف طرقًا.
Linux ISGDB2DHCPLibtinsUPD.
كل شيء تحول إلى أن يكون أكثر تعقيدًا ... اضطررت إلى كتابة شيطان طبيعي أو أكثر. والاستغناء عن وكيل ARP. الآن ، يجيب برنامج dap على arp ، كما يضيف / يزيل الطرق على الشبكات الفرعية للعملاء ، كما كان عليّ أن أتعلم كيفية العمل مع netlink. لقد تحولت إلى ميزة واحدة - عندما يتعرف Linux على ARP لبعض العناوين ، ثم بعد العثور على الواجهة - يأخذ العنوان الأول الذي يظهر من الآخر - والذي لا يستجيب له بعض العملاء - يتم حله باستخدام arptables.
بشكل عام ، يوجد بالفعل خيار عادي للرابط - هناك ، بالمناسبة ، يتم الاستماع إلى التغييرات في الطرق والعناوين وإضافة إزالة المسار عبر netlink (مع هذا الأخير ، كان الصداع فظيعًا)
جيثب