diff --git a/nixos/common/global/ssh.nix b/nixos/common/global/ssh.nix index 40a41e5..243ff12 100644 --- a/nixos/common/global/ssh.nix +++ b/nixos/common/global/ssh.nix @@ -9,11 +9,4 @@ ports = [22]; openFirewall = true; }; - - services.rsyslogd = { - enable = true; - extraConfig = '' - if $programname == 'sshd' then /var/log/sshd.log - ''; - }; } diff --git a/nixos/viridian/services/crowdsec/acquis.d/appsec.yaml b/nixos/viridian/services/crowdsec/acquis.d/appsec.yaml index f5cb42f..2494989 100644 --- a/nixos/viridian/services/crowdsec/acquis.d/appsec.yaml +++ b/nixos/viridian/services/crowdsec/acquis.d/appsec.yaml @@ -1,6 +1,5 @@ -listen_addr: 127.0.0.1:7422 appsec_config: crowdsecurity/appsec-default -name: traefik -source: appsec labels: type: appsec +listen_addr: 127.0.0.1:7422 +source: appsec diff --git a/nixos/viridian/services/crowdsec/acquis.d/syslog.yaml b/nixos/viridian/services/crowdsec/acquis.d/syslog.yaml new file mode 100644 index 0000000..811c059 --- /dev/null +++ b/nixos/viridian/services/crowdsec/acquis.d/syslog.yaml @@ -0,0 +1,5 @@ +source: journalctl +journalctl_filter: + - "_SYSTEMD_UNIT=ssh.service" +labels: + type: syslog diff --git a/nixos/viridian/services/crowdsec/acquis.d/traefik.yaml b/nixos/viridian/services/crowdsec/acquis.d/traefik.yaml new file mode 100644 index 0000000..e6a5972 --- /dev/null +++ b/nixos/viridian/services/crowdsec/acquis.d/traefik.yaml @@ -0,0 +1,5 @@ +poll_without_inotify: false +filenames: + - /var/log/traefik/access.log +labels: + type: traefik diff --git a/nixos/viridian/services/crowdsec/default.nix b/nixos/viridian/services/crowdsec/default.nix index b8471d3..691c394 100644 --- a/nixos/viridian/services/crowdsec/default.nix +++ b/nixos/viridian/services/crowdsec/default.nix @@ -21,14 +21,7 @@ in { group = "crowdsec"; }; - services.crowdsec = let - yaml = (pkgs.formats.yaml {}).generate; - acquisitions_file = yaml "acquisitions.yaml" { - source = "journalctl"; - journalctl_filter = ["_SYSTEMD_UNIT=sshd.service"]; - labels.type = "syslog"; - }; - in { + services.crowdsec = { enable = true; allowLocalJournalAccess = true; enrollKeyFile = config.age.secrets.enrollment-key.path; @@ -36,7 +29,6 @@ in { api.server = { listen_uri = "127.0.0.1:${port}"; }; - crowdsec_service.acquisition_path = acquisitions_file; crowdsec_service.acquisition_dir = ./acquis.d; }; }; @@ -80,6 +72,22 @@ in { if ! cscli collections list | grep -q "crowdsecurity/appsec-generic-rules"; then cscli collections install "crowdsecurity/appsec-generic-rules" fi + + if ! cscli collections list | grep -q "crowdsecurity/traefik"; then + cscli collections install "crowdsecurity/traefik" + fi + + if ! cscli collections list | grep -q "crowdsecurity/http-cve"; then + cscli collections install "crowdsecurity/http-cve" + fi + + if ! cscli collections list | grep -q "crowdsecurity/sshd"; then + cscli collections install "crowdsecurity/sshd" + fi + + if ! cscli collections list | grep -q "crowdsecurity/base-http-scenarios"; then + cscli collections install "crowdsecurity/base-http-scenarios" + fi ''; in [ "${bouncer}/bin/register-bouncer" diff --git a/nixos/viridian/services/crowdsec/firewall-bouncer-key.age b/nixos/viridian/services/crowdsec/firewall-bouncer-key.age deleted file mode 100644 index e57adc9..0000000 Binary files a/nixos/viridian/services/crowdsec/firewall-bouncer-key.age and /dev/null differ diff --git a/nixos/viridian/services/crowdsec/traefik-bouncer-key.age b/nixos/viridian/services/crowdsec/traefik-bouncer-key.age deleted file mode 100644 index 2ba698b..0000000 --- a/nixos/viridian/services/crowdsec/traefik-bouncer-key.age +++ /dev/null @@ -1,9 +0,0 @@ -age-encryption.org/v1 --> piv-p256 hdSnGw A6O6zvEq05hpB3GxDsrj2rUxr0P031TKreOe3ZAfUpJs -Ww8Qg1MV5dJoCYQEGSNLUnZdX7dO1cGu3XaQTyn97PA --> 0(D-grease b? xbW Qg ~cDE0j! -s5z0LGzRiWS6lMMphO19nB7qmvXkto4RJrcTSrOtPHbY9Iam2aeYA0qN4faK40Zs -XPc ---- q1PoY78SatX6wOKNW549+ndCCrNhveA8dHcHQpF+slk -l `=(;>Y[)Pfw.QW5L×KDTY$ -ٿz] \ No newline at end of file diff --git a/nixos/viridian/services/traefik/default.nix b/nixos/viridian/services/traefik/default.nix index 8e7f782..8014440 100644 --- a/nixos/viridian/services/traefik/default.nix +++ b/nixos/viridian/services/traefik/default.nix @@ -22,7 +22,7 @@ User = "traefik"; Group = "traefik"; LogsDirectory = "traefik"; - LogsDirectoryMode = "0750"; + LogsDirectoryMode = "0755"; }; # Reverse proxy and load balancer for HTTP and TCP-based applications @@ -50,6 +50,16 @@ accessLog = { filePath = "/var/log/traefik/access.log"; format = "json"; + filters.statusCodes = [ + "200-299" # log successful http requests + "400-599" # log failed http requests + ]; + # collect logs in-memory buffer before writing into log file + bufferingSize = "0"; + fields.headers = { + defaultMode = "drop"; # drop all headers per default + names.User-Agent = "keep"; # log user agent strings + }; }; # Install plugins @@ -63,7 +73,7 @@ # Authorize or block requests from IPs based on there reputation and behaviour. bouncer = { moduleName = "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"; - version = "v1.3.2"; + version = "v1.3.5"; }; }; @@ -99,21 +109,6 @@ ]; }; }; - # Used to expose metrics - metrics = { - address = ":8082"; - }; - }; - - # Provide metrics for the prometheus backend - metrics = { - prometheus = { - entryPoint = "metrics"; - buckets = ["0.1" "0.3" "1.2" "5.0"]; - addEntryPointsLabels = true; - addRoutersLabels = true; - addServicesLabels = true; - }; }; # Retrieve certificates from an ACME server @@ -141,19 +136,20 @@ insecureSkipVerify = true; }; }; - }; - # Scrape our traefik metrics - services.prometheus.scrapeConfigs = [ - { - job_name = "traefik"; - static_configs = [ - { - targets = ["127.0.0.1:8082"]; - } - ]; - } - ]; + dynamicConfigOptions.http.routers = { + traefik-dashboard = { + rule = "Host(`traefik.home.arpa`)"; + entryPoints = [ + "websecure" + ]; + middlewares = [ + "internal" + ]; + service = "api@internal"; + }; + }; + }; # Persist our traefik data & logs environment.persistence."/persist" = { diff --git a/nixos/viridian/services/traefik/middlewares.nix b/nixos/viridian/services/traefik/middlewares.nix index 28f84f7..6cbdc43 100644 --- a/nixos/viridian/services/traefik/middlewares.nix +++ b/nixos/viridian/services/traefik/middlewares.nix @@ -1,11 +1,4 @@ -{config, ...}: { - # Crowdsec Local API key for the bouncer. - age.secrets.traefik-bouncer-key = { - rekeyFile = ../crowdsec/traefik-bouncer-key.age; - owner = "traefik"; - group = "traefik"; - }; - +{...}: { # Attached to the routers, pieces of middleware are a means of tweaking the requests before they are sent to your service services.traefik.dynamicConfigOptions.http.middlewares = { # Restrict access to internal networks @@ -42,16 +35,31 @@ forceMonthlyUpdate = "true"; }; - # Disable Crowdsec IP checking but apply Crowdsec Appsec checking. - # This mode is intended to be used when Crowdsec IP checking is applied at the Firewall Level. + # Intrusion Prevention System crowdsec.plugin.bouncer = { enabled = "true"; - crowdsecMode = "appsec"; - crowdsecLapiKeyFile = config.age.secrets.traefik-bouncer-key.path; - crowdsecLapiScheme = "http"; - crowdsecLapiHost = "127.0.0.1:8080"; + defaultDecisionSeconds = "60"; + crowdsecMode = "live"; crowdsecAppsecEnabled = "true"; - crowdsecAppsecHost = "127.0.0.1:7422"; + crowdsecAppsecHost = "localhost:7422"; + crowdsecAppsecFailureBlock = "true"; + crowdsecAppsecUnreachableBlock = "true"; + crowdsecLapiKey = "18c725d5-3a22-4331-a8e8-abfd3018a7c0"; + crowdsecLapiHost = "localhost:8080"; + crowdsecLapiScheme = "http"; + crowdsecLapiTLSInsecureVerify = "false"; + forwardedHeadersTrustedIPs = [ + # private class ranges + "10.0.0.0/8" + "172.16.0.0/12" + "192.168.0.0/16" + ]; + clientTrustedIPs = [ + # private class ranges + "10.0.0.0/8" + "172.16.0.0/12" + "192.168.0.0/16" + ]; }; }; }