45 lines
1.7 KiB
Nix
45 lines
1.7 KiB
Nix
|
{ config
|
||
|
, lib
|
||
|
, pkgs
|
||
|
, ... }:
|
||
|
|
||
|
let
|
||
|
cfg = config.server;
|
||
|
in {
|
||
|
security.acme.certs = lib.flip builtins.mapAttrs (lib.filterAttrs (k: v: v.enableACME) config.services.nginx.virtualHosts) (k: v: {
|
||
|
postRun = let
|
||
|
python = pkgs.python3.withPackages (p: with p; [ cryptography pyasn1 pyasn1-modules ]);
|
||
|
tbs-hash = pkgs.writeScript "tbs-hash.py" ''
|
||
|
#!${python}/bin/python3
|
||
|
import hashlib
|
||
|
from pyasn1.codec.der.decoder import decode
|
||
|
from pyasn1.codec.der.encoder import encode
|
||
|
from pyasn1_modules import rfc5280
|
||
|
from cryptography import x509
|
||
|
|
||
|
with open('full.pem', 'rb') as f:
|
||
|
cert = x509.load_pem_x509_certificate(f.read())
|
||
|
tbs, _leftover = decode(cert.tbs_certificate_bytes, asn1Spec=rfc5280.TBSCertificate())
|
||
|
precert_exts = [v.dotted_string for k, v in x509.ExtensionOID.__dict__.items() if k.startswith('PRECERT_')]
|
||
|
exts = [ext for ext in tbs["extensions"] if str(ext["extnID"]) not in precert_exts]
|
||
|
tbs["extensions"].clear()
|
||
|
tbs["extensions"].extend(exts)
|
||
|
print(hashlib.sha256(encode(tbs)).hexdigest())
|
||
|
'';
|
||
|
in ''
|
||
|
${tbs-hash} > "/var/lib/certspotter/tbs-hashes/${k}"
|
||
|
'';
|
||
|
});
|
||
|
services.certspotter = {
|
||
|
enable = true;
|
||
|
extraFlags = [ ];
|
||
|
watchlist = [ ".pavluk.org" ];
|
||
|
hooks = lib.toList (pkgs.writeShellScript "certspotter-hook" ''
|
||
|
if [[ "$EVENT" == discovered_cert ]]; then
|
||
|
${pkgs.gnugrep}/bin/grep -r "$TBS_SHA256" /var/lib/certspotter/tbs-hashes/ && exit
|
||
|
fi
|
||
|
(echo "Subject: $SUMMARY" && echo && cat "$TEXT_FILENAME") | /run/wrappers/bin/sendmail -i webmaster-certspotter@${cfg.domainName}
|
||
|
'');
|
||
|
};
|
||
|
}
|