nix/modules/networking/caddy.nix
pazpi d86ded0d74 Use ACME for certificates
Simplifies a lot the configuration. It eliminates the overlay and it accepts the key via environment file
2024-11-06 12:09:39 +01:00

154 lines
3.6 KiB
Nix

{
config,
pkgs,
lib,
...
}:
with lib;
let
cfg = config.my.networking.caddy;
in
{
options.my.networking.caddy = {
enable = lib.mkEnableOption "Enable caddy as reverse proxy";
domain = lib.mkOption {
default = "example.com";
type = lib.types.str;
description = ''
The domain where Caddy is reachable
'';
};
email = lib.mkOption {
default = "user@domain.com";
type = lib.types.str;
description = ''
Email for Certbot
'';
};
};
config = lib.mkIf cfg.enable {
age.secrets = {
cloudflare-tegola-apiKey = {
file = ../../secrets/cloudflare-tegola-apiKey.age;
owner = config.services.caddy.user;
group = config.services.caddy.group;
};
};
# Insted on relying on caddy to provide TLS, we use certbot to get a certificate
# https://aottr.dev/posts/2024/08/homelab-setting-up-caddy-reverse-proxy-with-ssl-on-nixos/
security.acme = {
acceptTerms = true;
defaults.email = cfg.email;
# TESTING ONLY!
# defaults.server = "https://acme-staging-v02.api.letsencrypt.org/directory";
certs."${cfg.domain}" = {
group = config.services.caddy.group;
domain = "${cfg.domain}";
extraDomainNames = [ "*.${cfg.domain}" ];
dnsProvider = "cloudflare";
dnsResolver = "1.1.1.1:53";
dnsPropagationCheck = true;
environmentFile = config.age.secrets.cloudflare-tegola-apiKey.path;
};
};
services.caddy = {
enable = true;
globalConfig = ''
admin :2024
servers {
metrics
}
'';
extraConfig =
let
certPath = config.security.acme.certs."${cfg.domain}".directory;
in
''
(cloudflare) {
tls ${certPath}/cert.pem ${certPath}/key.pem {
protocols tls1.3
}
}
'';
};
systemd.services.caddy.serviceConfig = {
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
};
# By default, the module create a custom user but it lacks permission to read caddy files
systemd.services.promtail.serviceConfig = {
Group = lib.mkForce config.services.caddy.group;
User = lib.mkForce config.services.caddy.user;
};
services.promtail = {
enable = true;
configuration = {
server.http_listen_port = 9080;
server.grpc_listen_port = 0;
clients = [ { url = "http://metrics.internal:3100/loki/api/v1/push"; } ];
scrape_configs = [
{
job_name = "journal";
journal = {
max_age = "12h";
labels = {
job = "systemd-journal";
};
};
relabel_configs = [
{
source_labels = [ "__journal__systemd_unit" ];
regex = "(.*)\\.service";
target_label = "service";
}
{
source_labels = [ "__journal__hostname" ];
target_label = "hostname";
}
];
}
{
job_name = "caddy";
static_configs = [
{
targets = [ "localhost" ];
labels = {
job = "caddylogs";
__path__ = "${config.services.caddy.logDir}/*.log";
};
}
];
}
];
};
};
networking.firewall.allowedTCPPorts = [
80
443
2024
];
networking.firewall.allowedUDPPorts = [
80
443
];
};
}