Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion nixos/modules/virtualisation/qemu-vm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 {};
Expand Down
36 changes: 36 additions & 0 deletions nixos/tests/qemu-vm-restrictnetwork.nix
Original file line number Diff line number Diff line change
@@ -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")
'';
})