Jaringan IPeE toleran-lepat nganggo alat anu disampurnakeun

Halo. Ieu ngandung harti aya jaringan 5k klien. Nembe aya momen anu teu pikaresepeun pisan - di tengah jaringan kami gaduh Brocade RX8 sareng éta mimiti ngirim seueur pakét anu teu dipikanyaho-unicast, sabab jaringan dibagi kana vlans - ieu sawaréh henteu masalah, TAPI aya vlans husus pikeun alamat bodas, jsb. sarta aranjeunna stretched dina sakabéh arah jaringan. Janten ayeuna bayangkeun aliran asup ka alamat klien anu henteu diajar salaku murid wates sareng aliran ieu ngalayang ka arah tautan radio ka sababaraha (atanapi sadayana) désa - saluranna mampet - klien ambek - sedih ...

Tujuanana nyaéta ngarobih bug kana fitur. Kuring ieu pamikiran dina arah q-in-q sareng vlan klien full-fledged, tapi sagala sorts hardware kawas P3310, nalika dot1q diaktipkeun, eureun letting DHCP ngaliwatan, maranéhna ogé teu nyaho kumaha carana milih qinq selektif tur loba. pitfalls nanaon nu. Naon ip-unnambered sareng kumaha jalanna? Sakeudeung pisan: alamat gateway + rute dina panganteur. Pikeun tugas urang, urang kudu: motong shaper, ngadistribusikaeun alamat ka klien, nambahkeun ruteu ka klien ngaliwatan interfaces tangtu. Kumaha ngalakukeun sadayana ieu? Shaper - lisg, dhcp - db2dhcp dina dua server bebas, dhcprelay dijalankeun dina server aksés, ucarp ogé dijalankeun dina server aksés - pikeun cadangan. Tapi kumaha carana nambahkeun ruteu? Anjeun tiasa nambihan sadayana sateuacanna nganggo naskah anu ageung - tapi ieu sanés leres. Ku kituna urang bakal nyieun crutch ditulis sorangan.

Saatos milarian teleb dina Internét, kuring mendakan perpustakaan tingkat luhur anu saé pikeun C ++, anu ngamungkinkeun anjeun ngahirupkeun lalu lintas anu saé. Algoritma pikeun program anu nambihan rute nyaéta kieu - urang ngadangukeun pamundut arp dina antarmuka, upami urang gaduh alamat dina antarmuka lo dina server anu dipénta, teras urang tambahkeun rute ngalangkungan antarmuka ieu sareng tambahkeun arp statik. catetan ka ip ieu - sacara umum, sababaraha salinan-pastes, kecap sipat saeutik tur Anjeun geus rengse

Sumber tina '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;
    }
}

Aksara instalasi libtins

#!/bin/bash

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

Paréntah ngawangun binér

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

Kumaha ngajalankeunana?


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

Sumuhun - éta bakal ngawangun deui tabel dumasar kana sinyal HUP. Naha anjeun henteu nganggo netlink? Éta ngan kedul sareng Linux mangrupikeun skrip dina naskah - janten sadayana henteu kunanaon. Nya, rute mangrupikeun rute, naon salajengna? Salajengna, urang kedah ngirimkeun rute anu aya dina server ieu ka wates - di dieu, kusabab hardware luntur anu sami, kami nyandak jalur anu paling saeutik lalawanan - kami napelkeun tugas ieu ka BGP.

bgp confighostname *****
sandi *****
file log /var/log/bgp.log
!
# Nomer AS, alamat sareng jaringan fiktif
router bgp 12345
bgp router-id 1.2.3.4
redistribute disambungkeun
ngadistribusikaeun statik
tatangga 1.2.3.1 jauh-sakumaha 12345
tatangga 1.2.3.1 hareup-hop-diri
tatangga 1.2.3.1 rute-peta euweuh di
tatangga 1.2.3.1 rute-peta ékspor kaluar
!
aksés-daftar idin ékspor 1.2.3.0/24
!
ijin ékspor peta rute 10
cocog ékspor alamat ip
!
rute-peta ékspor mungkir 20

Hayu urang neruskeun. Supados server tiasa ngabales pamundut arp, anjeun kedah ngaktipkeun proxy arp.


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

Hayu urang ngaléngkah - ucarp. Urang sorangan nulis naskah peluncuran pikeun mujijat ieu.

Conto ngajalankeun hiji 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"

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

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

Pikeun dhcprelay tiasa dianggo dina antarmuka, peryogi alamatna. Ku alatan éta, dina panganteur anu kami anggo kami bakal nambahan alamat kénca - contona 10.255.255.1/32, 10.255.255.2/32, jsb. Kuring moal ngabejaan ka maneh kumaha ngonpigurasikeun relay - sagalana basajan.

Janten naon anu urang gaduh? Nyadangkeun gateways, konfigurasi otomatis ruteu, dhcp. Ieu set minimum - lisg ogé wraps sagalana sabudeureun éta sarta kami geus boga shaper a. Naha sadayana panjang sareng rumit? Naha henteu langkung gampang nyandak accel-pppd sareng nganggo pppoe sadayana? Henteu, éta henteu langkung saderhana - jalma boro tiasa nyocogkeun patchcord kana router, sanés deui pppoe. accel-ppp mangrupikeun hal anu saé - tapi éta henteu tiasa dianggo pikeun urang - aya seueur kasalahan dina kode - éta ancur, motong bengkok, sareng anu paling hanjelu nyaéta upami éta terang - maka jalma kedah ngamuat deui sagalana - teleponna beureum - teu jalan pisan. Naon kauntungan ngagunakeun ucarp tinimbang tetep hirup? Sumuhun, dina sagalana - aya 100 gateways, keepalived sarta hiji kasalahan dina config nu - sagalana teu jalan. 1 gateway teu dianggo kalayan ucarp. Ngeunaan kaamanan, aranjeunna nyarios yén anu kénca bakal ngadaptarkeun alamat pikeun diri sareng dianggo dina saham - pikeun ngontrol waktos ieu, urang nyetél dhcp-snooping + sumber-penjaga + inspeksi arp dina sadaya saklar / olts / basa. Mun klien nu teu boga dhpc tapi statik - acces-list on port nu.

Naha ieu sadayana dilakukeun? Pikeun ngancurkeun lalulintas nu teu dihoyongkeun. Ayeuna unggal switch boga vlan sorangan sarta kanyahoan-unicast geus euweuh pikasieuneun, saprak éta ngan perlu buka hiji port teu ka sadaya ... Muhun, efek samping mangrupakeun config parabot standardized, efisiensi gede dina allocating spasi alamat.

Kumaha ngonpigurasikeun lisg mangrupakeun topik misah. Tumbu ka perpustakaan napel. Panginten di luhur bakal ngabantosan batur pikeun ngahontal tujuanana. Vérsi 6 henteu acan dilaksanakeun dina jaringan kami - tapi bakal aya masalah - aya rencana pikeun nulis ulang lisg pikeun versi 6, sareng éta peryogi pikeun ngabenerkeun program anu nambihan rute.

Linux ISG
DB2DHCP
Libtins

sumber: www.habr.com

Tambahkeun komentar