From e039cb9d97d4a5939b6567c4b683cd8a8aa98777 Mon Sep 17 00:00:00 2001 From: pacien Date: Tue, 8 Nov 2022 17:50:47 +0100 Subject: nixos/qemu-vm: add option "restrictNetwork" This adds an option to the qemu virtualisation module to isolate the guest's from the host's and outside networks. This is particularly useful for development sandboxes for example. The option is disabled by default to preserve the current behaviour. --- nixos/modules/virtualisation/qemu-vm.nix | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'nixos') diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index edc6dfdc15ae9..f56cc2cdb8ddb 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -528,6 +528,20 @@ in ''; }; + virtualisation.restrictNetwork = + mkOption { + type = types.bool; + default = false; + example = true; + description = + lib.mdDoc '' + If this option is enabled, the guest will be isolated, i.e. it will + not be able to contact the host and no guest IP packets will be + routed over the host to the outside. This option does not affect + any explicitly set forwarding rules. + ''; + }; + virtualisation.vlans = mkOption { type = types.listOf types.ints.unsigned; @@ -934,10 +948,11 @@ in else "'guestfwd=${proto}:${guest.address}:${toString guest.port}-" + "cmd:${pkgs.netcat}/bin/nc ${host.address} ${toString host.port}'," ); + restrictNetworkOption = lib.optionalString cfg.restrictNetwork "restrict=on,"; in [ "-net nic,netdev=user.0,model=virtio" - "-netdev user,id=user.0,${forwardingOptions}\"$QEMU_NET_OPTS\"" + "-netdev user,id=user.0,${forwardingOptions}${restrictNetworkOption}\"$QEMU_NET_OPTS\"" ]; # FIXME: Consolidate this one day. -- cgit 1.4.1 From b25e0e8ebcd90009462765bb8c49c337ba6af082 Mon Sep 17 00:00:00 2001 From: pacien Date: Thu, 12 Jan 2023 19:50:27 +0100 Subject: nixos/tests: add qemu-vm-restrictnetwork test --- nixos/tests/all-tests.nix | 1 + nixos/tests/qemu-vm-restrictnetwork.nix | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 nixos/tests/qemu-vm-restrictnetwork.nix (limited to 'nixos') diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index fbbebc2520a3d..7ed310c0d7c39 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -533,6 +533,7 @@ in { public-inbox = handleTest ./public-inbox.nix {}; pulseaudio = discoverTests (import ./pulseaudio.nix); qboot = handleTestOn ["x86_64-linux" "i686-linux"] ./qboot.nix {}; + qemu-vm-restrictnetwork = handleTest ./qemu-vm-restrictnetwork.nix {}; quorum = handleTest ./quorum.nix {}; quake3 = handleTest ./quake3.nix {}; rabbitmq = handleTest ./rabbitmq.nix {}; diff --git a/nixos/tests/qemu-vm-restrictnetwork.nix b/nixos/tests/qemu-vm-restrictnetwork.nix new file mode 100644 index 0000000000000..49a105ef10767 --- /dev/null +++ b/nixos/tests/qemu-vm-restrictnetwork.nix @@ -0,0 +1,36 @@ +import ./make-test-python.nix ({ + name = "qemu-vm-restrictnetwork"; + + nodes = { + unrestricted = { config, pkgs, ... }: { + virtualisation.restrictNetwork = false; + }; + + restricted = { config, pkgs, ... }: { + virtualisation.restrictNetwork = true; + }; + }; + + testScript = '' + import os + + if os.fork() == 0: + # Start some HTTP server on the qemu host to test guest isolation. + from http.server import HTTPServer, BaseHTTPRequestHandler + HTTPServer(("", 8000), BaseHTTPRequestHandler).serve_forever() + + else: + start_all() + unrestricted.wait_for_unit("network-online.target") + restricted.wait_for_unit("network-online.target") + + # Guests should be able to reach each other on the same VLAN. + unrestricted.succeed("ping -c1 restricted") + restricted.succeed("ping -c1 unrestricted") + + # Only the unrestricted guest should be able to reach host services. + # 10.0.2.2 is the gateway mapping to the host's loopback interface. + unrestricted.succeed("curl -s http://10.0.2.2:8000") + restricted.fail("curl -s http://10.0.2.2:8000") + ''; +}) -- cgit 1.4.1