29027fd1e1
Using pkgs.lib on the spine of module evaluation is problematic because the pkgs argument depends on the result of module evaluation. To prevent an infinite recursion, pkgs and some of the modules are evaluated twice, which is inefficient. Using ‘with lib’ prevents this problem.
213 lines
6.1 KiB
Nix
213 lines
6.1 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
with pkgs;
|
|
|
|
let
|
|
cfg = config.networking.networkmanager;
|
|
|
|
stateDirs = "/var/lib/NetworkManager /var/lib/dhclient";
|
|
|
|
configFile = writeText "NetworkManager.conf" ''
|
|
[main]
|
|
plugins=keyfile
|
|
|
|
[keyfile]
|
|
${optionalString (config.networking.hostName != "") ''
|
|
hostname=${config.networking.hostName}
|
|
''}
|
|
|
|
[logging]
|
|
level=WARN
|
|
'';
|
|
|
|
/*
|
|
[network-manager]
|
|
Identity=unix-group:networkmanager
|
|
Action=org.freedesktop.NetworkManager.*
|
|
ResultAny=yes
|
|
ResultInactive=no
|
|
ResultActive=yes
|
|
|
|
[modem-manager]
|
|
Identity=unix-group:networkmanager
|
|
Action=org.freedesktop.ModemManager*
|
|
ResultAny=yes
|
|
ResultInactive=no
|
|
ResultActive=yes
|
|
*/
|
|
polkitConf = ''
|
|
polkit.addRule(function(action, subject) {
|
|
if (
|
|
subject.isInGroup("networkmanager")
|
|
&& subject.active
|
|
&& (action.id.indexOf("org.freedesktop.NetworkManager.") == 0
|
|
|| action.id.indexOf("org.freedesktop.ModemManager") == 0
|
|
))
|
|
{ return polkit.Result.YES; }
|
|
});
|
|
'';
|
|
|
|
ipUpScript = writeScript "01nixos-ip-up" ''
|
|
#!/bin/sh
|
|
if test "$2" = "up"; then
|
|
${config.systemd.package}/bin/systemctl start ip-up.target
|
|
fi
|
|
'';
|
|
|
|
ns = xs: writeText "nameservers" (
|
|
concatStrings (map (s: "nameserver ${s}\n") xs)
|
|
);
|
|
|
|
overrideNameserversScript = writeScript "02overridedns" ''
|
|
#!/bin/sh
|
|
tmp=`${coreutils}/bin/mktemp`
|
|
${gnused}/bin/sed '/nameserver /d' /etc/resolv.conf > $tmp
|
|
${gnugrep}/bin/grep 'nameserver ' /etc/resolv.conf | \
|
|
${gnugrep}/bin/grep -vf ${ns (cfg.appendNameservers ++ cfg.insertNameservers)} > $tmp.ns
|
|
${optionalString (cfg.appendNameservers != []) "${coreutils}/bin/cat $tmp $tmp.ns ${ns cfg.appendNameservers} > /etc/resolv.conf"}
|
|
${optionalString (cfg.insertNameservers != []) "${coreutils}/bin/cat $tmp ${ns cfg.insertNameservers} $tmp.ns > /etc/resolv.conf"}
|
|
${coreutils}/bin/rm -f $tmp $tmp.ns
|
|
'';
|
|
|
|
in {
|
|
|
|
###### interface
|
|
|
|
options = {
|
|
|
|
networking.networkmanager = {
|
|
|
|
enable = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Whether to use NetworkManager to obtain an IP address and other
|
|
configuration for all network interfaces that are not manually
|
|
configured. If enabled, a group <literal>networkmanager</literal>
|
|
will be created. Add all users that should have permission
|
|
to change network settings to this group.
|
|
'';
|
|
};
|
|
|
|
packages = mkOption {
|
|
type = types.listOf types.path;
|
|
default = [ ];
|
|
description = ''
|
|
Extra packages that provide NetworkManager plugins.
|
|
'';
|
|
apply = list: [ networkmanager modemmanager wpa_supplicant ] ++ list;
|
|
};
|
|
|
|
appendNameservers = mkOption {
|
|
type = types.listOf types.string;
|
|
default = [];
|
|
description = ''
|
|
A list of name servers that should be appended
|
|
to the ones configured in NetworkManager or received by DHCP.
|
|
'';
|
|
};
|
|
|
|
insertNameservers = mkOption {
|
|
type = types.listOf types.string;
|
|
default = [];
|
|
description = ''
|
|
A list of name servers that should be inserted before
|
|
the ones configured in NetworkManager or received by DHCP.
|
|
'';
|
|
};
|
|
|
|
};
|
|
};
|
|
|
|
|
|
###### implementation
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
assertions = [{
|
|
assertion = config.networking.wireless.enable == false;
|
|
message = "You can not use networking.networkmanager with services.networking.wireless";
|
|
}];
|
|
|
|
boot.kernelModules = [ "ppp_mppe" ]; # Needed for most (all?) PPTP VPN connections.
|
|
|
|
environment.etc = [
|
|
{ source = ipUpScript;
|
|
target = "NetworkManager/dispatcher.d/01nixos-ip-up";
|
|
}
|
|
{ source = configFile;
|
|
target = "NetworkManager/NetworkManager.conf";
|
|
}
|
|
{ source = "${networkmanager_openvpn}/etc/NetworkManager/VPN/nm-openvpn-service.name";
|
|
target = "NetworkManager/VPN/nm-openvpn-service.name";
|
|
}
|
|
{ source = "${networkmanager_vpnc}/etc/NetworkManager/VPN/nm-vpnc-service.name";
|
|
target = "NetworkManager/VPN/nm-vpnc-service.name";
|
|
}
|
|
{ source = "${networkmanager_openconnect}/etc/NetworkManager/VPN/nm-openconnect-service.name";
|
|
target = "NetworkManager/VPN/nm-openconnect-service.name";
|
|
}
|
|
{ source = "${networkmanager_pptp}/etc/NetworkManager/VPN/nm-pptp-service.name";
|
|
target = "NetworkManager/VPN/nm-pptp-service.name";
|
|
}
|
|
] ++ pkgs.lib.optional (cfg.appendNameservers == [] || cfg.insertNameservers == [])
|
|
{ source = overrideNameserversScript;
|
|
target = "NetworkManager/dispatcher.d/02overridedns";
|
|
};
|
|
|
|
environment.systemPackages = cfg.packages ++ [
|
|
networkmanager_openvpn
|
|
networkmanager_vpnc
|
|
networkmanager_openconnect
|
|
networkmanager_pptp
|
|
modemmanager
|
|
];
|
|
|
|
users.extraGroups = singleton {
|
|
name = "networkmanager";
|
|
gid = config.ids.gids.networkmanager;
|
|
};
|
|
|
|
systemd.packages = cfg.packages;
|
|
|
|
# Create an initialisation service that both starts
|
|
# NetworkManager when network.target is reached,
|
|
# and sets up necessary directories for NM.
|
|
systemd.services."networkmanager-init" = {
|
|
description = "NetworkManager initialisation";
|
|
wantedBy = [ "network.target" ];
|
|
wants = [ "NetworkManager.service" ];
|
|
before = [ "NetworkManager.service" ];
|
|
script = ''
|
|
mkdir -m 700 -p /etc/NetworkManager/system-connections
|
|
mkdir -m 755 -p ${stateDirs}
|
|
'';
|
|
serviceConfig.Type = "oneshot";
|
|
};
|
|
|
|
# Turn off NixOS' network management
|
|
networking = {
|
|
useDHCP = false;
|
|
wireless.enable = false;
|
|
};
|
|
|
|
powerManagement.resumeCommands = ''
|
|
systemctl restart NetworkManager
|
|
'';
|
|
|
|
security.polkit.extraConfig = polkitConf;
|
|
|
|
# openvpn plugin has only dbus interface
|
|
services.dbus.packages = cfg.packages ++ [
|
|
networkmanager_openvpn
|
|
networkmanager_vpnc
|
|
networkmanager_openconnect
|
|
networkmanager_pptp
|
|
modemmanager
|
|
];
|
|
|
|
services.udev.packages = cfg.packages;
|
|
};
|
|
}
|