You've already forked caddy-opnsense-blocker
Add MIT license and Nix packaging
This commit is contained in:
158
module.nix
Normal file
158
module.nix
Normal file
@@ -0,0 +1,158 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.caddy-opnsense-blocker;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
credentialsDirectory = "/run/credentials/caddy-opnsense-blocker.service";
|
||||
|
||||
credentialSettings = lib.optionalAttrs (cfg.credentials.opnsenseApiKeyFile != null) {
|
||||
opnsense.api_key_file = "${credentialsDirectory}/opnsense_api_key";
|
||||
} // lib.optionalAttrs (cfg.credentials.opnsenseApiSecretFile != null) {
|
||||
opnsense.api_secret_file = "${credentialsDirectory}/opnsense_api_secret";
|
||||
};
|
||||
|
||||
defaultSettings = {
|
||||
server = {
|
||||
listen_address = "127.0.0.1:9080";
|
||||
read_timeout = "5s";
|
||||
write_timeout = "10s";
|
||||
shutdown_timeout = "15s";
|
||||
};
|
||||
|
||||
storage.path = "/var/lib/${cfg.stateDirectoryName}/caddy-opnsense-blocker.db";
|
||||
};
|
||||
|
||||
mergedSettings = lib.recursiveUpdate defaultSettings (lib.recursiveUpdate credentialSettings cfg.settings);
|
||||
configFile = yamlFormat.generate "caddy-opnsense-blocker.yaml" mergedSettings;
|
||||
|
||||
loadCredential =
|
||||
lib.optional (cfg.credentials.opnsenseApiKeyFile != null)
|
||||
"opnsense_api_key:${toString cfg.credentials.opnsenseApiKeyFile}"
|
||||
++ lib.optional (cfg.credentials.opnsenseApiSecretFile != null)
|
||||
"opnsense_api_secret:${toString cfg.credentials.opnsenseApiSecretFile}";
|
||||
|
||||
opnsenseEnabled = lib.attrByPath [ "opnsense" "enabled" ] false mergedSettings;
|
||||
hasOPNsenseAPIKey =
|
||||
cfg.credentials.opnsenseApiKeyFile != null
|
||||
|| lib.hasAttrByPath [ "opnsense" "api_key" ] cfg.settings
|
||||
|| lib.hasAttrByPath [ "opnsense" "api_key_file" ] cfg.settings;
|
||||
hasOPNsenseAPISecret =
|
||||
cfg.credentials.opnsenseApiSecretFile != null
|
||||
|| lib.hasAttrByPath [ "opnsense" "api_secret" ] cfg.settings
|
||||
|| lib.hasAttrByPath [ "opnsense" "api_secret_file" ] cfg.settings;
|
||||
in {
|
||||
options.services.caddy-opnsense-blocker = {
|
||||
enable = lib.mkEnableOption "caddy-opnsense-blocker";
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.callPackage ./package.nix { };
|
||||
defaultText = lib.literalExpression "pkgs.callPackage ./package.nix { }";
|
||||
description = "Package used to run caddy-opnsense-blocker.";
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "caddy";
|
||||
description = "User account used by the service.";
|
||||
};
|
||||
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "caddy";
|
||||
description = "Primary group used by the service.";
|
||||
};
|
||||
|
||||
stateDirectoryName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "caddy-opnsense-blocker";
|
||||
description = "Systemd state directory name for the service.";
|
||||
};
|
||||
|
||||
credentials = {
|
||||
opnsenseApiKeyFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = "Path to the OPNsense API key loaded through systemd credentials.";
|
||||
};
|
||||
|
||||
opnsenseApiSecretFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = "Path to the OPNsense API secret loaded through systemd credentials.";
|
||||
};
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = yamlFormat.type;
|
||||
default = { };
|
||||
example = {
|
||||
opnsense = {
|
||||
enabled = true;
|
||||
base_url = "https://router.example.test";
|
||||
ensure_alias = true;
|
||||
alias.name = "blocked-ips";
|
||||
};
|
||||
|
||||
profiles.public-web = {
|
||||
auto_block = true;
|
||||
block_unexpected_posts = true;
|
||||
suspicious_path_prefixes = [ "/wp-admin" "/wp-login.php" "/.env" ];
|
||||
};
|
||||
|
||||
sources = [
|
||||
{
|
||||
name = "public-web";
|
||||
path = "/var/log/caddy/public-web.json";
|
||||
profile = "public-web";
|
||||
}
|
||||
];
|
||||
};
|
||||
description = "YAML-equivalent application settings written to a generated runtime configuration file.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = (cfg.credentials.opnsenseApiKeyFile == null) == (cfg.credentials.opnsenseApiSecretFile == null);
|
||||
message = "services.caddy-opnsense-blocker.credentials.opnsenseApiKeyFile and opnsenseApiSecretFile must either both be set or both be null.";
|
||||
}
|
||||
{
|
||||
assertion = !opnsenseEnabled || (hasOPNsenseAPIKey && hasOPNsenseAPISecret);
|
||||
message = "services.caddy-opnsense-blocker requires OPNsense credentials when settings.opnsense.enabled = true.";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services.caddy-opnsense-blocker = {
|
||||
description = "Caddy OPNsense blocker";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
StateDirectory = cfg.stateDirectoryName;
|
||||
WorkingDirectory = "/var/lib/${cfg.stateDirectoryName}";
|
||||
ExecStart = "${cfg.package}/bin/caddy-opnsense-blocker -config ${configFile}";
|
||||
LoadCredential = loadCredential;
|
||||
Restart = "always";
|
||||
RestartSec = "5s";
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
SystemCallArchitectures = "native";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user