8 cfg = config.virtualisation.virtualbox.host;
10 virtualbox = cfg.package.override {
17 extensionPack = if cfg.enableExtensionPack then pkgs.virtualboxExtpack else null;
20 kernelModules = config.boot.kernelPackages.virtualbox.override {
27 options.virtualisation.virtualbox.host = {
28 enable = lib.mkEnableOption "VirtualBox" // {
30 Whether to enable VirtualBox.
33 In order to pass USB devices from the host to the guests, the user
34 needs to be in the `vboxusers` group.
39 enableExtensionPack = lib.mkEnableOption "VirtualBox extension pack" // {
41 Whether to install the Oracle Extension Pack for VirtualBox.
44 You must set `nixpkgs.config.allowUnfree = true` in
45 order to use this. This requires you accept the VirtualBox PUEL.
50 package = lib.mkPackageOption pkgs "virtualbox" { };
52 addNetworkInterface = lib.mkOption {
53 type = lib.types.bool;
56 Automatically set up a vboxnet0 host-only network interface.
60 enableHardening = lib.mkOption {
61 type = lib.types.bool;
64 Enable hardened VirtualBox, which ensures that only the binaries in the
65 system path get access to the devices exposed by the kernel modules
66 instead of all users in the vboxusers group.
69 Disabling this can put your system's security at risk, as local users
70 in the vboxusers group can tamper with the VirtualBox device files.
75 headless = lib.mkOption {
76 type = lib.types.bool;
79 Use VirtualBox installation without GUI and Qt dependency. Useful to enable on servers
80 and when virtual machines are controlled only via SSH.
84 enableWebService = lib.mkOption {
85 type = lib.types.bool;
88 Build VirtualBox web service tool (vboxwebsrv) to allow managing VMs via other webpage frontend tools. Useful for headless servers.
92 enableKvm = lib.mkOption {
93 type = lib.types.bool;
96 Enable KVM support for VirtualBox. This increases compatibility with Linux kernel versions, because the VirtualBox kernel modules
99 This option is incompatible with `addNetworkInterface`.
101 Note: This is experimental. Please check https://github.com/cyberus-technology/virtualbox-kvm/issues.
106 config = lib.mkIf cfg.enable (
109 warnings = lib.mkIf (pkgs.config.virtualbox.enableExtensionPack or false) [
110 "'nixpkgs.virtualbox.enableExtensionPack' has no effect, please use 'virtualisation.virtualbox.host.enableExtensionPack'"
112 environment.systemPackages = [ virtualbox ];
117 source = "${virtualbox}/libexec/virtualbox/${program}";
130 ++ (lib.optionals (!cfg.headless) [
135 lib.mkIf cfg.enableHardening (
136 builtins.listToAttrs (
144 users.groups.vboxusers.gid = config.ids.gids.vboxusers;
146 services.udev.extraRules = ''
147 SUBSYSTEM=="usb_device", ACTION=="add", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
148 SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
149 SUBSYSTEM=="usb_device", ACTION=="remove", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
150 SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
153 (lib.mkIf cfg.enableKvm {
156 assertion = !cfg.addNetworkInterface;
157 message = "VirtualBox KVM only supports standard NAT networking for VMs. Please turn off virtualisation.virtualbox.host.addNetworkInterface.";
161 (lib.mkIf (!cfg.enableKvm) {
162 boot.kernelModules = [
167 boot.extraModulePackages = [ kernelModules ];
169 services.udev.extraRules = ''
170 KERNEL=="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
171 KERNEL=="vboxdrvu", OWNER="root", GROUP="root", MODE="0666", TAG+="systemd"
172 KERNEL=="vboxnetctl", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
175 # Since we lack the right setuid/setcap binaries, set up a host-only network by default.
177 (lib.mkIf cfg.addNetworkInterface {
178 systemd.services.vboxnet0 = {
179 description = "VirtualBox vboxnet0 Interface";
180 requires = [ "dev-vboxnetctl.device" ];
181 after = [ "dev-vboxnetctl.device" ];
184 "sys-subsystem-net-devices-vboxnet0.device"
186 path = [ virtualbox ];
187 serviceConfig.RemainAfterExit = true;
188 serviceConfig.Type = "oneshot";
189 serviceConfig.PrivateTmp = true;
190 environment.VBOX_USER_HOME = "/tmp";
192 if ! [ -e /sys/class/net/vboxnet0 ]; then
193 VBoxManage hostonlyif create
194 cat /tmp/VBoxSVC.log >&2
198 VBoxManage hostonlyif remove vboxnet0
202 networking.interfaces.vboxnet0.ipv4.addresses = [
204 address = "192.168.56.1";
208 # Make sure NetworkManager won't assume this interface being up
209 # means we have internet access.
210 networking.networkmanager.unmanaged = [ "vboxnet0" ];
212 (lib.mkIf config.networking.useNetworkd {
213 systemd.network.networks."40-vboxnet0".extraConfig = ''