at 16.09-beta 8.0 kB view raw
1{ config, lib, pkgs, ... }: 2 3with pkgs; 4with lib; 5 6let 7 cfg = config.networking.networkmanager; 8 9 # /var/lib/misc is for dnsmasq.leases. 10 stateDirs = "/var/lib/NetworkManager /var/lib/dhclient /var/lib/misc"; 11 12 configFile = writeText "NetworkManager.conf" '' 13 [main] 14 plugins=keyfile 15 16 [keyfile] 17 ${optionalString (config.networking.hostName != "") 18 ''hostname=${config.networking.hostName}''} 19 ${optionalString (cfg.unmanaged != []) 20 ''unmanaged-devices=${lib.concatStringsSep ";" cfg.unmanaged}''} 21 22 [logging] 23 level=WARN 24 25 [connection] 26 ipv6.ip6-privacy=2 27 ''; 28 29 /* 30 [network-manager] 31 Identity=unix-group:networkmanager 32 Action=org.freedesktop.NetworkManager.* 33 ResultAny=yes 34 ResultInactive=no 35 ResultActive=yes 36 37 [modem-manager] 38 Identity=unix-group:networkmanager 39 Action=org.freedesktop.ModemManager* 40 ResultAny=yes 41 ResultInactive=no 42 ResultActive=yes 43 */ 44 polkitConf = '' 45 polkit.addRule(function(action, subject) { 46 if ( 47 subject.isInGroup("networkmanager") 48 && (action.id.indexOf("org.freedesktop.NetworkManager.") == 0 49 || action.id.indexOf("org.freedesktop.ModemManager") == 0 50 )) 51 { return polkit.Result.YES; } 52 }); 53 ''; 54 55 ipUpScript = writeScript "01nixos-ip-up" '' 56 #!/bin/sh 57 if test "$2" = "up"; then 58 ${config.systemd.package}/bin/systemctl start ip-up.target 59 ${config.systemd.package}/bin/systemctl start network-online.target 60 fi 61 ''; 62 63 ns = xs: writeText "nameservers" ( 64 concatStrings (map (s: "nameserver ${s}\n") xs) 65 ); 66 67 overrideNameserversScript = writeScript "02overridedns" '' 68 #!/bin/sh 69 tmp=`${coreutils}/bin/mktemp` 70 ${gnused}/bin/sed '/nameserver /d' /etc/resolv.conf > $tmp 71 ${gnugrep}/bin/grep 'nameserver ' /etc/resolv.conf | \ 72 ${gnugrep}/bin/grep -vf ${ns (cfg.appendNameservers ++ cfg.insertNameservers)} > $tmp.ns 73 ${optionalString (cfg.appendNameservers != []) "${coreutils}/bin/cat $tmp $tmp.ns ${ns cfg.appendNameservers} > /etc/resolv.conf"} 74 ${optionalString (cfg.insertNameservers != []) "${coreutils}/bin/cat $tmp ${ns cfg.insertNameservers} $tmp.ns > /etc/resolv.conf"} 75 ${coreutils}/bin/rm -f $tmp $tmp.ns 76 ''; 77 78 dispatcherTypesSubdirMap = { 79 "basic" = ""; 80 "pre-up" = "pre-up.d/"; 81 "pre-down" = "pre-down.d/"; 82 }; 83 84in { 85 86 ###### interface 87 88 options = { 89 90 networking.networkmanager = { 91 92 enable = mkOption { 93 type = types.bool; 94 default = false; 95 description = '' 96 Whether to use NetworkManager to obtain an IP address and other 97 configuration for all network interfaces that are not manually 98 configured. If enabled, a group <literal>networkmanager</literal> 99 will be created. Add all users that should have permission 100 to change network settings to this group. 101 ''; 102 }; 103 104 unmanaged = mkOption { 105 type = types.listOf types.string; 106 default = []; 107 description = '' 108 List of interfaces that will not be managed by NetworkManager. 109 Interface name can be specified here, but if you need more fidelity 110 see "Device List Format" in NetworkManager.conf man page. 111 ''; 112 }; 113 114 # Ugly hack for using the correct gnome3 packageSet 115 basePackages = mkOption { 116 type = types.attrsOf types.package; 117 default = { inherit networkmanager modemmanager wpa_supplicant 118 networkmanager_openvpn networkmanager_vpnc 119 networkmanager_openconnect 120 networkmanager_pptp networkmanager_l2tp; }; 121 internal = true; 122 }; 123 124 packages = mkOption { 125 type = types.listOf types.path; 126 default = [ ]; 127 description = '' 128 Extra packages that provide NetworkManager plugins. 129 ''; 130 apply = list: (attrValues cfg.basePackages) ++ list; 131 }; 132 133 appendNameservers = mkOption { 134 type = types.listOf types.str; 135 default = []; 136 description = '' 137 A list of name servers that should be appended 138 to the ones configured in NetworkManager or received by DHCP. 139 ''; 140 }; 141 142 insertNameservers = mkOption { 143 type = types.listOf types.str; 144 default = []; 145 description = '' 146 A list of name servers that should be inserted before 147 the ones configured in NetworkManager or received by DHCP. 148 ''; 149 }; 150 151 dispatcherScripts = mkOption { 152 type = types.listOf (types.submodule { 153 options = { 154 source = mkOption { 155 type = types.str; 156 description = '' 157 A script source. 158 ''; 159 }; 160 161 type = mkOption { 162 type = types.enum (attrNames dispatcherTypesSubdirMap); 163 default = "basic"; 164 description = '' 165 Dispatcher hook type. Only basic hooks are currently available. 166 ''; 167 }; 168 }; 169 }); 170 default = []; 171 description = '' 172 A list of scripts which will be executed in response to network events. 173 ''; 174 }; 175 }; 176 }; 177 178 179 ###### implementation 180 181 config = mkIf cfg.enable { 182 183 assertions = [{ 184 assertion = config.networking.wireless.enable == false; 185 message = "You can not use networking.networkmanager with services.networking.wireless"; 186 }]; 187 188 boot.kernelModules = [ "ppp_mppe" ]; # Needed for most (all?) PPTP VPN connections. 189 190 environment.etc = with cfg.basePackages; [ 191 { source = ipUpScript; 192 target = "NetworkManager/dispatcher.d/01nixos-ip-up"; 193 } 194 { source = configFile; 195 target = "NetworkManager/NetworkManager.conf"; 196 } 197 { source = "${networkmanager_openvpn}/etc/NetworkManager/VPN/nm-openvpn-service.name"; 198 target = "NetworkManager/VPN/nm-openvpn-service.name"; 199 } 200 { source = "${networkmanager_vpnc}/etc/NetworkManager/VPN/nm-vpnc-service.name"; 201 target = "NetworkManager/VPN/nm-vpnc-service.name"; 202 } 203 { source = "${networkmanager_openconnect}/etc/NetworkManager/VPN/nm-openconnect-service.name"; 204 target = "NetworkManager/VPN/nm-openconnect-service.name"; 205 } 206 { source = "${networkmanager_pptp}/etc/NetworkManager/VPN/nm-pptp-service.name"; 207 target = "NetworkManager/VPN/nm-pptp-service.name"; 208 } 209 { source = "${networkmanager_l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name"; 210 target = "NetworkManager/VPN/nm-l2tp-service.name"; 211 } 212 ] ++ optional (cfg.appendNameservers == [] || cfg.insertNameservers == []) 213 { source = overrideNameserversScript; 214 target = "NetworkManager/dispatcher.d/02overridedns"; 215 } 216 ++ lib.imap (i: s: { 217 text = s.source; 218 target = "NetworkManager/dispatcher.d/${dispatcherTypesSubdirMap.${s.type}}03userscript${lib.fixedWidthNumber 4 i}"; 219 }) cfg.dispatcherScripts; 220 221 environment.systemPackages = cfg.packages; 222 223 users.extraGroups = [{ 224 name = "networkmanager"; 225 gid = config.ids.gids.networkmanager; 226 } 227 { 228 name = "nm-openvpn"; 229 gid = config.ids.gids.nm-openvpn; 230 }]; 231 users.extraUsers = [{ 232 name = "nm-openvpn"; 233 uid = config.ids.uids.nm-openvpn; 234 }]; 235 236 systemd.packages = cfg.packages; 237 238 systemd.services."network-manager" = { 239 wantedBy = [ "network.target" ]; 240 241 preStart = '' 242 mkdir -m 700 -p /etc/NetworkManager/system-connections 243 mkdir -m 755 -p ${stateDirs} 244 ''; 245 }; 246 247 # Turn off NixOS' network management 248 networking = { 249 useDHCP = false; 250 wireless.enable = false; 251 }; 252 253 powerManagement.resumeCommands = '' 254 ${config.systemd.package}/bin/systemctl restart network-manager 255 ''; 256 257 security.polkit.extraConfig = polkitConf; 258 259 services.dbus.packages = cfg.packages; 260 261 services.udev.packages = cfg.packages; 262 }; 263}