902e3b244b
We're using an autogenerated session secret and hence do not need it.
205 lines
5.8 KiB
Nix
205 lines
5.8 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
with lib; let
|
|
cfg = config.nixarr.autobrr;
|
|
nixarr = config.nixarr;
|
|
# Externalize username and group
|
|
user = "autobrr";
|
|
group = "autobrr";
|
|
|
|
# Define config format and template
|
|
configFormat = pkgs.formats.toml {};
|
|
configTemplate = configFormat.generate "autobrr.toml" cfg.settings;
|
|
in {
|
|
options.nixarr.autobrr = {
|
|
enable = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
example = true;
|
|
description = ''
|
|
Whether or not to enable the Autobrr service.
|
|
|
|
**Required options:** [`nixarr.enable`](#nixarr.enable)
|
|
'';
|
|
};
|
|
|
|
package = mkPackageOption pkgs "autobrr" {};
|
|
|
|
openFirewall = mkOption {
|
|
type = types.bool;
|
|
defaultText = literalExpression ''!nixarr.autobrr.vpn.enable'';
|
|
default = !cfg.vpn.enable;
|
|
example = true;
|
|
description = "Open firewall for the Autobrr port.";
|
|
};
|
|
|
|
vpn.enable = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
example = true;
|
|
description = ''
|
|
**Required options:** [`nixarr.vpn.enable`](#nixarr.vpn.enable)
|
|
|
|
Route Autobrr traffic through the VPN.
|
|
'';
|
|
};
|
|
|
|
settings = lib.mkOption {
|
|
type = lib.types.submodule {freeformType = configFormat.type;};
|
|
default = {
|
|
host = "0.0.0.0";
|
|
port = 7474;
|
|
checkForUpdates = false;
|
|
};
|
|
example = {
|
|
logLevel = "DEBUG";
|
|
};
|
|
description = ''
|
|
Autobrr configuration options.
|
|
|
|
See https://autobrr.com/configuration/autobrr for more information.
|
|
|
|
`sessionSecret` is automatically generated upon first installation and will be overridden.
|
|
'';
|
|
};
|
|
|
|
stateDir = mkOption {
|
|
type = types.path;
|
|
default = "${nixarr.stateDir}/autobrr";
|
|
defaultText = literalExpression ''"''${nixarr.stateDir}/autobrr"'';
|
|
example = "/nixarr/.state/autobrr";
|
|
description = "The location of the state directory for the Autobrr service.";
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
assertions = [
|
|
{
|
|
assertion = cfg.vpn.enable -> nixarr.vpn.enable;
|
|
message = ''
|
|
The nixarr.autobrr.vpn.enable option requires the
|
|
nixarr.vpn.enable option to be set, but it was not.
|
|
'';
|
|
}
|
|
{
|
|
assertion = cfg.enable -> nixarr.enable;
|
|
message = ''
|
|
The nixarr.autobrr.enable option requires the nixarr.enable
|
|
option to be set, but it was not.
|
|
'';
|
|
}
|
|
];
|
|
|
|
users = {
|
|
groups.${group} = {};
|
|
users.${user} = {
|
|
isSystemUser = true;
|
|
group = group;
|
|
};
|
|
};
|
|
|
|
# Create state directory with proper permissions
|
|
systemd.tmpfiles.rules = [
|
|
"d '${cfg.stateDir}' 0700 ${user} ${group} - -"
|
|
];
|
|
|
|
# Configure the autobrr service
|
|
services.autobrr = {
|
|
enable = true;
|
|
package = cfg.package;
|
|
# We need to provide a secretFile even though we're handling it ourselves
|
|
secretFile = "/dev/null"; # This is a placeholder that won't be used
|
|
settings = mkMerge [
|
|
# User settings
|
|
cfg.settings
|
|
# Override host if VPN is enabled
|
|
(mkIf cfg.vpn.enable {host = "192.168.15.1";})
|
|
];
|
|
};
|
|
|
|
# Override the autobrr service to use our state directory and session secret handling
|
|
systemd.services.autobrr = {
|
|
description = "Autobrr";
|
|
after = ["syslog.target" "network-online.target"];
|
|
wants = ["network-online.target"];
|
|
wantedBy = ["multi-user.target"];
|
|
path = [pkgs.openssl pkgs.dasel];
|
|
|
|
serviceConfig = {
|
|
Type = "simple";
|
|
User = user;
|
|
Group = "root";
|
|
UMask = 066;
|
|
DynamicUser = lib.mkForce false;
|
|
# disable SecretFilec
|
|
LoadCredential = lib.mkForce null;
|
|
# disable state directory
|
|
StateDirectory = lib.mkForce null;
|
|
ExecStartPre = lib.mkForce (pkgs.writeShellScript "autobrr-config-prep" ''
|
|
# Generate session secret if it doesn't exist
|
|
SESSION_SECRET_FILE="${cfg.stateDir}/session-secret"
|
|
if [ ! -f "$SESSION_SECRET_FILE" ]; then
|
|
openssl rand -base64 32 > "$SESSION_SECRET_FILE"
|
|
chmod 600 "$SESSION_SECRET_FILE"
|
|
fi
|
|
|
|
# Create config with session secret
|
|
SESSION_SECRET=$(cat "$SESSION_SECRET_FILE")
|
|
cp '${configTemplate}' "${cfg.stateDir}/config.toml"
|
|
chmod 600 "${cfg.stateDir}/config.toml"
|
|
${pkgs.dasel}/bin/dasel put -f "${cfg.stateDir}/config.toml" -v "$SESSION_SECRET" -o "${cfg.stateDir}/config.toml" "sessionSecret"
|
|
'');
|
|
ExecStart = lib.mkForce "${lib.getExe cfg.package} --config ${cfg.stateDir}";
|
|
Restart = "on-failure";
|
|
};
|
|
|
|
# Enable and specify VPN namespace to confine service in
|
|
vpnConfinement = mkIf cfg.vpn.enable {
|
|
enable = true;
|
|
vpnNamespace = "wg";
|
|
};
|
|
};
|
|
|
|
# Port mappings for VPN
|
|
vpnNamespaces.wg = mkIf cfg.vpn.enable {
|
|
portMappings = [
|
|
{
|
|
from = cfg.settings.port;
|
|
to = cfg.settings.port;
|
|
}
|
|
];
|
|
};
|
|
|
|
# Nginx proxy for VPN-confined service
|
|
services.nginx = mkIf cfg.vpn.enable {
|
|
enable = true;
|
|
recommendedTlsSettings = true;
|
|
recommendedOptimisation = true;
|
|
recommendedGzipSettings = true;
|
|
|
|
virtualHosts."127.0.0.1:${builtins.toString cfg.settings.port}" = {
|
|
listen = [
|
|
{
|
|
addr = "0.0.0.0";
|
|
port = cfg.settings.port;
|
|
}
|
|
];
|
|
locations."/" = {
|
|
recommendedProxySettings = true;
|
|
proxyWebsockets = true;
|
|
proxyPass = "http://192.168.15.1:${builtins.toString cfg.settings.port}";
|
|
};
|
|
};
|
|
};
|
|
|
|
# Open firewall ports if needed
|
|
networking.firewall = mkIf cfg.openFirewall {
|
|
allowedTCPPorts = [cfg.settings.port];
|
|
};
|
|
};
|
|
}
|