Una macchina Linux multihomed può implementare un vero modello Strong ES?
Caso d'uso specifico
Ho un sistema con cinque diverse interfacce, ciascuna connessa alla stessa sottorete, quindi lo stesso gateway per Internet.
- Vorrei ascoltare su ciascuna interfaccia separatamente sulla stessa porta e assicurarmi che i pacchetti escano sempre dalla stessa interfaccia in cui sono entrati e che i pacchetti che tentano di entrare nell'interfaccia "sbagliata" vengano scartati.
- Vorrei essere in grado di collegarmi a ciascuna interfaccia ed effettuare connessioni in uscita a destinazioni Internet che provengono sempre dallo stesso IP di origine a cui mi sono legato. Ad esempio,
curl --interface interface_ip http://ipecho.net/plain
dovrebbe mostrare sempre lo stesso indirizzo IP a cui mi sono legato con
--interface
. - Le route statiche potrebbero essere problematiche a causa dell'utilizzo di DHCP su una di queste interfacce.
RFC 1122
Da RFC 1122 – Requisiti per host Internet – Livelli di comunicazione, Sezione 3.3.4.2 – Requisiti multihoming:
Gli implementatori di host Internet hanno utilizzato due diversi
modelli concettuali per il multihoming, brevemente riassunti
nella discussione seguente. Questo documento non si basa su quale modello è preferito; ognuno sembra avere un
posto. Questa ambivalenza si riflette nel fatto che le questioni (A)
e (B) sono facoltative.
-
Modello ES forte
- Il modello Strong ES (End System, ovvero host)
enfatizza la distinzione host/gateway (ES/IS),
e pertanto sostituirebbe MUST con MAY nei problemi
(A ) e (B) sopra. Tende a modellare un
host multihomed come un insieme di host logici all'interno
dello stesso host fisico.Per quanto riguarda (A), i sostenitori del modello Strong ES
notano che i meccanismi di instradamento automatico di Internet
non potevano instradare un datagramma a un
interfaccia fisica che non corrispondeva al
indirizzo di destinazione.Nel modello Strong ES, il calcolo del percorso
per un datagramma in uscita è la mappatura:route(src IP addr, dest IP addr, TOS) -> gateway
Qui l'indirizzo di origine è incluso come parametro
per selezionare un gateway che sia direttamente
raggiungibile sull'interfaccia fisica corrispondente.
Tieni presente che questo modello richiede logicamente che in
in generale ci sia almeno un gateway predefinito e
preferibilmente più valori predefiniti per ogni origine IP
indirizzo.
Modello ES debole
- Questo punto di vista sminuisce la distinzione ES/IS e
sostituirebbe pertanto MUST NOT con MAY nei problemi
(A) e (B). Questo modello potrebbe essere il più
naturale per gli host che intercettano i protocolli di routing del gateway
ed è necessario per gli host che dispongono di
funzionalità di gateway incorporata.
Il modello ES debole può causare il fallimento del meccanismo di reindirizzamento
. Se un datagramma viene inviato a un'interfaccia fisica
che non corrisponde all'indirizzo di destinazione
, il gateway del primo hop
non si renderà conto quando deve inviare un reindirizzamento. D'altra parte
, se l'host dispone della funzionalità gateway
incorporata, dispone delle informazioni di instradamento
senza ascoltare i reindirizzamenti.
Nel modello Weak ES, il calcolo del percorso per un
datagramma in uscita è la mappatura:
route(dest IP addr, TOS) -> gateway, interface
Linux è un modello ES debole per impostazione predefinita, mentre FreeBSD e altre varietà Unix agiscono come sistemi ES forti. C'è un modo per farlo comportare più come un sistema Strong ES?
Cosa sysctl
o la configurazione in fase di compilazione dovrebbe essere impostata per farlo comportare come un Strong ES per impostazione predefinita, senza aggiungere regole di routing specifiche per nessuna nuova interfaccia che aggiungi? So che possiamo eseguire un filtro rigoroso del percorso dei sorgenti tramite net.ipv4.conf.default.rp_filter = 1
, ma sembra che ci sia molto di più. Come posso eseguire il routing basato sulla sorgente per impostazione predefinita?
Risposta accettata:
La semplice aggiunta di regole del firewall non sarà sufficiente per questo. Vuoi che il sistema instrada il traffico come se fossero due sistemi indipendenti che condividono lo stesso hardware e processi:ecco cos'è in effetti il modello Strong ES.
Correlati:Linux – pagina man trovata solo dopo aver eseguito con root?Quando miri a Strong ES Model in Linux, avrai prima bisogno di queste impostazioni sysctl:
net.ipv4.conf.all.arp_filter=1
net.ipv4.conf.all.arp_ignore=1 # or even 2
net.ipv4.conf.all.arp_announce=2
Queste impostazioni faranno sì che ARP si comporti in modo appropriato con il modello Strong ES, ovvero quando viene ricevuta una richiesta ARP, risponderà solo l'interfaccia con l'esatto indirizzo richiesto e solo se il traffico verso l'indirizzo di origine verrebbe effettivamente inviato attraverso quello specifico interfaccia.
Quindi, dal momento che hai cinque interfacce che desideri si comportino in modo diverso in termini di routing, dovrai impostare cinque tabelle di routing personalizzate. Potresti usare i numeri per identificarli, ma in genere è più chiaro specificare i nomi per loro. Quindi, scegli i numeri per ciascuno di essi compresi tra 1 e 252 e alcuni nomi adatti. (I numeri 0, 253, 254 e 255 sono riservati.)
Ad esempio, scegliamo 100 =rtable0, 101 =rtable1, 102 =rtable2, 103 =rtable3 e 104 =rtable4. Aggiungi questi numeri e nomi alla fine di /etc/iproute2/rt_tables
file:
# ...default stuff above...
100 rtable0
101 rtable1
102 rtable2
103 rtable3
104 rtable4
Quindi, popolare ogni tabella di routing personalizzata con un set minimo di voci di route appropriate per ciascuna interfaccia. (Sto sostituendo i valori effettivi con nomi di variabili di ambiente, si spera, descrittivi.)
ip route add $ETH0_NET dev eth0 proto static src $ETH0_IP table rtable0
ip route add default via $ETH0_GW dev eth0 proto static src $ETH0_IP table rtable0
ip route add $ETH1_NET dev eth1 proto static src $ETH1_IP table rtable1
ip route add default via $ETH1_GW dev eth1 proto static src $ETH1_IP table rtable1
# ... and so on, for all 5 interfaces
Infine, aggiungi regole di routing avanzate che verificheranno l'indirizzo di origine di ogni pacchetto e sceglieranno la tabella di routing da utilizzare di conseguenza:
ip rule add from $ETH0_IP table rtable0
ip rule add from $ETH1_IP table rtable1
#...
Per rendere persistente tutta questa configurazione durante i riavvii, potrebbe essere necessario scrivere script di avvio personalizzati (o possibilmente ifup-pre
o ifup-post
script) per adattarsi alle convenzioni della tua distribuzione Linux.
Per un'ulteriore assicurazione, potresti aggiungere regole iptables per interfaccia per eliminare silenziosamente tutti i pacchetti in arrivo che potrebbero essere ricevuti sull'interfaccia sbagliata. Se tutto va bene, il conteggio dei pacchetti per questi dovrebbe rimanere zero:se iniziano ad aumentare, potresti aver perso qualcosa nella configurazione.
iptables -A INPUT -m addrtype --dst-type UNICAST -i eth0 ! -d $ETH0_IP -j DROP
iptables -A INPUT -m addrtype --dst-type UNICAST -i eth1 ! -d $ETH1_IP -j DROP
# ... and so on for each interface
Nota: Una volta ho implementato una configurazione come questa basata su una vecchia discussione su Internet di Rick Jones e altri guru del networking. Hanno detto, parafrasando, “mentre tutto questo è chiaramente necessario per ottenere un comportamento Strong Host Model in Linux, non posso garantire che sia sufficiente per tutti i possibili casi d'uso”. Ha funzionato perfettamente per me; può o non può essere sufficiente per te, a seconda esattamente per cosa lo utilizzerai.
Avviso: assicurarsi di disporre di una sorta di accesso console locale o remoto al sistema durante l'impostazione di questa configurazione. È estremamente probabile che questa configurazione rovini completamente l'accesso alla rete mentre è solo a metà.
Sebbene sia possibile configurare N interfacce con solo (N-1) tabelle di routing personalizzate, la mia preferenza personale è quella di spostare tutta la configurazione di routing su tabelle personalizzate quando si utilizza il routing avanzato. Avere route -n
o ip route show
venire sostanzialmente vuoto mentre il sistema ha chiaramente connessioni di rete sarà un indizio molto grande che sta succedendo qualcosa di molto speciale. Tuttavia, quando ho impostato un sistema come questo, ho anche impostato un avviso permanente in /etc/motd
sull'instradamento avanzato in vigore e sulle posizioni degli script effettivi che lo configurano.