Merge pull request #262915 from chayleaf/certspotter
certspotter: init at 0.17.0; nixos/certspotter: init
This commit is contained in:
commit
37c7104f53
5 changed files with 259 additions and 0 deletions
|
@ -113,6 +113,8 @@
|
|||
|
||||
- [tuxedo-rs](https://github.com/AaronErhardt/tuxedo-rs), Rust utilities for interacting with hardware from TUXEDO Computers.
|
||||
|
||||
- [certspotter](https://github.com/SSLMate/certspotter), a certificate transparency log monitor. Available as [services.certspotter](#opt-services.certspotter.enable).
|
||||
|
||||
- [audiobookshelf](https://github.com/advplyr/audiobookshelf/), a self-hosted audiobook and podcast server. Available as [services.audiobookshelf](#opt-services.audiobookshelf.enable).
|
||||
|
||||
- [ZITADEL](https://zitadel.com), a turnkey identity and access management platform. Available as [services.zitadel](#opt-services.zitadel.enable).
|
||||
|
|
|
@ -767,6 +767,7 @@
|
|||
./services/monitoring/below.nix
|
||||
./services/monitoring/bosun.nix
|
||||
./services/monitoring/cadvisor.nix
|
||||
./services/monitoring/certspotter.nix
|
||||
./services/monitoring/cockpit.nix
|
||||
./services/monitoring/collectd.nix
|
||||
./services/monitoring/das_watchdog.nix
|
||||
|
|
74
nixos/modules/services/monitoring/certspotter.md
Normal file
74
nixos/modules/services/monitoring/certspotter.md
Normal file
|
@ -0,0 +1,74 @@
|
|||
# Cert Spotter {#module-services-certspotter}
|
||||
|
||||
Cert Spotter is a tool for monitoring [Certificate Transparency](https://en.wikipedia.org/wiki/Certificate_Transparency)
|
||||
logs.
|
||||
|
||||
## Service Configuration {#modules-services-certspotter-service-configuration}
|
||||
|
||||
A basic config that notifies you of all certificate changes for your
|
||||
domain would look as follows:
|
||||
|
||||
```nix
|
||||
services.certspotter = {
|
||||
enable = true;
|
||||
# replace example.org with your domain name
|
||||
watchlist = [ ".example.org" ];
|
||||
emailRecipients = [ "webmaster@example.org" ];
|
||||
};
|
||||
|
||||
# Configure an SMTP client
|
||||
programs.msmtp.enable = true;
|
||||
# Or you can use any other module that provides sendmail, like
|
||||
# services.nullmailer, services.opensmtpd, services.postfix
|
||||
```
|
||||
|
||||
In this case, the leading dot in `".example.org"` means that Cert
|
||||
Spotter should monitor not only `example.org`, but also all of its
|
||||
subdomains.
|
||||
|
||||
## Operation {#modules-services-certspotter-operation}
|
||||
|
||||
**By default, NixOS configures Cert Spotter to skip all certificates
|
||||
issued before its first launch**, because checking the entire
|
||||
Certificate Transparency logs requires downloading tens of terabytes of
|
||||
data. If you want to check the *entire* logs for previously issued
|
||||
certificates, you have to set `services.certspotter.startAtEnd` to
|
||||
`false` and remove all previously saved log state in
|
||||
`/var/lib/certspotter/logs`. The downloaded logs aren't saved, so if you
|
||||
add a new domain to the watchlist and want Cert Spotter to go through
|
||||
the logs again, you will have to remove `/var/lib/certspotter/logs`
|
||||
again.
|
||||
|
||||
After catching up with the logs, Cert Spotter will start monitoring live
|
||||
logs. As of October 2023, it uses around **20 Mbps** of traffic on
|
||||
average.
|
||||
|
||||
## Hooks {#modules-services-certspotter-hooks}
|
||||
|
||||
Cert Spotter supports running custom hooks instead of (or in addition
|
||||
to) sending emails. Hooks are shell scripts that will be passed certain
|
||||
environment variables.
|
||||
|
||||
To see hook documentation, see Cert Spotter's man pages:
|
||||
|
||||
```ShellSession
|
||||
nix-shell -p certspotter --run 'man 8 certspotter-script'
|
||||
```
|
||||
|
||||
For example, you can remove `emailRecipients` and send email
|
||||
notifications manually using the following hook:
|
||||
|
||||
```nix
|
||||
services.certspotter.hooks = [
|
||||
(pkgs.writeShellScript "certspotter-hook" ''
|
||||
function print_email() {
|
||||
echo "Subject: [certspotter] $SUMMARY"
|
||||
echo "Mime-Version: 1.0"
|
||||
echo "Content-Type: text/plain; charset=US-ASCII"
|
||||
echo
|
||||
cat "$TEXT_FILENAME"
|
||||
}
|
||||
print_email | ${config.services.certspotter.sendmailPath} -i webmaster@example.org
|
||||
'')
|
||||
];
|
||||
```
|
143
nixos/modules/services/monitoring/certspotter.nix
Normal file
143
nixos/modules/services/monitoring/certspotter.nix
Normal file
|
@ -0,0 +1,143 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.certspotter;
|
||||
|
||||
configDir = pkgs.linkFarm "certspotter-config" (
|
||||
lib.toList {
|
||||
name = "watchlist";
|
||||
path = pkgs.writeText "certspotter-watchlist" (builtins.concatStringsSep "\n" cfg.watchlist);
|
||||
}
|
||||
++ lib.optional (cfg.emailRecipients != [ ]) {
|
||||
name = "email_recipients";
|
||||
path = pkgs.writeText "certspotter-email_recipients" (builtins.concatStringsSep "\n" cfg.emailRecipients);
|
||||
}
|
||||
# always generate hooks dir when no emails are provided to allow running cert spotter with no hooks/emails
|
||||
++ lib.optional (cfg.emailRecipients == [ ] || cfg.hooks != [ ]) {
|
||||
name = "hooks.d";
|
||||
path = pkgs.linkFarm "certspotter-hooks" (lib.imap1 (i: path: {
|
||||
inherit path;
|
||||
name = "hook${toString i}";
|
||||
}) cfg.hooks);
|
||||
});
|
||||
in
|
||||
{
|
||||
options.services.certspotter = {
|
||||
enable = lib.mkEnableOption "Cert Spotter, a Certificate Transparency log monitor";
|
||||
|
||||
package = lib.mkPackageOptionMD pkgs "certspotter" { };
|
||||
|
||||
startAtEnd = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Whether to skip certificates issued before the first launch of Cert Spotter.
|
||||
Setting this to `false` will cause Cert Spotter to download tens of terabytes of data.
|
||||
'';
|
||||
default = true;
|
||||
};
|
||||
|
||||
sendmailPath = lib.mkOption {
|
||||
type = with lib.types; nullOr path;
|
||||
description = ''
|
||||
Path to the `sendmail` binary. By default, the local sendmail wrapper is used
|
||||
(see {option}`services.mail.sendmailSetuidWrapper`}).
|
||||
'';
|
||||
example = lib.literalExpression ''"''${pkgs.system-sendmail}/bin/sendmail"'';
|
||||
};
|
||||
|
||||
watchlist = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
description = "Domain names to watch. To monitor a domain with all subdomains, prefix its name with `.` (e.g. `.example.org`).";
|
||||
default = [ ];
|
||||
example = [ ".example.org" "another.example.com" ];
|
||||
};
|
||||
|
||||
emailRecipients = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
description = "A list of email addresses to send certificate updates to.";
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
hooks = lib.mkOption {
|
||||
type = with lib.types; listOf path;
|
||||
description = ''
|
||||
Scripts to run upon the detection of a new certificate. See `man 8 certspotter-script` or
|
||||
[the GitHub page](https://github.com/SSLMate/certspotter/blob/${pkgs.certspotter.src.rev or "master"}/man/certspotter-script.md)
|
||||
for more info.
|
||||
'';
|
||||
default = [ ];
|
||||
example = lib.literalExpression ''
|
||||
[
|
||||
(pkgs.writeShellScript "certspotter-hook" '''
|
||||
echo "Event summary: $SUMMARY."
|
||||
''')
|
||||
]
|
||||
'';
|
||||
};
|
||||
|
||||
extraFlags = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
description = "Extra command-line arguments to pass to Cert Spotter";
|
||||
example = [ "-no_save" ];
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = (cfg.emailRecipients != [ ]) -> (cfg.sendmailPath != null);
|
||||
message = ''
|
||||
You must configure the sendmail setuid wrapper (services.mail.sendmailSetuidWrapper)
|
||||
or services.certspotter.sendmailPath
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
services.certspotter.sendmailPath = let
|
||||
inherit (config.security) wrapperDir;
|
||||
inherit (config.services.mail) sendmailSetuidWrapper;
|
||||
in lib.mkMerge [
|
||||
(lib.mkIf (sendmailSetuidWrapper != null) (lib.mkOptionDefault "${wrapperDir}/${sendmailSetuidWrapper.program}"))
|
||||
(lib.mkIf (sendmailSetuidWrapper == null) (lib.mkOptionDefault null))
|
||||
];
|
||||
|
||||
users.users.certspotter = {
|
||||
description = "Cert Spotter user";
|
||||
group = "certspotter";
|
||||
home = "/var/lib/certspotter";
|
||||
isSystemUser = true;
|
||||
};
|
||||
users.groups.certspotter = { };
|
||||
|
||||
systemd.services.certspotter = {
|
||||
description = "Cert Spotter - Certificate Transparency Monitor";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment.CERTSPOTTER_CONFIG_DIR = configDir;
|
||||
environment.SENDMAIL_PATH = if cfg.sendmailPath != null then cfg.sendmailPath else "/run/current-system/sw/bin/false";
|
||||
script = ''
|
||||
export CERTSPOTTER_STATE_DIR="$STATE_DIRECTORY"
|
||||
cd "$CERTSPOTTER_STATE_DIR"
|
||||
${lib.optionalString cfg.startAtEnd ''
|
||||
if [[ ! -d logs ]]; then
|
||||
# Don't download certificates issued before the first launch
|
||||
exec ${cfg.package}/bin/certspotter -start_at_end ${lib.escapeShellArgs cfg.extraFlags}
|
||||
fi
|
||||
''}
|
||||
exec ${cfg.package}/bin/certspotter ${lib.escapeShellArgs cfg.extraFlags}
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = "certspotter";
|
||||
Group = "certspotter";
|
||||
StateDirectory = "certspotter";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ chayleaf ];
|
||||
meta.doc = ./certspotter.md;
|
||||
}
|
39
pkgs/by-name/ce/certspotter/package.nix
Normal file
39
pkgs/by-name/ce/certspotter/package.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{ lib
|
||||
, fetchFromGitHub
|
||||
, buildGoModule
|
||||
, lowdown
|
||||
}:
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "certspotter";
|
||||
version = "0.17.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "SSLMate";
|
||||
repo = "certspotter";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-6ghS+9b8FZiYdiTk54XRHP46lOq98sN1RDYvRYTt6eU=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-6dV9FoPV8UfS0z5RuuopE99fHcT3RAWCdDi7jpHzVRE=";
|
||||
|
||||
ldflags = [ "-s" "-w" ];
|
||||
|
||||
nativeBuildInputs = [ lowdown ];
|
||||
|
||||
postInstall = ''
|
||||
cd man
|
||||
make
|
||||
mkdir -p $out/share/man/man8
|
||||
mv *.8 $out/share/man/man8
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Certificate Transparency Log Monitor";
|
||||
homepage = "https://github.com/SSLMate/certspotter";
|
||||
changelog = "https://github.com/SSLMate/certspotter/blob/${src.rev}/CHANGELOG.md";
|
||||
license = licenses.mpl20;
|
||||
mainProgram = "certspotter";
|
||||
maintainers = with maintainers; [ chayleaf ];
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue