diff --git a/docker/compose/dc-crowdsec.yml b/docker/compose/dc-crowdsec.yml new file mode 100644 index 0000000..8f969e1 --- /dev/null +++ b/docker/compose/dc-crowdsec.yml @@ -0,0 +1,23 @@ +services: + crowdsec: + image: ${CROWDSEC_IMAGE}:${CROWDSEC_VERSION} + container_name: ${CROWDSEC_CONTAINER_NAME} + restart: ${CROWDSEC_RESTART_POLICY} + security_opt: + - no-new-privileges:true + networks: + - proxy + #proxy: + # ipv4_address: ${CROWDSEC_IP} # You can specify a static IP + environment: + GID: "${GID-1000}" + COLLECTIONS: ${CROWDSEC_COLLECTIONS} + volumes: + - /etc/localtime:/etc/localtime:ro + - ${DOCKERDIR}/crowdsec/acquis.d:/etc/crowdsec/acquis.d + #- ${DOCKERDIR}/crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml + - ${DOCKERDIR}/crowdsec/db:/var/lib/crowdsec/data/ + - ${DOCKERDIR}/crowdsec/config:/etc/crowdsec/ + - ${DOCKERDIR}/traefik/logs:/var/log/traefik/:ro + - /var/log/auth.log:/logs/auth.log:ro + - /var/log/syslog.log:/logs/syslog.log:ro diff --git a/docker/compose/dc-socket-proxy.yml b/docker/compose/dc-socket-proxy.yml new file mode 100644 index 0000000..71fa803 --- /dev/null +++ b/docker/compose/dc-socket-proxy.yml @@ -0,0 +1,45 @@ +########################### SERVICES +services: + # Docker Socket Proxy - Security Enchanced Proxy for Docker Socket + socket-proxy: + container_name: ${SOCKET_PROXY_CONTAINER_NAME} + image: ${SOCKET_PROXY_IMAGE}:${SOCKET_PROXY_VERSION} +# image: ghcr.io/tecnativa/docker-socket-proxy:latest + restart: ${SOCKET_PROXY_RESTART_POLICY} + networks: + socket_proxy: + ipv4_address: ${SOCKET_PROXY_IP} + privileged: true + ports: + # - "127.0.0.1:2375:2375" # Port 2375 should only ever get exposed to the internal network. When possible use this line. + # I use the next line instead, as I want portainer to manage multiple docker endpoints within my home network. + - "2375:2375" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + env_file: + - path: ./socket-proxy.env + #environment: + # - LOG_LEVEL=${LOG_LEVEL} + # - EVENTS=${EVENTS} + # - PING=${PING} + # - VERSION=${VERSION} + # - AUTH=${AUTH} + # - SECRETS=${SECRETS} + # - POST=${POST} + # - BUILD=${BUILD} + # - COMMIT=${COMMIT} + # - CONFIGS=${CONFIGS} + # - CONTAINERS=${CONTAINERS} + # - DISTRIBUTION=${DISTRIBUTION} + # - EXEC=${EXEC} + # - IMAGES=${IMAGES} + # - INFO=${INFO} + # - NETWORKS=${NETWORKS} + # - NODES=${NODES} + # - PLUGINS=${PLUGINS} + # - SERVICES=${SERVICES} + # - SESSION=${SESSION} + # - SWARM=${SWARM} + # - SYSTEM=${SYSTEM} + # - TASKS=${TASKS} + # - VOLUMES=${VOLUMES} diff --git a/docker/compose/dc-traefik-bouncer.yml b/docker/compose/dc-traefik-bouncer.yml new file mode 100644 index 0000000..beecce7 --- /dev/null +++ b/docker/compose/dc-traefik-bouncer.yml @@ -0,0 +1,16 @@ +services: + bouncer-traefik: + image: ${BT_IMAGE}:${BT_VERSION} + container_name: ${BT_CONTAINER_NAME} + restart: ${BT_RESTART_POLICY} + environment: + CROWDSEC_BOUNCER_API_KEY: uT3zy+bBevD4kQkEuxGEMrjWnW1yjHjqOw+8AbxPJIQ # docker exec -t crowdsec cscli bouncers add traefik-bouncer + CROWDSEC_AGENT_HOST: ${CROWDSEC_CONTAINER_NAME}:8080 + networks: + - proxy + #proxy: + #ipv4_address: ${BT_IP} +# depends_on: +# - crowdsec + security_opt: + - no-new-privileges:true diff --git a/docker/compose/dc-traefik.yml b/docker/compose/dc-traefik.yml new file mode 100644 index 0000000..75af1b2 --- /dev/null +++ b/docker/compose/dc-traefik.yml @@ -0,0 +1,105 @@ +services: + # Traefik 2 - Reverse Proxy + # Touch (create empty files) traefik.log and acme/acme.json. Set acme.json permissions to 600. + # touch $DOCKERDIR/traefik2/acme/acme.json + # chmod 600 $DOCKERDIR/traefik2/acme/acme.json + # touch $DOCKERDIR/traefik2/traefik.log + traefik: + container_name: ${TRAEFIK_CONTAINER_NAME} + image: ${TRAEFIK_IMAGE}:${TRAEFIK_VERSION} + restart: ${TRAEFIK_RESTART_POLICY} + security_opt: + - no-new-privileges:true + networks: + proxy: + ipv4_address: ${TRAEFIK_IP0} # You can specify a static IP + socket_proxy: + ipv4_address: ${TRAEFIK_IP1} + ports: + - 80:80 + - 443:443 + #env_file: + #- path: ./traefik.env + # required: true # default + #- path: ./override.env + # required: false + #environment: + # - CF_API_EMAIL_FILE=/run/secrets/cloudflare_email + # - CF_DNS_API_TOKEN_FILE=/run/secrets/cloudflare_api_token + command: # CLI arguments + - --global.checkNewVersion=true + - --global.sendAnonymousUsage=false #true + - --entryPoints.http.address=:80 + - --entrypoints.http.http.redirections.entryPoint.to=https + #- --entrypoints.http.http.middlewares=middlewares-crowdsec-bouncer@file + - --entryPoints.https.address=:443 + - --entrypoints.https.forwardedHeaders.trustedIPs=$CLOUDFLARE_IPS,$LOCAL_IPS +# - --entryPoints.traefik.address=:8080 + #(- --entryPoints.ping.address=:8081) + - --api=true + #(- --api.insecure=true) + - --api.dashboard=true + #(- --ping=true) + #(- --pilot.token=$TRAEFIK_PILOT_TOKEN) + - --serversTransport.insecureSkipVerify=true + - --log=true + - --log.level=INFO # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC + - --log.filePath= /var/log/traefik/traefik.log + - --accessLog=true + - --accessLog.filePath=/var/log/traefik/access.log + - --accessLog.bufferingSize=100 # Configuring a buffer of 100 lines + #- --accessLog.filters.statusCodes=400-499 + - --providers.docker=true + - --providers.docker.endpoint=${DOCKER_ENDPOINT} # Use Docker Socket Proxy instead for improved security + # Automatically set Host rule for services + #(- --providers.docker.defaultrule=Host(`{{ index .Labels "com.docker.compose.service" }}.$DOMAINNAME0`)) + - --providers.docker.exposedByDefault=false + #- --providers.redis=true + #- --providers.redis.endpoints=redis:6379 + #- --entrypoints.https.http.middlewares=middlewares-crowdsec-bouncer@file + - --entrypoints.https.http.tls.options=tls-opts@file + # Add dns-cloudflare as default certresolver for all services. Also enables TLS and no need to specify on individual services + - --entrypoints.https.http.tls.certresolver=${CERTRESOLVER} + - --entrypoints.https.http.tls.domains[0].main=$DOMAINNAME0 + - --entrypoints.https.http.tls.domains[0].sans=*.$DOMAINNAME0 + - --entrypoints.https.http.tls.domains[1].main=$DOMAINNAME1 # Pulls main cert for second domain + - --entrypoints.https.http.tls.domains[1].sans=*.$DOMAINNAME1 # Pulls wildcard cert for second domain + - --entrypoints.https.http.tls.domains[2].main=$DOMAINNAME2 + - --entrypoints.https.http.tls.domains[2].sans=*.$DOMAINNAME2 + - --entrypoints.https.http.tls.domains[3].main=$DOMAINNAME3 # Pulls main cert for second domain + - --entrypoints.https.http.tls.domains[3].sans=*.$DOMAINNAME3 # Pulls wildcard cert for second domain + - --providers.docker.network=proxy + - --providers.file.directory=/config # Load dynamic configuration from one or more .toml or .yml files in a directory + #(- --providers.file.filename=/path/to/file # Load dynamic configuration from a file) + - --providers.file.watch=true # Only works on top level files in the rules folder + - --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing + - --certificatesResolvers.$CERTRESOLVER.acme.email=${CF_API_EMAIL} + - --certificatesResolvers.$CERTRESOLVER.acme.storage=/acme.json + - --certificatesResolvers.$CERTRESOLVER.acme.dnsChallenge.provider=${DNS_PROVIDER} + - --certificatesResolvers.$CERTRESOLVER.acme.dnsChallenge.resolvers=${RESOLVER0} #,$RESOLVER1 + - --certificatesResolvers.$CERTRESOLVER.acme.dnsChallenge.delayBeforeCheck=90 # To delay DNS check and reduce LE hitrate + #healthcheck: + # test: ["CMD", "traefik", "healthcheck", "--ping"] + # interval: 5s + # retries: 3 + volumes: + - /etc/localtime:/etc/localtime:ro + #- ${DOCKERDIR}/traefik/traefik.yml:/traefik.yml:ro + - ${DOCKERDIR}/traefik/config:/config:ro # file provider directory + - ${DOCKERDIR}/traefik/acme.json:/acme.json # cert location - you must touch this file and change permissions to 600 + - ${DOCKERDIR}/traefik/logs:/var/log/traefik # for crowdsec - make sure to touch file before starting container + #secrets: + # - cloudflare_email + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.entrypoints=http" + - "traefik.http.routers.traefik.rule=Host(`test-proxy.${DOMAINNAME1}`)" + - "traefik.http.middlewares.traefik-auth.basicauth.users=${BASICAUTHUSER}" + - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https" + - "traefik.http.routers.traefik.middlewares=traefik-https-redirect" + - "traefik.http.routers.traefik-secure.entrypoints=https" + - "traefik.http.routers.traefik-secure.rule=Host(`test-proxy.${DOMAINNAME1}`)" + - "traefik.http.routers.traefik-secure.middlewares=chain-no-auth@file" + #- "traefik.http.routers.traefik-secure.middlewares=traefik-auth" + - "traefik.http.routers.traefik-secure.service=api@internal" diff --git a/docker/compose/socket-proxy.env b/docker/compose/socket-proxy.env new file mode 100644 index 0000000..c4177a0 --- /dev/null +++ b/docker/compose/socket-proxy.env @@ -0,0 +1,33 @@ + +#PORT=53000 +LOG_LEVEL=info # debug,info,notice,warning,err,crit,alert,emerg +## Variables match the URL prefix (i.e. AUTH blocks access to /auth/* parts of the API, etc.). +# 0 to revoke access. +# 1 to grant access. +## Granted by Default +EVENTS=1 +PING=1 +VERSION=1 +#Revoked by Default +# Security critical +AUTH=0 +SECRETS=0 +POST=1 # Watchtower +# Not always needed +BUILD=0 +COMMIT=0 +CONFIGS=0 +CONTAINERS=1 # Traefik, portainer, etc. +DISTRIBUTION=0 +EXEC=1 +IMAGES=1 # Portainer +INFO=1 # Portainer +NETWORKS=1 # Portainer +NODES=0 +PLUGINS=0 +SERVICES=1 # Portainer +SESSION=0 +SWARM=0 +SYSTEM=0 +TASKS=1 # Portaienr +VOLUMES=1 # Portainer