Compare commits
No commits in common. "648ea5613bf45424762d9f847e4ff1319f256a4e" and "73e5916cc58f505aaa06fe5231f1823f34d793a2" have entirely different histories.
648ea5613b
...
73e5916cc5
28
README.md
28
README.md
@ -13,29 +13,10 @@ of "limen", or "of the threshold". Your router stands at the threshold
|
|||||||
of your (online) home and everything you send to/receive from the
|
of your (online) home and everything you send to/receive from the
|
||||||
outside word goes across it.
|
outside word goes across it.
|
||||||
|
|
||||||
|
## What about NixWRT?
|
||||||
|
|
||||||
## Current status (does it work yet?)
|
This is an in-progress rewrite of NixWRT, incorporating Lessons
|
||||||
|
Learned.
|
||||||
Liminix is pre-1.0. We are still finding new and better ways to do things,
|
|
||||||
and there is no attempt to maintain backward compatibility with the old
|
|
||||||
ways. This will change when it settles down.
|
|
||||||
|
|
||||||
In general: development mostly happens on the `main` branch, which is
|
|
||||||
therefore not guaranteed to build or to work on every commit. For the
|
|
||||||
latest functioning version, see [the CI system](https://build.liminix.org/jobset/liminix/build) and pick a
|
|
||||||
revision with all jobs green.
|
|
||||||
|
|
||||||
In particular, as of July 2023, a significant re-arrangement of
|
|
||||||
modules and services is ongoing:
|
|
||||||
|
|
||||||
* if you are using out-of-tree configurations created before commit
|
|
||||||
2e50368, especially if they reference things under pkgs.liminix,
|
|
||||||
they will need updating. Look at changes to examples/rotuer.nix
|
|
||||||
for guidance
|
|
||||||
|
|
||||||
* the same is intermittently true for examples/{extensino,arhcive}.nix
|
|
||||||
where I've updated rotuer and not updated them to match.
|
|
||||||
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
@ -44,9 +25,6 @@ by running
|
|||||||
|
|
||||||
nix-shell -p sphinx --run "make -C doc html"
|
nix-shell -p sphinx --run "make -C doc html"
|
||||||
|
|
||||||
Rendered documentation corresponding to the latest commit on `main`
|
|
||||||
is published to [https://www.liminix.org/doc/](https://www.liminix.org/doc/)
|
|
||||||
|
|
||||||
|
|
||||||
## Extremely online
|
## Extremely online
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ let
|
|||||||
secrets = import ./rotuer-secrets.nix;
|
secrets = import ./rotuer-secrets.nix;
|
||||||
inherit (pkgs.liminix.networking)
|
inherit (pkgs.liminix.networking)
|
||||||
address
|
address
|
||||||
|
hostapd
|
||||||
interface
|
interface
|
||||||
route;
|
route;
|
||||||
inherit (pkgs.liminix.services) oneshot longrun bundle target;
|
inherit (pkgs.liminix.services) oneshot longrun bundle target;
|
||||||
@ -34,19 +35,43 @@ in rec {
|
|||||||
../modules/standard.nix
|
../modules/standard.nix
|
||||||
../modules/ppp
|
../modules/ppp
|
||||||
../modules/dnsmasq
|
../modules/dnsmasq
|
||||||
../modules/firewall
|
|
||||||
../modules/hostapd
|
|
||||||
];
|
];
|
||||||
rootfsType = "jffs2";
|
rootfsType = "jffs2";
|
||||||
hostname = "rotuer";
|
hostname = "rotuer";
|
||||||
kernel = {
|
kernel = {
|
||||||
config = {
|
config = {
|
||||||
BRIDGE = "y";
|
BRIDGE = "y";
|
||||||
|
|
||||||
|
NETFILTER_XT_MATCH_CONNTRACK = "y";
|
||||||
|
|
||||||
|
IP6_NF_IPTABLES= "y"; # do we still need these
|
||||||
|
IP_NF_IPTABLES= "y"; # if using nftables directly
|
||||||
|
|
||||||
|
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";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.hostap = config.system.service.hostapd {
|
services.hostap = hostapd (config.hardware.networkInterfaces.wlan_24) {
|
||||||
interface = config.hardware.networkInterfaces.wlan_24;
|
|
||||||
params = {
|
params = {
|
||||||
ssid = "liminix";
|
ssid = "liminix";
|
||||||
country_code = "GB";
|
country_code = "GB";
|
||||||
@ -63,8 +88,7 @@ in rec {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.hostap5 = config.system.service.hostapd {
|
services.hostap5 = hostapd (config.hardware.networkInterfaces.wlan_5) {
|
||||||
interface = config.hardware.networkInterfaces.wlan_5;
|
|
||||||
params = rec {
|
params = rec {
|
||||||
ssid = "liminix_5";
|
ssid = "liminix_5";
|
||||||
country_code = "GB";
|
country_code = "GB";
|
||||||
@ -196,9 +220,35 @@ in rec {
|
|||||||
dependencies = [ services.wan ];
|
dependencies = [ services.wan ];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.firewall = config.system.service.firewall {
|
services.firewall =
|
||||||
ruleset = import ./rotuer-firewall.nix;
|
let
|
||||||
};
|
script= pkgs.firewallgen "firewall.nft" (import ./rotuer-firewall.nix);
|
||||||
|
kmodules = pkgs.kernel-modules.override {
|
||||||
|
kernelSrc = config.system.outputs.kernel.src;
|
||||||
|
modulesupport = config.system.outputs.kernel.modulesupport;
|
||||||
|
kconfig = {
|
||||||
|
NFT_FIB_IPV4 = "m";
|
||||||
|
NFT_FIB_IPV6 = "m";
|
||||||
|
NF_TABLES = "m";
|
||||||
|
NF_CT_PROTO_DCCP = "y";
|
||||||
|
NF_CT_PROTO_SCTP = "y";
|
||||||
|
NF_CT_PROTO_UDPLITE = "y";
|
||||||
|
# NF_CONNTRACK_FTP = "m";
|
||||||
|
NFT_CT = "m";
|
||||||
|
};
|
||||||
|
targets = [
|
||||||
|
"nft_fib_ipv4"
|
||||||
|
"nft_fib_ipv6"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in oneshot {
|
||||||
|
name = "firewall";
|
||||||
|
up = ''
|
||||||
|
sh ${kmodules}/load.sh
|
||||||
|
${script};
|
||||||
|
'';
|
||||||
|
down = "${pkgs.nftables}/bin/nft flush ruleset";
|
||||||
|
};
|
||||||
|
|
||||||
services.packet_forwarding =
|
services.packet_forwarding =
|
||||||
let
|
let
|
||||||
|
@ -26,11 +26,6 @@ in {
|
|||||||
};
|
};
|
||||||
kernel = {
|
kernel = {
|
||||||
src = mkOption { type = types.package; } ;
|
src = mkOption { type = types.package; } ;
|
||||||
modular = mkOption {
|
|
||||||
type = types.boolean;
|
|
||||||
default = true;
|
|
||||||
description = "support loadable kernel modules";
|
|
||||||
};
|
|
||||||
extraPatchPhase = mkOption {
|
extraPatchPhase = mkOption {
|
||||||
default = "true";
|
default = "true";
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
@ -72,15 +67,14 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
kernel = rec {
|
kernel = rec {
|
||||||
modular = true; # disabling this is not yet supported
|
|
||||||
config = {
|
config = {
|
||||||
IKCONFIG = "y";
|
IKCONFIG = "y";
|
||||||
IKCONFIG_PROC = "y";
|
IKCONFIG_PROC = "y";
|
||||||
PROC_FS = "y";
|
PROC_FS = "y";
|
||||||
|
|
||||||
KEXEC = "y";
|
KEXEC = "y";
|
||||||
MODULES = if modular then "y" else "n";
|
MODULES = "y";
|
||||||
MODULE_SIG = if modular then "y" else "n";
|
MODULE_SIG = "y";
|
||||||
DEBUG_FS = "y";
|
DEBUG_FS = "y";
|
||||||
|
|
||||||
MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE = "y";
|
MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE = "y";
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
{ lib, pkgs, config, ...}:
|
|
||||||
let
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
inherit (pkgs.liminix.services) oneshot;
|
|
||||||
|
|
||||||
kconf = isModule :
|
|
||||||
# setting isModule false is utterly untested and mostly
|
|
||||||
# unimplemented: I say this to preempt any "how on earth is this
|
|
||||||
# even supposed to work?" questions
|
|
||||||
let yes = if isModule then "m" else "y";
|
|
||||||
in {
|
|
||||||
NFT_FIB_IPV4 = yes;
|
|
||||||
NFT_FIB_IPV6 = yes;
|
|
||||||
NF_TABLES = yes;
|
|
||||||
NF_CT_PROTO_DCCP = "y";
|
|
||||||
NF_CT_PROTO_SCTP = "y";
|
|
||||||
NF_CT_PROTO_UDPLITE = "y";
|
|
||||||
# NF_CONNTRACK_FTP = yes;
|
|
||||||
NFT_CT = yes;
|
|
||||||
};
|
|
||||||
kmodules = pkgs.kernel-modules.override {
|
|
||||||
kernelSrc = config.system.outputs.kernel.src;
|
|
||||||
modulesupport = config.system.outputs.kernel.modulesupport;
|
|
||||||
targets = [
|
|
||||||
"nft_fib_ipv4"
|
|
||||||
"nft_fib_ipv6"
|
|
||||||
];
|
|
||||||
kconfig = kconf true;
|
|
||||||
};
|
|
||||||
loadModules = oneshot {
|
|
||||||
name = "firewall-modules";
|
|
||||||
up = "sh ${kmodules}/load.sh";
|
|
||||||
down = "sh ${kmodules}/unload.sh";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
system.service.firewall = mkOption {
|
|
||||||
type = types.anything; # types.functionTo pkgs.liminix.lib.types.service;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config = {
|
|
||||||
system.service.firewall = params :
|
|
||||||
let svc = (pkgs.callPackage ./service.nix {}) params;
|
|
||||||
in svc // { dependencies = svc.dependencies ++ [loadModules]; };
|
|
||||||
|
|
||||||
# For historical reasons the kernel config is split between
|
|
||||||
# monolithic options and modules. TODO: go through this list
|
|
||||||
# and see what can be moved into the "kconf" definiton above
|
|
||||||
kernel.config = {
|
|
||||||
NETFILTER_XT_MATCH_CONNTRACK = "y";
|
|
||||||
|
|
||||||
IP6_NF_IPTABLES= "y";
|
|
||||||
IP_NF_IPTABLES= "y";
|
|
||||||
|
|
||||||
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";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
liminix
|
|
||||||
, lib
|
|
||||||
, firewallgen
|
|
||||||
, nftables
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (liminix.services) oneshot;
|
|
||||||
inherit (liminix.lib) typeChecked;
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
t = {
|
|
||||||
ruleset = mkOption {
|
|
||||||
type = types.anything; # we could usefully define this more tightly
|
|
||||||
description = "firewall ruleset";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
params:
|
|
||||||
let
|
|
||||||
inherit (typeChecked "firewall" t params) ruleset;
|
|
||||||
script = firewallgen "firewall.nft" ruleset;
|
|
||||||
in oneshot {
|
|
||||||
name = "firewall";
|
|
||||||
up = script;
|
|
||||||
down = "${nftables}/bin/nft flush ruleset";
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
{ lib, pkgs, config, ...}:
|
|
||||||
let
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
system.service.hostapd = mkOption {
|
|
||||||
type = types.functionTo types.package;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config = {
|
|
||||||
system.service.hostapd = pkgs.callPackage ./service.nix {};
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,34 +1,23 @@
|
|||||||
|
# This is not a friendly interface to configuring a wireless AP: it
|
||||||
|
# just passes everything straight through to the hostapd config. When
|
||||||
|
# we've worked out what the sensible options are to expose, we'll add
|
||||||
|
# them as top-level attributes and rename params to extraParams
|
||||||
|
|
||||||
{
|
{
|
||||||
liminix
|
liminix
|
||||||
, hostapd
|
, hostapd
|
||||||
, writeText
|
|
||||||
, lib
|
, lib
|
||||||
|
, writeText
|
||||||
|
}:
|
||||||
|
interface:
|
||||||
|
{
|
||||||
|
params ? {}
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (liminix.services) longrun;
|
inherit (liminix.services) longrun;
|
||||||
inherit (lib) concatStringsSep mapAttrsToList;
|
inherit (lib) concatStringsSep mapAttrsToList;
|
||||||
inherit (liminix.lib) typeChecked;
|
inherit (builtins) toString;
|
||||||
inherit (lib) mkOption types;
|
|
||||||
|
|
||||||
# This is not a friendly interface to configuring a wireless AP: it
|
|
||||||
# just passes everything straight through to the hostapd config.
|
|
||||||
# When we've worked out what the sensible options are to expose,
|
|
||||||
# we'll add them as top-level attributes and rename params to
|
|
||||||
# extraParams
|
|
||||||
|
|
||||||
t = {
|
|
||||||
interface = mkOption {
|
|
||||||
type = liminix.lib.types.service;
|
|
||||||
};
|
|
||||||
params = mkOption {
|
|
||||||
type = types.attrs;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
args:
|
|
||||||
let
|
|
||||||
inherit (typeChecked "hostapd" t args)
|
|
||||||
interface params;
|
|
||||||
name = "${interface.device}.hostapd";
|
name = "${interface.device}.hostapd";
|
||||||
defaults = {
|
defaults = {
|
||||||
driver = "nl80211";
|
driver = "nl80211";
|
Loading…
Reference in New Issue
Block a user