There is nothing in this commit except for the changes made by nix-shell -p nixfmt-rfc-style --run "nixfmt ." If this has mucked up your open branches then sorry about that. You can probably nixfmt them to match before merging
199 lines
4.9 KiB
Nix
199 lines
4.9 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
lib,
|
|
...
|
|
}:
|
|
let
|
|
svc = config.system.service;
|
|
cfg = config.profile.gateway;
|
|
inherit (lib)
|
|
mkOption
|
|
mkEnableOption
|
|
mkIf
|
|
types
|
|
;
|
|
inherit (pkgs) liminix serviceFns;
|
|
inherit (liminix.services) bundle oneshot;
|
|
hostaps =
|
|
let
|
|
defaults = {
|
|
auth_algs = 1; # 1=wpa2, 2=wep, 3=both
|
|
wpa = 2; # 1=wpa, 2=wpa2, 3=both
|
|
wpa_key_mgmt = "WPA-PSK";
|
|
wpa_pairwise = "TKIP CCMP"; # auth for wpa (may not need this?)
|
|
rsn_pairwise = "CCMP"; # auth for wpa2
|
|
};
|
|
in
|
|
lib.mapAttrs' (
|
|
name: value:
|
|
let
|
|
attrs = defaults // { ssid = name; } // value;
|
|
in
|
|
lib.nameValuePair "hostap-${name}" (
|
|
svc.hostapd.build {
|
|
interface = attrs.interface;
|
|
params = lib.filterAttrs (k: v: k != "interface") attrs;
|
|
}
|
|
)
|
|
) cfg.wireless.networks;
|
|
in
|
|
{
|
|
|
|
options.profile.gateway = {
|
|
lan = {
|
|
interfaces = mkOption {
|
|
type = types.listOf liminix.lib.types.interface;
|
|
default = [ ];
|
|
};
|
|
address = mkOption {
|
|
type = types.attrs;
|
|
};
|
|
prefix = mkOption { type = types.str; };
|
|
dhcp = {
|
|
start = mkOption { type = types.int; };
|
|
end = mkOption { type = types.int; };
|
|
hosts = mkOption { type = types.attrs; };
|
|
localDomain = mkOption { type = types.str; };
|
|
};
|
|
};
|
|
|
|
firewall = {
|
|
enable = mkEnableOption "firewall";
|
|
rules = mkOption { type = types.attrsOf types.attrs; };
|
|
zones = mkOption {
|
|
type = types.attrsOf (types.listOf liminix.lib.types.service);
|
|
default = {
|
|
lan = [ config.services.int ];
|
|
wan = [ config.services.wan ];
|
|
};
|
|
};
|
|
};
|
|
|
|
wan = {
|
|
interface = mkOption { type = liminix.lib.types.interface; };
|
|
dhcp6.enable = mkOption { type = types.bool; };
|
|
};
|
|
|
|
wireless = mkOption {
|
|
type = types.attrsOf types.anything;
|
|
};
|
|
};
|
|
|
|
imports = [
|
|
../wlan.nix
|
|
../network
|
|
../ppp
|
|
../dnsmasq
|
|
../dhcp6c
|
|
../firewall
|
|
../hostapd
|
|
../bridge
|
|
../ntp
|
|
../ssh
|
|
{ config.services = hostaps; }
|
|
];
|
|
|
|
config = {
|
|
services.int = svc.network.address.build (
|
|
{
|
|
interface = svc.bridge.primary.build { ifname = "int"; };
|
|
}
|
|
// cfg.lan.address
|
|
);
|
|
|
|
services.bridge = svc.bridge.members.build {
|
|
primary = config.services.int;
|
|
members = cfg.lan.interfaces;
|
|
};
|
|
|
|
services.wan = cfg.wan.interface;
|
|
|
|
services.packet_forwarding = svc.network.forward.build { };
|
|
|
|
services.dhcp6c =
|
|
let
|
|
client = svc.dhcp6c.client.build {
|
|
interface = config.services.wan;
|
|
};
|
|
bundl = bundle {
|
|
name = "dhcp6c";
|
|
contents = [
|
|
(svc.dhcp6c.prefix.build {
|
|
inherit client;
|
|
interface = config.services.int;
|
|
})
|
|
(svc.dhcp6c.address.build {
|
|
inherit client;
|
|
interface = config.services.wan;
|
|
})
|
|
];
|
|
};
|
|
in
|
|
mkIf cfg.wan.dhcp6.enable bundl;
|
|
|
|
services.dns =
|
|
let
|
|
interface = config.services.int;
|
|
dcfg = cfg.lan.dhcp;
|
|
in
|
|
svc.dnsmasq.build {
|
|
resolvconf = config.services.resolvconf;
|
|
inherit interface;
|
|
ranges = [
|
|
"${cfg.lan.prefix}.${toString dcfg.start},${cfg.lan.prefix}.${toString dcfg.end}"
|
|
# ra-stateless: sends router advertisements with the O and A
|
|
# bits set, and provides a stateless DHCP service. The client
|
|
# will use a SLAAC address, and use DHCP for other
|
|
# configuration information.
|
|
"::,constructor:$(output ${interface} ifname),ra-stateless"
|
|
];
|
|
|
|
hosts = dcfg.hosts;
|
|
upstreams = [ "/${dcfg.localDomain}/" ];
|
|
domain = dcfg.localDomain;
|
|
};
|
|
|
|
services.defaultroute4 = svc.network.route.build {
|
|
via = "$(output ${config.services.wan} address)";
|
|
target = "default";
|
|
dependencies = [ config.services.wan ];
|
|
};
|
|
|
|
services.defaultroute6 = svc.network.route.build {
|
|
via = "$(output ${config.services.wan} ipv6-peer-address)";
|
|
target = "default";
|
|
interface = config.services.wan;
|
|
};
|
|
|
|
services.firewall = mkIf cfg.firewall.enable (
|
|
svc.firewall.build {
|
|
extraRules = cfg.firewall.rules;
|
|
inherit (cfg.firewall) zones;
|
|
}
|
|
);
|
|
|
|
services.resolvconf = oneshot rec {
|
|
dependencies = [ config.services.wan ];
|
|
name = "resolvconf";
|
|
up = ''
|
|
( in_outputs ${name}
|
|
echo "nameserver $(output ${config.services.wan} ns1)" > resolv.conf
|
|
echo "nameserver $(output ${config.services.wan} ns2)" >> resolv.conf
|
|
chmod 0444 resolv.conf
|
|
)
|
|
'';
|
|
};
|
|
|
|
filesystem =
|
|
let
|
|
inherit (pkgs.pseudofile) dir symlink;
|
|
in
|
|
dir {
|
|
etc = dir {
|
|
"resolv.conf" = symlink "${config.services.resolvconf}/.outputs/resolv.conf";
|
|
};
|
|
};
|
|
};
|
|
}
|