mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-09-02 20:28:50 +02:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70ad0365f0 | ||
|
|
8975216af8 | ||
|
|
e6b10b8ac4 | ||
|
|
1f11531509 | ||
|
|
ee97250acf |
@@ -26,25 +26,25 @@ run_local:
|
||||
docker compose -f docker-compose.local.yml up -d --remove-orphans
|
||||
|
||||
run_behindproxy:
|
||||
docker compose -f examples/behind-proxy/docker-compose.cloudflare.yml up -d --remove-orphans
|
||||
docker compose -f examples/behind-proxy/docker-compose.yml up -d --remove-orphans
|
||||
|
||||
run_cacheredis:
|
||||
docker compose -f examples/redis-cache/docker-compose.redis.yml up -d --remove-orphans
|
||||
docker compose -f examples/redis-cache/docker-compose.yml up -d --remove-orphans
|
||||
|
||||
run_trustedips:
|
||||
docker compose -f examples/trusted-ips/docker-compose.trusted.yml up -d --remove-orphans
|
||||
docker compose -f examples/trusted-ips/docker-compose.yml up -d --remove-orphans
|
||||
|
||||
run_binaryvm:
|
||||
cd examples/binary-vm/ && sudo vagrant up
|
||||
|
||||
run_tlsauth:
|
||||
docker compose -f examples/tls-auth/docker-compose.tls-auth.yml down && docker compose -f examples/tls-auth/docker-compose.tls-auth.yml up -d && docker compose -f examples/tls-auth/docker-compose.tls-auth.yml restart && docker compose -f examples/tls-auth/docker-compose.tls-auth.yml logs -f
|
||||
docker compose -f examples/tls-auth/docker-compose.yml up -d --remove-orphans
|
||||
|
||||
run_appsec:
|
||||
docker compose -f examples/appsec-enabled/docker-compose.appsec-enabled.yml up -d
|
||||
docker compose -f examples/appsec-enabled/docker-compose.yml up -d
|
||||
|
||||
run_captcha:
|
||||
docker compose -f examples/captcha/docker-compose.captcha.yml up -d
|
||||
docker compose -f examples/captcha/docker-compose.yml up -d
|
||||
|
||||
run_custom_ban_page:
|
||||
docker compose -f examples/custom-ban-page/docker-compose.yml up -d
|
||||
@@ -62,19 +62,25 @@ restart:
|
||||
docker compose -f docker-compose.yml restart
|
||||
|
||||
restart_behindproxy:
|
||||
docker compose -f examples/behind-proxy/docker-compose.cloudflare.yml restart
|
||||
docker compose -f examples/behind-proxy/docker-compose.yml restart
|
||||
|
||||
restart_cacheredis:
|
||||
docker compose -f examples/redis-cache/docker-compose.redis.yml restart
|
||||
docker compose -f examples/redis-cache/docker-compose.yml restart
|
||||
|
||||
restart_trustedips:
|
||||
docker compose -f examples/trusted-ips/docker-compose.trusted.yml restart
|
||||
docker compose -f examples/trusted-ips/docker-compose.yml restart
|
||||
|
||||
restart_tlsauth:
|
||||
docker compose -f examples/tls-auth/docker-compose.tls-auth.yml
|
||||
docker compose -f examples/tls-auth/docker-compose.yml
|
||||
|
||||
restart_appsec:
|
||||
docker compose -f examples/tls-auth/docker-compose.appsec-enabled.yml
|
||||
docker compose -f examples/tls-auth/docker-compose.yml
|
||||
|
||||
restart_captcha:
|
||||
docker compose -f examples/captcha/docker-compose.yml
|
||||
|
||||
restart_custombanpage:
|
||||
docker compose -f examples/custom-ban-page/docker-compose.yml
|
||||
|
||||
show_logs:
|
||||
docker compose -f docker-compose.yml restart
|
||||
@@ -86,11 +92,13 @@ show_dev_logs:
|
||||
docker compose -f docker-compose.dev.yml logs -f
|
||||
|
||||
clean_all_docker:
|
||||
docker compose -f examples/behind-proxy/docker-compose.cloudflare.yml down --remove-orphans
|
||||
docker compose -f examples/redis-cache/docker-compose.redis.yml down --remove-orphans
|
||||
docker compose -f examples/trusted-ips/docker-compose.trusted.yml down --remove-orphans
|
||||
docker compose -f examples/tls-auth/docker-compose.tls-auth.yml down --remove-orphans
|
||||
docker compose -f examples/appsec-enabled/docker-compose.appsec-enabled.yml down --remove-orphans
|
||||
docker compose -f examples/behind-proxy/docker-compose.yml down --remove-orphans
|
||||
docker compose -f examples/redis-cache/docker-compose.yml down --remove-orphans
|
||||
docker compose -f examples/trusted-ips/docker-compose.yml down --remove-orphans
|
||||
docker compose -f examples/tls-auth/docker-compose.yml down --remove-orphans
|
||||
docker compose -f examples/appsec-enabled/docker-compose.yml down --remove-orphans
|
||||
docker compose -f examples/captcha/docker-compose.yml down --remove-orphans
|
||||
docker compose -f examples/custom-ban-page/docker-compose.yml down --remove-orphans
|
||||
docker compose -f docker-compose.local.yml down --remove-orphans
|
||||
docker compose -f docker-compose.yml down --remove-orphans
|
||||
|
||||
@@ -101,3 +109,6 @@ clean_vagrant:
|
||||
show_metrics:
|
||||
docker exec crowdsec cscli metrics
|
||||
|
||||
show_decisions:
|
||||
docker exec crowdsec cscli decisions list
|
||||
|
||||
|
||||
@@ -317,7 +317,7 @@ Only one instance of the plugin is *possible*.
|
||||
- Enable the plugin
|
||||
- LogLevel
|
||||
- string
|
||||
- default: `INFO`, expected values are: `INFO`, `DEBUG`
|
||||
- default: `INFO`, expected values are: `INFO`, `DEBUG`, `ERROR`, log are written to `stdout` / `stderr`
|
||||
- CrowdsecMode
|
||||
- string
|
||||
- default: `live`, expected values are: `none`, `live`, `stream`, `alone`, `appsec`
|
||||
@@ -396,6 +396,10 @@ Only one instance of the plugin is *possible*.
|
||||
- int64
|
||||
- default: 60
|
||||
- Used only in `stream` mode, the interval between requests to fetch blacklisted IPs from LAPI
|
||||
- UpdateMaxFailure
|
||||
- int64
|
||||
- default: 0
|
||||
- Used only in `stream` and `alone` mode, the maximum number of time we can not reach Crowdsec before blocking traffic (set -1 to never block)
|
||||
- DefaultDecisionSeconds
|
||||
- int64
|
||||
- default: 60
|
||||
@@ -475,6 +479,7 @@ http:
|
||||
enabled: false
|
||||
logLevel: DEBUG
|
||||
updateIntervalSeconds: 60
|
||||
updateMaxFailure: 0
|
||||
defaultDecisionSeconds: 60
|
||||
httpTimeoutSeconds: 10
|
||||
crowdsecMode: live
|
||||
|
||||
+18
-9
@@ -43,6 +43,7 @@ const (
|
||||
var (
|
||||
isStartup = true
|
||||
isCrowdsecStreamHealthy = true
|
||||
updateFailure = 0
|
||||
ticker chan bool
|
||||
)
|
||||
|
||||
@@ -69,6 +70,7 @@ type Bouncer struct {
|
||||
crowdsecPassword string
|
||||
crowdsecScenarios []string
|
||||
updateInterval int64
|
||||
updateMaxFailure int
|
||||
defaultDecisionTimeout int64
|
||||
customHeader string
|
||||
crowdsecStreamRoute string
|
||||
@@ -150,6 +152,7 @@ func New(ctx context.Context, next http.Handler, config *configuration.Config, n
|
||||
crowdsecPassword: config.CrowdsecCapiPassword,
|
||||
crowdsecScenarios: config.CrowdsecCapiScenarios,
|
||||
updateInterval: config.UpdateIntervalSeconds,
|
||||
updateMaxFailure: config.UpdateMaxFailure,
|
||||
customHeader: config.ForwardedHeadersCustomName,
|
||||
defaultDecisionTimeout: config.DefaultDecisionSeconds,
|
||||
banTemplateString: banTemplateString,
|
||||
@@ -282,7 +285,7 @@ func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if isCrowdsecStreamHealthy {
|
||||
handleNextServeHTTP(bouncer, remoteIP, rw, req)
|
||||
} else {
|
||||
bouncer.log.Debug(fmt.Sprintf("ServeHTTP isCrowdsecStreamHealthy:false ip:%s", remoteIP))
|
||||
bouncer.log.Debug(fmt.Sprintf("ServeHTTP isCrowdsecStreamHealthy:false ip:%s updateFailure:%d", remoteIP, updateFailure))
|
||||
handleBanServeHTTP(bouncer, rw)
|
||||
}
|
||||
} else {
|
||||
@@ -324,12 +327,15 @@ type Login struct {
|
||||
Expire string `json:"expire"`
|
||||
}
|
||||
|
||||
// To append Headers we need to call rw.WriteHeader after set any header.
|
||||
func handleBanServeHTTP(bouncer *Bouncer, rw http.ResponseWriter) {
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
if bouncer.banTemplateString != "" {
|
||||
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
fmt.Fprint(rw, bouncer.banTemplateString)
|
||||
if bouncer.banTemplateString == "" {
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
fmt.Fprint(rw, bouncer.banTemplateString)
|
||||
}
|
||||
|
||||
func handleRemediationServeHTTP(bouncer *Bouncer, remoteIP, remediation string, rw http.ResponseWriter, req *http.Request) {
|
||||
@@ -358,10 +364,15 @@ func handleNextServeHTTP(bouncer *Bouncer, remoteIP string, rw http.ResponseWrit
|
||||
|
||||
func handleStreamTicker(bouncer *Bouncer) {
|
||||
if err := handleStreamCache(bouncer); err != nil {
|
||||
isCrowdsecStreamHealthy = false
|
||||
bouncer.log.Error(err.Error())
|
||||
bouncer.log.Debug(fmt.Sprintf("handleStreamTicker updateFailure:%d isCrowdsecStreamHealthy:%t %s", updateFailure, isCrowdsecStreamHealthy, err.Error()))
|
||||
if bouncer.updateMaxFailure != -1 && updateFailure >= bouncer.updateMaxFailure && isCrowdsecStreamHealthy {
|
||||
isCrowdsecStreamHealthy = false
|
||||
bouncer.log.Error(fmt.Sprintf("handleStreamTicker:error updateFailure:%d %s", updateFailure, err.Error()))
|
||||
}
|
||||
updateFailure++
|
||||
} else {
|
||||
isCrowdsecStreamHealthy = true
|
||||
updateFailure = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,7 +468,6 @@ func getToken(bouncer *Bouncer) error {
|
||||
var login Login
|
||||
err = json.Unmarshal(body, &login)
|
||||
if err != nil {
|
||||
isCrowdsecStreamHealthy = false
|
||||
return fmt.Errorf("getToken:parsingBody %w", err)
|
||||
}
|
||||
if login.Code == 200 && len(login.Token) > 0 {
|
||||
@@ -516,7 +526,6 @@ func handleStreamCache(bouncer *Bouncer) error {
|
||||
bouncer.cacheClient.Delete(decision.Value)
|
||||
}
|
||||
bouncer.log.Debug("handleStreamCache:updated")
|
||||
isCrowdsecStreamHealthy = true
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.11.0"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -49,14 +49,15 @@ services:
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.enabled=true"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.loglevel=DEBUG"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecappsecenabled=true"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecmode=stream"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseclapikey=40796d93c2958f9e58345514e67740e5="
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.6.0
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
COLLECTIONS: crowdsecurity/traefik crowdsecurity/appsec-virtual-patching
|
||||
COLLECTIONS: crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules
|
||||
CUSTOM_HOSTNAME: crowdsec
|
||||
BOUNCER_KEY_TRAEFIK: 40796d93c2958f9e58345514e67740e5=
|
||||
volumes:
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.11.0"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -12,7 +12,7 @@ services:
|
||||
- "--entrypoints.web.address=:80"
|
||||
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0-beta3"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0"
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
# - './ban.html:/ban.html:ro'
|
||||
@@ -59,11 +59,11 @@ services:
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.forwardedheaderstrustedips=172.21.0.5"
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.6.0
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
COLLECTIONS: crowdsecurity/traefik
|
||||
COLLECTIONS: crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules
|
||||
CUSTOM_HOSTNAME: crowdsec
|
||||
# We need to register one api key per service we will use
|
||||
BOUNCER_KEY_TRAEFIK: FIXME-LAPI-KEY-1=
|
||||
|
||||
@@ -2,7 +2,7 @@ version: "3.8"
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.10.7"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -15,12 +15,12 @@ services:
|
||||
- "--entrypoints.web.address=:80"
|
||||
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.2.0"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0"
|
||||
# - "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- logs-appsec-enabled:/var/log/traefik
|
||||
- ./../../:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
# - ./../../:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
ports:
|
||||
- 8000:80
|
||||
- 8080:8080
|
||||
@@ -51,11 +51,11 @@ services:
|
||||
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.6.0
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
COLLECTIONS: crowdsecurity/traefik
|
||||
COLLECTIONS: crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules
|
||||
CUSTOM_HOSTNAME: crowdsec
|
||||
BOUNCER_KEY_TRAEFIK_DEV: 40796d93c2958f9e58345514e67740e5
|
||||
volumes:
|
||||
|
||||
+6
-8
@@ -1,8 +1,6 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
cloudflare:
|
||||
image: "traefik:v2.10.4"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "cloudflare"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -21,7 +19,7 @@ services:
|
||||
- 8080:8080
|
||||
|
||||
traefik:
|
||||
image: "traefik:v2.10.4"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -35,7 +33,7 @@ services:
|
||||
- "--entrypoints.web.forwardedheaders.trustedips=172.21.0.5"
|
||||
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.1.13"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- logs-traefik:/var/log/traefik
|
||||
@@ -47,7 +45,7 @@ services:
|
||||
|
||||
whoami-foo:
|
||||
image: traefik/whoami
|
||||
container_name: "simple-service-foo"
|
||||
container_name: "simple-service-foo-cloudflare"
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
@@ -66,7 +64,7 @@ services:
|
||||
|
||||
whoami-bar:
|
||||
image: traefik/whoami
|
||||
container_name: "simple-service-bar"
|
||||
container_name: "simple-service-bar-cloudflare"
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
@@ -81,7 +79,7 @@ services:
|
||||
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.5.2
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt-get update && sudo apt-get install wget -y
|
||||
# DEBIAN_FRONTEND=noninteractive sudo apt-get upgrade -y --assume-yes
|
||||
wget -O traefik.tar.gz "https://github.com/traefik/traefik/releases/download/v2.10.4/traefik_v2.10.4_linux_amd64.tar.gz"
|
||||
wget -O traefik.tar.gz "https://github.com/traefik/traefik/releases/download/v3.0.0/traefik_v3.0.0_linux_amd64.tar.gz"
|
||||
tar -zxvf traefik.tar.gz
|
||||
# inspired from https://gist.github.com/ubergesundheit/7c9d875befc2d7bfd0bf43d8b3862d85
|
||||
sudo mv ./traefik /usr/local/bin/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt-get update && apt-get install wget -y
|
||||
wget -O whoami.tar.gz "https://github.com/traefik/whoami/releases/download/v1.9.0/whoami_v1.9.0_linux_amd64.tar.gz"
|
||||
wget -O whoami.tar.gz "https://github.com/traefik/whoami/releases/download/v1.10.1/whoami_v1.10.1_linux_amd64.tar.gz"
|
||||
tar -zxvf whoami.tar.gz
|
||||
# inspired from https://gist.github.com/ubergesundheit/7c9d875befc2d7bfd0bf43d8b3862d85
|
||||
sudo mv ./whoami /usr/local/bin/
|
||||
|
||||
@@ -32,7 +32,7 @@ It is not directly accessible from Traefik even when importing the plugin, so [d
|
||||
```yaml
|
||||
...
|
||||
traefik:
|
||||
image: "traefik:v2.11.0"
|
||||
image: "traefik:v3.0.0"
|
||||
volumes:
|
||||
- './captcha.html:/captcha.html'
|
||||
...
|
||||
@@ -52,7 +52,7 @@ More information is available on configuring Crowdsec in the [official documenta
|
||||
```yaml
|
||||
...
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.6.0
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
volumes:
|
||||
# For captcha and ban mixed decision
|
||||
- './profiles.yaml:/etc/crowdsec/profiles.yaml:ro'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.11.0"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -12,14 +12,14 @@ services:
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
|
||||
# - "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
# - "--experimental.plugins.bouncer.version=v1.2.0"
|
||||
- "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0"
|
||||
# - "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- logs-captcha-enabled:/var/log/traefik
|
||||
- './captcha.html:/captcha.html'
|
||||
- ./../../:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
# - ./../../:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
ports:
|
||||
- 8000:80
|
||||
- 8080:8080
|
||||
@@ -55,7 +55,7 @@ services:
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.captchaHTMLFilePath=/captcha.html"
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.6.0
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.11.0"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -12,14 +12,14 @@ services:
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
|
||||
# - "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
# - "--experimental.plugins.bouncer.version=v1.3.0-beta3"
|
||||
- "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0"
|
||||
# - "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- logs-custom-ban-page-enabled:/var/log/traefik
|
||||
- './ban.html:/ban.html'
|
||||
- ./../../:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
# - ./../../:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
ports:
|
||||
- 8000:80
|
||||
- 8080:8080
|
||||
@@ -46,7 +46,7 @@ services:
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.banHtmlFilePath=/ban.html"
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.6.0
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
|
||||
@@ -32,13 +32,15 @@ minikube start
|
||||
helm repo add traefik https://traefik.github.io/charts
|
||||
helm repo update
|
||||
kubectl create ns traefik
|
||||
helm upgrade --version v26.1.0 --install --namespace=traefik \
|
||||
helm upgrade --version v28.0.0 --install --namespace=traefik \
|
||||
--values=./traefik/values.yml \
|
||||
traefik traefik/traefik
|
||||
```
|
||||
|
||||
_A [bug](https://github.com/traefik/traefik-helm-chart/commit/e7ce1b410c858642069033305eb6362f26689f16) has been fixed in chart 26.1.0 that could prevent plugin to be loaded_
|
||||
|
||||
_v28.0.0 of the Traefik helm chart is only compatible with v3 of Traefik_
|
||||
|
||||
#### View the Traefik dashboard
|
||||
|
||||
> Port forward the dashboard:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
image:
|
||||
tag: v1.6.0
|
||||
tag: v1.6.1-2
|
||||
|
||||
agent:
|
||||
acquisition:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# dashboard.yaml
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: dashboard
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: bouncer
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
image:
|
||||
tag: v2.11
|
||||
tag: v3.0.0
|
||||
|
||||
logs:
|
||||
general:
|
||||
@@ -14,4 +14,4 @@ experimental:
|
||||
plugins:
|
||||
bouncer:
|
||||
moduleName: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
version: "v1.2.0"
|
||||
version: "v1.3.0"
|
||||
|
||||
+4
-6
@@ -1,8 +1,6 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.10.4"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -15,7 +13,7 @@ services:
|
||||
- "--entrypoints.web.address=:80"
|
||||
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.1.13"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0"
|
||||
# - "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
@@ -52,7 +50,7 @@ services:
|
||||
|
||||
whoami-redis-secure:
|
||||
image: traefik/whoami
|
||||
container_name: "simple-service-bar"
|
||||
container_name: "simple-service-bar-redis"
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
@@ -73,7 +71,7 @@ services:
|
||||
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.5.2
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
+7
-9
@@ -1,8 +1,6 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.10.4"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -15,16 +13,18 @@ services:
|
||||
- "--entrypoints.web.address=:80"
|
||||
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.1.13"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0"
|
||||
# - "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
# - ./../../:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
ports:
|
||||
- 80:80
|
||||
- 8080:8080
|
||||
|
||||
whoami-foo:
|
||||
image: traefik/whoami
|
||||
container_name: "simple-service-foo"
|
||||
container_name: "simple-service-foo-alone"
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
@@ -37,9 +37,7 @@ services:
|
||||
# - "traefik.http.middlewares.crowdsec.plugin.bouncer.loglevel=DEBUG"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecmode=alone"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseclapikey=40796d93c2958f9e58345514e67740e5"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.CrowdsecCapiMachineId=logincacacalfkrjebfreifgzfblezgyfoerxsqxsqxsqxsr"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.CrowdsecCapiPassword=Password2"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.CrowdsecCapiMachineId=FIXME"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.CrowdsecCapiPassword=FIXME"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseccapiscenarios=crowdsecurity/sshd,crowdsecurity/asterisk_bf,crowdsecurity/asterisk_user_enum,crowdsecurity/base-http-scenarios"
|
||||
|
||||
volumes:
|
||||
logs-local:
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:22.04
|
||||
FROM ubuntu:24.04
|
||||
|
||||
RUN apt-get update && apt-get install -y curl wget
|
||||
RUN VERSION=$(curl --silent "https://api.github.com/repos/cloudflare/cfssl/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') && VNUMBER=${VERSION#"v"} && wget https://github.com/cloudflare/cfssl/releases/download/${VERSION}/cfssl_${VNUMBER}_linux_amd64 -O cfssl && chmod +x cfssl && mv cfssl /usr/local/bin
|
||||
|
||||
@@ -72,11 +72,11 @@ The service `whoami-bar` will authenticate with a **client certificate** signed
|
||||
|
||||
Access to a route that communicate via https and authenticate with API-key:
|
||||
```
|
||||
curl http://localhost:80/foo
|
||||
curl http://localhost:8000/foo
|
||||
```
|
||||
Access to a route that communicate via https and authenticate with a client certificate:
|
||||
```
|
||||
curl http://localhost:80/bar
|
||||
curl http://localhost:8000/bar
|
||||
```
|
||||
Access to the traefik dashboard
|
||||
```
|
||||
@@ -89,5 +89,4 @@ make run_tlsauth
|
||||
```
|
||||
|
||||
Note:
|
||||
> This example is still in Beta and use a new version of Crowdsec (v1.4.3) at time of writing
|
||||
A functionnality has been disabled in Crowdsec in order to make the example work DISABLE_AGENT: "true"
|
||||
> Traefik need to be restart if certificates are regenerated after his launch
|
||||
+12
-9
@@ -1,8 +1,6 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.10.4"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -15,7 +13,7 @@ services:
|
||||
- "--entrypoints.web.address=:80"
|
||||
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.1.13"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0"
|
||||
# - "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
@@ -25,10 +23,11 @@ services:
|
||||
# - ./../../:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
|
||||
ports:
|
||||
- 80:80
|
||||
- 8000:80
|
||||
- 8080:8080
|
||||
depends_on:
|
||||
- crowdsec
|
||||
- gencert
|
||||
|
||||
# Use HTTPS scheme but with lapikey authentication
|
||||
# whoami-foo:
|
||||
@@ -63,10 +62,10 @@ services:
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseclapischeme=https"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecLapiTLSCertificateAuthorityFile=/etc/traefik/crowdsec-certs/inter.pem"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecLapiTLSCertificateBouncerFile=/etc/traefik/crowdsec-certs/bouncer.pem"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecLapiTLSCertificateBouncerKeyFile=/etc/traefik/crowdsec-certs/bouncer-key.pem"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecLapiTLSCertificateBouncerKeyFile=/etc/traefik/crowdsec-certs/bouncer-key.pem"
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.5.2
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
@@ -80,11 +79,13 @@ services:
|
||||
CERT_FILE: "/etc/crowdsec/certs/server.pem"
|
||||
KEY_FILE: "/etc/crowdsec/certs/server-key.pem"
|
||||
CACERT_FILE: "/etc/crowdsec/certs/inter.pem"
|
||||
# CLIENT_CERT_FILE: "/etc/crowdsec/certs/bouncer.pem"
|
||||
# CLIENT_CERT_FILE: "/etc/crowdsec/certs/bouncer.pem"
|
||||
AGENTS_ALLOWED_OU: "agent-ou"
|
||||
BOUNCERS_ALLOWED_OU: "bouncer-ou"
|
||||
LEVEL_DEBUG: "true"
|
||||
# Disabled because it restart in loop otherwise
|
||||
DISABLE_AGENT: "true"
|
||||
# DISABLE_AGENT: "true"
|
||||
# Disabled for the examples
|
||||
DISABLE_ONLINE_API: "true"
|
||||
volumes:
|
||||
@@ -97,7 +98,9 @@ services:
|
||||
- crowdsec-config-tls-auth:/etc/crowdsec/
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
|
||||
depends_on:
|
||||
- gencert
|
||||
|
||||
gencert:
|
||||
build: .
|
||||
volumes:
|
||||
+5
-7
@@ -1,8 +1,6 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.10.4"
|
||||
image: "traefik:v3.0.0"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
@@ -15,7 +13,7 @@ services:
|
||||
- "--entrypoints.web.address=:80"
|
||||
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.1.13"
|
||||
- "--experimental.plugins.bouncer.version=v1.3.0"
|
||||
# - "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
@@ -29,7 +27,7 @@ services:
|
||||
|
||||
whoami1:
|
||||
image: traefik/whoami
|
||||
container_name: "simple-service-foo"
|
||||
container_name: "simple-service-foo-trustedips"
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
@@ -48,7 +46,7 @@ services:
|
||||
|
||||
whoami2:
|
||||
image: traefik/whoami
|
||||
container_name: "simple-service-bar"
|
||||
container_name: "simple-service-bar-trustedips"
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
@@ -67,7 +65,7 @@ services:
|
||||
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.5.2
|
||||
image: crowdsecurity/crowdsec:v1.6.1-2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
@@ -86,6 +86,8 @@ func (c *Client) ServeHTTP(rw http.ResponseWriter, r *http.Request, remoteIP str
|
||||
http.Redirect(rw, r, r.URL.String(), http.StatusFound)
|
||||
return
|
||||
}
|
||||
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
err = c.captchaTemplate.Execute(rw, map[string]string{
|
||||
"SiteKey": c.siteKey,
|
||||
"FrontendJS": captcha[c.provider].js,
|
||||
|
||||
@@ -57,6 +57,7 @@ type Config struct {
|
||||
CrowdsecCapiPasswordFile string `json:"crowdsecCapiPasswordFile,omitempty"`
|
||||
CrowdsecCapiScenarios []string `json:"crowdsecCapiScenarios,omitempty"`
|
||||
UpdateIntervalSeconds int64 `json:"updateIntervalSeconds,omitempty"`
|
||||
UpdateMaxFailure int `json:"updateMaxFailure,omitempty"`
|
||||
DefaultDecisionSeconds int64 `json:"defaultDecisionSeconds,omitempty"`
|
||||
HTTPTimeoutSeconds int64 `json:"httpTimeoutSeconds,omitempty"`
|
||||
ForwardedHeadersCustomName string `json:"forwardedHeadersCustomName,omitempty"`
|
||||
@@ -100,6 +101,7 @@ func New() *Config {
|
||||
CrowdsecLapiKey: "",
|
||||
CrowdsecLapiTLSInsecureVerify: false,
|
||||
UpdateIntervalSeconds: 60,
|
||||
UpdateMaxFailure: 0,
|
||||
DefaultDecisionSeconds: 60,
|
||||
HTTPTimeoutSeconds: 10,
|
||||
CaptchaProvider: "",
|
||||
@@ -318,6 +320,10 @@ func validateParamsRequired(config *Config) error {
|
||||
return fmt.Errorf("%v: cannot be less than 1", key)
|
||||
}
|
||||
}
|
||||
if config.UpdateMaxFailure < -1 {
|
||||
return fmt.Errorf("UpdateMaxFailure: cannot be less than -1")
|
||||
}
|
||||
|
||||
if !contains([]string{NoneMode, LiveMode, StreamMode, AloneMode, AppsecMode}, config.CrowdsecMode) {
|
||||
return fmt.Errorf("CrowdsecMode: must be one of 'none', 'live', 'stream', 'alone' or 'appsec'")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user