ch4mp
ch4mp

Reputation: 12744

How to configure spring-cloud-gateway with letsencrypt cluster-issuer on k8s?

I'm trying to configure a K8s Ingress for a spring-cloud-gateway instance deployed on Kubernetes, but can't figure out how to serve it with a valid SSL certificate.

Here is my ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-production
    acme.cert-manager.io/http01-edit-in-place: "true"
  name: demo-bff
  namespace: demo-bff
spec:
  rules:
  - host: bff.demo.c4-soft.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: bff-gateway
            port:
              number: 8080
  tls:
    - hosts:
        - bff.demo.c4-soft.com
      secretName: demo-bff-tls

The letsencrypt-production cluster-issuer is successfully used from another namespace to expose Keycloak.

I believe the issue is in my gateway configuration not correctly routing / authorizing the HTTP-01 challenge. Anyone knows how to configure spring-cloud-gateway with cert-manager, a cluster-issuer and letsencrypt?

What I tried so far for gateway config (in addition to standard OAuth2 client configuration):

spring:
  cloud:
    gateway:
      default-filters:
      - TokenRelay=
      - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
      - SaveSession
      routes:
      - id: letsencrypt
        uri: http://cert-manager-webhook
        predicates:
        - Path=/.well-known/acme-challenge/**

extract of kubectl get services --all-namespaces

cert-manager    service/cert-manager-webhook                 ClusterIP      10.3.8.243     <none>           443/TCP                      4d2h
default         service/kubernetes                           ClusterIP      10.3.0.1       <none>           443/TCP                      4d2h
demo-bff        service/bff-gateway                          ClusterIP      10.3.49.122    <none>           8080/TCP                     175m
ingress-nginx   service/ingress-nginx-controller             LoadBalancer   10.3.86.83     148.113.158.14   80:30664/TCP,443:31206/TCP   4d2h
ingress-nginx   service/ingress-nginx-controller-admission   ClusterIP      10.3.31.34     <none>           443/TCP                      4d2h
kube-system     service/kube-dns                             ClusterIP      10.3.0.10      <none>           53/UDP,53/TCP,9153/TCP       4d2h

Upvotes: 0

Views: 396

Answers (1)

ch4mp
ch4mp

Reputation: 12744

I finally got it working by changing two things:

  • switch the cert-manager-webhook URI to https (the service is bound to port 443, as can be seen above)
  • ensure the /.well-known/acme-challenge/** path-matcher has permitAll() in exchanges authorization
spring:
  cloud:
    gateway:
      default-filters:
      - TokenRelay=
      - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
      - SaveSession
      routes:
      - id: letsencrypt
        uri: https://cert-manager-webhook
        predicates:
        - Path=/.well-known/acme-challenge/**
com:
  c4-soft:
    springaddons:
      security:
        client:
          security-matchers: /**
          permit-all:
          - /login/**
          - /oauth2/**
          - /
          - /login-options
          - "/me"
          - /ui/**
          - /actuator/health/readiness
          - /actuator/health/liveness
          - /.well-known/acme-challenge/**

The com.c4-soft.springaddons.security properties are used by an alternate Spring Boot starter of mine (wrapping spring-boot-starter-oauth2-client). Those reported here are used in http.authorizeExchange(authorizeExchange -> authorizeExchange.pathMatchers(permitAll).permitAll()).

Upvotes: 0

Related Questions