at v206 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 dispatcherTypesSubdirMap = { 75 "basic" = ""; 76 "pre-up" = "pre-up.d/"; 77 "pre-down" = "pre-down.d/"; 78 }; 79 80in { 81 82 ###### interface 83 84 options = { 85 86 networking.networkmanager = { 87 88 enable = mkOption { 89 type = types.bool; 90 default = false; 91 description = '' 92 Whether to use NetworkManager to obtain an IP address and other 93 configuration for all network interfaces that are not manually 94 configured. If enabled, a group <literal>networkmanager</literal> 95 will be created. Add all users that should have permission 96 to change network settings to this group. 97 ''; 98 }; 99 100 # Ugly hack for using the correct gnome3 packageSet 101 basePackages = mkOption { 102 type = types.attrsOf types.path; 103 default = { inherit networkmanager modemmanager wpa_supplicant 104 networkmanager_openvpn networkmanager_vpnc 105 networkmanager_openconnect 106 networkmanager_pptp networkmanager_l2tp; }; 107 internal = true; 108 }; 109 110 packages = mkOption { 111 type = types.listOf types.path; 112 default = [ ]; 113 description = '' 114 Extra packages that provide NetworkManager plugins. 115 ''; 116 apply = list: (attrValues cfg.basePackages) ++ list; 117 }; 118 119 appendNameservers = mkOption { 120 type = types.listOf types.str; 121 default = []; 122 description = '' 123 A list of name servers that should be appended 124 to the ones configured in NetworkManager or received by DHCP. 125 ''; 126 }; 127 128 insertNameservers = mkOption { 129 type = types.listOf types.str; 130 default = []; 131 description = '' 132 A list of name servers that should be inserted before 133 the ones configured in NetworkManager or received by DHCP. 134 ''; 135 }; 136 137 dispatcherScripts = mkOption { 138 type = types.listOf (types.submodule { 139 options = { 140 source = mkOption { 141 type = types.str; 142 description = '' 143 A script source. 144 ''; 145 }; 146 147 type = mkOption { 148 type = types.enum (attrNames dispatcherTypesSubdirMap); 149 default = "basic"; 150 description = '' 151 Dispatcher hook type. Only basic hooks are currently available. 152 ''; 153 }; 154 }; 155 }); 156 default = []; 157 description = '' 158 A list of scripts which will be executed in response to network events. 159 ''; 160 }; 161 }; 162 }; 163 164 165 ###### implementation 166 167 config = mkIf cfg.enable { 168 169 assertions = [{ 170 assertion = config.networking.wireless.enable == false; 171 message = "You can not use networking.networkmanager with services.networking.wireless"; 172 }]; 173 174 boot.kernelModules = [ "ppp_mppe" ]; # Needed for most (all?) PPTP VPN connections. 175 176 environment.etc = with cfg.basePackages; [ 177 { source = ipUpScript; 178 target = "NetworkManager/dispatcher.d/01nixos-ip-up"; 179 } 180 { source = configFile; 181 target = "NetworkManager/NetworkManager.conf"; 182 } 183 { source = "${networkmanager_openvpn}/etc/NetworkManager/VPN/nm-openvpn-service.name"; 184 target = "NetworkManager/VPN/nm-openvpn-service.name"; 185 } 186 { source = "${networkmanager_vpnc}/etc/NetworkManager/VPN/nm-vpnc-service.name"; 187 target = "NetworkManager/VPN/nm-vpnc-service.name"; 188 } 189 { source = "${networkmanager_openconnect}/etc/NetworkManager/VPN/nm-openconnect-service.name"; 190 target = "NetworkManager/VPN/nm-openconnect-service.name"; 191 } 192 { source = "${networkmanager_pptp}/etc/NetworkManager/VPN/nm-pptp-service.name"; 193 target = "NetworkManager/VPN/nm-pptp-service.name"; 194 } 195 { source = "${networkmanager_l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name"; 196 target = "NetworkManager/VPN/nm-l2tp-service.name"; 197 } 198 ] ++ optional (cfg.appendNameservers == [] || cfg.insertNameservers == []) 199 { source = overrideNameserversScript; 200 target = "NetworkManager/dispatcher.d/02overridedns"; 201 } 202 ++ lib.imap (i: s: { 203 text = s.source; 204 target = "NetworkManager/dispatcher.d/${dispatcherTypesSubdirMap.${s.type}}03userscript${lib.fixedWidthNumber 4 i}"; 205 }) cfg.dispatcherScripts; 206 207 environment.systemPackages = cfg.packages; 208 209 users.extraGroups = singleton { 210 name = "networkmanager"; 211 gid = config.ids.gids.networkmanager; 212 }; 213 214 systemd.packages = cfg.packages; 215 216 # Create an initialisation service that both starts 217 # NetworkManager when network.target is reached, 218 # and sets up necessary directories for NM. 219 systemd.services."networkmanager-init" = { 220 description = "NetworkManager initialisation"; 221 wantedBy = [ "network.target" ]; 222 wants = [ "network-manager.service" ]; 223 before = [ "network-manager.service" ]; 224 script = '' 225 mkdir -m 700 -p /etc/NetworkManager/system-connections 226 mkdir -m 755 -p ${stateDirs} 227 ''; 228 serviceConfig.Type = "oneshot"; 229 }; 230 231 # Turn off NixOS' network management 232 networking = { 233 useDHCP = false; 234 wireless.enable = false; 235 }; 236 237 powerManagement.resumeCommands = '' 238 ${config.systemd.package}/bin/systemctl restart network-manager 239 ''; 240 241 security.polkit.extraConfig = polkitConf; 242 243 services.dbus.packages = cfg.packages; 244 245 services.udev.packages = cfg.packages; 246 }; 247}