Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Help] modsecurity plugin + csr + traefik #19

Open
lordraiden opened this issue May 30, 2023 · 1 comment
Open

[Help] modsecurity plugin + csr + traefik #19

lordraiden opened this issue May 30, 2023 · 1 comment

Comments

@lordraiden
Copy link

lordraiden commented May 30, 2023

I'm have read the doc from this project and https://github.com/coreruleset/modsecurity-crs-docker/tree/master

Everything works but as son as I enable the modsecurity middleware I get a blank page. Any idea what I'm doing wrong? I'm publishing the sites in https and the entrypoints redirects http to https, has this something to do?

Any help or working example are welcome, thanks

This is my current setup, domains are fake

### Traefik.yml static

global:
  checkNewVersion: true
  sendAnonymousUsage: false

serversTransport:
  insecureSkipVerify: true # allow insecure backend connections

entryPoints: # Not used in apps, but redirect everything from HTTP to HTTPS

  http80:
    address: :80
    http:
      redirections:
        entryPoint:
          to: https443
          scheme: https
          permanent: true

  # HTTPS endpoint, with domain wildcard
  https443:
    address: :443
    #forwardedHeaders:
    #  trustedIPs: *trustedIps # Reuse list of Cloudflare Trusted IP's above for HTTPS requests
    http:
      tls:
        certResolver: letsencrypt
        domains:
          - main: testesttes.com.es
            sans:
              - '*.testesttes.com.es'
      middlewares:
        - securityHeaders@file

providers:
  providersThrottleDuration: 15s
  file:
    filename: /etc/traefik/fileConfig.yml
    watch: true

  # Docker provider for connecting all apps that are inside of the docker network
  docker:
    watch: true
    network: br2 # Add Your Docker Network Name Here
    # Default host rule to containername.domain.example
    defaultRule: "Host(`{{ index .Labels \"com.docker.compose.service\"}}.testesttes.com.es`)"
    swarmModeRefreshSeconds: 15s
    exposedByDefault: false
    endpoint: "tcp://socketproxy:2375" 

# Enable traefik ui
api:
  dashboard: true
  insecure: false

# Log level INFO|DEBUG|ERROR
log:
  level: INFO # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
  filePath: "/etc/traefik/logs/traefik.log"
accesslog:
  filePath: "/etc/traefik/logs/access.log"
  bufferingSize: 100
  filters:
    statusCodes: 
      - "204-299"
      - "400-499"
      - "500-599"

# Use letsencrypt to generate ssl serficiates
certificatesResolvers:
  letsencrypt:
    acme:
      email: server@server.com
      storage: /etc/traefik/acme.json
      dnsChallenge:
        provider: cloudflare
        # Used to make sure the dns challenge is propagated to the rights dns servers
        resolvers:
          - "1.1.1.1:53"
          - "1.0.0.1:53"
        delayBeforeCheck: 90

# Traefik plugins
experimental:
  plugins:
    crowdsec-bouncer-traefik-plugin:
      moduleName: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
      version: "v1.1.12"
    
    traefik-modsecurity-plugin:
      moduleName: "github.com/acouvreur/traefik-modsecurity-plugin"
      version: "v1.3.0"

### this is fileconfig.yml / Dynamic


http:

# Home Assistant
  routers:

    homeassistant:
      entryPoints:
        - https443
      rule: 'Host(`ha.dasdassdaadsdas.com.es`)'
      service: homeassistant
      middlewares:
        - traefik-ha-csbouncer
        - traefik-modsecurity

  services:

    homeassistant:
      loadBalancer:
        servers:
          - url: http://10.10.10.100:8123/

  ## MIDDLEWARES ##
  middlewares:
    
    traefik-ha-csbouncer:
      plugin:
        crowdsec-bouncer-traefik-plugin:
          enabled: true
          logLevel: INFO
          updateIntervalSeconds: 30 # stream mode only
          #defaultDecisionSeconds: 60 # live mode only
          crowdsecMode: stream
          crowdsecLapiKey: asdasdasdasdasdasdasdasda# Api key for 'traefik-ha'
          crowdsecLapiHost: 10.10.50.11:8080
          crowdsecLapiScheme: http
          crowdsecLapiTLSInsecureVerify: false
          #forwardedHeadersTrustedIPs:   # List of IPs of trusted Proxies that are in front of traefik (ex: Cloudflare)
          clientTrustedIPs: 
            - 10.10.10.1/24
          forwardedHeadersCustomName: X-Forwarded-For
          redisCacheEnabled: true
          redisCacheHost: redis-cs:6379
          redisCachePassword: asdasdasdasdasdasdasdas
          redisCacheDatabase: 1
          
    traefik-modsecurity:  
      plugin:
        traefik-modsecurity-plugin:
          #MaxBodySize: "52428800"
          ModsecurityUrl: http://modsecurity:80
          TimeoutMillis: "2000"

    # Security headers
    securityHeaders:
      headers:
        customResponseHeaders:
          X-Robots-Tag: "none,noarchive,nosnippet,notranslate,noimageindex"
          server: ""
          X-Forwarded-Proto: "https"
        sslProxyHeaders:
          X-Forwarded-Proto: "https"
        referrerPolicy: "strict-origin-when-cross-origin"
        hostsProxyHeaders:
          - "X-Forwarded-Host"
        customRequestHeaders:
          X-Forwarded-Proto: "https"
        framedeny: true # Set frameDeny to true to add the X-Frame-Options header with the value of DENY.
        contentTypeNosniff: true # Set contentTypeNosniff to true to add the X-Content-Type-Options header with the value nosniff.
        browserXssFilter: true
        forceSTSHeader: true
        stsIncludeSubdomains: true
        stsSeconds: 63072000
        stsPreload: true

# Only use secure ciphers - https://ssl-config.mozilla.org/#server=traefik&version=2.6.0&config=intermediate&guideline=5.6
tls:
  options:
    default:
      minVersion: VersionTLS12
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305

### Docker compose

###############################################################
# Web Proxy DMZ 
###############################################################

version: '3.9'

# Services ####################################################

services:

## Traefik ####################################################
  traefik:
    container_name: ProxyDMZ-Traefik
    image: traefik:latest
    restart: unless-stopped
    depends_on:
      - socketproxy
    networks:
      netsocketproxy:
      netmodsecurity:
      netredis:
      br2:
        ipv4_address: 10.10.50.10
    dns: 10.10.50.5
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080" # Dashboard port
    volumes:
      - "/mnt/user/Docker/WebProxyDMZ/Traefik:/etc/traefik/"
    environment:
      - TZ
      - DOCKER_HOST=socketproxy
      - CF_API_EMAIL_FILE
      - CF_DNS_API_TOKEN_FILE
    secrets:
      - CF_API_EMAIL
      - CF_DNS_API_TOKEN
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.localwhitelist2.ipwhitelist.sourcerange=10.10.10.1/24"
      - "traefik.http.routers.traefik-dashboard.middlewares=localwhitelist2"
      - "traefik.http.services.traefik-dashboard.loadbalancer.server.port=8080" #required
      - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.saddsaasdasd.com.es`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
      - "traefik.http.routers.traefik-dashboard.tls=true"
      - "traefik.http.routers.traefik-dashboard.tls.certresolver=letsencrypt"
      - "traefik.http.routers.traefik-dashboard.service=api@internal" #required
      - "traefik.http.routers.api.service=api@internal" #required
      #- "traefik.http.routers.api.tls=true"
      #- "traefik.http.routers.traefik-dashboard.entrypoints=https443"
      - "com.centurylinklabs.watchtower.enable=true"

## Docker Socket Proxy ########################################
  socketproxy:
    container_name: ProxyDMZ-SocketProxy
    image: tecnativa/docker-socket-proxy
    privileged: true
    restart: unless-stopped
    networks:
      - netsocketproxy
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    environment:
      - LOG_LEVEL=notice # debug,info,notice,warning,err,crit,alert,emerg
      - CONTAINERS=1
      - POST=0
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

## DDNS Updater ###############################################
  ddns-updater:
    image: qmcgaw/ddns-updater
    container_name: ProxyDMZ-DDNSUpdater
    restart: unless-stopped
    networks:
      br1:
        ipv4_address: 10.10.40.6
    ports:
      - 8002:8080/tcp
    volumes:
      - /mnt/user/Docker/WebProxyDMZ/DDNS-updater:/updater/data
    environment:
      - TZ
      #- CONFIG
      - PERIOD=5m
      - UPDATE_COOLDOWN_PERIOD=5m
      - PUBLICIP_FETCHERS=dns
      - PUBLICIP_HTTP_PROVIDERS=all
      - PUBLICIPV4_HTTP_PROVIDERS=all
      - PUBLICIPV6_HTTP_PROVIDERS=all
      - PUBLICIP_DNS_PROVIDERS=cloudflare
      - PUBLICIP_DNS_TIMEOUT=3s
      - HTTP_TIMEOUT=10s
      - LISTENING_PORT=8080
      - ROOT_URL=/
      - BACKUP_PERIOD=0 # 0 to disable
      - BACKUP_DIRECTORY=/updater/data
      - LOG_LEVEL=info
      - LOG_CALLER=hidden
      - SHOUTRRR_ADDRESSES_FILE
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

## ModSecurity Core Rule Set (CRS) ############################

  modsecurity:
    image: owasp/modsecurity-crs:apache
    container_name: ProxyDMZ-ModSecurity
    restart: unless-stopped
    networks:
      - netmodsecurity
    #volumes:
    #  - /mnt/user/Docker/WebProxyDMZ/ModSecurity/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:/etc/modsecurity.d/owasp-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
    #  - /mnt/user/Docker/WebProxyDMZ/ModSecurity/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf:/etc/modsecurity.d/owasp-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
    environment:
      - PARANOIA=1
      - ANOMALY_INBOUND=10
      - ANOMALY_OUTBOUND=5
      - BACKEND=http://traefik:80
    
## CrowdSec ###################################################

  crowdsec:
    image: crowdsecurity/crowdsec
    container_name: ProxyDMZ-CrowdSec
    restart: unless-stopped
    networks:
      br2:
        ipv4_address: 10.10.50.11
    dns: 10.10.50.5    
    ports:
      - 8080:8080
     #- 6060:6060 # PROMETEUS
    volumes:
      - /mnt/user/Docker/WebProxyDMZ/CrowdSec/data:/var/lib/crowdsec/data
      - /mnt/user/Docker/WebProxyDMZ/CrowdSec:/etc/crowdsec
      - /mnt/user/Docker/WebProxyDMZ/Traefik/logs:/var/log/traefik:ro
      - /mnt/user/Docker/HomeAssistant:/var/log/homeassistant:ro    
    environment:
      TZ:
      COLLECTIONS: "crowdsecurity/traefik crowdsecurity/home-assistant crowdsecurity/http-cve crowdsecurity/whitelist-good-actors"
      #GID: "${GID-1000}"
      PUID:
      PGID:
      CUSTOM_HOSTNAME: CrowdSecDMZ
      DISABLE_LOCAL_API: "false" # True Only after successfully registering and validating remote agent below.
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

## CrowdSec - Redis ###########################################

  redis-cs:
    image: redis:alpine
    container_name: ProxyDMZ-CrowdSec-Redis
    restart: unless-stopped
    depends_on:
      - crowdsec
    command: [ "sh", "-c", "exec redis-server --requirepass $REDIS_PASSWORD" ]  # redis-cli -a "password" --stat # select 1 # dbsize
    networks:
      netredis:
    dns: 10.10.50.5
    volumes:
      - /mnt/user/Docker/Nextcloud/redis:/data
    environment:
      - TZ
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

# Networks ####################################################

networks:
  br2:
    driver: macvlan
    external: true
  br1:
    driver: macvlan
    external: true
  netsocketproxy:
    internal: true
  netredis:
    internal: true
  netmodsecurity:
    internal: true

# Secrets ##############################################

secrets:
  # Traefik - CF_API_EMAIL
  CF_API_EMAIL:
    file: $SECRETSDIR/CF_API_EMAIL
  # Traefik - CF_API_EMAIL
  CF_DNS_API_TOKEN:
    file: $SECRETSDIR/CF_DNS_API_TOKEN

@lordraiden
Copy link
Author

lordraiden commented May 30, 2023

Now it's solved, I miss the dummy part
Note that I used traefik/whoami and not the proposed one, since it was deprecated

## ModSecurity Core Rule Set (CRS) ############################
# https://blog.xentoo.info/2022/01/22/traefik-reverse-proxy-with-modsecurity/
  modsecurity:
    image: owasp/modsecurity-crs:apache
    container_name: ProxyDMZ-ModSecurity
    restart: unless-stopped
    networks:
      - netmodsecurity
    volumes:
      - /mnt/user/Docker/WebProxyDMZ/ModSecurity/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:/etc/modsecurity.d/owasp-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
      - /mnt/user/Docker/WebProxyDMZ/ModSecurity/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf:/etc/modsecurity.d/owasp-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
    environment:
      - PARANOIA=1
      - ANOMALY_INBOUND=10
      - ANOMALY_OUTBOUND=5
      - BACKEND=http://dummy

  dummy:
    image: traefik/whoami
    container_name: ProxyDMZ-ModSecurity-Dummy
    restart: unless-stopped
    networks:
      - netmodsecurity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant