213 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, lib, pkgs, ... }:
 | 
						|
 | 
						|
with pkgs;
 | 
						|
with lib;
 | 
						|
 | 
						|
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";
 | 
						|
      }
 | 
						|
    ] ++ 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;
 | 
						|
  };
 | 
						|
}
 |