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