mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-14 06:00:33 +03:00
Merge remote-tracking branch 'upstream/staging-next' into down-integrate-staging
This commit is contained in:
commit
08b22e605b
377 changed files with 13801 additions and 5789 deletions
|
@ -17,6 +17,9 @@ let
|
|||
|
||||
firmware-pkg = pkgs.system76-firmware;
|
||||
firmwareConfig = mkIf cfg.firmware-daemon.enable {
|
||||
# Make system76-firmware-cli usable by root from the command line.
|
||||
environment.systemPackages = [ firmware-pkg ];
|
||||
|
||||
services.dbus.packages = [ firmware-pkg ];
|
||||
|
||||
systemd.services.system76-firmware-daemon = {
|
||||
|
|
|
@ -288,6 +288,7 @@
|
|||
./services/continuous-integration/hail.nix
|
||||
./services/continuous-integration/hercules-ci-agent/default.nix
|
||||
./services/continuous-integration/hydra/default.nix
|
||||
./services/continuous-integration/github-runner.nix
|
||||
./services/continuous-integration/gitlab-runner.nix
|
||||
./services/continuous-integration/gocd-agent/default.nix
|
||||
./services/continuous-integration/gocd-server/default.nix
|
||||
|
@ -680,6 +681,7 @@
|
|||
./services/networking/gnunet.nix
|
||||
./services/networking/go-neb.nix
|
||||
./services/networking/go-shadowsocks2.nix
|
||||
./services/networking/gobgpd.nix
|
||||
./services/networking/gogoclient.nix
|
||||
./services/networking/gvpe.nix
|
||||
./services/networking/hans.nix
|
||||
|
@ -864,6 +866,7 @@
|
|||
./services/security/shibboleth-sp.nix
|
||||
./services/security/sks.nix
|
||||
./services/security/sshguard.nix
|
||||
./services/security/step-ca.nix
|
||||
./services/security/tor.nix
|
||||
./services/security/torify.nix
|
||||
./services/security/torsocks.nix
|
||||
|
|
299
nixos/modules/services/continuous-integration/github-runner.nix
Normal file
299
nixos/modules/services/continuous-integration/github-runner.nix
Normal file
|
@ -0,0 +1,299 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.github-runner;
|
||||
svcName = "github-runner";
|
||||
systemdDir = "${svcName}/${cfg.name}";
|
||||
# %t: Runtime directory root (usually /run); see systemd.unit(5)
|
||||
runtimeDir = "%t/${systemdDir}";
|
||||
# %S: State directory root (usually /var/lib); see systemd.unit(5)
|
||||
stateDir = "%S/${systemdDir}";
|
||||
# %L: Log directory root (usually /var/log); see systemd.unit(5)
|
||||
logsDir = "%L/${systemdDir}";
|
||||
in
|
||||
{
|
||||
options.services.github-runner = {
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to enable GitHub Actions runner.
|
||||
|
||||
Note: GitHub recommends using self-hosted runners with private repositories only. Learn more here:
|
||||
<link xlink:href="https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners"
|
||||
>About self-hosted runners</link>.
|
||||
'';
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Repository to add the runner to.
|
||||
|
||||
Changing this option triggers a new runner registration.
|
||||
'';
|
||||
example = "https://github.com/nixos/nixpkgs";
|
||||
};
|
||||
|
||||
tokenFile = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
The full path to a file which contains the runner registration token.
|
||||
The file should contain exactly one line with the token without any newline.
|
||||
The token can be used to re-register a runner of the same name but is time-limited.
|
||||
|
||||
Changing this option or the file's content triggers a new runner registration.
|
||||
'';
|
||||
example = "/run/secrets/github-runner/nixos.token";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
# Same pattern as for `networking.hostName`
|
||||
type = types.strMatching "^$|^[[:alnum:]]([[:alnum:]_-]{0,61}[[:alnum:]])?$";
|
||||
description = ''
|
||||
Name of the runner to configure. Defaults to the hostname.
|
||||
|
||||
Changing this option triggers a new runner registration.
|
||||
'';
|
||||
example = "nixos";
|
||||
default = config.networking.hostName;
|
||||
};
|
||||
|
||||
runnerGroup = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
Name of the runner group to add this runner to (defaults to the default runner group).
|
||||
|
||||
Changing this option triggers a new runner registration.
|
||||
'';
|
||||
default = null;
|
||||
};
|
||||
|
||||
extraLabels = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = ''
|
||||
Extra labels in addition to the default (<literal>["self-hosted", "Linux", "X64"]</literal>).
|
||||
|
||||
Changing this option triggers a new runner registration.
|
||||
'';
|
||||
example = literalExample ''[ "nixos" ]'';
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
replace = mkOption {
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Replace any existing runner with the same name.
|
||||
|
||||
Without this flag, registering a new runner with the same name fails.
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
description = ''
|
||||
Extra packages to add to <literal>PATH</literal> of the service to make them available to workflows.
|
||||
'';
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
warnings = optionals (isStorePath cfg.tokenFile) [
|
||||
''
|
||||
`services.github-runner.tokenFile` points to the Nix store and, therefore, is world-readable.
|
||||
Consider using a path outside of the Nix store to keep the token private.
|
||||
''
|
||||
];
|
||||
|
||||
systemd.services.${svcName} = {
|
||||
description = "GitHub Actions runner";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network.target" "network-online.target" ];
|
||||
|
||||
environment = {
|
||||
HOME = runtimeDir;
|
||||
RUNNER_ROOT = runtimeDir;
|
||||
};
|
||||
|
||||
path = (with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
git
|
||||
gnutar
|
||||
gzip
|
||||
]) ++ [
|
||||
config.nix.package
|
||||
] ++ cfg.extraPackages;
|
||||
|
||||
serviceConfig = rec {
|
||||
ExecStart = "${pkgs.github-runner}/bin/runsvc.sh";
|
||||
|
||||
# Does the following, sequentially:
|
||||
# - Copy the current and the previous `tokenFile` to the $RUNTIME_DIRECTORY
|
||||
# and make it accessible to the service user to allow for a content
|
||||
# comparison.
|
||||
# - If the module configuration or the token has changed, clear the state directory.
|
||||
# - Configure the runner.
|
||||
# - Copy the configured `tokenFile` to the $STATE_DIRECTORY and make it
|
||||
# inaccessible to the service user.
|
||||
# - Set up the directory structure by creating the necessary symlinks.
|
||||
ExecStartPre =
|
||||
let
|
||||
# Wrapper script which expects the full path of the state, runtime and logs
|
||||
# directory as arguments. Overrides the respective systemd variables to provide
|
||||
# unambiguous directory names. This becomes relevant, for example, if the
|
||||
# caller overrides any of the StateDirectory=, RuntimeDirectory= or LogDirectory=
|
||||
# to contain more than one directory. This causes systemd to set the respective
|
||||
# environment variables with the path of all of the given directories, separated
|
||||
# by a colon.
|
||||
writeScript = name: lines: pkgs.writeShellScript "${svcName}-${name}.sh" ''
|
||||
set -euo pipefail
|
||||
|
||||
STATE_DIRECTORY="$1"
|
||||
RUNTIME_DIRECTORY="$2"
|
||||
LOGS_DIRECTORY="$3"
|
||||
|
||||
${lines}
|
||||
'';
|
||||
currentConfigPath = "$STATE_DIRECTORY/.nixos-current-config.json";
|
||||
runnerRegistrationConfig = getAttrs [ "name" "tokenFile" "url" "runnerGroup" "extraLabels" ] cfg;
|
||||
newConfigPath = builtins.toFile "${svcName}-config.json" (builtins.toJSON runnerRegistrationConfig);
|
||||
currentConfigTokenFilename = ".current-token";
|
||||
newConfigTokenFilename = ".new-token";
|
||||
runnerCredFiles = [
|
||||
".credentials"
|
||||
".credentials_rsaparams"
|
||||
".runner"
|
||||
];
|
||||
ownConfigTokens = writeScript "own-config-tokens" ''
|
||||
# Copy current and new token file to runtime dir and make it accessible to the service user
|
||||
cp ${escapeShellArg cfg.tokenFile} "$RUNTIME_DIRECTORY/${newConfigTokenFilename}"
|
||||
chmod 600 "$RUNTIME_DIRECTORY/${newConfigTokenFilename}"
|
||||
chown "$USER" "$RUNTIME_DIRECTORY/${newConfigTokenFilename}"
|
||||
|
||||
if [[ -e "$STATE_DIRECTORY/${currentConfigTokenFilename}" ]]; then
|
||||
cp "$STATE_DIRECTORY/${currentConfigTokenFilename}" "$RUNTIME_DIRECTORY/${currentConfigTokenFilename}"
|
||||
chmod 600 "$RUNTIME_DIRECTORY/${currentConfigTokenFilename}"
|
||||
chown "$USER" "$RUNTIME_DIRECTORY/${currentConfigTokenFilename}"
|
||||
fi
|
||||
'';
|
||||
disownConfigTokens = writeScript "disown-config-tokens" ''
|
||||
# Make the token inaccessible to the runner service user
|
||||
chmod 600 "$STATE_DIRECTORY/${currentConfigTokenFilename}"
|
||||
chown root:root "$STATE_DIRECTORY/${currentConfigTokenFilename}"
|
||||
'';
|
||||
unconfigureRunner = writeScript "unconfigure" ''
|
||||
differs=
|
||||
# Set `differs = 1` if current and new runner config differ or if `currentConfigPath` does not exist
|
||||
${pkgs.diffutils}/bin/diff -q '${newConfigPath}' "${currentConfigPath}" >/dev/null 2>&1 || differs=1
|
||||
# Also trigger a registration if the token content changed
|
||||
${pkgs.diffutils}/bin/diff -q \
|
||||
"$RUNTIME_DIRECTORY"/{${currentConfigTokenFilename},${newConfigTokenFilename}} \
|
||||
>/dev/null 2>&1 || differs=1
|
||||
|
||||
if [[ -n "$differs" ]]; then
|
||||
echo "Config has changed, removing old runner state."
|
||||
echo "The old runner will still appear in the GitHub Actions UI." \
|
||||
"You have to remove it manually."
|
||||
find "$STATE_DIRECTORY/" -mindepth 1 -delete
|
||||
fi
|
||||
'';
|
||||
configureRunner = writeScript "configure" ''
|
||||
empty=$(ls -A "$STATE_DIRECTORY")
|
||||
if [[ -z "$empty" ]]; then
|
||||
echo "Configuring GitHub Actions Runner"
|
||||
token=$(< "$RUNTIME_DIRECTORY"/${newConfigTokenFilename})
|
||||
RUNNER_ROOT="$STATE_DIRECTORY" ${pkgs.github-runner}/bin/config.sh \
|
||||
--unattended \
|
||||
--work "$RUNTIME_DIRECTORY" \
|
||||
--url ${escapeShellArg cfg.url} \
|
||||
--token "$token" \
|
||||
--labels ${escapeShellArg (concatStringsSep "," cfg.extraLabels)} \
|
||||
--name ${escapeShellArg cfg.name} \
|
||||
${optionalString cfg.replace "--replace"} \
|
||||
${optionalString (cfg.runnerGroup != null) "--runnergroup ${escapeShellArg cfg.runnerGroup}"}
|
||||
|
||||
# Move the automatically created _diag dir to the logs dir
|
||||
mkdir -p "$STATE_DIRECTORY/_diag"
|
||||
cp -r "$STATE_DIRECTORY/_diag/." "$LOGS_DIRECTORY/"
|
||||
rm -rf "$STATE_DIRECTORY/_diag/"
|
||||
|
||||
# Cleanup token from config
|
||||
rm -f "$RUNTIME_DIRECTORY"/${currentConfigTokenFilename}
|
||||
mv "$RUNTIME_DIRECTORY"/${newConfigTokenFilename} "$STATE_DIRECTORY/${currentConfigTokenFilename}"
|
||||
|
||||
# Symlink to new config
|
||||
ln -s '${newConfigPath}' "${currentConfigPath}"
|
||||
fi
|
||||
'';
|
||||
setupRuntimeDir = writeScript "setup-runtime-dirs" ''
|
||||
# Link _diag dir
|
||||
ln -s "$LOGS_DIRECTORY" "$RUNTIME_DIRECTORY/_diag"
|
||||
|
||||
# Link the runner credentials to the runtime dir
|
||||
ln -s "$STATE_DIRECTORY"/{${lib.concatStringsSep "," runnerCredFiles}} "$RUNTIME_DIRECTORY/"
|
||||
'';
|
||||
in
|
||||
map (x: "${x} ${escapeShellArgs [ stateDir runtimeDir logsDir ]}") [
|
||||
"+${ownConfigTokens}" # runs as root
|
||||
unconfigureRunner
|
||||
configureRunner
|
||||
"+${disownConfigTokens}" # runs as root
|
||||
setupRuntimeDir
|
||||
];
|
||||
|
||||
# Contains _diag
|
||||
LogsDirectory = [ systemdDir ];
|
||||
# Default RUNNER_ROOT which contains ephemeral Runner data
|
||||
RuntimeDirectory = [ systemdDir ];
|
||||
# Home of persistent runner data, e.g., credentials
|
||||
StateDirectory = [ systemdDir ];
|
||||
StateDirectoryMode = "0700";
|
||||
WorkingDirectory = runtimeDir;
|
||||
|
||||
# By default, use a dynamically allocated user
|
||||
DynamicUser = true;
|
||||
|
||||
KillMode = "process";
|
||||
KillSignal = "SIGTERM";
|
||||
|
||||
# Hardening (may overlap with DynamicUser=)
|
||||
# The following options are only for optimizing:
|
||||
# systemd-analyze security github-runner
|
||||
AmbientCapabilities = "";
|
||||
CapabilityBoundingSet = "";
|
||||
# ProtectClock= adds DeviceAllow=char-rtc r
|
||||
DeviceAllow = "";
|
||||
LockPersonality = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
UMask = "0066";
|
||||
|
||||
# Needs network access
|
||||
PrivateNetwork = false;
|
||||
# Cannot be true due to Node
|
||||
MemoryDenyWriteExecute = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -163,7 +163,7 @@ in
|
|||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
"DATABASE nextcloud" = "ALL PRIVILEGES";
|
||||
"DATABASE \"nextcloud\"" = "ALL PRIVILEGES";
|
||||
"ALL TABLES IN SCHEMA public" = "ALL PRIVILEGES";
|
||||
}
|
||||
'';
|
||||
|
|
|
@ -88,6 +88,13 @@ in
|
|||
example = "/run/redis/redis.sock";
|
||||
};
|
||||
|
||||
unixSocketPerm = mkOption {
|
||||
type = types.int;
|
||||
default = 750;
|
||||
description = "Change permissions for the socket";
|
||||
example = 700;
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.str;
|
||||
default = "notice"; # debug, verbose, notice, warning
|
||||
|
@ -204,7 +211,6 @@ in
|
|||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
unixsocketperm = "700";
|
||||
loadmodule = [ "/path/to/my_module.so" "/path/to/other_module.so" ];
|
||||
}
|
||||
'';
|
||||
|
@ -256,7 +262,7 @@ in
|
|||
slowlog-max-len = cfg.slowLogMaxLen;
|
||||
}
|
||||
(mkIf (cfg.bind != null) { bind = cfg.bind; })
|
||||
(mkIf (cfg.unixSocket != null) { unixsocket = cfg.unixSocket; })
|
||||
(mkIf (cfg.unixSocket != null) { unixsocket = cfg.unixSocket; unixsocketperm = "${toString cfg.unixSocketPerm}"; })
|
||||
(mkIf (cfg.slaveOf != null) { slaveof = "${cfg.slaveOf.ip} ${cfg.slaveOf.port}"; })
|
||||
(mkIf (cfg.masterAuth != null) { masterauth = cfg.masterAuth; })
|
||||
(mkIf (cfg.requirePass != null) { requirepass = cfg.requirePass; })
|
||||
|
@ -277,11 +283,18 @@ in
|
|||
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/redis-server /run/redis/redis.conf";
|
||||
RuntimeDirectory = "redis";
|
||||
StateDirectory = "redis";
|
||||
Type = "notify";
|
||||
# User and group
|
||||
User = "redis";
|
||||
Group = "redis";
|
||||
# Runtime directory and mode
|
||||
RuntimeDirectory = "redis";
|
||||
RuntimeDirectoryMode = "0750";
|
||||
# State directory and mode
|
||||
StateDirectory = "redis";
|
||||
StateDirectoryMode = "0700";
|
||||
# Access write directories
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ let
|
|||
|
||||
haveAliases = cfg.postmasterAlias != "" || cfg.rootAlias != ""
|
||||
|| cfg.extraAliases != "";
|
||||
haveCanonical = cfg.canonical != "";
|
||||
haveTransport = cfg.transport != "";
|
||||
haveVirtual = cfg.virtual != "";
|
||||
haveLocalRecipients = cfg.localRecipients != null;
|
||||
|
@ -244,6 +245,7 @@ let
|
|||
;
|
||||
|
||||
aliasesFile = pkgs.writeText "postfix-aliases" aliases;
|
||||
canonicalFile = pkgs.writeText "postfix-canonical" cfg.canonical;
|
||||
virtualFile = pkgs.writeText "postfix-virtual" cfg.virtual;
|
||||
localRecipientMapFile = pkgs.writeText "postfix-local-recipient-map" (concatMapStrings (x: x + " ACCEPT\n") cfg.localRecipients);
|
||||
checkClientAccessFile = pkgs.writeText "postfix-check-client-access" cfg.dnsBlacklistOverrides;
|
||||
|
@ -529,6 +531,15 @@ in
|
|||
";
|
||||
};
|
||||
|
||||
canonical = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Entries for the <citerefentry><refentrytitle>canonical</refentrytitle>
|
||||
<manvolnum>5</manvolnum></citerefentry> table.
|
||||
'';
|
||||
};
|
||||
|
||||
virtual = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
|
@ -941,6 +952,9 @@ in
|
|||
(mkIf haveAliases {
|
||||
services.postfix.aliasFiles.aliases = aliasesFile;
|
||||
})
|
||||
(mkIf haveCanonical {
|
||||
services.postfix.mapFiles.canonical = canonicalFile;
|
||||
})
|
||||
(mkIf haveTransport {
|
||||
services.postfix.mapFiles.transport = transportFile;
|
||||
})
|
||||
|
|
|
@ -29,6 +29,16 @@ in
|
|||
default = "jellyfin";
|
||||
description = "Group under which jellyfin runs.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open the default ports in the firewall for the media server. The
|
||||
HTTP/HTTPS ports can be changed in the Web UI, so this option should
|
||||
only be used if they are unchanged.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -104,6 +114,12 @@ in
|
|||
jellyfin = {};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
# from https://jellyfin.org/docs/general/networking/index.html
|
||||
allowedTCPPorts = [ 8096 8920 ];
|
||||
allowedUDPPorts = [ 1900 7359 ];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ minijackson ];
|
||||
|
|
64
nixos/modules/services/networking/gobgpd.nix
Normal file
64
nixos/modules/services/networking/gobgpd.nix
Normal file
|
@ -0,0 +1,64 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.gobgpd;
|
||||
format = pkgs.formats.toml { };
|
||||
confFile = format.generate "gobgpd.conf" cfg.settings;
|
||||
in {
|
||||
options.services.gobgpd = {
|
||||
enable = mkEnableOption "GoBGP Routing Daemon";
|
||||
|
||||
settings = mkOption {
|
||||
type = format.type;
|
||||
default = { };
|
||||
description = ''
|
||||
GoBGP configuration. Refer to
|
||||
<link xlink:href="https://github.com/osrg/gobgp#documentation"/>
|
||||
for details on supported values.
|
||||
'';
|
||||
example = literalExample ''
|
||||
{
|
||||
global = {
|
||||
config = {
|
||||
as = 64512;
|
||||
router-id = "192.168.255.1";
|
||||
};
|
||||
};
|
||||
neighbors = [
|
||||
{
|
||||
config = {
|
||||
neighbor-address = "10.0.255.1";
|
||||
peer-as = 65001;
|
||||
};
|
||||
}
|
||||
{
|
||||
config = {
|
||||
neighbor-address = "10.0.255.2";
|
||||
peer-as = 65002;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.gobgpd ];
|
||||
systemd.services.gobgpd = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
description = "GoBGP Routing Daemon";
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
ExecStartPre = "${pkgs.gobgpd}/bin/gobgpd -f ${confFile} -d";
|
||||
ExecStart = "${pkgs.gobgpd}/bin/gobgpd -f ${confFile} --sdnotify";
|
||||
ExecReload = "${pkgs.gobgpd}/bin/gobgpd -r";
|
||||
DynamicUser = true;
|
||||
AmbientCapabilities = "cap_net_bind_service";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -484,6 +484,8 @@ in {
|
|||
})
|
||||
];
|
||||
|
||||
boot.kernelModules = [ "ctr" ];
|
||||
|
||||
security.polkit.extraConfig = polkitConf;
|
||||
|
||||
services.dbus.packages = cfg.packages
|
||||
|
|
|
@ -242,7 +242,7 @@ in
|
|||
"default.action"
|
||||
] ++ optional cfg.inspectHttps (toString inspectAction);
|
||||
} // (optionalAttrs cfg.enableTor {
|
||||
forward-socks5 = "127.0.0.1:9063 .";
|
||||
forward-socks5 = "/ 127.0.0.1:9063 .";
|
||||
toggle = true;
|
||||
enable-remote-toggle = false;
|
||||
enable-edit-actions = false;
|
||||
|
|
|
@ -4,10 +4,22 @@ with lib;
|
|||
|
||||
let
|
||||
cfg = config.services.spacecookie;
|
||||
configFile = pkgs.writeText "spacecookie.json" (lib.generators.toJSON {} {
|
||||
inherit (cfg) hostname port root;
|
||||
});
|
||||
|
||||
spacecookieConfig = {
|
||||
listen = {
|
||||
inherit (cfg) port;
|
||||
};
|
||||
} // cfg.settings;
|
||||
|
||||
format = pkgs.formats.json {};
|
||||
|
||||
configFile = format.generate "spacecookie.json" spacecookieConfig;
|
||||
|
||||
in {
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "services" "spacecookie" "root" ] [ "services" "spacecookie" "settings" "root" ])
|
||||
(mkRenamedOptionModule [ "services" "spacecookie" "hostname" ] [ "services" "spacecookie" "settings" "hostname" ])
|
||||
];
|
||||
|
||||
options = {
|
||||
|
||||
|
@ -15,32 +27,149 @@ in {
|
|||
|
||||
enable = mkEnableOption "spacecookie";
|
||||
|
||||
hostname = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = "The hostname the service is reachable via. Clients will use this hostname for further requests after loading the initial gopher menu.";
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.spacecookie;
|
||||
defaultText = literalExample "pkgs.spacecookie";
|
||||
example = literalExample "pkgs.haskellPackages.spacecookie";
|
||||
description = ''
|
||||
The spacecookie derivation to use. This can be used to
|
||||
override the used package or to use another version.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to open the necessary port in the firewall for spacecookie.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 70;
|
||||
description = "Port the gopher service should be exposed on.";
|
||||
description = ''
|
||||
Port the gopher service should be exposed on.
|
||||
'';
|
||||
};
|
||||
|
||||
root = mkOption {
|
||||
type = types.path;
|
||||
default = "/srv/gopher";
|
||||
description = "The root directory spacecookie serves via gopher.";
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
default = "[::]";
|
||||
description = ''
|
||||
Address to listen on. Must be in the
|
||||
<literal>ListenStream=</literal> syntax of
|
||||
<link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.socket.html">systemd.socket(5)</link>.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = format.type;
|
||||
|
||||
options.hostname = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
The hostname the service is reachable via. Clients
|
||||
will use this hostname for further requests after
|
||||
loading the initial gopher menu.
|
||||
'';
|
||||
};
|
||||
|
||||
options.root = mkOption {
|
||||
type = types.path;
|
||||
default = "/srv/gopher";
|
||||
description = ''
|
||||
The directory spacecookie should serve via gopher.
|
||||
Files in there need to be world-readable since
|
||||
the spacecookie service file sets
|
||||
<literal>DynamicUser=true</literal>.
|
||||
'';
|
||||
};
|
||||
|
||||
options.log = {
|
||||
enable = mkEnableOption "logging for spacecookie"
|
||||
// { default = true; example = false; };
|
||||
|
||||
hide-ips = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
If enabled, spacecookie will hide personal
|
||||
information of users like IP addresses from
|
||||
log output.
|
||||
'';
|
||||
};
|
||||
|
||||
hide-time = mkOption {
|
||||
type = types.bool;
|
||||
# since we are starting with systemd anyways
|
||||
# we deviate from the default behavior here:
|
||||
# journald will add timestamps, so no need
|
||||
# to double up.
|
||||
default = true;
|
||||
description = ''
|
||||
If enabled, spacecookie will not print timestamps
|
||||
at the beginning of every log line.
|
||||
'';
|
||||
};
|
||||
|
||||
level = mkOption {
|
||||
type = types.enum [
|
||||
"info"
|
||||
"warn"
|
||||
"error"
|
||||
];
|
||||
default = "info";
|
||||
description = ''
|
||||
Log level for the spacecookie service.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
description = ''
|
||||
Settings for spacecookie. The settings set here are
|
||||
directly translated to the spacecookie JSON config
|
||||
file. See
|
||||
<link xlink:href="https://sternenseemann.github.io/spacecookie/spacecookie.json.5.html">spacecookie.json(5)</link>
|
||||
for explanations of all options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !(cfg.settings ? user);
|
||||
message = ''
|
||||
spacecookie is started as a normal user, so the setuid
|
||||
feature doesn't work. If you want to run spacecookie as
|
||||
a specific user, set:
|
||||
systemd.services.spacecookie.serviceConfig = {
|
||||
DynamicUser = false;
|
||||
User = "youruser";
|
||||
Group = "yourgroup";
|
||||
}
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = !(cfg.settings ? listen || cfg.settings ? port);
|
||||
message = ''
|
||||
The NixOS spacecookie module uses socket activation,
|
||||
so the listen options have no effect. Use the port
|
||||
and address options in services.spacecookie instead.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
systemd.sockets.spacecookie = {
|
||||
description = "Socket for the Spacecookie Gopher Server";
|
||||
wantedBy = [ "sockets.target" ];
|
||||
listenStreams = [ "[::]:${toString cfg.port}" ];
|
||||
listenStreams = [ "${cfg.address}:${toString cfg.port}" ];
|
||||
socketConfig = {
|
||||
BindIPv6Only = "both";
|
||||
};
|
||||
|
@ -53,7 +182,7 @@ in {
|
|||
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
ExecStart = "${pkgs.haskellPackages.spacecookie}/bin/spacecookie ${configFile}";
|
||||
ExecStart = "${lib.getBin cfg.package}/bin/spacecookie ${configFile}";
|
||||
FileDescriptorStoreMax = 1;
|
||||
|
||||
DynamicUser = true;
|
||||
|
@ -79,5 +208,9 @@ in {
|
|||
RestrictAddressFamilies = "AF_UNIX AF_INET6";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
134
nixos/modules/services/security/step-ca.nix
Normal file
134
nixos/modules/services/security/step-ca.nix
Normal file
|
@ -0,0 +1,134 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.step-ca;
|
||||
settingsFormat = (pkgs.formats.json { });
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ mohe2015 ];
|
||||
|
||||
options = {
|
||||
services.step-ca = {
|
||||
enable = lib.mkEnableOption "the smallstep certificate authority server";
|
||||
openFirewall = lib.mkEnableOption "opening the certificate authority server port";
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.step-ca;
|
||||
description = "Which step-ca package to use.";
|
||||
};
|
||||
address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "127.0.0.1";
|
||||
description = ''
|
||||
The address (without port) the certificate authority should listen at.
|
||||
This combined with <option>services.step-ca.port</option> overrides <option>services.step-ca.settings.address</option>.
|
||||
'';
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
example = 8443;
|
||||
description = ''
|
||||
The port the certificate authority should listen on.
|
||||
This combined with <option>services.step-ca.address</option> overrides <option>services.step-ca.settings.address</option>.
|
||||
'';
|
||||
};
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types; attrsOf anything;
|
||||
description = ''
|
||||
Settings that go into <filename>ca.json</filename>. See
|
||||
<link xlink:href="https://smallstep.com/docs/step-ca/configuration">
|
||||
the step-ca manual</link> for more information. The easiest way to
|
||||
configure this module would be to run <literal>step ca init</literal>
|
||||
to generate <filename>ca.json</filename> and then import it using
|
||||
<literal>builtins.fromJSON</literal>.
|
||||
<link xlink:href="https://smallstep.com/docs/step-cli/basic-crypto-operations#run-an-offline-x509-certificate-authority">This article</link>
|
||||
may also be useful if you want to customize certain aspects of
|
||||
certificate generation for your CA.
|
||||
You need to change the database storage path to <filename>/var/lib/step-ca/db</filename>.
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
The <option>services.step-ca.settings.address</option> option
|
||||
will be ignored and overwritten by
|
||||
<option>services.step-ca.address</option> and
|
||||
<option>services.step-ca.port</option>.
|
||||
</para>
|
||||
</warning>
|
||||
'';
|
||||
};
|
||||
intermediatePasswordFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
example = "/run/keys/smallstep-password";
|
||||
description = ''
|
||||
Path to the file containing the password for the intermediate
|
||||
certificate private key.
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
Make sure to use a quoted absolute path instead of a path literal
|
||||
to prevent it from being copied to the globally readable Nix
|
||||
store.
|
||||
</para>
|
||||
</warning>
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.step-ca.enable (
|
||||
let
|
||||
configFile = settingsFormat.generate "ca.json" (cfg.settings // {
|
||||
address = cfg.address + ":" + toString cfg.port;
|
||||
});
|
||||
in
|
||||
{
|
||||
assertions =
|
||||
[
|
||||
{
|
||||
assertion = !lib.isStorePath cfg.intermediatePasswordFile;
|
||||
message = ''
|
||||
<option>services.step-ca.intermediatePasswordFile</option> points to
|
||||
a file in the Nix store. You should use a quoted absolute path to
|
||||
prevent this.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
systemd.packages = [ cfg.package ];
|
||||
|
||||
# configuration file indirection is needed to support reloading
|
||||
environment.etc."smallstep/ca.json".source = configFile;
|
||||
|
||||
systemd.services."step-ca" = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ configFile ];
|
||||
unitConfig = {
|
||||
ConditionFileNotEmpty = ""; # override upstream
|
||||
};
|
||||
serviceConfig = {
|
||||
Environment = "HOME=%S/step-ca";
|
||||
WorkingDirectory = ""; # override upstream
|
||||
ReadWriteDirectories = ""; # override upstream
|
||||
|
||||
# LocalCredential handles file permission problems arising from the use of DynamicUser.
|
||||
LoadCredential = "intermediate_password:${cfg.intermediatePasswordFile}";
|
||||
|
||||
ExecStart = [
|
||||
"" # override upstream
|
||||
"${cfg.package}/bin/step-ca /etc/smallstep/ca.json --password-file \${CREDENTIALS_DIRECTORY}/intermediate_password"
|
||||
];
|
||||
|
||||
# ProtectProc = "invisible"; # not supported by upstream yet
|
||||
# ProcSubset = "pid"; # not supported by upstream upstream yet
|
||||
# PrivateUsers = true; # doesn't work with privileged ports therefore not supported by upstream
|
||||
|
||||
DynamicUser = true;
|
||||
StateDirectory = "step-ca";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
|
@ -157,7 +157,7 @@ let
|
|||
proxy_connect_timeout 60;
|
||||
proxy_send_timeout 60;
|
||||
proxy_read_timeout 60;
|
||||
proxy_http_version 1.0;
|
||||
proxy_http_version 1.1;
|
||||
include ${recommendedProxyConfig};
|
||||
''}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ in
|
|||
./tinywm.nix
|
||||
./twm.nix
|
||||
./windowmaker.nix
|
||||
./wmderland.nix
|
||||
./wmii.nix
|
||||
./xmonad.nix
|
||||
./yeahwm.nix
|
||||
|
|
61
nixos/modules/services/x11/window-managers/wmderland.nix
Normal file
61
nixos/modules/services/x11/window-managers/wmderland.nix
Normal file
|
@ -0,0 +1,61 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.xserver.windowManager.wmderland;
|
||||
in
|
||||
|
||||
{
|
||||
options.services.xserver.windowManager.wmderland = {
|
||||
enable = mkEnableOption "wmderland";
|
||||
|
||||
extraSessionCommands = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
description = ''
|
||||
Shell commands executed just before wmderland is started.
|
||||
'';
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = with pkgs; [
|
||||
rofi
|
||||
dunst
|
||||
light
|
||||
hsetroot
|
||||
feh
|
||||
rxvt-unicode
|
||||
];
|
||||
example = literalExample ''
|
||||
with pkgs; [
|
||||
rofi
|
||||
dunst
|
||||
light
|
||||
hsetroot
|
||||
feh
|
||||
rxvt-unicode
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
Extra packages to be installed system wide.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.xserver.windowManager.session = singleton {
|
||||
name = "wmderland";
|
||||
start = ''
|
||||
${cfg.extraSessionCommands}
|
||||
|
||||
${pkgs.wmderland}/bin/wmderland &
|
||||
waitPID=$!
|
||||
'';
|
||||
};
|
||||
environment.systemPackages = [
|
||||
pkgs.wmderland pkgs.wmderlandc
|
||||
] ++ cfg.extraPackages;
|
||||
};
|
||||
}
|
|
@ -157,6 +157,7 @@ in
|
|||
|
||||
systemd.services.docker = {
|
||||
wantedBy = optional cfg.enableOnBoot "multi-user.target";
|
||||
after = [ "network.target" "docker.socket" ];
|
||||
requires = [ "docker.socket" ];
|
||||
environment = proxy_env;
|
||||
serviceConfig = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue