Host iptables firewall e libvirt VM senza connessione

Postate qui per tutte le discussioni legate a Linux in generale.

Moderatore: Staff

Regole del forum
1) Citare sempre la versione di Slackware usata, la versione del Kernel e magari anche la versione della libreria coinvolta. Questi dati aiutano le persone che possono rispondere.
2) Per evitare confusione prego inserire in questo forum solo topic che riguardano appunto Gnu/Linux in genere, se l'argomento è specifico alla Slackware usate uno dei forum Slackware o Slackware64.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3975
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Host iptables firewall e libvirt VM senza connessione

Messaggio da joe »

Su host slackware ho da sempre uno script iptables come firewall. L'avevo scopiazzato ancora dal vecchio wikislacky. Regole molto semplici:
  • di default imposta DROP per tutto
  • accetta tutto verso e dall'interfaccia di loopback
  • accetta tutti i pacchetti provenienti da risposte a richieste "estabilished"
  • accetta tutto il il traffico in uscita
Ho messo in piedi una VM con Linux Mint usando libvirt e virt-manager. E ho notato che non riesce a collegarsi ad iternet, né a contattare l'host.

A livello di rete, grazie a libvirt, viene creata una nuova interfaccia bridge virtuale: virbr0. Di default ha IP:

Codice: Seleziona tutto

192.168.122.1
E alle varie VM sempre attraverso libvirt viene automaticamente assegnato IP via DHCP sulla rete:

Codice: Seleziona tutto

192.168.122.0/24

Se spengo il firewall dell'host, che significa impostare iptables su ACCEPT per tutte le chains, ecco che non si hanno problemi: la VM acquisisce l'IP di LAN e ha accesso ad internet senza limitazioni.
Però spegnere il firewall va bene solo per testare la configurazione. È decisamente meglio predisporre qualche regola aggiuntiva rispetto a quelle stringenti di default.
La domanda banale è quali sono queste regole?

Ne ho approfittato per chiedere a "gemini" (via tgpt, molto comodo). Dice:

Codice: Seleziona tutto

╭─ Bot
Dovresti aggiungere regole per:

1.  **Consentire il forwarding tramite l'interfaccia virbr0:
**  $IPTAB -A FORWARD -i virbr0 -j ACCEPT  **
**  $IPTAB -A FORWARD -o virbr0 -j ACCEPT **.

2.  **Mascherare il traffico proveniente dalle VM (NAT):
** $IPTAB -t nat -A POSTROUTING -o <interfaccia_verso_internet> -j MASQUERADE

Sostituisci <interfaccia_verso_internet> con l'interfaccia di rete che si connette a Internet (es. eth0, wlan0).
Sembra ragionevole... Ma io non mi fido per mia somma ignoranza...
Cosa ne pensate?

(non le ho ancora provate, avevo già iniziato questo messaggio quando m'è venuto in mente di chiedere anche al bot).

Avatar utente
ponce
Iper Master
Iper Master
Messaggi: 3107
Iscritto il: mer 5 mar 2008, 16:45
Nome Cognome: Matteo Bernardini
Slackware: slackware64-current
Kernel: 6.16.4
Desktop: lxde
Località: Pisa
Contatta:

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da ponce »

ma hai interfacce di rete su rete pubblica (situazione veramente particolare al giorno d'oggi) o ti connetti tramite un router? nel secondo caso un firewall non e' che sia molto utile (il router ha gia' un suo firewall)...

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3975
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da joe »

Ho un router, ma da sempre ho anche il firewall impostato sul sistema.

Con l'aiuto di Gemini ho ottenuto una configurazione funzionante:

Codice: Seleziona tutto

set_libvirt(){
  echo "Attivo Rete libvirt"
  ${IPTAB} -I INPUT -i virbr0 -p udp --dport 67 --sport 68 -j ACCEPT $text "DHCP da virbr0"
  ${IPTAB} -I OUTPUT -o virbr0 -p udp --sport 67 --dport 68 -j ACCEPT $text "DHCP verso virbr0"
  ${IPTAB} -I FORWARD -i virbr0 -j ACCEPT $text "Forward da virbr0"
  ${IPTAB} -I FORWARD -o virbr0 -j ACCEPT $text "Forward verso virbr0"
  ${IPTAB} -t nat -A POSTROUTING -o eth0 -j MASQUERADE $text "NAT per virbr0"
}
Questa serie di regole fa sì che la macchina virtuale riesca ad ottenere l'IP dal sistema host via libvirt e interfaccia virbr0 e non abbia problemi a comunicare con lo stesso sistema host e col mondo esterno.
In pratica viene aperta la porta dell'host per le richieste che giungono a virbr0 su porta 67 del DHCP e (forse questa non serviva) vinene lasciato passare in uscita le risposte da porta 67 verso la 68 che immagino sia quella del client CM che richiede l'indirizzo di rete LAN, la virtuale ovvio.

Come dicevo forse ci sono regole sovrabbondanti, ne bastavano meno probabilmente... se qualcuno sapesse dare un chiarimento e ne avesse voglia... grazie in anticipo!

rik70
Iper Master
Iper Master
Messaggi: 2552
Iscritto il: gio 10 mar 2011, 9:21
Slackware: 15.0
Kernel: 5.15.x-generic
Desktop: Sway
Distribuzione: Arch Linux

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da rik70 »

Se ho capito bene la questione, il tuo problema potrebbe essere una sovrapposizione di regole iptables.

Se per ipotesi hai delle reti 'nat' gestite da libvirt e impostate per attivarsi all'avvio quando lanci il relativo demone, quest'ultimo crea delle regole iptables relative alle interfacce di rete virtuali e non.
Tali regole probabilmente le aggiunge a quelle esistenti create dal tuo script, le quali continuano ad avere una priorità maggiore dovuta forse alla "sequenza" con cui sono aggiunte le successive nelle "catene" iptables.

Io fossi in te partirei da una situazione "pulita" per capire quali regole iptables "scrive" libvirtd all'avvio e se possibile come - utilizza il flag '-A' o '-I' ? - e "tarerei" il tuo script di conseguenza.

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3975
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da joe »

Le regole iptables del mio script sono molto semplici:

- chiudi tutto
- apri le connessioni in uscita
- apri quelle in entrata provenienti da "risposte" a mie richieste (established)
- apri quelle in entrata per l'interfaccia di loopback device

A questa situazione ho poi aggiunto delle aperture per porte in ingresso per vari servizi, tipo p2p bittorrent amule, un server vpn ecc... ma sono tutte regole semplici che influiscono solo sulla tabella "filter" di iptables.

Per quanto riguarda libvirt, sì di suo attiva una rete nat chiamata con molta fatasia "default" che è visibile dalle VM.
E lato host crea l'interfaccia virbr0 che fa un po' anche da gateway per le VM.
Non sapevo che venissero aggiunte anche delle regole iptables da libvirt. Ne ho letto in effetti cercando una soluzione, ma credevo si riferissero ad impostazioni personalizzate e non dalla situazione di default.

Va be', posso fare una prova semplice:
- spengo il firewall e verifico che non vi siano regole attive (tutto aperto)
- poi accendo libvirt che creerà anche la rete virtuale "default", virbr0 e quant'altro
- e a quel punto ri-verifico le regole iptables in essere

Così salteranno all'occhio eventuali regole che si fossero aggiunte. Proviamo...

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3975
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da joe »

No, ho fatto la prova, e la situazione delle regole iptables, prima e dopo l'avvio di libvirt è la stessa.
Disattivato il firewall, zero regole, tutto risulta su ACCEPT, ho controllato sia tabella filter che nat che mangle ecc.. raw security, tutte insomma. E zero regole.
Poi ho avviato libvirt, e non ne appaiono di nuove.
A quel punto ho avviato anche la macchina virtuale con Linux Mint (è un dual boot con win11 in realtà) e però ricontrollando iptables, non ci sono regole aggiuntive.

In conclusione sul mio sistema (Slackware 15.0) senza impostare apposta roba in libvirt, al suo avvio non vengono toccate le regole iptables.

Per la cronaca il pacchetto libvirt installato è il seguente.

Codice: Seleziona tutto

/var/log/packages/libvirt-10.10.0-x86_64-1_SBo
/var/log/packages/libvirt-glib-5.0.0-x86_64-1_SBo
/var/log/packages/libvirt-python-10.10.0-x86_64-1_SBo

rik70
Iper Master
Iper Master
Messaggi: 2552
Iscritto il: gio 10 mar 2011, 9:21
Slackware: 15.0
Kernel: 5.15.x-generic
Desktop: Sway
Distribuzione: Arch Linux

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da rik70 »

E se provi ad arrestare e poi avviare manualmente le reti libvirt?
Sono di tipo 'nat'? Se sì, dovrebbe creare le regole iptables.

Controlla anche in '/etc/libvirt/network.conf' alla voce 'firewall_backend' se è impostato 'iptables'.

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3975
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da joe »

Codice: Seleziona tutto

~# virsh net-list --all
 Nome      Stato    Avvio automatico   Persistent
---------------------------------------------------
 default   attivo   yes                yes
La rete, ce n'è solo una, è messa in piedi in modo "nat" credo, cioè sì, libvirt assegna alla macchina virtuale un IP locale 192.168.122.0/24. E sull'host attiva l'interfaccia virbr0 192.168.122.1 che fa da gateway tra i due.
Host e guest comunicano attraverso virbr0.

Il fil "network.conf" è completamente commentato.
Però è una modifica apportata da me perché vedo che c'è anche un network.conf.orig, in quello c'era la stringa:

Codice: Seleziona tutto

firewall_backend = "iptables"
Però ecco, non è più attivo praticamente perché l'ho sostituito con la versione completamente commentata.
Avevo avuto qualche intoppo in passato con la rete e libvirt, nel senso che disattivandola poi non riuscivo più a riattivarla. Forse quella modifica al network.conf era dovuta proprio a risolvere quel problema.

Ad ogni modo non ci sono regole iptables che libvirt sovrapponga a quelle del mio script quando attiva la sua rete "default".
Il problema delle VM che non riescono a raggiungere l'host, credo non sia un problema, ma una conseguenza del mio script che mette in piedi una politica molto stringente: il sistema host si rifiuta di accettare richieste dall'esterno (e 192.168.122.0/24 è una rete esterna, locale ma comunque esterna).
Quando la macchina virtuale guest tenta di collegarsi al gateway virbr0 per ottenere l'IP via dhcp, in qualche modo non riesce a raggiungere libvirt, perché iptables blocca la richiesta da 192.168.122.50 ad esempio e così la VM non riesce a collegarsi neanche alla lan virtuale, cioè non riesce ad essere assegnata con un ip della rete "default".

Mi sembra normale questa cosa e anzi mi conferma che lo script del mio firewall sia ben coperto.
Però è anche chiaro d'altra parte che per far funzionare le VM servono regole iptables aggiuntive da attivare solo quando ci sono VM attive con libvirt.

Avatar utente
ponce
Iper Master
Iper Master
Messaggi: 3107
Iscritto il: mer 5 mar 2008, 16:45
Nome Cognome: Matteo Bernardini
Slackware: slackware64-current
Kernel: 6.16.4
Desktop: lxde
Località: Pisa
Contatta:

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da ponce »

Non vorrei sbagliarmi ma mi sembra che i nuovi libvirt usino nftables di default (sono sull'autobus)...

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3975
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da joe »

Questo è il contenuto del file:

Codice: Seleziona tutto

/etc/libvirt/network.conf

Codice: Seleziona tutto

# Master configuration file for the network driver.
# All settings described here are optional - if omitted, sensible
# defaults are used.

# firewall_backend:
#
#   determines which subsystem to use to setup firewall packet
#   filtering rules for virtual networks.
#
#   Supported settings:
#
#     iptables - use iptables commands to construct the firewall
#     nftables - use nft commands to construct the firewall
#
#   If firewall_backend isn't configured, libvirt will choose the
#   first available backend from the following list:
#
#     [nftables, iptables]
#
#   If no backend is available on the host, then the network driver
#   will fail to start, and an error will be logged.
#
#   (NB: switching from one backend to another while there are active
#   virtual networks *is* supported. The change will take place the
#   next time that libvirtd/virtnetworkd is restarted - all existing
#   virtual networks will have their old firewalls removed, and then
#   reloaded using the new backend.)
#
#firewall_backend = "nftables"
Nel mio caso non è configurato uno specifico backend.
Sul sistema sono presenti entrambi i paccchetti, sia iptables che nftables.
Quale scelga non lo so. Posso vedere a sto punto se ci sono regole nftables attive:

Codice: Seleziona tutto

~# nft list ruleset


table ip libvirt_network {
	chain forward {
		type filter hook forward priority filter; policy accept;
		counter packets 2417 bytes 1853037 jump guest_cross
		counter packets 2417 bytes 1853037 jump guest_input
		counter packets 943 bytes 115193 jump guest_output
	}

	chain guest_output {
		ip saddr 192.168.122.0/24 iif "virbr0" counter packets 943 bytes 115193 accept
		iif "virbr0" counter packets 0 bytes 0 reject
	}

	chain guest_input {
		oif "virbr0" ip daddr 192.168.122.0/24 ct state established,related counter packets 1474 bytes 1737844 accept
		oif "virbr0" counter packets 0 bytes 0 reject
	}

	chain guest_cross {
		iif "virbr0" oif "virbr0" counter packets 0 bytes 0 accept
	}

	chain guest_nat {
		type nat hook postrouting priority srcnat; policy accept;
		ip saddr 192.168.122.0/24 ip daddr 224.0.0.0/24 counter packets 1 bytes 40 return
		ip saddr 192.168.122.0/24 ip daddr 255.255.255.255 counter packets 0 bytes 0 return
		meta l4proto tcp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 71 bytes 4260 masquerade to :1024-65535
		meta l4proto udp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 54 bytes 57936 masquerade to :1024-65535
		ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade
	}
}
table ip6 libvirt_network {
	chain forward {
		type filter hook forward priority filter; policy accept;
		counter packets 0 bytes 0 jump guest_cross
		counter packets 0 bytes 0 jump guest_input
		counter packets 0 bytes 0 jump guest_output
	}

	chain guest_output {
	}

	chain guest_input {
	}

	chain guest_cross {
	}

	chain guest_nat {
		type nat hook postrouting priority srcnat; policy accept;
	}
}
Sembra proprio che libvirt abbia scelto nftables piuttosto che iptables.

Quindi ricapitolando, spegnendo iptables, tutto su ACCEPT, libvirt mette in piedi comunque delle regole usando nftables che costruisce il NAT tra virbr0 e le varie VM.
Così tutto funziona come dovrebbe.

Però io voglio iptables attivo sull'host e allo stesso tempo le VM funzionanti e abilitate alla rete. Sia rete tra host e guest e che tra guest e internet.

Potrei provare a specificare di usare iptables nel network.conf di ibvirt e riavviare tutta la baracca...
Così si dovrebbero vedere le regole che libvirt mette in piedi tradotte nella modalità iptables.
In teoria dovrebbero andarsi a sovrappore alle mie regole per l'host spero senza andare a comprometterle.

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3975
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Host iptables firewall e libvirt VM senza connessione

Messaggio da joe »

Dunque sì, il problema era dovuto a:

1. regole iptables stringenti sull'host gestite da iptables
2. attivazione di regole via ntftables all'avvio della rete virtuale messa in piedi da libvirt

La conseguenza era che le VM si trovavano bloccate dalle regole iptables dell'host e non potevano comunicare con l'host. In particolare non potevano raggiungere neanche il gateway virbr0 ed interfacciarsi con l'host e col mondo esterno.
Da evidenziare che l'interfaccia virtuale della VM (su mint l'interfaccia ethernet virtuale "enp0n1") non riusciva neanche ad ottenere l'IP via dhcp.

Soluzione:
se sull'host il firewall è gestito con regole iptables, allora anche libvirt deve aggiungere le proprie usando sempre iptables e non nftables.
In questo modo l'insieme di regole iptables dovrebbe mantenere l'impostazione di sistema (script firewall iptables) permettendo alle VM di comunicare con host e mondo esterno grazie alle nuove regole iptables aggiunte da libvirt.

Per farlo occorre impostare il backend su iptables in /etc/libvirt/network.conf:

Codice: Seleziona tutto

firewall_backend = "iptables"
Così lanciando:

Codice: Seleziona tutto

iptables -L
dal sistema host si vedono le numerose regole iptables introdotte da libvirt.

Rispondi