Come posizionare la VM praticamente oltre l'host in rete


0

Ho scritto un programma che simula una macchina semplice. Questo programma ha il suo MAC e usa socket raw per scrivere frame raw ethernet, gestendo in modo efficace IP / ARP-Tables ecc. È possibile comunicare con il mondo esterno, ma ho problemi con la connessione host-to-guest e guest-to-host. Al momento utilizzo un'interfaccia MacVLan in Modalità Ponte , ma i pacchetti destinati all'host non arrivano mai in nessuno dei due macvlan1 o il sottostante eth0 . Anche i miei interruttori non supportano il forcina funzione richiesta per il modalità vepa .

Ho provato a riprodurlo questo post dove un utente ha avuto un problema simile, ma in primo luogo la risposta non ha funzionato per me e in secondo luogo la risposta dell'utente finito

Sarebbe stato molto più facile con un MacVlan, anche se ..,

Quindi, come impostare un macvlan in modo che l'ospite possa comunicare con il mondo esterno e il padrone di casa?

Vorrei anche usare il bridging (come in questo post ) se potesse funzionare per me. (Inoltre, vorrei evitare di predefinire gli IP statici)


Giusto per chiarire: si esegue il programma che utilizza socket non elaborati in uno spazio dei nomi di rete separato e si è configurato un macvlan all'interno di questo spazio dei nomi con un master eth0 nello spazio dei nomi principale e abilitato l'inoltro / il routing in modo che i pacchetti siano correttamente inserisci l'interfaccia di macvlan? Non ho mai provato a utilizzare socket raw io stesso, e non sono completamente sicuro dei dettagli di come funzionano; al tuo posto avrei usato un tap interfaccia (che è quindi facile da collegare).
dirkt

Non sono a conoscenza degli spazi dei nomi, ma in modo esatto sì. L'inoltro avviene automaticamente dal kernel. Ho provato a utilizzare un'interfaccia TAP con il bridging. La "VM" ha ricevuto tutti i pacchetti, ma in qualche modo tutti i pacchetti che ha scritto nel TAP sono svaniti. Come faresti a collegare correttamente l'interfaccia TAP?
Cirromulus

Se non lo hai messo in uno spazio dei nomi, il macvlan è fondamentalmente inutile. "L'inoltro avviene automaticamente dal kernel" è esattamente il punto problematico: in quale luogo vengono iniettati? Se ho capito bene, i socket raw / packet sono fondamentalmente pensati per i nuovi protocolli IP, non per simulare macchine con il proprio hardware di rete. Ecco perché, ad es. QEMU ha interfacce di tocco. Colleghi un'interfaccia tap come qualsiasi altra interfaccia: ip link set tap0 master br0 ecc. E usare tcpdump -ni tap0 per verificare se i pacchetti "in qualche modo spariscono".
dirkt

Inoltre, ci sono molti programmi di esempio con le implementazioni tun / tap funzionanti.
dirkt

Risposte:


0

Ok, ho dovuto giocare con le prese crude ora.

Però, prese crude ( man 7 raw, socket(AF_INET, SOCK_RAW, ...) ) funziona davvero sul layer 3. Hai detto di scrivere frame raw ethernet e di fare ARP, quindi forse vuoi dire prese del pacchetto ( man 7 packet, socket(AF_PACKET, SOCK_RAW, ...) ).

Per entrambi i pacchetti socket e raw socket, i pacchetti non sono correttamente instradati, ma collocati direttamente nella parte in uscita di una particolare interfaccia. Questa interfaccia può essere determinata vincolandola per nome o cercando l'indirizzo di destinazione. Quindi "l'inoltro avviene automaticamente dal kernel" non è vero: l'inoltro non avviene affatto. In particolare, se la destinazione è un indirizzo locale, il pacchetto non viene reindirizzato tramite l'interfaccia di loopback.

Questo rende questo metodo totalmente inadatto per la simulazione di un dispositivo con un "extra endpoint di interfaccia" nell'host.

Per quanto riguarda i macvlans, la modalità bridge è descritta come

Il macvlan è un ponte banale che non ha bisogno di imparare come questo   conosce ogni indirizzo MAC che può ricevere, quindi non ha bisogno di implementarlo   apprendimento o stp. Il che lo rende semplice e stupido e veloce.

Prendo questo per indicare che i macvlans eseguono il bridging esaminando l'indirizzo MAC dell'interfaccia originale e ogni altro indirizzo MAC aggiunto da un macvlan. Il che significa che mentre si sta emulando l'indirizzo MAC tramite socket non elaborati, il codice macvlan non sa che esiste un indirizzo MAC "aggiuntivo" e quindi non può trovare alcuna destinazione per esso.

Aggiungete che i socket raw e packet hanno bisogno di root (che non dovrebbe essere necessario per un'applicazione che emula qualche altro dispositivo), quindi, a mio parere, i socket raw e packet sono totalmente inadatti per questo tipo di applicazione. Sono orientati verso l'implementazione di nuovi protocolli IP o altri elementi di rete di basso livello nello spazio utente e nient'altro.

Quindi il mio consiglio sarebbe ancora: Non usare socket raw / packet. Usa un'interfaccia tap, come fanno QEMU o altri emulatori. Ciò consentirà alla tua applicazione di funzionare come non-root, e sarai in grado di configurare qualsiasi configurazione di rete nell'host che ti piace (instradarlo sul layer 3 o collegarlo al layer 2).


Non sapevo che non è stato eseguito il routing quando si usano socket packet. Informazioni su MacVLan: il dispositivo virtuale utilizza il MAC esatto elencato in MacVLan da un comando ioctl. Non sono sicuro di come mettere i pacchetti grezzi su un tap, ma questa domanda sarebbe off-topic qui. Grazie.
Cirromulus

Non sono ancora del tutto sicuro di dove vengano iniettati pacchetti grezzi, ma poiché sembrano ignorare la maggior parte del normale codice di routing del kernel, è del tutto possibile che ignorino anche il codice di bridging di macvlan e passino direttamente alla coda in uscita dell'interfaccia associata. E viceversa, i pacchetti in entrata catturati dagli hook raw / packet socket potrebbero non vedere mai il codice di bridging macvlan. Immagino che uno dovrebbe controllare la fonte del kernel per essere sicuro (e sono troppo pigro per farlo adesso).
dirkt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.