diff --git a/docker-compose.yml b/docker-compose.yml index 6495eb6..e4c4b9c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,12 +3,13 @@ # Here I will include all "child" docker compose files that I need. # The paths can relative to this file or absolue. I've used INCLUDE_PATH variable to make it more cofigurable. -# Whenever I need to remove some service then I can comment out the lines here. +# Whenever I need to remove some service then I can comment out the lines here. include: - path: - ${SERVICE_PATH}/caddy/caddy.yml + - ${SERVICE_PATH}/crowdsec/crowdsec.yml - ${SERVICE_PATH}/headscale/headscale.yml - - ${SERVICE_PATH}/watchtower/watchtower.yml + # - ${SERVICE_PATH}/traefik/traefik.yml env_file: ${SERVICE_PATH}/.env networks: diff --git a/services/crowdsec/crowdsec.yml b/services/crowdsec/crowdsec.yml new file mode 100644 index 0000000..a76c254 --- /dev/null +++ b/services/crowdsec/crowdsec.yml @@ -0,0 +1,23 @@ +services: + crowdsec: + extends: + file: ${TEMPLATES_PATH} + service: default + container_name: crowdsec + image: crowdsecurity/crowdsec:v1.7.4 + environment: + COLLECTIONS: crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules crowdsecurity/http-cve + CROWDSEC_BOUNCER_API_KEY: ${CROWDSEC_API_KEY} + CUSTOM_HOSTNAME: crowdsec + ports: + - 6061:8080 + - 6060:6060 + networks: + - ip4net + volumes: + - ${SERVICE_PATH}/crowdsec/config/acquis.yaml:/etc/crowdsec/acquis.yaml:ro + - ${SERVICE_PATH}/crowdsec/config:/etc/crowdsec + - ${SERVICE_PATH}/crowdsec/data:/var/lib/crowdsec/data + - /var/log/traefik:/var/log/crowdsec:ro + - /var/log/syslog:/var/log/syslog:ro + - /var/log/kern.log:/var/log/kern.log:ro diff --git a/services/traefik/config/config.yml b/services/traefik/config/config.yml new file mode 100644 index 0000000..6859554 --- /dev/null +++ b/services/traefik/config/config.yml @@ -0,0 +1,164 @@ +http: + middlewares: + + # Crowdsec + crowdsec-bouncer: + plugin: + crowdsec-bouncer-plugin: + enabled: true + logLevel: INFO + updateIntervalSeconds: 60 + crowdsecMode: stream + crowdsecAppsecEnabled: true + crowdsecAppsecHost: crowdsec:7422 + crowdsecLapiScheme: http + crowdsecLapiHost: crowdsec:8080 + # generated using "docker exec crowdsec cscli bouncers add crowdsecBouncer" + crowdseclapikey: {{ env "TRAEFIK_CROWDSEC_API_KEY" }} + forwardedHeadersTrustedIPs: + - 10.0.6.0/24 + clientTrustedIPs: + - 192.168.178.0/24 + captchaProvider: hcaptcha + captchaSiteKey: b2d20610-8dda-4f40-8688-7ca8e1e628f8 # found in hcaptcha account + captchaSecretKey: ES_9511d34bbec34dada169afad0a36991a + captchaGracePeriodSeconds: 1800 + captchaHTMLFilePath: /captcha.html + banHTMLFilePath: /ban.html + + routers: + authelia: + rule: "Host(`auth.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + audiobookshelf: + rule: "Host(`audiobookshelf.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + gitea: + rule: "Host(`gitea.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + headscale: + rule: "Host(`headscale.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + immich: + rule: "Host(`immich.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + lldap: + rule: "Host(`lldap.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + linkwarden: + rule: "Host(`linkwarden.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + mealie: + rule: "Host(`mealie.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + navidrome: + rule: "Host(`navidrome.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + ntfy: + rule: "Host(`ntfy.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + paperless: + rule: "Host(`paperless.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + pdf: + rule: "Host(`pdf.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + radicale: + rule: "Host(`radicale.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + rss: + rule: "Host(`rss.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + superset: + rule: "Host(`superset.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + vaultwarden: + rule: "Host(`vaultwarden.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + vikunja: + rule: "Host(`vikunja.{{ env "TRAEFIK_PUBLIC_DOMAIN" }}`)" + service: node + entryPoints: https + tls: {} + middlewares: crowdsec-bouncer@file + + services: + node: + loadBalancer: + servers: + - url: {{ env TRAEFIK_MAIN_SERVER_NODE_IP }} + +tls: + stores: + default: + defaultCertificate: + certFile: /etc/certs/server.crt + keyFile: /etc/certs/server.key + certificates: + - certFile: /etc/certs/server.crt + keyFile: /etc/certs/server.key + diff --git a/services/traefik/config/traefik.yml b/services/traefik/config/traefik.yml new file mode 100644 index 0000000..35c4d1d --- /dev/null +++ b/services/traefik/config/traefik.yml @@ -0,0 +1,67 @@ +api: + dashboard: true + +log: + level: "INFO" + +serversTransport: + insecureSkipVerify: true + +accessLog: + filePath: "/var/log/traefik/access.log" # location of traefik logs for crowdsec + format: json + bufferingSize: 100 # Configuring a buffer of 100 lines + filters: + statusCodes: + - "204-299" + - "400-499" + - "500-559" # logged status codes + +entryPoints: + http: + address: "[::]:80" # Create the HTTP entrypoint on port 80 + forwardedHeaders: + insecure: false + trustedIPs: + - "10.0.0.0/8" + - "192.168.178.0/16" + - "2a07:600:200:1::/64" + proxyProtocol: + insecure: false + trustedIPs: + - "10.0.0.0/8" + - "192.168.178.0/16" + - "2a07:600:200:1::/64" + http: + redirections: # HTTPS redirection (80 to 443) + entryPoint: + to: "https" # The target element + scheme: "https" # The redirection target scheme + permanent: true # The target element + + https: + address: "[::]:443" # Create the HTTPS entrypoint on port 443 + forwardedHeaders: + insecure: false + trustedIPs: + - "10.0.0.0/8" + - "192.168.178.0/16" + - "2a07:600:200:1::/64" + proxyProtocol: + insecure: false + trustedIPs: + - "10.0.0.0/8" + - "192.168.178.0/16" + - "2a07:600:200:1::/64" + +providers: + docker: + endpoint: "unix:///var/run/docker.sock" # Listen to the UNIX Docker socket + exposedByDefault: false + file: + directory: "/etc/traefik" # Link to the dynamic configuration + watch: true # Watch for modifications + providersThrottleDuration: "10" # Configuration reload frequency + +metrics: + prometheus: {} diff --git a/services/traefik/html/ban.html b/services/traefik/html/ban.html new file mode 100644 index 0000000..0fd982b --- /dev/null +++ b/services/traefik/html/ban.html @@ -0,0 +1,338 @@ + + + +
+This security check has been powered by
+ + + CrowdSec + +This security check has been powered by
+ + + CrowdSec + +