diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 0de5a1b..6d25707 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -11,6 +11,8 @@ jobs: outputs: node-labels: ${{ steps.filter.outputs.node-labels }} coredns: ${{ steps.filter.outputs.coredns }} + traefik: ${{ steps.filter.outputs.traefik }} + crowdsec: ${{ steps.filter.outputs.crowdsec }} steps: - uses: actions/checkout@v5 with: @@ -23,6 +25,10 @@ jobs: - 'node-labels/**' coredns: - 'coredns/**' + traefik: + - 'traefik/**' + crowdsec: + - 'crowdsec/**' deploy-node-labels: runs-on: ubuntu-latest @@ -56,3 +62,78 @@ jobs: - name: Restart coredns run: | kubectl -n kube-system rollout restart deployment coredns + + deploy-traefik: + runs-on: ubuntu-latest + needs: check-changes + if: ${{ needs.check-changes.outputs.traefik == 'true' }} + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: azure/setup-kubectl@776406bce94f63e41d621b960d78ee25c8b76ede # v4 + - uses: azure/k8s-set-context@ae59a723ba9abe7a9655538854a025448dbab4aa # v4 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBECONFIG }} + - name: Set ionos api credentials + uses: azure/k8s-create-secret@6e0ba8047235646753f2a3a3b359b4d0006ff218 # v5 + with: + namespace: kube-system + secret-name: ionos-api-credentials + secret-type: generic + data: | + { + "apiKey": "${{ secrets.IONOS_API_KEY }}" + } + - name: Set admin basic auth credentials + uses: azure/k8s-create-secret@6e0ba8047235646753f2a3a3b359b4d0006ff218 # v5 + with: + namespace: kube-system + secret-name: admin-basic-auth-credentials + secret-type: generic + data: | + { + "username": "bmV0YWRtaW4=", + "password": "${{ secrets.ADMIN_BASIC_AUTH_PASSWORD }}" + } + - name: Set crowdsec bouncer api key + uses: azure/k8s-create-secret@6e0ba8047235646753f2a3a3b359b4d0006ff218 # v5 + with: + namespace: kube-system + secret-name: crowdsec-bouncer-api-key + secret-type: generic + data: | + { + "api-key": "${{ secrets.CROWDSEC_BOUNCER_API_KEY }}" + } + - name: Deploy + uses: azure/k8s-deploy@6f7c489cecd8da05646259d9fa3daae92e095c7b # v5.0.4 + with: + action: deploy + manifests: "traefik/" + strategy: basic + namespace: kube-system + + deploy-crowdsec: + runs-on: ubuntu-latest + needs: check-changes + if: ${{ needs.check-changes.outputs.crowdsec == 'true' }} + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: https://gitea.t000-n.de/t.behrendt/k_deploy_workflows/.gitea/actions/extract-namespace-from-repo-name@v0 + id: namespace + with: + repo: ${{ github.repository }} + - uses: azure/setup-kubectl@776406bce94f63e41d621b960d78ee25c8b76ede # v4 + - uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4 + with: + version: "3.15.0" + - uses: azure/k8s-set-context@ae59a723ba9abe7a9655538854a025448dbab4aa # v4 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBECONFIG }} + - name: Deploy helm + uses: helmfile/helmfile-action@f64d5db9f8660aae0205b5fcfc56577d44acefab # v2.1.0 + with: + helmfile-args: apply + helm-plugins: https://github.com/databus23/helm-diff@v3.12.0 + helmfile-workdirectory: "crowdsec" diff --git a/.gitea/workflows/validate.yaml b/.gitea/workflows/validate.yaml index da68584..ad6abb0 100644 --- a/.gitea/workflows/validate.yaml +++ b/.gitea/workflows/validate.yaml @@ -31,3 +31,40 @@ jobs: - name: Validate run: | kubectl apply -n kube-system -f coredns + + validate-traefik: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: azure/setup-kubectl@776406bce94f63e41d621b960d78ee25c8b76ede # v4 + - uses: azure/k8s-set-context@ae59a723ba9abe7a9655538854a025448dbab4aa # v4 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBECONFIG }} + - name: Validate + uses: azure/k8s-lint@6aefe5066f95e73d2b140d8835cc95583b886989 # v3 + with: + namespace: kube-system + lintType: dryrun + manifests: "traefik/" + + validate-crowdsec: + runs-on: + - ubuntu-latest + - linux_amd64 + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: azure/setup-kubectl@776406bce94f63e41d621b960d78ee25c8b76ede # v4 + - uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4 + with: + version: "3.15.0" + - uses: azure/k8s-set-context@ae59a723ba9abe7a9655538854a025448dbab4aa # v4 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBECONFIG }} + - name: Validate Helm + uses: helmfile/helmfile-action@f64d5db9f8660aae0205b5fcfc56577d44acefab # v2.1.0 + with: + helmfile-args: diff + helm-plugins: https://github.com/databus23/helm-diff@v3.12.0 + helmfile-workdirectory: "crowdsec" diff --git a/crowdsec/helmfile.yaml b/crowdsec/helmfile.yaml new file mode 100644 index 0000000..8c390a7 --- /dev/null +++ b/crowdsec/helmfile.yaml @@ -0,0 +1,12 @@ +repositories: + - name: crowdsec + url: https://crowdsecurity.github.io/helm-charts + +releases: + - name: crowdsec + namespace: kube-system + createNamespace: false + chart: crowdsec/crowdsec + version: 0.20.0 + values: + - values.yaml diff --git a/crowdsec/values.yaml b/crowdsec/values.yaml new file mode 100644 index 0000000..abc842f --- /dev/null +++ b/crowdsec/values.yaml @@ -0,0 +1,35 @@ +container_runtime: containerd + +agent: + enabled: true + acquisition: + - namespace: kube-system + podName: traefik-* + program: traefik + metrics: + enabled: false + +lapi: + enabled: true + replicas: 1 + metrics: + enabled: true + persistentVolume: + data: + enabled: true + size: 1Gi + config: + enabled: true + size: 100Mi + +config: + config.yaml.local: | + api: + server: + auto_registration: + enabled: true + token: "${REGISTRATION_TOKEN}" + allowed_ranges: + - "10.0.0.0/8" + - "172.16.0.0/12" + - "192.168.0.0/16" diff --git a/traefik/traefik-config.yaml b/traefik/traefik-config.yaml new file mode 100644 index 0000000..7ecb60f --- /dev/null +++ b/traefik/traefik-config.yaml @@ -0,0 +1,100 @@ +apiVersion: helm.cattle.io/v1 +kind: HelmChartConfig +metadata: + name: traefik + namespace: kube-system +spec: + valuesContent: |- + nodeSelector: + kubernetes.io/hostname: k3sh0 + providers: + kubernetesCRD: + allowCrossNamespace: true + certResolvers: + letsencrypt: + email: admin@t00n.de + dnsChallenge: + provider: ionos + delayBeforeCheck: 60 + resolvers: + - 1.1.1.1 + storage: /data/acme-ionos.json + ingressRoute: + dashboard: + enabled: true + matchRule: Host(`traefik.monitor.k8s.t000-n.de`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`)) + middlewares: + - name: localipfilter + entryPoints: ["websecure"] + env: + - name: IONOS_API_KEY + valueFrom: + secretKeyRef: + key: apiKey + name: ionos-api-credentials + - name: CROWDSEC_BOUNCER_API_KEY + valueFrom: + secretKeyRef: + name: crowdsec-bouncer-api-key + key: api-key + ports: + web: + port: 8000 + expose: true + exposedPort: 80 + nodePort: 32080 + websecure: + port: 8443 + expose: true + exposedPort: 443 + nodePort: 32443 + tls: + enabled: true + certResolver: "letsencrypt" + service: + enabled: true + single: true + type: LoadBalancer + spec: + externalTrafficPolicy: Local + externalIPs: + - 192.168.0.50 + - 192.168.0.51 + - 192.168.0.52 + - 192.168.0.53 + persistence: + enabled: true + name: data + accessMode: ReadWriteMany + size: 1Gi + storageClass: longhorn + path: /data + extraObjects: + - apiVersion: traefik.containo.us/v1alpha1 + kind: Middleware + metadata: + name: localipfilter + namespace: kube-system + spec: + ipWhiteList: + sourceRange: + - 192.168.0.0/24 + - 172.16.0.0/16 + - 10.0.0.0/8 + - apiVersion: traefik.containo.us/v1alpha1 + kind: Middleware + metadata: + name: adminbasicauth + namespace: kube-system + spec: + basicAuth: + secret: adminbasicauthsecret + experimental: + plugins: + crowdsec-bouncer-traefik-plugin: + moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin + version: v1.4.6 + additionalArguments: + - "--providers.kubernetescrd" + - "--entrypoints.web.http.middlewares=crowdsec-bouncer@kubernetescrd" + - "--entrypoints.websecure.http.middlewares=internal-crowdsec-bouncer@kubernetescrd"