diff --git a/README.md b/README.md index 6582acd..4f75520 100644 --- a/README.md +++ b/README.md @@ -25,24 +25,26 @@ The stacks here produce: ## Networks -To use both Traefik instances you will need to create two, [externally-managed](https://docs.docker.com/reference/cli/docker/network/create/) docker networks. One for each Traefik instance in order to [separate internal and external services.](https://blog.foxxmd.dev/posts/migrating-to-traefik/#separating-internalexternal-services) +Read more about [user-defined](https://blog.foxxmd.dev/posts/migrating-to-traefik/#user-defined-vs-default-bridge-networking) and [overlay networks](https://blog.foxxmd.dev/posts/migrating-to-traefik/#swarm-and-overlay) in the blog post. + +To use both Traefik instances you will need to create two, [user-defined](https://blog.foxxmd.dev/posts/migrating-to-traefik/#user-defined-vs-default-bridge-networking) docker networks. One for each Traefik instance in order to [separate internal and external services.](https://blog.foxxmd.dev/posts/migrating-to-traefik/#separating-internalexternal-services) If you have multiple machines running Docker and want to route traffic to all of them I would **highly recommend** setting up [Docker Swarm and using Overlay networks](https://blog.foxxmd.dev/posts/migrating-to-traefik/#swarm-and-overlay) for this (it's easy and zero cost to your existing setup!) ```shell -docker network create --driver=overlay --attachable internal_overlay +docker network create --driver=overlay --attachable internal_web ``` ```shell -docker network create --driver=overlay --attachable --subnet=10.99.0.0/24 public_overlay +docker network create --driver=overlay --attachable --subnet=10.99.0.0/24 public_web ``` If you are not using overlay networks then replace `overlay` with `bridge`. -While not *necessary* you should also create two more [externally-managed](https://docs.docker.com/reference/cli/docker/network/create/) docker networks for use with traefik-kop and crowdsec. These make hostname resolution easier and are used in the example stacks. If you do not want to use them then environmental variables referencing hostnames using these networks can be replaced with HOST:IP and the network can be commented out where found in stacks. +While not *necessary* you should also create two more user-defined docker networks for use with traefik-kop and crowdsec. These make hostname resolution easier and are used in the example stacks. If you do not want to use them then environmental variables referencing hostnames using these networks can be replaced with HOST:IP and the network can be commented out where found in stacks. ```shell -docker network create --driver=overlay --internal --attachable kop_overlay -docker network create --driver=overlay --internal --attachable crowdsec_overlay +docker network create --driver=overlay --internal --attachable kop_net +docker network create --driver=overlay --internal --attachable crowdsec_net ``` ## DNS diff --git a/authentik/.env.example b/authentik/.env.example index 715208b..cc5d3dc 100644 --- a/authentik/.env.example +++ b/authentik/.env.example @@ -1,5 +1,5 @@ AUTHENTIK_TAG=2025.2 -PG_PASS=[[AUTHENTIK_PG_PASS]] -AUTHENTIK_SECRET_KEY=[[AUTHENTIK_SECRET_KEY]] -AUTHENTIK_TRAEFIK_OUTPUT_TOKEN=[[AUTHENTIK_TRAEFIK_OUTPUT_TOKEN]] -AUTHENTIK_TRAEFIK_EXT_OUTPOST_TOKEN=[[AUTHENTIK_TRAEFIK_EXT_OUTPOST_TOKEN]] +PG_PASS=[[CHANGEME_AUTHENTIK_PG_PASS]] +AUTHENTIK_SECRET_KEY=[[CHANGEME_AUTHENTIK_SECRET_KEY]] +AUTHENTIK_TRAEFIK_OUTPUT_TOKEN=[[CHANGEME_AUTHENTIK_TRAEFIK_OUTPUT_TOKEN]] +AUTHENTIK_TRAEFIK_EXT_OUTPOST_TOKEN=[[CHANGEME_AUTHENTIK_TRAEFIK_EXT_OUTPOST_TOKEN]] diff --git a/authentik/compose.yaml b/authentik/compose.yaml index 100a5f0..78f908c 100644 --- a/authentik/compose.yaml +++ b/authentik/compose.yaml @@ -34,7 +34,7 @@ services: networks: - default authentik-server: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.5} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG} restart: unless-stopped command: server environment: @@ -53,7 +53,7 @@ services: # - "${COMPOSE_PORT_HTTP:-9000}:9000" # - "${COMPOSE_PORT_HTTPS:-9443}:9443" networks: - - public_overlay + - public_web - default depends_on: authentik-postgresql: @@ -68,7 +68,7 @@ services: traefik.enable: true traefik.http.routers.authentik.rule: Host(`auth.CHANGEME.com`) traefik.http.services.authentik.loadbalancer.server.port: 9000 - traefik.docker.network: public_overlay + traefik.docker.network: public_web traefik.public: true authentik-proxy: image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG:-2024.10.5} @@ -76,7 +76,7 @@ services: # - 9000:9000 # - 9443:9443 networks: - - public_overlay + - public_web - default environment: AUTHENTIK_REDIS__HOST: authentik-redis @@ -134,7 +134,7 @@ services: networks: default: internal: true - public_overlay: + public_web: external: true volumes: diff --git a/crowdsec/compose.yaml b/crowdsec/compose.yaml index 5640b3f..5dd6095 100644 --- a/crowdsec/compose.yaml +++ b/crowdsec/compose.yaml @@ -2,7 +2,7 @@ services: crowdsec: image: "crowdsecurity/crowdsec:latest" networks: - - crowdsec_overlay + - crowdsec_net - default environment: - "CUSTOM_HOSTNAME=cs-decision" @@ -21,7 +21,7 @@ services: crowdsec-ingest: image: "crowdsecurity/crowdsec:latest" networks: - - crowdsec_overlay + - crowdsec_net - default environment: - "COLLECTIONS=crowdsecurity/linux crowdsecurity/traefik crowdsecurity/whitelist-good-actors" @@ -43,5 +43,5 @@ services: - "./crowdsec-ingest/data:/var/lib/crowdsec/data" - "./crowdsec-ingest/logs:/var/log/crowdsec" networks: - crowdsec_overlay: + crowdsec_net: external: true \ No newline at end of file diff --git a/crowdsec/crowdsec/config/notifications/discord.yaml b/crowdsec/crowdsec/config/notifications/discord.yaml index 88c150f..8fbd3dd 100644 --- a/crowdsec/crowdsec/config/notifications/discord.yaml +++ b/crowdsec/crowdsec/config/notifications/discord.yaml @@ -35,7 +35,7 @@ format: | ] } -url: https://discord.com/api/webhooks/YOUR_WEBHOOK_HERE +url: https://discord.com/api/webhooks/CHANGME_YOUR_WEBHOOK_HERE method: POST diff --git a/crowdsec/crowdsec_ingest/config/acquis.yaml b/crowdsec/crowdsec_ingest/config/acquis.yaml index 6f83af4..c1b9e51 100644 --- a/crowdsec/crowdsec_ingest/config/acquis.yaml +++ b/crowdsec/crowdsec_ingest/config/acquis.yaml @@ -9,8 +9,8 @@ # --- source: docker container_name: - - traefik-external-traefik-access-logs-1 -# use tcp://192.168.TRAEFIK_EXTERNAL_HOST.IP:2375 if not using crowdsec_overlay + - traefik-external-access-logs +# use tcp://192.168.TRAEFIK_EXTERNAL_HOST.IP:2375 if not using crowdsec_net docker_host: tcp://traefik-ext-socket-proxy:2375 labels: type: traefik diff --git a/example_services/compose-ext-auth-service.yaml b/example_services/compose-ext-auth-service.yaml index e2ac905..ddc19e0 100644 --- a/example_services/compose-ext-auth-service.yaml +++ b/example_services/compose-ext-auth-service.yaml @@ -3,14 +3,14 @@ services: echo: image: mendhak/http-https-echo:36 networks: - - public_overlay + - public_web labels: traefik.enable: true traefik.http.routers.echo2.rule: Host(`echo2.CHANGEME.com`) traefik.http.services.echo2.loadbalancer.server.port: 8080 traefik.http.routers.echo2.middlewares: authentik-proxy@docker - traefik.docker.network: public_overlay + traefik.docker.network: public_web kop.namespace: public networks: - internal_overlay: + internal_web: external: true \ No newline at end of file diff --git a/example_services/compose-external-service.yaml b/example_services/compose-external-service.yaml index f3f2c59..fb05394 100644 --- a/example_services/compose-external-service.yaml +++ b/example_services/compose-external-service.yaml @@ -3,13 +3,13 @@ services: echo: image: mendhak/http-https-echo:36 networks: - - public_overlay + - public_web labels: traefik.enable: true traefik.http.routers.echo1.rule: Host(`echo1.CHANGEME.com`) traefik.http.services.echo1.loadbalancer.server.port: 8080 - traefik.docker.network: public_overlay + traefik.docker.network: public_web kop.namespace: public networks: - public_overlay: + public_web: external: true \ No newline at end of file diff --git a/example_services/compose-internal-service.yaml b/example_services/compose-internal-service.yaml index 1427a66..c98b68c 100644 --- a/example_services/compose-internal-service.yaml +++ b/example_services/compose-internal-service.yaml @@ -3,12 +3,12 @@ services: echo: image: mendhak/http-https-echo:36 networks: - - internal_overlay + - internal_web labels: traefik.enable: true traefik.http.routers.echo1.rule: Host(`echo1.CHANGEME.casa`) traefik.http.services.echo1.loadbalancer.server.port: 8080 - traefik.docker.network: internal_overlay + traefik.docker.network: internal_web networks: - internal_overlay: + internal_web: external: true \ No newline at end of file diff --git a/traefik_external/.env.example b/traefik_external/.env.example index a424dcd..bf1277c 100644 --- a/traefik_external/.env.example +++ b/traefik_external/.env.example @@ -1,4 +1,4 @@ -CF_DNS_API_TOKEN=NOT_REAL_UaOYrCYkeEPk6q1H -CF_TRAEFIK_TUNNEL_TOKEN=NOT_REAL_ceFh5BEalnUrHxFPmhAAAAgE49iGjj -CS_TRAEFIK_BOUNCER_KEY=NOT_REAL_ln3Q3cof5zm9X3SHRpBdkZ +CF_DNS_API_TOKEN=CHANGEME_UaOYrCYkeEPk6q1H +CF_TRAEFIK_TUNNEL_TOKEN=CHANGEME_ceFh5BEalnUrHxFPmhAAAAgE49iGjj +CS_TRAEFIK_BOUNCER_KEY=CHANGEME_ln3Q3cof5zm9X3SHRpBdkZ BOUNCER_HOST=crowdsec:8080 \ No newline at end of file diff --git a/traefik_external/compose.yaml b/traefik_external/compose.yaml index 9606105..6d3234a 100644 --- a/traefik_external/compose.yaml +++ b/traefik_external/compose.yaml @@ -3,9 +3,9 @@ services: traefik: image: "traefik:v3.3" networks: - - public_overlay + - public_web - traefik_internal - - crowdsec_overlay + - crowdsec_net depends_on: - traefik-external-redis ports: @@ -58,6 +58,7 @@ services: traefik-access-logs: image: alpine + container_name: traefik-external-access-logs volumes: - ./traefik/log:/var/log:ro command: > @@ -73,7 +74,7 @@ services: - "6379:6379" networks: - traefik_internal - - kop_overlay + - kop_net healthcheck: test: ['CMD', 'redis-cli', 'ping'] volumes: @@ -92,7 +93,7 @@ services: context: https://github.com/logdyhq/logdy-core.git read_only: true networks: - - internal_overlay + - internal_web volumes: - ./traefik/log:/var/log:ro - ./logdy/logdy.json:/config/logdy.json @@ -109,7 +110,7 @@ services: traefik.enable: true traefik.http.routers.logdy-traefik-external.rule: Host(`traefik-log-external.CHANGEME.casa`) traefik.http.services.logdy-traefik-external.loadbalancer.server.port: 8080 - traefik.docker.network: internal_overlay + traefik.docker.network: internal_web homepage.group: Monitoring homepage.name: Traefik Logs (External) homepage.icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/logdy.png @@ -119,7 +120,7 @@ services: image: lscr.io/linuxserver/socket-proxy:latest container_name: traefik-ext-socket-proxy networks: - - crowdsec_overlay + - crowdsec_net environment: - CONTAINERS=1 - POST=0 @@ -138,11 +139,11 @@ networks: ipam: config: - subnet: 172.28.0.0/16 - public_overlay: + public_web: external: true - internal_overlay: + internal_web: external: true - kop_overlay: + kop_net: external: true - crowdsec_overlay: + crowdsec_net: external: true \ No newline at end of file diff --git a/traefik_external/logdy/logdy.json b/traefik_external/logdy/logdy.json index 504612b..4e62af3 100644 --- a/traefik_external/logdy/logdy.json +++ b/traefik_external/logdy/logdy.json @@ -311,7 +311,7 @@ { "id": "m_632328", "name": "additional_info", - "handlerTsCode": "(line: Message): Message | void => {\n\n let external = true;\n let me = false;\n\n const client = line.json_content.ClientHost;\n const host = line.json_content.RequestHost;\n const uaString = line.json_content['request_User-Agent'];\n\n external = !client.includes('192.168.0') && client !== \"2600:1700:1e1f:YOUR:IPV6\";\n me = client === \"192.168.TREFIK_EXTERNAL.HOST\" || client === \"2600:1700:1e1f:YOUR:IPV6\"\n\n const urlPattern = /^(?:([A-Za-z]+?):\\/\\/)?(?:[^@\\n]+@)?(?:([A-Za-z]+?)\\.)?([^:\\/\\n?]+)(.*)/;\n\n let hostname = '-',\n subdomain = '-',\n uaUrl;\n\n if (host !== '-') {\n\n const urlMatch = host.match(urlPattern);\n\n if (urlMatch) {\n if (urlMatch[3].includes('.')) {\n subdomain = urlMatch[2];\n hostname = urlMatch[3];\n } else {\n hostname = `${urlMatch[2]}.${urlMatch[3]}`;\n }\n if (external && hostname === \"CHANGEME.casa\") {\n external = false;\n }\n }\n }\n\n const regUrlPattern = /\\+([(http(s)?):\\/\\/(www\\.)?a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,20}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*))/;\n const uaMatch = uaString.match(regUrlPattern);\n if (uaMatch) {\n uaUrl = uaMatch[1];\n }\n\n line.json_content.subdomain = subdomain;\n line.json_content.hostname = hostname;\n line.json_content.external = external;\n line.json_content.me = me;\n line.json_content.uaUrl = uaUrl;\n\n return line;\n}" + "handlerTsCode": "(line: Message): Message | void => {\n\n let external = true;\n let me = false;\n\n const client = line.json_content.ClientHost;\n const host = line.json_content.RequestHost;\n const uaString = line.json_content['request_User-Agent'];\n\n external = !client.includes('192.168.0') && client !== \"2600:1700:1e1f:YOUR:IPV6\";\n me = client === \"192.168.TREFIK_EXTERNAL.HOST_CHANGEME\" || client === \"2600:1700:1e1f:YOUR:IPV6CHANGME\"\n\n const urlPattern = /^(?:([A-Za-z]+?):\\/\\/)?(?:[^@\\n]+@)?(?:([A-Za-z]+?)\\.)?([^:\\/\\n?]+)(.*)/;\n\n let hostname = '-',\n subdomain = '-',\n uaUrl;\n\n if (host !== '-') {\n\n const urlMatch = host.match(urlPattern);\n\n if (urlMatch) {\n if (urlMatch[3].includes('.')) {\n subdomain = urlMatch[2];\n hostname = urlMatch[3];\n } else {\n hostname = `${urlMatch[2]}.${urlMatch[3]}`;\n }\n if (external && hostname === \"CHANGEME.casa\") {\n external = false;\n }\n }\n }\n\n const regUrlPattern = /\\+([(http(s)?):\\/\\/(www\\.)?a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,20}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*))/;\n const uaMatch = uaString.match(regUrlPattern);\n if (uaMatch) {\n uaUrl = uaMatch[1];\n }\n\n line.json_content.subdomain = subdomain;\n line.json_content.hostname = hostname;\n line.json_content.external = external;\n line.json_content.me = me;\n line.json_content.uaUrl = uaUrl;\n\n return line;\n}" } ], "entriesOrder": "desc" diff --git a/traefik_external/traefik/dynamic_config/global.yml b/traefik_external/traefik/dynamic_config/global.yml index 7444ffe..d03d4d2 100644 --- a/traefik_external/traefik/dynamic_config/global.yml +++ b/traefik_external/traefik/dynamic_config/global.yml @@ -3,7 +3,7 @@ http: anyreg: redirectregex: regex: ^.* - replacement: https://MY_SITE.com + replacement: https://MY_SITE_CHANGEME.com cloudflarewarp: plugin: cloudflarewarp: diff --git a/traefik_internal/.env.example b/traefik_internal/.env.example index 32e0f73..950961b 100644 --- a/traefik_internal/.env.example +++ b/traefik_internal/.env.example @@ -1 +1 @@ -CF_DNS_API_TOKEN=MY_DNS_TOKEN \ No newline at end of file +CF_DNS_API_TOKEN=MY_DNS_TOKEN_CHANGEME \ No newline at end of file diff --git a/traefik_internal/compose.yaml b/traefik_internal/compose.yaml index 77ef2c9..1b91347 100644 --- a/traefik_internal/compose.yaml +++ b/traefik_internal/compose.yaml @@ -4,7 +4,7 @@ services: image: "traefik:v3.3" networks: - traefik_internal - - internal_overlay + - internal_web depends_on: - traefik-internal-redis ports: @@ -68,7 +68,7 @@ services: - "6379:6379" networks: - traefik_internal - - kop_overlay + - kop_net healthcheck: test: ['CMD', 'redis-cli', 'ping'] volumes: @@ -79,7 +79,7 @@ services: context: https://github.com/logdyhq/logdy-core.git read_only: true networks: - - internal_overlay + - internal_web - traefik_internal volumes: - ./traefik/log:/var/log:ro @@ -106,7 +106,7 @@ services: networks: traefik_internal: - kop_overlay: + kop_net: external: true - internal_overlay: + internal_web: external: true \ No newline at end of file diff --git a/traefik_internal/logdy/logdy.json b/traefik_internal/logdy/logdy.json index d96cdc2..1168a5d 100644 --- a/traefik_internal/logdy/logdy.json +++ b/traefik_internal/logdy/logdy.json @@ -311,7 +311,7 @@ { "id": "m_632328", "name": "additional_info", - "handlerTsCode": "(line: Message): Message | void => {\n\n let external = true;\n let me = false;\n\n const client = line.json_content.ClientHost;\n const host = line.json_content.RequestHost;\n const uaString = line.json_content['request_User-Agent'];\n\n external = !client.includes('192.168.0') && client !== \"2600:1700:1e1f:YOUR:IPV6\";\n me = client === \"192.168.YOUR_HOST.IP\" || client === \"2600:1700:1e1f:YOUR:IPV6\"\n\n const urlPattern = /^(?:([A-Za-z]+?):\\/\\/)?(?:[^@\\n]+@)?(?:([A-Za-z]+?)\\.)?([^:\\/\\n?]+)(.*)/;\n\n let hostname = '-',\n subdomain = '-',\n uaUrl;\n\n if (host !== '-') {\n\n const urlMatch = host.match(urlPattern);\n\n if (urlMatch) {\n if (urlMatch[3].includes('.')) {\n subdomain = urlMatch[2];\n hostname = urlMatch[3];\n } else {\n hostname = `${urlMatch[2]}.${urlMatch[3]}`;\n }\n if (external && hostname === \"CHANGEME.casa\") {\n external = false;\n }\n }\n }\n\n const regUrlPattern = /\\+([(http(s)?):\\/\\/(www\\.)?a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,20}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*))/;\n const uaMatch = uaString.match(regUrlPattern);\n if (uaMatch) {\n uaUrl = uaMatch[1];\n }\n\n line.json_content.subdomain = subdomain;\n line.json_content.hostname = hostname;\n line.json_content.external = external;\n line.json_content.me = me;\n line.json_content.uaUrl = uaUrl;\n\n return line;\n}" + "handlerTsCode": "(line: Message): Message | void => {\n\n let external = true;\n let me = false;\n\n const client = line.json_content.ClientHost;\n const host = line.json_content.RequestHost;\n const uaString = line.json_content['request_User-Agent'];\n\n external = !client.includes('192.168.YOURIP.CHANGEME') && client !== \"2600:1700:1e1f:YOUR:IPV6CHANGEME\";\n me = client === \"192.168.YOUR_HOST_IP.CHANGEME\" || client === \"2600:1700:1e1f:YOUR:IPV6CHANGEME\"\n\n const urlPattern = /^(?:([A-Za-z]+?):\\/\\/)?(?:[^@\\n]+@)?(?:([A-Za-z]+?)\\.)?([^:\\/\\n?]+)(.*)/;\n\n let hostname = '-',\n subdomain = '-',\n uaUrl;\n\n if (host !== '-') {\n\n const urlMatch = host.match(urlPattern);\n\n if (urlMatch) {\n if (urlMatch[3].includes('.')) {\n subdomain = urlMatch[2];\n hostname = urlMatch[3];\n } else {\n hostname = `${urlMatch[2]}.${urlMatch[3]}`;\n }\n if (external && hostname === \"CHANGEME.casa\") {\n external = false;\n }\n }\n }\n\n const regUrlPattern = /\\+([(http(s)?):\\/\\/(www\\.)?a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,20}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*))/;\n const uaMatch = uaString.match(regUrlPattern);\n if (uaMatch) {\n uaUrl = uaMatch[1];\n }\n\n line.json_content.subdomain = subdomain;\n line.json_content.hostname = hostname;\n line.json_content.external = external;\n line.json_content.me = me;\n line.json_content.uaUrl = uaUrl;\n\n return line;\n}" } ], "entriesOrder": "desc" diff --git a/traefik_internal/traefik/dynamic_config/sites.yml b/traefik_internal/traefik/dynamic_config/sites.yml index 2a10ad4..416e3b6 100644 --- a/traefik_internal/traefik/dynamic_config/sites.yml +++ b/traefik_internal/traefik/dynamic_config/sites.yml @@ -16,8 +16,8 @@ # homeassistant: # loadBalancer: # servers: -# - url: "http://192.168.0.101:8123" +# - url: "http://192.168.0.CHANGEME:8123" # unraid: # loadBalancer: # servers: -# - url: "http://192.168.0.110:80" +# - url: "http://192.168.0.CHANGEME:80" diff --git a/traefik_kop/.env.example b/traefik_kop/.env.example index 849fd6a..038bbd9 100644 --- a/traefik_kop/.env.example +++ b/traefik_kop/.env.example @@ -1,2 +1,2 @@ -HOSTNAME=MyCoolMachine -BIND_IP=192.168.0.101 +HOSTNAME=MyCoolMachine_CHANGEME +BIND_IP=192.168.0.CHANGEME diff --git a/traefik_kop/compose.yaml b/traefik_kop/compose.yaml index 344a523..abb49fa 100644 --- a/traefik_kop/compose.yaml +++ b/traefik_kop/compose.yaml @@ -11,7 +11,7 @@ services: depends_on: - socket-proxy networks: - - kop_overlay + - kop_net - default traefik-kop-internal: image: "ghcr.io/jittering/traefik-kop:latest" @@ -24,7 +24,7 @@ services: depends_on: - socket-proxy networks: - - kop_overlay + - kop_net - default socket-proxy: image: lscr.io/linuxserver/socket-proxy:latest @@ -51,5 +51,5 @@ services: networks: default: internal: true - kop_overlay: + kop_net: external: true \ No newline at end of file