{ config, pkgs, ... }: { # Enable containers containers.caddy = { autoStart = true; privateNetwork = true; hostAddress = "10.0.1.18"; localAddress = "10.0.2.1"; config = { config, pkgs, ... }: { nixpkgs.overlays = [ ( _final: prev: let plugins = [ "github.com/caddy-dns/cloudflare" ]; goImports = prev.lib.flip prev.lib.concatMapStrings plugins (pkg: " _ \"${pkg}\"\n"); goGets = prev.lib.flip prev.lib.concatMapStrings plugins (pkg: "go get ${pkg}\n "); main = '' package main import ( caddycmd "github.com/caddyserver/caddy/v2/cmd" _ "github.com/caddyserver/caddy/v2/modules/standard" ${goImports} ) func main() { caddycmd.Main() } ''; in { caddy-cloudflare = prev.buildGoModule { pname = "caddy-cloudflare"; version = prev.caddy.version; runVend = true; subPackages = [ "cmd/caddy" ]; src = prev.caddy.src; vendorHash = "sha256-fTcMtg5GGEgclIwJCav0jjWpqT+nKw2OF1Ow0MEEitk="; overrideModAttrs = ( _: { preBuild = '' echo '${main}' > cmd/caddy/main.go ${goGets} ''; postInstall = "cp go.sum go.mod $out/ && ls $out/"; } ); postPatch = '' echo '${main}' > cmd/caddy/main.go cat cmd/caddy/main.go ''; postConfigure = '' cp vendor/go.sum ./ cp vendor/go.mod ./ ''; meta = with prev.lib; { homepage = "https://caddyserver.com"; description = "Fast, cross-platform HTTP/2 web server with automatic HTTPS"; license = licenses.asl20; maintainers = with maintainers; [ Br1ght0ne techknowlogick ]; }; }; } ) ]; systemd.services.caddy.serviceConfig.AmbientCapabilities = "CAP_NET_BIND_SERVICE"; # Caddy web server services.caddy = { enable = true; email = "jalle008@proton.me"; enableReload = true; package = pkgs.caddy-cloudflare; adapter = "''"; # Required to enable JSON # virtualHosts = { # } configFile = pkgs.writeText "Caddyfile" ( builtins.toJSON { apps.http.servers.main = { listen = [ ":443" ]; routes = [ { match = [ { host = [ "authentik.mjallen.dev" ]; } ]; handle = [ { handler = "reverse_proxy"; upstreams = [ { dial = "http://10.0.1.18:9000"; } ]; } ]; } ]; }; apps.tls.automation.policies = [ { issuers = [ { module = "acme"; challenges = { dns = { provider = { name = "cloudflare"; api_token = "{env.CLOUDFLARE_API_TOKEN}"; }; resolvers = [ "1.1.1.1" ]; }; }; } ]; } ]; } ); # configFile = pkgs.writeText "Caddyfile" '' # apps.tls.automation.policies = [{ # issuers = [{ # module = "acme"; # challenges = { # dns = { # provider = { # name = "cloudflare"; # api_token = "{env.CLOUDFLARE_API_TOKEN}"; # }; # resolvers = [ "1.1.1.1" ]; # }; # }; # }]; # # Wildcard certificate for all subdomains # *.mjallen.dev { # tls { # dns cloudflare {env.CLOUDFLARE_API_TOKEN} # } # } # :80 { # respond "Hello from Caddy!" # } # :443 { # respond "Hello from Caddy!" # } # authentik.mjallen.dev { # reverse_proxy 10.0.1.18:9000 # } # ''; }; # Environment variable for DNS challenge environment.etc."caddy/cloudflare.env" = { mode = "0600"; text = '' CLOUDFLARE_API_TOKEN=HYhx7cN6e-O6QQJNKd9g7RpgvCzY-aegOPU2iQwB ''; }; # Fail2Ban configuration environment.etc."fail2ban/filter.d/caddy.local" = { mode = "0644"; text = '' [Definition] failregex = ^ .* "(GET|POST|PUT|DELETE|HEAD|OPTIONS) .* HTTP/\d\.\d" (4\d{2}|5\d{2}) ignoreregex = ''; }; services.fail2ban = { enable = true; jails = { caddy = { settings = { filter = "caddy"; logpath = "/var/log/caddy/access.log"; maxretry = 5; bantime = "30m"; }; }; }; }; # Ensure logging for Caddy services.caddy.logDir = "/var/log/caddy"; # Open necessary firewall ports networking.firewall = { enable = true; allowedTCPPorts = [ 80 443 ]; }; # Install additional packages if needed environment.systemPackages = with pkgs; [ caddy fail2ban ]; system.stateVersion = "23.11"; }; }; networking.nat = { forwardPorts = [ { destination = "10.0.2.1:80"; sourcePort = 80; } { destination = "10.0.2.1:443"; sourcePort = 443; } ]; }; }