Compare commits
10 Commits
2ecaa3bef8
...
67080627a1
Author | SHA1 | Date |
---|---|---|
Daniel Barlow | 67080627a1 | |
Daniel Barlow | 269c9cd916 | |
Daniel Barlow | 95ebddb661 | |
Daniel Barlow | a66510c9e6 | |
Daniel Barlow | 75aa01513c | |
Daniel Barlow | d3fd6f5c0a | |
Daniel Barlow | 90302f0944 | |
Daniel Barlow | 00bf3446f1 | |
Daniel Barlow | 0d8abbc314 | |
Daniel Barlow | 4c3883a5e7 |
11
THOUGHTS.txt
11
THOUGHTS.txt
|
@ -4331,3 +4331,14 @@ aside: "trigger" is the least bad word I've thought of so far for
|
|||
these services that stop/start other services
|
||||
|
||||
telent: yeah, in general 'ps afuxww' (or s6-ps -H :)) is the way to solve this, look for hung s6-rc processes and in particular their s6-svlisten1 children, where the command line will show what service is still waiting for readiness
|
||||
|
||||
Sat Mar 16 23:28:10 GMT 2024
|
||||
|
||||
We have the gl-ar750 booting with the bridge members added by trigger, and
|
||||
it seems to work.
|
||||
|
||||
One thing worth flagging is that we have to run s6-rc with the -b
|
||||
(block if locked) flag in the trigger otherwise the triggered service
|
||||
just doesn't come up if there's something else starting at the same
|
||||
time. There are warnings in the s6-rc docs about doing this, though.
|
||||
We need to think hard about whether we can end up calling s6-rc recursively
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
...
|
||||
}: let
|
||||
secrets = import ./extneder-secrets.nix;
|
||||
svc = config.system.service;
|
||||
in rec {
|
||||
boot = {
|
||||
tftp = {
|
||||
|
@ -23,45 +24,11 @@ in rec {
|
|||
imports = [
|
||||
"${modulesPath}/profiles/wap.nix"
|
||||
"${modulesPath}/vlan"
|
||||
"${modulesPath}/ssh"
|
||||
];
|
||||
|
||||
hostname = "extneder";
|
||||
|
||||
kernel = {
|
||||
config = {
|
||||
|
||||
NETFILTER_XT_MATCH_CONNTRACK = "y";
|
||||
|
||||
IP6_NF_IPTABLES = "y"; # do we still need these
|
||||
IP_NF_IPTABLES = "y"; # if using nftables directly
|
||||
|
||||
# these are copied from rotuer and need review.
|
||||
# we're not running a firewall, so why do we need
|
||||
# nftables config?
|
||||
IP_NF_NAT = "y";
|
||||
IP_NF_TARGET_MASQUERADE = "y";
|
||||
NETFILTER = "y";
|
||||
NETFILTER_ADVANCED = "y";
|
||||
NETFILTER_XTABLES = "y";
|
||||
|
||||
NFT_COMPAT = "y";
|
||||
NFT_CT = "y";
|
||||
NFT_LOG = "y";
|
||||
NFT_MASQ = "y";
|
||||
NFT_NAT = "y";
|
||||
NFT_REJECT = "y";
|
||||
NFT_REJECT_INET = "y";
|
||||
|
||||
NF_CONNTRACK = "y";
|
||||
NF_NAT = "y";
|
||||
NF_NAT_MASQUERADE = "y";
|
||||
NF_TABLES = "y";
|
||||
NF_TABLES_INET = "y";
|
||||
NF_TABLES_IPV4 = "y";
|
||||
NF_TABLES_IPV6 = "y";
|
||||
};
|
||||
};
|
||||
|
||||
profile.wap = {
|
||||
interfaces = with config.hardware.networkInterfaces; [
|
||||
lan
|
||||
|
@ -80,6 +47,7 @@ in rec {
|
|||
};
|
||||
};
|
||||
|
||||
services.sshd = svc.ssh.build {};
|
||||
users.root.passwd = lib.mkForce secrets.root.passwd;
|
||||
defaultProfile.packages = with pkgs; [nftables strace tcpdump swconfig];
|
||||
}
|
||||
|
|
|
@ -48,21 +48,38 @@ in rec {
|
|||
wlan wlan5
|
||||
lan0 lan1 lan2 lan3 lan4
|
||||
];
|
||||
inherit (secrets.lan) prefix;
|
||||
address = {
|
||||
family = "inet"; address ="${secrets.lan.prefix}.1"; prefixLength = 24;
|
||||
};
|
||||
dhcp = {
|
||||
start = 10;
|
||||
end = 240;
|
||||
hosts = { } // lib.optionalAttrs (builtins.pathExists ./static-leases.nix) (import ./static-leases.nix);
|
||||
localDomain = "lan";
|
||||
};
|
||||
};
|
||||
wan = {
|
||||
interface = config.hardware.networkInterfaces.wan;
|
||||
username = secrets.l2tp.name;
|
||||
password = secrets.l2tp.password;
|
||||
dhcp6.enable = true;
|
||||
};
|
||||
firewall = {
|
||||
enable = true;
|
||||
rules =
|
||||
let defaults = import ./demo-firewall.nix;
|
||||
in lib.recursiveUpdate defaults secrets.firewallRules;
|
||||
};
|
||||
wireless.networks = {
|
||||
telent = {
|
||||
"${secrets.ssid}" = {
|
||||
interface = config.hardware.networkInterfaces.wlan;
|
||||
ssid = secrets.ssid;
|
||||
hw_mode="g";
|
||||
channel = "2";
|
||||
ieee80211n = 1;
|
||||
} // wirelessConfig;
|
||||
telent5 = rec {
|
||||
"${secrets.ssid}5" = rec {
|
||||
interface = config.hardware.networkInterfaces.wlan5;
|
||||
ssid = "${secrets.ssid}5";
|
||||
hw_mode="a";
|
||||
channel = 36;
|
||||
ht_capab = "[HT40+]";
|
||||
|
@ -83,95 +100,6 @@ in rec {
|
|||
|
||||
users.root = secrets.root;
|
||||
|
||||
services.dns =
|
||||
let interface = config.services.int;
|
||||
in svc.dnsmasq.build {
|
||||
resolvconf = services.resolvconf;
|
||||
inherit interface;
|
||||
ranges = [
|
||||
"${secrets.lan.prefix}.10,${secrets.lan.prefix}.240"
|
||||
# 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"
|
||||
];
|
||||
|
||||
# You can add static addresses for the DHCP server here. I'm
|
||||
# not putting my actual MAC addresses in a public git repo ...
|
||||
hosts = { } // lib.optionalAttrs (builtins.pathExists ./static-leases.nix) (import ./static-leases.nix);
|
||||
upstreams = [ "/${secrets.domainName}/" ];
|
||||
domain = secrets.domainName;
|
||||
};
|
||||
|
||||
services.wan = svc.pppoe.build {
|
||||
interface = config.hardware.networkInterfaces.wan;
|
||||
ppp-options = [
|
||||
"debug" "+ipv6" "noauth"
|
||||
"name" secrets.l2tp.name
|
||||
"password" secrets.l2tp.password
|
||||
];
|
||||
};
|
||||
|
||||
services.resolvconf = oneshot rec {
|
||||
dependencies = [ services.wan ];
|
||||
name = "resolvconf";
|
||||
up = ''
|
||||
. ${serviceFns}
|
||||
( in_outputs ${name}
|
||||
echo "nameserver $(output ${services.wan} ns1)" > resolv.conf
|
||||
echo "nameserver $(output ${services.wan} ns2)" >> resolv.conf
|
||||
chmod 0444 resolv.conf
|
||||
)
|
||||
'';
|
||||
};
|
||||
|
||||
filesystem =
|
||||
let inherit (pkgs.pseudofile) dir symlink;
|
||||
in dir {
|
||||
etc = dir {
|
||||
"resolv.conf" = symlink "${services.resolvconf}/.outputs/resolv.conf";
|
||||
};
|
||||
};
|
||||
|
||||
services.defaultroute4 = svc.network.route.build {
|
||||
via = "$(output ${services.wan} address)";
|
||||
target = "default";
|
||||
dependencies = [ services.wan ];
|
||||
};
|
||||
|
||||
services.defaultroute6 = svc.network.route.build {
|
||||
via = "$(output ${services.wan} ipv6-peer-address)";
|
||||
target = "default";
|
||||
interface = services.wan;
|
||||
};
|
||||
|
||||
services.firewall = svc.firewall.build {
|
||||
ruleset =
|
||||
let defaults = import ./demo-firewall.nix;
|
||||
in lib.recursiveUpdate defaults secrets.firewallRules;
|
||||
};
|
||||
|
||||
services.packet_forwarding = svc.network.forward.build { };
|
||||
|
||||
services.dhcp6c =
|
||||
let client = svc.dhcp6c.client.build {
|
||||
interface = services.wan;
|
||||
};
|
||||
in bundle {
|
||||
name = "dhcp6c";
|
||||
contents = [
|
||||
(svc.dhcp6c.prefix.build {
|
||||
inherit client;
|
||||
interface = config.services.int;
|
||||
})
|
||||
(svc.dhcp6c.address.build {
|
||||
inherit client;
|
||||
interface = config.services.wan;
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
defaultProfile.packages = with pkgs; [
|
||||
min-collect-garbage
|
||||
nftables
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
let
|
||||
svc = config.system.service;
|
||||
cfg = config.profile.gateway;
|
||||
inherit (lib) mkOption mkEnableOption mdDoc types optional optionals;
|
||||
inherit (pkgs) liminix;
|
||||
inherit (lib) mkOption mkEnableOption mkIf mdDoc types optional optionals;
|
||||
inherit (pkgs) liminix serviceFns;
|
||||
inherit (liminix.services) bundle oneshot;
|
||||
hostaps =
|
||||
let
|
||||
defaults = {
|
||||
|
@ -35,7 +36,27 @@ in {
|
|||
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; };
|
||||
};
|
||||
|
||||
wan = {
|
||||
interface = mkOption { type = liminix.lib.types.interface; };
|
||||
username = mkOption { type = types.str; };
|
||||
password = mkOption { type = types.str; };
|
||||
dhcp6.enable = mkOption { type = types.bool; };
|
||||
};
|
||||
|
||||
wireless = mkOption {
|
||||
type = types.attrsOf types.anything;
|
||||
};
|
||||
|
@ -64,59 +85,97 @@ in {
|
|||
primary = config.services.int;
|
||||
members = cfg.lan.interfaces;
|
||||
};
|
||||
|
||||
services.wan = svc.pppoe.build {
|
||||
inherit (cfg.wan) interface;
|
||||
ppp-options = [
|
||||
"debug" "+ipv6" "noauth"
|
||||
"name" cfg.wan.username
|
||||
"password" cfg.wan.password
|
||||
];
|
||||
};
|
||||
|
||||
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 {
|
||||
ruleset = cfg.firewall.rules;
|
||||
});
|
||||
|
||||
|
||||
services.resolvconf = oneshot rec {
|
||||
dependencies = [ config.services.wan ];
|
||||
name = "resolvconf";
|
||||
up = ''
|
||||
. ${serviceFns}
|
||||
( 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# services.dns =
|
||||
# let interface = services.int;
|
||||
# in svc.dnsmasq.build {
|
||||
# resolvconf = services.resolvconf;
|
||||
# inherit interface;
|
||||
# ranges = [
|
||||
# "${secrets.lan.prefix}.10,${secrets.lan.prefix}.240"
|
||||
# # 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"
|
||||
# ];
|
||||
|
||||
# # You can add static addresses for the DHCP server here. I'm
|
||||
# # not putting my actual MAC addresses in a public git repo ...
|
||||
# hosts = { } // lib.optionalAttrs (builtins.pathExists ./static-leases.nix) (import ./static-leases.nix);
|
||||
# upstreams = [ "/${secrets.domainName}/" ];
|
||||
# domain = secrets.domainName;
|
||||
# };
|
||||
|
||||
# services.wan = svc.pppoe.build {
|
||||
# interface = config.hardware.networkInterfaces.wan;
|
||||
# ppp-options = [
|
||||
# "debug" "+ipv6" "noauth"
|
||||
# "name" secrets.l2tp.name
|
||||
# "password" secrets.l2tp.password
|
||||
# ];
|
||||
# };
|
||||
|
||||
# services.resolvconf = oneshot rec {
|
||||
# dependencies = [ services.wan ];
|
||||
# name = "resolvconf";
|
||||
# up = ''
|
||||
# . ${serviceFns}
|
||||
# ( in_outputs ${name}
|
||||
# echo "nameserver $(output ${services.wan} ns1)" > resolv.conf
|
||||
# echo "nameserver $(output ${services.wan} ns2)" >> resolv.conf
|
||||
# chmod 0444 resolv.conf
|
||||
# )
|
||||
# '';
|
||||
# };
|
||||
|
||||
# filesystem =
|
||||
# let inherit (pkgs.pseudofile) dir symlink;
|
||||
# in dir {
|
||||
# etc = dir {
|
||||
# "resolv.conf" = symlink "${services.resolvconf}/.outputs/resolv.conf";
|
||||
# };
|
||||
# };
|
||||
|
||||
# services.defaultroute4 = svc.network.route.build {
|
||||
# via = "$(output ${services.wan} address)";
|
||||
# target = "default";
|
||||
|
@ -135,24 +194,6 @@ in {
|
|||
# in lib.recursiveUpdate defaults secrets.firewallRules;
|
||||
# };
|
||||
|
||||
# services.packet_forwarding = svc.network.forward.build { };
|
||||
|
||||
# services.dhcp6c =
|
||||
# let client = svc.dhcp6c.client.build {
|
||||
# interface = services.wan;
|
||||
# };
|
||||
# in bundle {
|
||||
# name = "dhcp6c";
|
||||
# contents = [
|
||||
# (svc.dhcp6c.prefix.build {
|
||||
# inherit client;
|
||||
# interface = services.int;
|
||||
# })
|
||||
# (svc.dhcp6c.address.build {
|
||||
# inherit client;
|
||||
# interface = services.wan;
|
||||
# })
|
||||
# ];
|
||||
# };
|
||||
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ in {
|
|||
../network
|
||||
../hostapd
|
||||
../bridge
|
||||
../ssh
|
||||
{ config.services = hostaps; }
|
||||
];
|
||||
|
||||
|
@ -54,7 +53,6 @@ in {
|
|||
};
|
||||
};
|
||||
config = {
|
||||
services.sshd = svc.ssh.build {};
|
||||
|
||||
services.int = svc.bridge.primary.build {
|
||||
ifname = "int";
|
||||
|
|
Loading…
Reference in New Issue