depot/third_party/nixpkgs/nixos/modules/services/web-servers/stargazer.nix
Default email c7e6337bd0 Project import generated by Copybara.
GitOrigin-RevId: 08e4dc3a907a6dfec8bb3bbf1540d8abbffea22b
2023-04-29 12:46:19 -04:00

198 lines
5.6 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.stargazer;
routesFormat = pkgs.formats.ini { };
globalFile = pkgs.writeText "global.ini" ''
listen = ${concatStringsSep " " cfg.listen}
connection-logging = ${boolToString cfg.connectionLogging}
log-ip = ${boolToString cfg.ipLog}
log-ip-partial = ${boolToString cfg.ipLogPartial}
request-timeout = ${toString cfg.requestTimeout}
response-timeout = ${toString cfg.responseTimeout}
[:tls]
store = ${toString cfg.store}
organization = ${cfg.certOrg}
gen-certs = ${boolToString cfg.genCerts}
regen-certs = ${boolToString cfg.regenCerts}
${optionalString (cfg.certLifetime != "") "cert-lifetime = ${cfg.certLifetime}"}
'';
routesFile = routesFormat.generate "router.ini" cfg.routes;
configFile = pkgs.runCommand "config.ini" { } ''
cat ${globalFile} ${routesFile} > $out
'';
in
{
options.services.stargazer = {
enable = mkEnableOption (lib.mdDoc "Stargazer Gemini server");
listen = lib.mkOption {
type = types.listOf types.str;
default = [ "0.0.0.0" ] ++ optional config.networking.enableIPv6 "[::0]";
defaultText = literalExpression ''[ "0.0.0.0" ] ++ lib.optional config.networking.enableIPv6 "[::0]"'';
example = literalExpression ''[ "10.0.0.12" "[2002:a00:1::]" ]'';
description = lib.mdDoc ''
Address and port to listen on.
'';
};
connectionLogging = lib.mkOption {
type = types.bool;
default = true;
description = lib.mdDoc "Whether or not to log connections to stdout.";
};
ipLog = lib.mkOption {
type = types.bool;
default = false;
description = lib.mdDoc "Log client IP addresses in the connection log.";
};
ipLogPartial = lib.mkOption {
type = types.bool;
default = false;
description = lib.mdDoc "Log partial client IP addresses in the connection log.";
};
requestTimeout = lib.mkOption {
type = types.int;
default = 5;
description = lib.mdDoc ''
Number of seconds to wait for the client to send a complete
request. Set to 0 to disable.
'';
};
responseTimeout = lib.mkOption {
type = types.int;
default = 0;
description = lib.mdDoc ''
Number of seconds to wait for the client to send a complete
request and for stargazer to finish sending the response.
Set to 0 to disable.
'';
};
store = lib.mkOption {
type = types.path;
default = /var/lib/gemini/certs;
description = lib.mdDoc ''
Path to the certificate store on disk. This should be a
persistent directory writable by Stargazer.
'';
};
certOrg = lib.mkOption {
type = types.str;
default = "stargazer";
description = lib.mdDoc ''
The name of the organization responsible for the X.509
certificate's /O name.
'';
};
genCerts = lib.mkOption {
type = types.bool;
default = true;
description = lib.mdDoc ''
Set to false to disable automatic certificate generation.
Use if you want to provide your own certs.
'';
};
regenCerts = lib.mkOption {
type = types.bool;
default = true;
description = lib.mdDoc ''
Set to false to turn off automatic regeneration of expired certificates.
Use if you want to provide your own certs.
'';
};
certLifetime = lib.mkOption {
type = types.str;
default = "";
description = lib.mdDoc ''
How long certs generated by Stargazer should live for.
Certs live forever by default.
'';
example = literalExpression "\"1y\"";
};
routes = lib.mkOption {
type = routesFormat.type;
default = { };
description = lib.mdDoc ''
Routes that Stargazer should server.
[Refer to upstream docs](https://git.sr.ht/~zethra/stargazer/tree/main/item/doc/stargazer.ini.5.txt)
'';
example = literalExpression ''
{
"example.com" = {
root = "/srv/gemini/example.com";
};
"example.com:/man" = {
root = "/cgi-bin";
cgi = true;
};
"other.org~(.*)" = {
redirect = "gemini://example.com";
rewrite = "\1";
};
}
'';
};
user = mkOption {
type = types.str;
default = "stargazer";
description = lib.mdDoc "User account under which stargazer runs.";
};
group = mkOption {
type = types.str;
default = "stargazer";
description = lib.mdDoc "Group account under which stargazer runs.";
};
};
config = mkIf cfg.enable {
systemd.services.stargazer = {
description = "Stargazer gemini server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.stargazer}/bin/stargazer ${configFile}";
Restart = "always";
# User and group
User = cfg.user;
Group = cfg.group;
};
};
# Create default cert store
system.activationScripts.makeStargazerCertDir =
optionalAttrs (cfg.store == /var/lib/gemini/certs) ''
mkdir -p /var/lib/gemini/certs
chown -R ${cfg.user}:${cfg.group} /var/lib/gemini/certs
'';
users.users = optionalAttrs (cfg.user == "stargazer") {
stargazer = {
group = cfg.group;
isSystemUser = true;
};
};
users.groups = optionalAttrs (cfg.group == "stargazer") {
stargazer = { };
};
};
meta.maintainers = with lib.maintainers; [ gaykitty ];
}