179 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, lib, pkgs, ... }:
 | 
						|
 | 
						|
# TODO:
 | 
						|
#
 | 
						|
# asserts
 | 
						|
#   ensure that the nl80211 module is loaded/compiled in the kernel
 | 
						|
#   wpa_supplicant and hostapd on the same wireless interface doesn't make any sense
 | 
						|
 | 
						|
with lib;
 | 
						|
 | 
						|
let
 | 
						|
 | 
						|
  cfg = config.services.hostapd;
 | 
						|
 | 
						|
  configFile = pkgs.writeText "hostapd.conf" ''
 | 
						|
    interface=${cfg.interface}
 | 
						|
    driver=${cfg.driver}
 | 
						|
    ssid=${cfg.ssid}
 | 
						|
    hw_mode=${cfg.hwMode}
 | 
						|
    channel=${toString cfg.channel}
 | 
						|
 | 
						|
    # logging (debug level)
 | 
						|
    logger_syslog=-1
 | 
						|
    logger_syslog_level=2
 | 
						|
    logger_stdout=-1
 | 
						|
    logger_stdout_level=2
 | 
						|
 | 
						|
    ctrl_interface=/var/run/hostapd
 | 
						|
    ctrl_interface_group=${cfg.group}
 | 
						|
 | 
						|
    ${if cfg.wpa then ''
 | 
						|
      wpa=1
 | 
						|
      wpa_passphrase=${cfg.wpaPassphrase}
 | 
						|
      '' else ""}
 | 
						|
 | 
						|
    ${cfg.extraConfig}
 | 
						|
  '' ;
 | 
						|
 | 
						|
in
 | 
						|
 | 
						|
{
 | 
						|
  ###### interface
 | 
						|
 | 
						|
  options = {
 | 
						|
 | 
						|
    services.hostapd = {
 | 
						|
 | 
						|
      enable = mkOption {
 | 
						|
        default = false;
 | 
						|
        description = ''
 | 
						|
          Enable putting a wireless interface into infrastructure mode,
 | 
						|
          allowing other wireless devices to associate with the wireless
 | 
						|
          interface and do wireless networking. A simple access point will
 | 
						|
          <option>enable hostapd.wpa</option>,
 | 
						|
          <option>hostapd.wpaPassphrase</option>, and
 | 
						|
          <option>hostapd.ssid</option>, as well as DHCP on the wireless
 | 
						|
          interface to provide IP addresses to the associated stations, and
 | 
						|
          NAT (from the wireless interface to an upstream interface).
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      interface = mkOption {
 | 
						|
        default = "";
 | 
						|
        example = "wlp2s0";
 | 
						|
        description = ''
 | 
						|
          The interfaces <command>hostapd</command> will use.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      driver = mkOption {
 | 
						|
        default = "nl80211";
 | 
						|
        example = "hostapd";
 | 
						|
        type = types.string;
 | 
						|
        description = ''
 | 
						|
          Which driver <command>hostapd</command> will use.
 | 
						|
          Most applications will probably use the default.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      ssid = mkOption {
 | 
						|
        default = "nixos";
 | 
						|
        example = "mySpecialSSID";
 | 
						|
        type = types.string;
 | 
						|
        description = "SSID to be used in IEEE 802.11 management frames.";
 | 
						|
      };
 | 
						|
 | 
						|
      hwMode = mkOption {
 | 
						|
        default = "g";
 | 
						|
        type = types.string;
 | 
						|
        description = ''
 | 
						|
          Operation mode.
 | 
						|
          (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g).
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      channel = mkOption {
 | 
						|
        default = 7;
 | 
						|
        example = 11;
 | 
						|
        type = types.int;
 | 
						|
        description = ''
 | 
						|
          Channel number (IEEE 802.11)
 | 
						|
          Please note that some drivers do not use this value from
 | 
						|
          <command>hostapd</command> and the channel will need to be configured
 | 
						|
          separately with <command>iwconfig</command>.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      group = mkOption {
 | 
						|
        default = "wheel";
 | 
						|
        example = "network";
 | 
						|
        type = types.string;
 | 
						|
        description = ''
 | 
						|
          Members of this group can control <command>hostapd</command>.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      wpa = mkOption {
 | 
						|
        default = true;
 | 
						|
        description = ''
 | 
						|
          Enable WPA (IEEE 802.11i/D3.0) to authenticate with the access point.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      wpaPassphrase = mkOption {
 | 
						|
        default = "my_sekret";
 | 
						|
        example = "any_64_char_string";
 | 
						|
        type = types.string;
 | 
						|
        description = ''
 | 
						|
          WPA-PSK (pre-shared-key) passphrase. Clients will need this
 | 
						|
          passphrase to associate with this access point.
 | 
						|
          Warning: This passphrase will get put into a world-readable file in
 | 
						|
          the Nix store!
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      extraConfig = mkOption {
 | 
						|
        default = "";
 | 
						|
        example = ''
 | 
						|
          auth_algo=0
 | 
						|
          ieee80211n=1
 | 
						|
          ht_capab=[HT40-][SHORT-GI-40][DSSS_CCK-40]
 | 
						|
          '';
 | 
						|
        type = types.string;
 | 
						|
        description = "Extra configuration options to put in hostapd.conf.";
 | 
						|
      };
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
 | 
						|
  ###### implementation
 | 
						|
 | 
						|
  config = mkIf cfg.enable {
 | 
						|
 | 
						|
    assertions = [
 | 
						|
      { assertion = (cfg.hwMode == "a" || cfg.hwMode == "b" || cfg.hwMode == "g");
 | 
						|
        message = "hwMode must be a/b/g";
 | 
						|
      }
 | 
						|
      { assertion = (cfg.channel >= 1 && cfg.channel <= 13);
 | 
						|
        message = "channel must be between 1 and 13";
 | 
						|
      }];
 | 
						|
 | 
						|
    environment.systemPackages =  [ pkgs.hostapd ];
 | 
						|
 | 
						|
    systemd.services.hostapd =
 | 
						|
      { description = "hostapd wireless AP";
 | 
						|
 | 
						|
        path = [ pkgs.hostapd ];
 | 
						|
        wantedBy = [ "network.target" ];
 | 
						|
 | 
						|
        after = [ "${cfg.interface}-cfg.service" "nat.service" "bind.service" "dhcpd.service"];
 | 
						|
 | 
						|
        serviceConfig =
 | 
						|
          { ExecStart = "${pkgs.hostapd}/bin/hostapd ${configFile}";
 | 
						|
            Restart = "always";
 | 
						|
          };
 | 
						|
      };
 | 
						|
  };
 | 
						|
}
 |