1# LXC Configuration 2 3{ 4 config, 5 lib, 6 pkgs, 7 ... 8}: 9 10let 11 cfg = config.virtualisation.lxc; 12in 13 14{ 15 meta = { 16 maintainers = lib.teams.lxc.members; 17 }; 18 19 options.virtualisation.lxc = { 20 enable = lib.mkOption { 21 type = lib.types.bool; 22 default = false; 23 description = '' 24 This enables Linux Containers (LXC), which provides tools 25 for creating and managing system or application containers 26 on Linux. 27 ''; 28 }; 29 30 unprivilegedContainers = lib.mkEnableOption "support for unprivileged users to launch containers"; 31 32 systemConfig = lib.mkOption { 33 type = lib.types.lines; 34 default = ""; 35 description = '' 36 This is the system-wide LXC config. See 37 {manpage}`lxc.system.conf(5)`. 38 ''; 39 }; 40 package = lib.mkPackageOption pkgs "lxc" { }; 41 42 defaultConfig = lib.mkOption { 43 type = lib.types.lines; 44 default = ""; 45 description = '' 46 Default config (default.conf) for new containers, i.e. for 47 network config. See {manpage}`lxc.container.conf(5)`. 48 ''; 49 }; 50 51 usernetConfig = lib.mkOption { 52 type = lib.types.lines; 53 default = ""; 54 description = '' 55 This is the config file for managing unprivileged user network 56 administration access in LXC. See {manpage}`lxc-usernet(5)`. 57 ''; 58 }; 59 60 bridgeConfig = lib.mkOption { 61 type = lib.types.lines; 62 default = ""; 63 description = '' 64 This is the config file for override lxc-net bridge default settings. 65 ''; 66 }; 67 }; 68 69 ###### implementation 70 71 config = lib.mkIf cfg.enable { 72 environment.systemPackages = [ cfg.package ]; 73 environment.etc."lxc/lxc.conf".text = cfg.systemConfig; 74 environment.etc."lxc/lxc-usernet".text = cfg.usernetConfig; 75 environment.etc."lxc/default.conf".text = cfg.defaultConfig; 76 environment.etc."lxc/lxc-net".text = cfg.bridgeConfig; 77 environment.pathsToLink = [ "/share/lxc" ]; 78 systemd.tmpfiles.rules = [ "d /var/lib/lxc/rootfs 0755 root root -" ]; 79 80 security.apparmor.packages = [ cfg.package ]; 81 security.apparmor.policies = { 82 "bin.lxc-start".profile = '' 83 include ${cfg.package}/etc/apparmor.d/usr.bin.lxc-start 84 ''; 85 "lxc-containers".profile = '' 86 include ${cfg.package}/etc/apparmor.d/lxc-containers 87 ''; 88 }; 89 90 # We don't need the `lxc-user` group, unless the unprivileged containers are enabled. 91 users.groups = lib.mkIf cfg.unprivilegedContainers { lxc-user = { }; }; 92 93 # `lxc-user-nic` needs suid to attach to bridge for unpriv containers. 94 security.wrappers = lib.mkIf cfg.unprivilegedContainers { 95 lxcUserNet = { 96 source = "${pkgs.lxc}/libexec/lxc/lxc-user-nic"; 97 setuid = true; 98 owner = "root"; 99 group = "lxc-user"; 100 program = "lxc-user-nic"; 101 permissions = "u+rx,g+x,o-rx"; 102 }; 103 }; 104 105 # Add lxc-net service if unpriv mode is enabled. 106 systemd.packages = lib.mkIf cfg.unprivilegedContainers [ pkgs.lxc ]; 107 systemd.services = lib.mkIf cfg.unprivilegedContainers { 108 lxc-net = { 109 enable = true; 110 wantedBy = [ "multi-user.target" ]; 111 path = [ 112 pkgs.iproute2 113 pkgs.iptables 114 pkgs.getent 115 pkgs.dnsmasq 116 ]; 117 }; 118 }; 119 }; 120}