Compare commits
5 Commits
2a29a00dfe
...
dc4b7ebffd
Author | SHA1 | Date | |
---|---|---|---|
dc4b7ebffd | |||
bd8d00fe13 | |||
b81604870b | |||
3ea40f95dc | |||
2942c465b9 |
25
THOUGHTS.txt
25
THOUGHTS.txt
@ -2015,3 +2015,28 @@ everyone can use it.
|
|||||||
|
|
||||||
- also the type_service type defn exists only locally in modules.nix,
|
- also the type_service type defn exists only locally in modules.nix,
|
||||||
and we would like to refer to it elsewhere
|
and we would like to refer to it elsewhere
|
||||||
|
|
||||||
|
Thu Aug 10 21:46:36 BST 2023
|
||||||
|
|
||||||
|
to finish service/modules milestone
|
||||||
|
|
||||||
|
[done] there are some modules not using serviceDefn
|
||||||
|
- modules included by standard.nix should have all their options
|
||||||
|
grouped together in docs
|
||||||
|
how can we determine which they are? or maybe "modules that
|
||||||
|
don't contain services" is an acceptable criterion
|
||||||
|
maybe this is not actually an issue, if the modules are
|
||||||
|
reasonably coherent. It looks odd now because base.nix is a mess
|
||||||
|
- print the module pathname so people know what to import
|
||||||
|
- docs don't print the examples
|
||||||
|
- and seem to be getting the default wrong too
|
||||||
|
- decide what we deem to be "internal" (if anything)
|
||||||
|
is `filesystem` internal, for example? or `busybox`? they're
|
||||||
|
both mostly _used_ internally but may still be valuable to expose
|
||||||
|
- maybe document outputs separately or not at all?
|
||||||
|
- bridge to be one service instead of two?
|
||||||
|
[done] get rid of services/
|
||||||
|
- anything else in rotuer.nix that we should servicify
|
||||||
|
- services for liminix.networking
|
||||||
|
- a nice way to specify service dependencies
|
||||||
|
- do another video
|
||||||
|
5
ci.nix
5
ci.nix
@ -34,12 +34,13 @@ let
|
|||||||
];
|
];
|
||||||
src = ./doc;
|
src = ./doc;
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
cat ${(import ./doc/extract-options.nix).doc} | fennel --correlate parse-options.fnl > modules.rst
|
cat ${(import ./doc/extract-options.nix).doc} > options.json
|
||||||
|
cat options.json | fennel --correlate parse-options.fnl > modules.rst
|
||||||
make html
|
make html
|
||||||
'';
|
'';
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir -p $out/nix-support $out/share/doc/
|
mkdir -p $out/nix-support $out/share/doc/
|
||||||
# (cd _build && tar cf $out/share/doc/liminix_manual.tar html)
|
cp modules.rst options.json $out
|
||||||
cp -a _build/html $out/share/doc/liminix
|
cp -a _build/html $out/share/doc/liminix
|
||||||
echo "file source-dist \"$out/share/doc/liminix\"" \
|
echo "file source-dist \"$out/share/doc/liminix\"" \
|
||||||
> $out/nix-support/hydra-build-products
|
> $out/nix-support/hydra-build-products
|
||||||
|
@ -20,38 +20,44 @@
|
|||||||
(.. lines (string.gsub l "^## *" "") "\n"))))))
|
(.. lines (string.gsub l "^## *" "") "\n"))))))
|
||||||
|
|
||||||
(fn strip-newlines [text]
|
(fn strip-newlines [text]
|
||||||
(and text
|
(-> text
|
||||||
(-> text
|
(string.gsub "\n([^\n])" " %1")
|
||||||
(string.gsub "\n([^\n])" " %1")
|
(string.gsub "\n\n+" "\n")))
|
||||||
(string.gsub "\n\n+" "\n"))))
|
|
||||||
|
|
||||||
(fn indent [n text]
|
(fn indent [n text]
|
||||||
(let [margin (string.rep " " n)]
|
(let [margin (string.rep " " n)]
|
||||||
(.. margin (string.gsub text "\n +" (.. "\n" margin )))))
|
(.. margin (string.gsub (or text "") "\n +" (.. "\n" margin )))))
|
||||||
|
|
||||||
|
(fn indent-literal [n text]
|
||||||
|
(let [margin (string.rep " " n)]
|
||||||
|
(.. margin (string.gsub (or text "") "\n" (.. "\n" margin )))))
|
||||||
|
|
||||||
(fn extract-text [description]
|
(fn extract-text [description]
|
||||||
(and description
|
(match description
|
||||||
; (do (print (view description)) true)
|
{ :_type "literalExpression" : text } text
|
||||||
(-> (match description
|
(where s (= (type s) "string")) description
|
||||||
{ :type "literalExpression" : text } text
|
_ nil))
|
||||||
{} nil
|
|
||||||
nil nil
|
|
||||||
t description)
|
|
||||||
strip-newlines)))
|
|
||||||
|
|
||||||
(fn print-option [o offset]
|
(fn print-option [o offset]
|
||||||
(let [i (or offset 0)]
|
(let [i (or offset 0)]
|
||||||
(print (indent i (.. " * option ``" o.name "``")))
|
(print (indent i (.. " * option ``" o.name "``")))
|
||||||
(print (indent (+ 4 i)
|
(case (-?> o.description extract-text strip-newlines)
|
||||||
(or (extract-text o.description) "(no description)")))
|
descr (print (indent (+ 4 i) descr)))
|
||||||
(print)
|
(print)
|
||||||
(print (indent (+ 4 i) (.. "**type** " o.type "\n")))
|
(print (indent (+ 4 i) (.. "**type** " o.type "\n")))
|
||||||
(print (indent (+ 4 i)
|
(when o.example
|
||||||
(.. "**default** "
|
(print (indent (+ 4 i) "**example**")) (print)
|
||||||
(or (extract-text (?. o :default)) "(none)")
|
(print (indent (+ 4 i) ".. code-block:: nix"))
|
||||||
"\n"
|
(print)
|
||||||
)))
|
(print (indent-literal (+ 8 i) (extract-text o.example)) "\n")
|
||||||
(print )))
|
(print))
|
||||||
|
|
||||||
|
(when (extract-text o.default)
|
||||||
|
(print (indent (+ 4 i) "**default**")) (print)
|
||||||
|
(print (indent (+ 4 i) ".. code-block:: nix"))
|
||||||
|
(print)
|
||||||
|
(print (indent-literal (+ 8 i) (extract-text o.default)) "\n")
|
||||||
|
(print))))
|
||||||
|
|
||||||
(fn print-service [o]
|
(fn print-service [o]
|
||||||
(print (.. " * service ``" o.name "``"))
|
(print (.. " * service ``" o.name "``"))
|
||||||
@ -83,13 +89,3 @@
|
|||||||
(if (= o.type "parametrisable s6-rc service definition")
|
(if (= o.type "parametrisable s6-rc service definition")
|
||||||
(print-service o)
|
(print-service o)
|
||||||
(print-option o)))))))
|
(print-option o)))))))
|
||||||
|
|
||||||
;; for each element el, add to table modules keyed on
|
|
||||||
;; el.declarations
|
|
||||||
|
|
||||||
;; for each value in modules
|
|
||||||
;; print title
|
|
||||||
;; elements = (sort elements on el.name)
|
|
||||||
;; for each el in elements
|
|
||||||
;; is option or service? print whichever
|
|
||||||
;;
|
|
||||||
|
@ -50,6 +50,7 @@ in rec {
|
|||||||
../modules/hostapd
|
../modules/hostapd
|
||||||
../modules/bridge
|
../modules/bridge
|
||||||
../modules/ntp
|
../modules/ntp
|
||||||
|
../modules/ssh
|
||||||
];
|
];
|
||||||
rootfsType = "jffs2";
|
rootfsType = "jffs2";
|
||||||
hostname = "rotuer";
|
hostname = "rotuer";
|
||||||
@ -95,25 +96,7 @@ in rec {
|
|||||||
makestep = { threshold = 1.0; limit = 3; };
|
makestep = { threshold = 1.0; limit = 3; };
|
||||||
};
|
};
|
||||||
|
|
||||||
services.sshd = longrun {
|
services.sshd = svc.ssh.build { };
|
||||||
name = "sshd";
|
|
||||||
# env -i clears the environment so we don't pass anything weird to
|
|
||||||
# ssh sessions. Dropbear params are
|
|
||||||
# -e pass environment to child
|
|
||||||
# -E log to stderr
|
|
||||||
# -R create hostkeys if needed
|
|
||||||
# -P pid-file
|
|
||||||
# -F don't fork into background
|
|
||||||
|
|
||||||
run = ''
|
|
||||||
if test -d /persist; then
|
|
||||||
mkdir -p /persist/secrets/dropbear
|
|
||||||
ln -s /persist/secrets/dropbear /run
|
|
||||||
fi
|
|
||||||
PATH=${lib.makeBinPath config.defaultProfile.packages}:/bin
|
|
||||||
exec env -i ENV=/etc/ashrc PATH=$PATH ${dropbear}/bin/dropbear -e -E -R -P /run/dropbear.pid -F
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
users.root = secrets.root;
|
users.root = secrets.root;
|
||||||
|
|
||||||
@ -129,7 +112,7 @@ in rec {
|
|||||||
domain = "fake.liminix.org";
|
domain = "fake.liminix.org";
|
||||||
};
|
};
|
||||||
|
|
||||||
services.wan = svc.pppoe {
|
services.wan = svc.pppoe.build {
|
||||||
interface = config.hardware.networkInterfaces.wan;
|
interface = config.hardware.networkInterfaces.wan;
|
||||||
ppp-options = [
|
ppp-options = [
|
||||||
"debug" "+ipv6" "noauth"
|
"debug" "+ipv6" "noauth"
|
||||||
|
@ -12,6 +12,9 @@ let
|
|||||||
type_service = pkgs.liminix.lib.types.service;
|
type_service = pkgs.liminix.lib.types.service;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
imports = [
|
||||||
|
./kernel.nix # this is a separate module for doc purposes
|
||||||
|
];
|
||||||
options = {
|
options = {
|
||||||
# analogous to nixos systemPackages, but we don't symlink into
|
# analogous to nixos systemPackages, but we don't symlink into
|
||||||
# /run/current-system, we just add the paths in /etc/profile
|
# /run/current-system, we just add the paths in /etc/profile
|
||||||
@ -28,23 +31,6 @@ in {
|
|||||||
default = "squashfs";
|
default = "squashfs";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
kernel = {
|
|
||||||
src = mkOption { type = types.package; } ;
|
|
||||||
modular = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "support loadable kernel modules";
|
|
||||||
};
|
|
||||||
extraPatchPhase = mkOption {
|
|
||||||
default = "true";
|
|
||||||
type = types.lines;
|
|
||||||
} ;
|
|
||||||
config = mkOption {
|
|
||||||
# mostly the values are y n or m, but sometimes
|
|
||||||
# other strings are also used
|
|
||||||
type = types.attrsOf types.nonEmptyStr;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
boot = {
|
boot = {
|
||||||
commandLine = mkOption {
|
commandLine = mkOption {
|
||||||
type = types.listOf types.nonEmptyStr;
|
type = types.listOf types.nonEmptyStr;
|
||||||
@ -75,52 +61,6 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
kernel = rec {
|
|
||||||
modular = true; # disabling this is not yet supported
|
|
||||||
config = {
|
|
||||||
IKCONFIG = "y";
|
|
||||||
IKCONFIG_PROC = "y";
|
|
||||||
PROC_FS = "y";
|
|
||||||
|
|
||||||
KEXEC = "y";
|
|
||||||
MODULES = if modular then "y" else "n";
|
|
||||||
MODULE_SIG = if modular then "y" else "n";
|
|
||||||
DEBUG_FS = "y";
|
|
||||||
|
|
||||||
MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE = "y";
|
|
||||||
MIPS_BOOTLOADER_CMDLINE_COOKIE = "\"liminix\"";
|
|
||||||
MIPS_CMDLINE_DTB_EXTEND = "y";
|
|
||||||
|
|
||||||
# basic networking protocols
|
|
||||||
NET = "y";
|
|
||||||
UNIX = "y";
|
|
||||||
INET = "y";
|
|
||||||
IPV6 = "y";
|
|
||||||
PACKET = "y"; # for ppp, tcpdump ...
|
|
||||||
SYSVIPC= "y";
|
|
||||||
|
|
||||||
# disabling this option causes the kernel to use an "empty"
|
|
||||||
# initramfs instead: it has a /dev/console node and not much
|
|
||||||
# else. Note that pid 1 is started *before* the root
|
|
||||||
# filesystem is mounted and it expects /dev/console to be
|
|
||||||
# present already
|
|
||||||
BLK_DEV_INITRD = lib.mkDefault "n"; # overriden by initramfs module
|
|
||||||
|
|
||||||
# s6-linux-init mounts this on /dev
|
|
||||||
DEVTMPFS = "y";
|
|
||||||
# some or all of these may be fix for "tmpfs: Unknown parameter 'mode'" error
|
|
||||||
TMPFS = "y";
|
|
||||||
TMPFS_POSIX_ACL = "y";
|
|
||||||
TMPFS_XATTR = "y";
|
|
||||||
|
|
||||||
FW_LOADER = "y";
|
|
||||||
FW_LOADER_COMPRESS = "y";
|
|
||||||
# We don't have a user helper, so we get multiple 60s pauses
|
|
||||||
# at boot time unless we disable trying to call it.
|
|
||||||
# https://lkml.org/lkml/2013/8/5/175
|
|
||||||
FW_LOADER_USER_HELPER = "n";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
boot.commandLine = [
|
boot.commandLine = [
|
||||||
"console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8"
|
"console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8"
|
||||||
"root=${config.hardware.rootDevice}"
|
"root=${config.hardware.rootDevice}"
|
||||||
|
94
modules/kernel.nix
Normal file
94
modules/kernel.nix
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
## Kernel-related options
|
||||||
|
## ======================
|
||||||
|
##
|
||||||
|
##
|
||||||
|
|
||||||
|
{ lib, pkgs, config, ...}:
|
||||||
|
let
|
||||||
|
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ;
|
||||||
|
inherit (pkgs.pseudofile) dir symlink;
|
||||||
|
inherit (pkgs.liminix.networking) address interface;
|
||||||
|
inherit (pkgs.liminix.services) bundle;
|
||||||
|
|
||||||
|
type_service = pkgs.liminix.lib.types.service;
|
||||||
|
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
kernel = {
|
||||||
|
src = mkOption { type = types.package; } ;
|
||||||
|
modular = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "support loadable kernel modules";
|
||||||
|
};
|
||||||
|
extraPatchPhase = mkOption {
|
||||||
|
default = "true";
|
||||||
|
type = types.lines;
|
||||||
|
} ;
|
||||||
|
config = mkOption {
|
||||||
|
description = ''
|
||||||
|
Kernel config options, as listed in Kconfig* files in the
|
||||||
|
kernel source tree. Do not include the leading "CONFIG_"
|
||||||
|
prefix when defining these. Most values are "y", "n" or "m",
|
||||||
|
but sometimes other strings are also used.
|
||||||
|
'';
|
||||||
|
type = types.attrsOf types.nonEmptyStr;
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
BRIDGE = "y";
|
||||||
|
TMPFS = "y";
|
||||||
|
FW_LOADER_USER_HELPER = "n";
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
kernel = rec {
|
||||||
|
modular = true; # disabling this is not yet supported
|
||||||
|
config = {
|
||||||
|
IKCONFIG = "y";
|
||||||
|
IKCONFIG_PROC = "y";
|
||||||
|
PROC_FS = "y";
|
||||||
|
|
||||||
|
KEXEC = "y";
|
||||||
|
MODULES = if modular then "y" else "n";
|
||||||
|
MODULE_SIG = if modular then "y" else "n";
|
||||||
|
DEBUG_FS = "y";
|
||||||
|
|
||||||
|
MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE = "y";
|
||||||
|
MIPS_BOOTLOADER_CMDLINE_COOKIE = "\"liminix\"";
|
||||||
|
MIPS_CMDLINE_DTB_EXTEND = "y";
|
||||||
|
|
||||||
|
# basic networking protocols
|
||||||
|
NET = "y";
|
||||||
|
UNIX = "y";
|
||||||
|
INET = "y";
|
||||||
|
IPV6 = "y";
|
||||||
|
PACKET = "y"; # for ppp, tcpdump ...
|
||||||
|
SYSVIPC= "y";
|
||||||
|
|
||||||
|
# disabling this option causes the kernel to use an "empty"
|
||||||
|
# initramfs instead: it has a /dev/console node and not much
|
||||||
|
# else. Note that pid 1 is started *before* the root
|
||||||
|
# filesystem is mounted and it expects /dev/console to be
|
||||||
|
# present already
|
||||||
|
BLK_DEV_INITRD = lib.mkDefault "n"; # overriden by initramfs module
|
||||||
|
|
||||||
|
# s6-linux-init mounts this on /dev
|
||||||
|
DEVTMPFS = "y";
|
||||||
|
# some or all of these may be fix for "tmpfs: Unknown parameter 'mode'" error
|
||||||
|
TMPFS = "y";
|
||||||
|
TMPFS_POSIX_ACL = "y";
|
||||||
|
TMPFS_XATTR = "y";
|
||||||
|
|
||||||
|
FW_LOADER = "y";
|
||||||
|
FW_LOADER_COMPRESS = "y";
|
||||||
|
# We don't have a user helper, so we get multiple 60s pauses
|
||||||
|
# at boot time unless we disable trying to call it.
|
||||||
|
# https://lkml.org/lkml/2013/8/5/175
|
||||||
|
FW_LOADER_USER_HELPER = "n";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -11,14 +11,24 @@
|
|||||||
{ lib, pkgs, config, ...}:
|
{ lib, pkgs, config, ...}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types;
|
inherit (lib) mkOption types;
|
||||||
|
inherit (pkgs) liminix;
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
system.service.pppoe = mkOption {
|
system.service.pppoe = mkOption {
|
||||||
type = types.functionTo types.package;
|
type = liminix.lib.types.serviceDefn;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
system.service.pppoe = pkgs.callPackage ./pppoe.nix {};
|
system.service.pppoe = pkgs.liminix.callService ./pppoe.nix {
|
||||||
|
interface = mkOption {
|
||||||
|
type = liminix.lib.types.service;
|
||||||
|
description = "ethernet interface to run PPPoE over";
|
||||||
|
};
|
||||||
|
ppp-options = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "options supplied on ppp command line";
|
||||||
|
};
|
||||||
|
};
|
||||||
kernel = {
|
kernel = {
|
||||||
config = {
|
config = {
|
||||||
PPP = "y";
|
PPP = "y";
|
||||||
|
@ -6,25 +6,9 @@
|
|||||||
, writeAshScript
|
, writeAshScript
|
||||||
, serviceFns
|
, serviceFns
|
||||||
} :
|
} :
|
||||||
|
{ interface, ppp-options }:
|
||||||
let
|
let
|
||||||
inherit (liminix.services) longrun;
|
inherit (liminix.services) longrun;
|
||||||
inherit (liminix.lib) typeChecked;
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
|
|
||||||
t = {
|
|
||||||
interface = mkOption {
|
|
||||||
type = liminix.lib.types.service;
|
|
||||||
description = "ethernet interface to run PPPoE over";
|
|
||||||
};
|
|
||||||
ppp-options = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
description = "options supplied on ppp command line";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
params:
|
|
||||||
let
|
|
||||||
inherit (typeChecked "pppoe.nix" t params) interface ppp-options;
|
|
||||||
name = "${interface.device}.pppoe";
|
name = "${interface.device}.pppoe";
|
||||||
ip-up = writeAshScript "ip-up" {} ''
|
ip-up = writeAshScript "ip-up" {} ''
|
||||||
. ${serviceFns}
|
. ${serviceFns}
|
||||||
@ -55,7 +39,6 @@ let
|
|||||||
"usepeerdns"
|
"usepeerdns"
|
||||||
"logfd" "2"
|
"logfd" "2"
|
||||||
];
|
];
|
||||||
|
|
||||||
in
|
in
|
||||||
longrun {
|
longrun {
|
||||||
inherit name;
|
inherit name;
|
||||||
|
50
modules/ssh/default.nix
Normal file
50
modules/ssh/default.nix
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
## Secure Shell
|
||||||
|
## ============
|
||||||
|
##
|
||||||
|
## Provide SSH service using Dropbear
|
||||||
|
|
||||||
|
{ lib, pkgs, config, ...}:
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
inherit (pkgs) liminix;
|
||||||
|
mkBoolOption = description : mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
inherit description;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
system.service.ssh = mkOption {
|
||||||
|
type = liminix.lib.types.serviceDefn;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config.system.service = {
|
||||||
|
ssh = liminix.callService ./ssh.nix {
|
||||||
|
address = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Listen on specified address";
|
||||||
|
example = "127.0.0.1";
|
||||||
|
};
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 22;
|
||||||
|
description = "Listen on specified TCP port";
|
||||||
|
};
|
||||||
|
allowRoot = mkBoolOption "Allow root to login";
|
||||||
|
allowPasswordLogin = mkBoolOption "Allow login using password (disable for public key auth only)";
|
||||||
|
allowPasswordLoginForRoot = mkBoolOption "Allow root to login using password (disable for public key auth only)";
|
||||||
|
allowLocalPortForward = mkBoolOption "Enable local port forwarding";
|
||||||
|
allowRemotePortForward = mkBoolOption "Enable remote port forwarding";
|
||||||
|
allowRemoteConnectionToForwardedPorts = mkOption {
|
||||||
|
type = types.bool; default = false;
|
||||||
|
description = "Allow remote hosts to connect to local forwarded ports (by default they are bound to loopback)";
|
||||||
|
};
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.separatedString " ";
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
42
modules/ssh/ssh.nix
Normal file
42
modules/ssh/ssh.nix
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
liminix
|
||||||
|
, dropbear
|
||||||
|
, serviceFns
|
||||||
|
, lib
|
||||||
|
}:
|
||||||
|
p :
|
||||||
|
let
|
||||||
|
inherit (liminix.services) longrun;
|
||||||
|
inherit (lib) concatStringsSep;
|
||||||
|
options =
|
||||||
|
[
|
||||||
|
"-e" # pass environment to child
|
||||||
|
"-E" # log to stderr
|
||||||
|
"-R" # create hostkeys if needed
|
||||||
|
"-P /run/dropbear.pid"
|
||||||
|
"-F" # don't fork into background
|
||||||
|
] ++
|
||||||
|
(lib.optional (! p.allowRoot) "-w") ++
|
||||||
|
(lib.optional (! p.allowPasswordLogin) "-s") ++
|
||||||
|
(lib.optional (! p.allowPasswordLoginForRoot) "-g") ++
|
||||||
|
(lib.optional (! p.allowLocalPortForward) "-j") ++
|
||||||
|
(lib.optional (! p.allowRemotePortForward) "-k") ++
|
||||||
|
(lib.optional (! p.allowRemoteConnectionToForwardedPorts) "-a") ++
|
||||||
|
[(if p.address != null
|
||||||
|
then "-p ${p.address}:${p.port}"
|
||||||
|
else "-p ${builtins.toString p.port}")] ++
|
||||||
|
[p.extraConfig];
|
||||||
|
in
|
||||||
|
longrun {
|
||||||
|
name = "sshd";
|
||||||
|
# env -i clears the environment so we don't pass anything weird to
|
||||||
|
# ssh sessions
|
||||||
|
run = ''
|
||||||
|
if test -d /persist; then
|
||||||
|
mkdir -p /persist/secrets/dropbear
|
||||||
|
ln -s /persist/secrets/dropbear /run
|
||||||
|
fi
|
||||||
|
. /etc/profile # sets PATH but do we need this? it's the same file as ashrc
|
||||||
|
exec env -i ENV=/etc/ashrc PATH=$PATH ${dropbear}/bin/dropbear ${concatStringsSep " " options}
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user