commit 591667f0f737bffe2f5d8675da2df3e9d978a464 Author: Gbanyan Date: Wed Apr 16 16:01:11 2025 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2711d48 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +certs + +# Ignore log files +logs/*.log +*.log +# Ignore acme.json (contains sensitive certificate data) +acme.json + +# Ignore Docker-related files +docker-compose.override.yml + +# Ignore temporary files +*.tmp +*.swp +*.bak + +# Ignore node_modules if using Node.js in this folder +node_modules/ + +# Ignore environment files +.env +.env.* + +# Ignore backup files +*.~* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..73a7136 --- /dev/null +++ b/README.md @@ -0,0 +1,79 @@ +# GB Traefik Setup + +This repository contains the configuration files and setup instructions for deploying [Traefik](https://traefik.io/), a modern reverse proxy and load balancer. + +Configuration files is customized for Gbanyan personal usage. + +## Prerequisites + +- Docker installed on your system +- Docker Compose (if using `docker-compose.yml`) + +## Getting Started + +1. Clone this repository: + ```bash + git clone https://gitea.gbanyan.net/gbanyan/GB-Traefik.git + cd GB-Traefik + ``` + +2. Update the `traefik.yml` and `docker-compose.yml` files as needed for your environment. + +3. Start Traefik: + ```bash + docker compose up -d + ``` + +4. Access the Traefik dashboard (if enabled) at `http://:8080`. + +## Configuration + +- **.env**: Cloudflare E-mail and API Token for SSL DNS Challenge +- **Traefik Configuration**: Modify `traefik.yml`, `dynamic.yml` to customize Traefik's behavior. +- **Docker Compose**: Use `docker-compose.yml` to define services and networks. + + +## Detail: + +My traefik is split into internal and external entrypoint. + +Internal entrypoint is for private and secure service without exposing. + +Each entrypoint is bind to different ip address for isolation. + +Then, other docker service is attached to different entrypoin guided by label in docker compose + +```yaml +label: + - "traefik.http.routers.service-name.entrypoints=websecure" +``` + +Besides the entrypoint setup, I add cloudflare proxy, crowdsec-bouncer, compression with brotli middlrewares method in traefik.yml and dynamic.yml + +Adding middlewares is also guided by labels: + +```yaml +label: + - "traefik.http.routers.service-name.middlewares=cloudflarewarp@file,crowdsec@file,compress-middleware@file" +``` + +The order of middlewares is meaningful. + +Traefik has ability to auto apply SSL certs. +Just offer the required DNS API authentication (Like cloudflare). + +Please refer the traefik documentation. + +The following is an example of a docker service I hosted in its docker-compose.yaml: + +```yaml +labels: + - "traefik.enable=true" + - "traefik.http.routers.ghost.entrypoints=websecure" + - "traefik.http.routers.ghost.rule=Host(`blog.gbanyan.net`)" + - "traefik.http.services.ghost.loadbalancer.server.port=2368" + - "traefik.http.routers.ghost.tls.certresolver=letsencrypt" + - "traefik.http.routers.ghost.middlewares=cloudflarewarp@file,crowdsec@file,compress-middleware@file" + - "com.centurylinklabs.watchtower.enable=true" + - "traefik.docker.network=traefik_default" +``` \ No newline at end of file diff --git a/access.log.1.gz b/access.log.1.gz new file mode 100755 index 0000000..cf4afd9 Binary files /dev/null and b/access.log.1.gz differ diff --git a/access.log.2.gz b/access.log.2.gz new file mode 100755 index 0000000..af20683 Binary files /dev/null and b/access.log.2.gz differ diff --git a/access.log.3.gz b/access.log.3.gz new file mode 100755 index 0000000..9381d05 Binary files /dev/null and b/access.log.3.gz differ diff --git a/access.log.4.gz b/access.log.4.gz new file mode 100755 index 0000000..c942658 Binary files /dev/null and b/access.log.4.gz differ diff --git a/access.log.5.gz b/access.log.5.gz new file mode 100755 index 0000000..c88fc46 Binary files /dev/null and b/access.log.5.gz differ diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..d7e4003 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,41 @@ +services: + traefik: + image: traefik:latest + container_name: traefik + network_mode: host + # ports: + # - 10.0.0.225:80:80 + # - 10.0.0.225:443:443 + # - 192.168.50.4:8080:8080 + # - 192.168.50.4:80:80 + # - 192.168.50.4:443:443 # Added port mapping for the dashboard + restart: unless-stopped + environment: + - CLOUDFLARE_EMAIL=${CLOUDFLARE_EMAIL} + - CLOUDFLARE_DNS_API_TOKEN=${CLOUDFLARE_DNS_API_TOKEN} + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./certs:/letsencrypt + #- ./dashboard_authfile:/dashboard_authfile:ro + - ./dynamic.yml:/dynamic.yml + - ./traefik.yml:/traefik.yml + - ./traefik.log:/var/log/traefik/traefik.log + - ./access.log:/var/log/traefik/access.log + # networks: + # - traefik_default + # - internal_traefik_default + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.rule=Host(`traefik.gbanyan.net`)" + - "traefik.http.routers.traefik.entrypoints=internal_websecure" + - "traefik.http.routers.traefik.tls.certresolver=letsencrypt" + - "traefik.http.routers.traefik.service=api@internal" + - "com.centurylinklabs.watchtower.enable=true" # Added label for Watchtower + # "traefik.http.middlewares.auth.basicauth.usersfile=/dashboard_authfile" + - "traefik.http.services.traefik.loadbalancer.server.port=8080" + +# networks: +# traefik_default: +# external: true +# internal_traefik_default: +# external: true diff --git a/dynamic.yml b/dynamic.yml new file mode 100644 index 0000000..114e507 --- /dev/null +++ b/dynamic.yml @@ -0,0 +1,47 @@ +http: + middlewares: + block-ip-access: + headers: + customRequestHeaders: + Host: "" # This will catch requests with no Host header or invalid ones + cloudflarewarp: + plugin: + cloudflare: + trustedCIDRs: [] + overwriteRequestHeader: true + debug: true + crowdsec: + plugin: + bouncer: + enabled: true + crowdsecMode: stream + crowdsecLapiHost: "localhost:8080" + crowdsecLapiKey: gFJjSzdbB0GCe/1Y9HcxMPP1vQmoa4psZOFyleJZJVQ + compress-middleware: + compress: + encodings: + - br + - gzip + defaultEncoding: br + routers: + block-direct-access: + rule: "HostRegexp(`{host:.+}`)" # Matches any host + service: noop@internal + priority: 1 # Low priority to catch unmatched requests + entryPoints: + - web + - websecure + middlewares: + - block-ip-access + netdata: + rule: Host(`netdata.gbanyan.net`) + service: netdata + entryPoints: ["internal_websecure"] + tls: + certResolver: letsencrypt + + services: + netdata: + loadBalancer: + servers: + - url: "http://127.0.0.1:19999" diff --git a/traefik.yml b/traefik.yml new file mode 100644 index 0000000..605d772 --- /dev/null +++ b/traefik.yml @@ -0,0 +1,103 @@ +## STATIC CONFIGURATION + +log: + level: "DEBUG" + filePath: "/var/log/traefik/traefik.log" +accessLog: + filePath: "/var/log/traefik/access.log" + filters: + statusCodes: + - "200-299" # log successful http requests + - "400-599" # log failed http requests + +api: + insecure: false + dashboard: true + +entryPoints: + web: + address: "10.0.0.225:80" + forwardedHeaders: + trustedIPs: &trustedIps + # Start of Cloudlare's public IP list + - 103.21.244.0/22 + - 103.22.200.0/22 + - 103.31.4.0/22 + - 104.16.0.0/13 + - 104.24.0.0/14 + - 108.162.192.0/18 + - 131.0.72.0/22 + - 141.101.64.0/18 + - 162.158.0.0/15 + - 172.64.0.0/13 + - 173.245.48.0/20 + - 188.114.96.0/20 + - 190.93.240.0/20 + - 197.234.240.0/22 + - 198.41.128.0/17 + - 2400:cb00::/32 + - 2606:4700::/32 + - 2803:f800::/32 + - 2405:b500::/32 + - 2405:8100::/32 + - 2a06:98c0::/29 + - 2c0f:f248::/32 + # End of Cloudlare's public IP list + http: + redirections: # HTTPS redirection (80 to 443) + entryPoint: + to: "websecure" # The target element + scheme: "https" + websecure: + address: "10.0.0.225:443" + forwardedHeaders: + # Reuse the list of Cloudflare's public IPs from above + trustedIPs: *trustedIps + http3: {} + internal_web: + address: "192.168.50.4:80" + http: + redirections: # HTTPS redirection (80 to 443) + entryPoint: + to: "internal_websecure" # The target element + scheme: "https" + internal_websecure: + address: "192.168.50.4:443" + http3: {} + metrics: + address: "127.0.0.1:8082" + +global: + checknewversion: false # Periodically check if a new version has been released. + sendanonymoususage: false # Periodically send anonymous usage statistics. + +providers: + docker: + exposedByDefault: false +# network: traefik_default # Ensure this matches the Docker network + file: + filename: "/dynamic.yml" # Enable dynamic configuration file +certificatesResolvers: + letsencrypt: + acme: + email: gbanyan.huang@gmail.com + storage: /letsencrypt/acme.json + dnsChallenge: + provider: cloudflare + resolvers: + - "1.1.1.1:53" + - "8.8.8.8:53" +# caServer: "https://acme-staging.api.letsencrypt.org/directory" + +metrics: + prometheus: + entryPoint: metrics + +experimental: + plugins: + cloudflare: + moduleName: github.com/agence-gaya/traefik-plugin-cloudflare + version: v1.2.0 + bouncer: + moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin + version: v1.4.2