python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / networking / hostapd.nix
blob63bb44256dd69e3ffd202299b5755f19be4ade38
1 { config, lib, pkgs, utils, ... }:
3 # TODO:
5 # asserts
6 #   ensure that the nl80211 module is loaded/compiled in the kernel
7 #   wpa_supplicant and hostapd on the same wireless interface doesn't make any sense
9 with lib;
11 let
13   cfg = config.services.hostapd;
15   escapedInterface = utils.escapeSystemdPath cfg.interface;
17   configFile = pkgs.writeText "hostapd.conf" ''
18     interface=${cfg.interface}
19     driver=${cfg.driver}
20     ssid=${cfg.ssid}
21     hw_mode=${cfg.hwMode}
22     channel=${toString cfg.channel}
23     ${optionalString (cfg.countryCode != null) "country_code=${cfg.countryCode}"}
24     ${optionalString (cfg.countryCode != null) "ieee80211d=1"}
26     # logging (debug level)
27     logger_syslog=-1
28     logger_syslog_level=${toString cfg.logLevel}
29     logger_stdout=-1
30     logger_stdout_level=${toString cfg.logLevel}
32     ctrl_interface=/run/hostapd
33     ctrl_interface_group=${cfg.group}
35     ${optionalString cfg.wpa ''
36       wpa=2
37       wpa_passphrase=${cfg.wpaPassphrase}
38     ''}
39     ${optionalString cfg.noScan "noscan=1"}
41     ${cfg.extraConfig}
42   '' ;
47   ###### interface
49   options = {
51     services.hostapd = {
53       enable = mkOption {
54         type = types.bool;
55         default = false;
56         description = lib.mdDoc ''
57           Enable putting a wireless interface into infrastructure mode,
58           allowing other wireless devices to associate with the wireless
59           interface and do wireless networking. A simple access point will
60           {option}`enable hostapd.wpa`,
61           {option}`hostapd.wpaPassphrase`, and
62           {option}`hostapd.ssid`, as well as DHCP on the wireless
63           interface to provide IP addresses to the associated stations, and
64           NAT (from the wireless interface to an upstream interface).
65         '';
66       };
68       interface = mkOption {
69         default = "";
70         example = "wlp2s0";
71         type = types.str;
72         description = lib.mdDoc ''
73           The interfaces {command}`hostapd` will use.
74         '';
75       };
77       noScan = mkOption {
78         type = types.bool;
79         default = false;
80         description = lib.mdDoc ''
81           Do not scan for overlapping BSSs in HT40+/- mode.
82           Caution: turning this on will violate regulatory requirements!
83         '';
84       };
86       driver = mkOption {
87         default = "nl80211";
88         example = "hostapd";
89         type = types.str;
90         description = lib.mdDoc ''
91           Which driver {command}`hostapd` will use.
92           Most applications will probably use the default.
93         '';
94       };
96       ssid = mkOption {
97         default = "nixos";
98         example = "mySpecialSSID";
99         type = types.str;
100         description = lib.mdDoc "SSID to be used in IEEE 802.11 management frames.";
101       };
103       hwMode = mkOption {
104         default = "g";
105         type = types.enum [ "a" "b" "g" ];
106         description = lib.mdDoc ''
107           Operation mode.
108           (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g).
109         '';
110       };
112       channel = mkOption {
113         default = 7;
114         example = 11;
115         type = types.int;
116         description = lib.mdDoc ''
117           Channel number (IEEE 802.11)
118           Please note that some drivers do not use this value from
119           {command}`hostapd` and the channel will need to be configured
120           separately with {command}`iwconfig`.
121         '';
122       };
124       group = mkOption {
125         default = "wheel";
126         example = "network";
127         type = types.str;
128         description = lib.mdDoc ''
129           Members of this group can control {command}`hostapd`.
130         '';
131       };
133       wpa = mkOption {
134         type = types.bool;
135         default = true;
136         description = lib.mdDoc ''
137           Enable WPA (IEEE 802.11i/D3.0) to authenticate with the access point.
138         '';
139       };
141       wpaPassphrase = mkOption {
142         default = "my_sekret";
143         example = "any_64_char_string";
144         type = types.str;
145         description = lib.mdDoc ''
146           WPA-PSK (pre-shared-key) passphrase. Clients will need this
147           passphrase to associate with this access point.
148           Warning: This passphrase will get put into a world-readable file in
149           the Nix store!
150         '';
151       };
153       logLevel = mkOption {
154         default = 2;
155         type = types.int;
156         description = lib.mdDoc ''
157           Levels (minimum value for logged events):
158           0 = verbose debugging
159           1 = debugging
160           2 = informational messages
161           3 = notification
162           4 = warning
163         '';
164       };
166       countryCode = mkOption {
167         default = null;
168         example = "US";
169         type = with types; nullOr str;
170         description = lib.mdDoc ''
171           Country code (ISO/IEC 3166-1). Used to set regulatory domain.
172           Set as needed to indicate country in which device is operating.
173           This can limit available channels and transmit power.
174           These two octets are used as the first two octets of the Country String
175           (dot11CountryString).
176           If set this enables IEEE 802.11d. This advertises the countryCode and
177           the set of allowed channels and transmit power levels based on the
178           regulatory limits.
179         '';
180       };
182       extraConfig = mkOption {
183         default = "";
184         example = ''
185           auth_algo=0
186           ieee80211n=1
187           ht_capab=[HT40-][SHORT-GI-40][DSSS_CCK-40]
188           '';
189         type = types.lines;
190         description = lib.mdDoc "Extra configuration options to put in hostapd.conf.";
191       };
192     };
193   };
196   ###### implementation
198   config = mkIf cfg.enable {
200     environment.systemPackages =  [ pkgs.hostapd ];
202     services.udev.packages = optionals (cfg.countryCode != null) [ pkgs.crda ];
204     systemd.services.hostapd =
205       { description = "hostapd wireless AP";
207         path = [ pkgs.hostapd ];
208         after = [ "sys-subsystem-net-devices-${escapedInterface}.device" ];
209         bindsTo = [ "sys-subsystem-net-devices-${escapedInterface}.device" ];
210         requiredBy = [ "network-link-${cfg.interface}.service" ];
211         wantedBy = [ "multi-user.target" ];
213         serviceConfig =
214           { ExecStart = "${pkgs.hostapd}/bin/hostapd ${configFile}";
215             Restart = "always";
216           };
217       };
218   };