Mailu / helm-charts

Development repo for helm charts
125 stars 129 forks source link

Proxy Protocol support #264

Open ArnCo opened 1 year ago

ArnCo commented 1 year ago

Is your feature request related to a problem? Please describe. I would like to expose my mail services through traefik. I currently run them as hostPorts.

Describe the solution you'd like Support proxy protocol, as described here: https://mailu.io/2.0/releases.html#proxy-protocol-support

Additional context Mailu 2 now supports proxy protocol.

Let me know how I can help :-)

ArnCo commented 1 year ago

So I have started investigating how it could work. Proxy protocol is supposed to be activated through the PROXY_PROTOCOL env variable, which i have set in the extraEnvVars of the front container:

  extraEnvVars:
    - name: PROXY_PROTOCOL
      value: "mail"

In order to route the TCP traffic from my traefik load balancer, I have created the following CRDs:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: mailu-smtp
  namespace: mailu
spec:
  entryPoints:
    - smtp
  routes:
  - match: HostSNI(`*`)
    services:
    - name: mailu-front
      port: 25
      proxyProtocol:
        version: 2
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: mailu-imaps
  namespace: mailu
spec:
  entryPoints:
    - imaps
  routes:
  - match: HostSNI(`*`)
    services:
    - name: mailu-front
      port: 993
      proxyProtocol:
        version: 2
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: mailu-smtps
  namespace: mailu
spec:
  entryPoints:
    - smtps
  routes:
    - match: HostSNI(`*`)
      services:
      - name: mailu-front
        port: 465
        proxyProtocol:
          version: 2
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: mailu-starttls
  namespace: mailu
spec:
  entryPoints:
    - starttls
  routes:
  - match: HostSNI(`*`)
    services:
      - name: mailu-front
        port: 587
        proxyProtocol:
          version: 2

This configuration is functional, BUT results in an open relay, (the front container sees the reverse-proxy IP, and does not seem to use Proxy Protocol in order to resolve the real source IP. Any ideas?

ArnCo commented 1 year ago

Well, I got it working with the following extraEnvVars:

  extraEnvVars:
    - name: PROXY_PROTOCOL
      value: "mail"
    - name: REAL_IP_FROM
      value: "10.42.0.0/16,fd23:23:42:0::/56"

The service now listens both on IPV4 and IPV6 and successfully resolves origin IPs, so no more open relay! I am not sure what would be the best to integrate it in the Chart, however as realIpFrom can already be set under the ingress, maybe proxy_protocol should be added there as well.

ArnCo commented 1 year ago

Hi again :-) I came across an issue on my dual stack (IPv4 + IPv6) deployment. It looks like Dovecot is not happy when Proxy Protocol specifies and IPv6 address while the real IP (of the traefik load balancer) is IPv4, which is the default behavior of traefik, and cannot be changed. For the record, I get this error only for IPv6 originate donnections on dovecot, postfix handles them without any problem:

imap-login: Error: haproxy(v1): Client disconnected: Proxied local address is invalid (address=`10.42.4.15', rip=10.42.4.15)

Anybody thinking about a solution here ? At the moment I just rolled back my imap DNS record to IPv4 only, and everything works like a charm, while postfix is running fully dual stack. Cheers, ArnC

m5ingh commented 1 year ago

I am trying to recreate this on my k3s cluster, but am getting error entryPoint "imaps/smtp/smtps/starttls" doesn't exist. I would be really thankful if you can share broadly steps to recreate this setup and relevant parts of associated yamls

jjangga0214 commented 9 months ago

@m5ingh

getting error entryPoint "imaps/smtp/smtps/starttls" doesn't exist.

You should first create the entrypoints from traefik's side. And then refer to the entrypoints from IngressRoute.

For example, traefik's helm chart has ports value. web, websecure, and treafik are defined by defaults, but you can customize them or add more entrypoints.

    ports:
        web:
          expose: true
          port: 8080
          exposedPort: 80
          protocol: TCP
        websecure:
          expose: true
          port: 8443
          exposedPort: 443
          protocol: TCP
        traefik:
          expose: true
          port: 39000
          exposedPort: 9000
          protocol: TCP
        smtp:
          expose: true
          port: 30025
          exposedPort: 25
          protocol: TCP
        pop3:
          expose: true
          port: 30110
          exposedPort: 110
          protocol: TCP
        imap:
          expose: true
          port: 30143
          exposedPort: 143
          protocol: TCP
        smtps:
          expose: true
          port: 30465
          exposedPort: 465
          protocol: TCP
        starttls:
          expose: true
          port: 30587
          exposedPort: 587
          protocol: TCP
        imaps:
          expose: true
          port: 30993
          exposedPort: 993
          protocol: TCP
        pop3s:
          expose: true
          port: 30995
          exposedPort: 995
          protocol: TCP