This commit is contained in:
2025-07-05 15:05:44 -03:00
parent f63e476946
commit a11b851492
8 changed files with 288 additions and 0 deletions

1
.env.example Normal file
View File

@@ -0,0 +1 @@
CF_DNS_API_TOKEN=""

28
compose.yml Normal file
View File

@@ -0,0 +1,28 @@
---
services:
traefik:
image: docker.io/library/traefik:v3.4.3
container_name: traefik
ports:
- 80:80
- 443:443
volumes:
- /run/docker.sock:/run/docker.sock:ro
- ./config/:/etc/traefik/
- ./certs/:/var/traefik/certs/:rw
- traefik_logs1:/var/log/traefik
environment:
- CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
networks:
- proxy
- crowd1
restart: unless-stopped
volumes:
traefik_logs1:
networks:
proxy:
external: true # <-- (Optional) Change this to false if you want to create a new network
crowd1:
external: true

88
config/dynamic.yml Normal file
View File

@@ -0,0 +1,88 @@
# traefik/config/dynamic.yml
http:
middlewares:
secureHeaders:
headers:
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
accessControlMaxAge: 100
hostsProxyHeaders:
- "X-Forwarded-Host"
referrerPolicy: "same-origin"
sslRedirect: true
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: true
forceSTSHeader: true
contentTypeNosniff: true
browserXssFilter: true
customFrameOptionsValue: SAMEORIGIN
# Argentina + VPS
ar-only:
plugin:
geoblock:
allowedIPAddresses:
# - VPS IP # If isnt on your country.
countries:
- AR # your country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
silentStartUp: true
allowLocalRequests: true
logLocalRequests: true
logAllowedRequests: false
logApiRequests: false
api: "https://get.geojs.io/v1/ip/country/{ip}"
apiTimeoutMs: 500
cacheSize: 25
forceMonthlyUpdate: true
allowUnknownCountries: false
unknownCountryApiResponse: "nil"
crowdsec:
plugin:
bouncer:
enabled: true
logLevel: INFO
updateIntervalSeconds: 15
updateMaxFailure: 0
defaultDecisionSeconds: 15
httpTimeoutSeconds: 10
crowdsecMode: stream
crowdsecAppsecEnabled: true
crowdsecAppsecHost: crowdsec:7422
crowdsecAppsecFailureBlock: true
crowdsecAppsecUnreachableBlock: true
crowdsecLapiKey: ##REPLACE_API_KEY## # Replace CrowdSec API key (docker exec crowdsec cscli bouncers add crowdsecBouncer)
# crowdsecLapiKeyFile: /etc/traefik/cs-privateKey-foo
crowdsecLapiHost: crowdsec:8080
crowdsecLapiScheme: http
forwardedHeadersTrustedIPs:
# - YOUR.VPS.IP # Reverse Proxy IP address
clientTrustedIPs:
- 10.0.0.216/24 # Internal LAN IP addresses
default-whitelist:
IPAllowList:
sourceRange:
- "10.0.0.0/24"
secured:
chain:
middlewares:
- crowdsec
- default-whitelist
- secureHeaders
tls:
options:
default:
minVersion: "VersionTLS12"
maxVersion: "VersionTLS13"
cipherSuites:
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
curvePreferences:
- CurveP521
- CurveP384

88
config/traefik.yml Normal file
View File

@@ -0,0 +1,88 @@
---
global:
checkNewVersion: false
sendAnonymousUsage: true
# --> (Optional) Change log level and format here
# - level: [TRACE, DEBUG, INFO, WARN, ERROR, FATAL]
#log:
# level: DEBUG
# <--
# --> (Optional) Enable accesslog here
#accessLog:
# <--
api:
dashboard: false
insecure: false
# -- Change EntryPoints here
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
# <--
websecure:
address: :443
http:
# middlewares:
# - "crowdsec@file"
tls:
options: default
# <--
# -- Configure your CertificateResolver here
certificatesResolvers:
cloudflare:
acme:
tlsChallenge: {}
email: mail@domain.com # <-- Change this to your email
storage: /var/traefik/certs/cloudflare-acme.json
caServer: "https://acme-v02.api.letsencrypt.org/directory"
dnsChallenge:
provider: cloudflare # <-- (Optional) Change this to your DNS provider
delayBeforeCheck: 0
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
# <--
# --> Log for crowdsec
log:
level: "INFO"
filePath: "/var/log/traefik/traefik.log"
accessLog:
filePath: "/var/log/traefik/access.log"
# <--
# --> (Optional) Disable TLS Cert verification check
# serversTransport:
# insecureSkipVerify: true
# <--
# --> Providers
providers:
docker:
exposedByDefault: false # <-- (Optional) Change this to true if you want to expose all services
# Specify discovery network - This ensures correct name resolving and possible issues with containers, that are in multiple networks.
# E.g. Database container in a separate network and a container in the frontend and database network.
network:
- proxy
file:
directory: /etc/traefik
watch: true
experimental:
plugins:
geoblock:
moduleName: "github.com/PascalMinder/geoblock"
version: "v0.3.3"
bouncer:
moduleName: "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
version: "v1.4.4"
# <--

27
crowdsec/compose.yml Normal file
View File

@@ -0,0 +1,27 @@
# https://github.com/TechnoBoom/YT-Files/blob/master/IDS-IPS-Crowdsec-Traefik/README.md
# https://www.youtube.com/watch?v=rkYrpzHakj8
services:
crowdsec:
image: crowdsecurity/crowdsec:latest
container_name: crowdsec
environment:
GID: "${GID-1001}" # with `id -g` you can get your GID
COLLECTIONS: "crowdsecurity/linux crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules"
volumes:
- ./config/acquis.yaml:/etc/crowdsec/acquis.yaml
- crowdsec-db:/var/lib/crowdsec/data/
- crowdsec-config:/etc/crowdsec/
- traefik_traefik_logs1:/var/log/traefik/:ro
networks:
- crowd1 # internal crowdsec + traefik network
restart: unless-stopped
networks:
crowd1:
external: true
volumes:
crowdsec-db:
crowdsec-config:
traefik_traefik_logs1:
external: true

View File

@@ -0,0 +1,13 @@
filenames:
- /var/log/traefik/*
labels:
type: traefik
---
listen_addr: 0.0.0.0:7422
appsec_config: crowdsecurity/virtual-patching
name: myAppSecComponent
source: appsec
labels:
type: appsec

20
labels.yml Normal file
View File

@@ -0,0 +1,20 @@
labels:
# Basic routing
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.rule=Host(`app.domain.xyz`)"
- "traefik.http.routers.app.tls=true"
- "traefik.http.routers.app.tls.certresolver=cloudflare"
- "traefik.http.routers.app.middlewares=secureHeaders"
- "traefik.http.routers.app.middlewares=crowdsec@file"
# Custom port (if not 80)
- "traefik.http.services.app.loadbalancer.server.port=3000"
# Multiple domains
- "traefik.http.routers.app.rule=Host(`app.domain.xyz`) || Host(`www.app.domain.xyz`)"
# Path-based routing
- "traefik.http.routers.app.rule=Host(`domain.xyz`) && PathPrefix(`/app`)"
# For Argentina-only apps
- "traefik.http.routers.app.middlewares=ar-only@file"

23
whoami.yml Normal file
View File

@@ -0,0 +1,23 @@
services:
whoami:
image: traefik/whoami
container_name: whoami
restart: unless-stopped
networks:
- proxy
labels:
# Basic routing
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.rule=Host(`app.domain.xyz`)"
- "traefik.http.routers.app.tls=true"
- "traefik.http.routers.app.tls.certresolver=cloudflare"
- "traefik.http.routers.app.middlewares=secureHeaders"
- "traefik.http.routers.app.middlewares=crowdsec@file"
# For Argentina-only apps
- "traefik.http.routers.app.middlewares=ar-only@file"
networks:
proxy:
external: true