Sveiki. Tas nozÄ«mÄ, ka pastÄv 5 8 klientu tÄ«kls. Nesen pienÄca ne pÄrÄk patÄ«kams brÄ«dis - tÄ«kla centrÄ mums ir Brocade RXXNUMX un tas sÄka sÅ«tÄ«t daudz nezinÄmu-unicast pakeÅ”u, jo tÄ«kls ir sadalÄ«ts vlanos - tÄ daļÄji nav problÄma, BET ir speciÄlie vlani baltajÄm adresÄm utt. un tie ir izstiepti visos tÄ«kla virzienos. TÄtad tagad iedomÄjieties ienÄkoÅ”o plÅ«smu uz klienta adresi, kurÅ” nemÄcÄs kÄ pierobežas students un Ŕī plÅ«sma lido uz radiosaiti uz kÄdu (vai visu) ciematu - kanÄls ir aizsÄrÄjis - klienti ir dusmÄ«gi - skumjas...
MÄrÄ·is ir pÄrvÄrst kļūdu par lÄ«dzekli. Es domÄju q-in-q virzienÄ ar pilnvÄrtÄ«gu klienta vlan, bet visÄda aparatÅ«ra kÄ P3310, kad dot1q ir iespÄjots, beidz laist DHCP cauri, viÅi arÄ« nemÄk selektÄ«vo qinq un daudzi Å”Äda veida slazdiem. Kas ir ip unnambered un kÄ tas darbojas? Ä»oti Ä«si: vÄrtejas adrese + marÅ”ruts saskarnÄ. MÅ«su uzdevumam ir nepiecieÅ”ams: izgriezt veidotÄju, izplatÄ«t adreses klientiem, pievienot klientiem marÅ”rutus, izmantojot noteiktas saskarnes. KÄ to visu izdarÄ«t? Shaper - lisg, dhcp - db2dhcp uz diviem neatkarÄ«giem serveriem, piekļuves serveros darbojas dhcprelay, piekļuves serveros darbojas arÄ« ucarp - dublÄÅ”anai. Bet kÄ pievienot marÅ”rutus? JÅ«s varat pievienot visu iepriekÅ”, izmantojot lielu skriptu, taÄu tÄ nav taisnÄ«ba. TÄtad mÄs taisÄ«sim paÅ”rakstÄ«tu kruÄ·i.
PÄc pamatÄ«gas meklÄÅ”anas internetÄ atradu brÄ«niŔķīgu augsta lÄ«meÅa bibliotÄku priekÅ” C++, kas ļauj smuki izÅ”Åaukt trafiku. Programmas, kas pievieno marÅ”rutus, algoritms ir Å”Äds - mÄs klausÄmies arp pieprasÄ«jumus interfeisÄ, ja mums ir adrese uz lo interfeisa serverÄ«, kas tiek pieprasÄ«ta, tad mÄs pievienojam marÅ”rutu caur Å”o saskarni un pievienojam statisku arp ieraksti uz Å”o ip - vispÄr pÄris copy-paste, nedaudz Ä«paŔības vÄrda un darÄ«ts
'marÅ”rutÄtÄja' avoti
#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 instalÄcijas skripts
#!/bin/bash
git clone https://github.com/mfontanini/libtins.git
cd libtins
mkdir build
cd build
cmake ../
make
make install
ldconfig
Komanda izveidot binÄro
g++ main.cpp -o arp-rt -O3 -std=c++11 -lpthread -ltins
KÄ to palaist?
start-stop-daemon --start --exec /opt/ipoe/arp-routes/arp-rt -b -m -p /opt/ipoe/arp-routes/daemons/eth0.800.pid -- eth0.800
JÄ - tas pÄrbÅ«vÄs tabulas, pamatojoties uz HUP signÄlu. KÄpÄc neizmantoji netlink? Tas ir tikai slinkums un Linux ir skripts uz skripta ā tÄtad viss kÄrtÄ«bÄ. Nu, marÅ”ruti ir marÅ”ruti, kas tÄlÄk? TÄlÄk mums ir jÄnosÅ«ta marÅ”ruti, kas atrodas Å”ajÄ serverÄ«, uz robežu - Å”eit tÄs paÅ”as novecojuÅ”Äs aparatÅ«ras dÄļ mÄs izvÄlÄjÄmies mazÄkÄs pretestÄ«bas ceļu - mÄs uzdevÄm Å”o uzdevumu BGP.
bgp konfigurÄcijaresursdatora nosaukums *******
parole *****
žurnÄla fails /var/log/bgp.log
!
# AS numurs, adreses un tīkli ir fiktīvi
marÅ”rutÄtÄjs bgp 12345
bgp router-id 1.2.3.4
pÄrdalÄ«t savienots
pÄrdalÄ«t statisko
kaimiÅÅ” 1.2.3.1 tÄlvadÄ«bas pults ā kÄ 12345
kaimiÅÅ” 1.2.3.1 next-hop-self
kaimiÅÅ” 1.2.3.1 marÅ”ruta karte nav iekÅ”Ä
kaimiÅÅ” 1.2.3.1 marÅ”ruta kartes eksports ÄrÄ
!
piekļuves saraksta izveŔanas atļauja 1.2.3.0/24
!
marŔruta kartes izveŔanas atļauja 10
atbilst IP adreses eksportam
!
marŔruta kartes eksporta aizliegums 20
TurpinÄsim. Lai serveris atbildÄtu uz ARP pieprasÄ«jumiem, ir jÄiespÄjo arp starpniekserveris.
echo 1 > /proc/sys/net/ipv4/conf/eth0.800/proxy_arp
Ejam tÄlÄk - ucarp. MÄs paÅ”i rakstÄm Ŕī brÄ«numa palaiÅ”anas skriptus.
Viena dÄmona palaiÅ”anas piemÄrs
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
uz leju.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
Lai dhcprelay darbotos saskarnÄ, tai ir nepiecieÅ”ama adrese. TÄpÄc mÅ«su izmantotajÄs saskarnÄs mÄs pievienosim kreisÄs adreses - piemÄram, 10.255.255.1/32, 10.255.255.2/32 utt. Es jums neteikÅ”u, kÄ konfigurÄt releju - viss ir vienkÄrÅ”i.
Kas tad mums ir? VÄrteju dublÄÅ”ana, marÅ”rutu automÄtiska konfigurÄÅ”ana, dhcp. Tas ir minimÄlais komplekts - lisg arÄ« apvij visu un mums jau ir veidotÄjs. KÄpÄc viss ir tik garÅ” un mulsinoÅ”i? Vai nav vieglÄk paÅemt accel-pppd un lietot pppoe vispÄr? NÄ, tas nav vienkÄrÅ”Äk ā cilvÄki diez vai var ievietot ielÄpu vadu marÅ”rutÄtÄjÄ, nemaz nerunÄjot par pppoe. accel-ppp ir forÅ”a lieta - bet mums nederÄja - daudz kļūdu kodÄ - drÅ«p, Ŕķībi griež, un pats skumjÄkais ir tas, ka ja uzgaismoja - tad cilvÄkiem vajag pÄrlÄdÄt viss - telefoni ir sarkani - tas vispÄr nedarbojÄs. KÄda ir ucarp izmantoÅ”anas priekÅ”rocÄ«ba, nevis saglabÄÅ”ana? JÄ, visÄ - ir 100 vÄrtejas, Keepalived un viena kļūda konfigurÄcijÄ - viss nedarbojas. 1 vÄrteja nedarbojas ar ucarp. Par droŔību saka, ka kreisie reÄ£istrÄs sev adreses un izmantos uz share - lai kontrolÄtu Å”o momentu, uzstÄdÄ«jÄm dhcp-snooping + source-guard + arp pÄrbaude uz visiem slÄdžiem/oltiem/bÄzÄm. Ja klientam nav dhpc, bet statisks - piekļuves saraksts portÄ.
KÄpÄc tas viss tika darÄ«ts? Lai iznÄ«cinÄtu nevÄlamu satiksmi. Tagad katram slÄdzim ir savs vlan un nezinÄmais-unicast vairs nav biedÄjoÅ”i, jo jÄiet tikai uz vienu portu, nevis uz visiem... Nu, blakusefekti ir standartizÄta aprÄ«kojuma konfigurÄcija, lielÄka efektivitÄte adreÅ”u telpas pieŔķirÅ”anÄ.
KÄ konfigurÄt lisg ir atseviŔķa tÄma. Saites uz bibliotÄkÄm ir pievienotas. IespÄjams, iepriekÅ”minÄtais kÄdam palÄ«dzÄs sasniegt savus mÄrÄ·us. 6. versija vÄl netiek ieviesta mÅ«su tÄ«klÄ - taÄu bÅ«s problÄma - ir plÄnots pÄrrakstÄ«t lisg 6. versijai, un bÅ«s jÄlabo programma, kas pievieno marÅ”rutus.
Avots: www.habr.com