diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index fcd4bfd7..dfd38164 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -34,8 +34,6 @@ http { '' $scheme; } - # Disable the main http server when on kubernetes (port 80 and 443) - {% if KUBERNETES_INGRESS != 'true' %} # Main HTTP server server { # Favicon stuff @@ -54,8 +52,8 @@ http { listen 80; listen [::]:80; - # Only enable HTTPS if TLS is enabled with no error - {% if TLS and not TLS_ERROR %} + # Only enable HTTPS if TLS is enabled with no error and not on kubernetes + {% if KUBERNETES_INGRESS != 'true' and TLS and not TLS_ERROR %} listen 443 ssl http2; listen [::]:443 ssl http2; @@ -76,15 +74,15 @@ http { add_header X-XSS-Protection '1; mode=block'; add_header Referrer-Policy 'same-origin'; - # In any case, enable the proxy for certbot if the flavor is letsencrypt - {% if TLS_FLAVOR in [ 'letsencrypt', 'mail-letsencrypt' ] %} + # In any case, enable the proxy for certbot if the flavor is letsencrypt and not on kubernetes + {% if KUBERNETES_INGRESS != 'true' and TLS_FLAVOR in [ 'letsencrypt', 'mail-letsencrypt' ] %} location ^~ /.well-known/acme-challenge/ { proxy_pass http://127.0.0.1:8008; } {% endif %} # If TLS is failing, prevent access to anything except certbot - {% if TLS_ERROR and not TLS_FLAVOR == "mail" %} + {% if KUBERNETES_INGRESS != 'true' and TLS_ERROR and not TLS_FLAVOR == "mail" %} location / { return 403; } @@ -167,7 +165,6 @@ http { return 204; } } - {% endif %} # Forwarding authentication server server { diff --git a/docs/kubernetes/mailu/admin-ingress.yaml b/docs/kubernetes/mailu/admin-ingress.yaml deleted file mode 100644 index 72aafa68..00000000 --- a/docs/kubernetes/mailu/admin-ingress.yaml +++ /dev/null @@ -1,86 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: mailu-admin-ingress - namespace: mailu-mailserver - annotations: - kubernetes.io/tls-acme: "true" - nginx.ingress.kubernetes.io/proxy-body-size: "0" - certmanager.k8s.io/cluster-issuer: letsencrypt-stage - ingress.kubernetes.io/permanent-redirect: "https://mail.example.com/admin/ui/" - ingress.kubernetes.io/follow-redirects: "true" - labels: - app: mailu - role: mail - tier: backend -spec: - tls: - - hosts: - - "mail.example.com" - secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt - rules: - - host: "mail.example.com" - http: - paths: - - path: "/admin" - backend: - serviceName: admin - servicePort: 80 ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: mailu-admin-ui-ingress - namespace: mailu-mailserver - annotations: - kubernetes.io/tls-acme: "true" - certmanager.k8s.io/cluster-issuer: letsencrypt-stage - ingress.kubernetes.io/rewrite-target: "/ui" - ingress.kubernetes.io/configuration-snippet: | - proxy_set_header X-Forwarded-Prefix /admin; - labels: - app: mailu - role: mail - tier: backend -spec: - tls: - - hosts: - - "mail.example.com" - secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt - rules: - - host: "mail.example.com" - http: - paths: - - path: "/admin/ui" - backend: - serviceName: admin - servicePort: 80 ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: mailu-admin-static-ingress - namespace: mailu-mailserver - annotations: - kubernetes.io/tls-acme: "true" - certmanager.k8s.io/cluster-issuer: letsencrypt-stage - ingress.kubernetes.io/rewrite-target: "/static" - ingress.kubernetes.io/configuration-snippet: | - proxy_set_header X-Forwarded-Prefix /admin; - labels: - app: mailu - role: mail - tier: backend -spec: - tls: - - hosts: - - "mail.example.com" - secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt - rules: - - host: "mail.example.com" - http: - paths: - - path: "/admin/static" - backend: - serviceName: admin - servicePort: 80 \ No newline at end of file diff --git a/docs/kubernetes/mailu/front.yaml b/docs/kubernetes/mailu/front.yaml index 9951f30c..a1d5acb2 100644 --- a/docs/kubernetes/mailu/front.yaml +++ b/docs/kubernetes/mailu/front.yaml @@ -27,7 +27,6 @@ spec: - matchExpressions: - key: node-role.kubernetes.io/node operator: Exists - hostNetwork: true nodeSelector: node-role.kubernetes.io/node: "" dnsPolicy: ClusterFirstWithHostNet @@ -46,34 +45,45 @@ spec: ports: - name: pop3 containerPort: 110 + hostPort: 110 protocol: TCP - name: pop3s containerPort: 995 + hostPort: 995 protocol: TCP - name: imap containerPort: 143 + hostPort: 143 protocol: TCP - name: imaps containerPort: 993 + hostPort: 993 protocol: TCP - name: smtp containerPort: 25 + hostPort: 25 protocol: TCP + - name: smtps + containerPort: 465 + hostPort: 465 + protocol: TCP + - name: smtpd + containerPort: 587 + hostPort: 587 + protocol: TCP + # internal services (not exposed externally) - name: smtp-auth containerPort: 10025 protocol: TCP - name: imap-auth containerPort: 10143 protocol: TCP - - name: smtps - containerPort: 465 - protocol: TCP - - name: smtpd - containerPort: 587 - protocol: TCP - name: auth containerPort: 8000 protocol: TCP + - name: http + containerPort: 80 + protocol: TCP resources: requests: memory: 100Mi @@ -133,3 +143,6 @@ spec: - name: imap-auth port: 10143 protocol: TCP + - name: http + port: 80 + protocol: TCP diff --git a/docs/kubernetes/mailu/index.rst b/docs/kubernetes/mailu/index.rst index ab5f3ca4..2222016e 100644 --- a/docs/kubernetes/mailu/index.rst +++ b/docs/kubernetes/mailu/index.rst @@ -15,7 +15,7 @@ cluster. This is the current structure: - ``NGINX Ingress controller``: Listens to the nodes ports 80 & 443. We have chosen to have a double NGINX stack for Mailu. - ``Cert manager``: Creates automatic Lets Encrypt certificates based on an ``Ingress``-objects domain name. -- ``Mailu NGINX Front daemonset``: This daemonset runs in parallel with the Nginx Ingress Controller and only listens on all E-mail specific ports (25, 110, 143, 587,...) +- ``Mailu NGINX Front daemonset``: This daemonset runs in parallel with the Nginx Ingress Controller and only listens on all E-mail specific ports (25, 110, 143, 587,...). It also listens on 80 and delegates the various http endpoints to the correct services. - ``Mailu components``: All Mailu components (imap, smtp, security, webmail,...) are split into separate files to make them more handy to use, you can find the ``YAML`` files in this directory What you need @@ -24,7 +24,9 @@ What you need - A working Kubernetes cluster (tested with 1.10.5) - A working `cert-manager`_ installation - A working nginx-ingress controller needed for the lets-encrypt - certificates. You can find those files in the ``nginx`` subfolder + certificates. You can find those files in the ``nginx`` subfolder. + Other ingress controllers that support cert-manager (e.g. traefik) + should also work. Cert manager ^^^^^^^^^^^^ @@ -67,8 +69,8 @@ An example of a production and a staging ``clusterIssuer``: name: letsencrypt-prod server: https://acme-v02.api.letsencrypt.org/directory -**IMPORTANT**: All ``*-ingress.yaml`` files use the ``letsencrypt-stage`` ``clusterIssuer``. If you are ready for production, -change this field in all ``*-ingress.yaml`` files to ``letsencrypt-prod`` or whatever name you chose for the production. +**IMPORTANT**: ``ingress.yaml`` uses the ``letsencrypt-stage`` ``clusterIssuer``. If you are ready for production, +change this field in ``ingress.yaml`` file to ``letsencrypt-prod`` or whatever name you chose for the production. If you choose for ``Issuer`` instead of ``clusterIssuer`` you also need to change the annotation to ``certmanager.k8s.io/issuer`` instead of ``certmanager.k8s.io/cluster-issuer`` Deploying Mailu @@ -83,7 +85,7 @@ Personalization - All services run in the same namespace, currently ``mailu-mailserver``. So if you want to use a different one, change the ``namespace`` value in **every** file - Check the ``storage-class`` field in the ``pvc.yaml`` file, you can also change the sizes to your liking. Note that you need ``RWX`` (read-write-many) and ``RWO`` (read-write-once) storageclasses. - Check the ``configmap.yaml`` and adapt it to your needs. Be sure to check the kubernetes DNS values at the end (if you use a different namespace) -- Check the ``*-ingress.yaml`` files and change it to the domain you want (this is for the kubernetes ingress controller to handle the admin, webmail, webdav and auth connections) +- Check the ``ingress.yaml`` file and change it to the domain you want (this is for the kubernetes ingress controller to handle the admin, webmail, webdav and auth connections) Installation ------------ @@ -107,10 +109,7 @@ To start Mailu, run the following commands from the ``docs/kubernetes/mailu`` di kubectl create -f fetchmail.yaml kubectl create -f admin.yaml kubectl create -f webdav.yaml - kubectl create -f admin-ingress.yaml - kubectl create -f webdav-ingress.yaml - kubectl create -f security-ingress.yaml - kubectl create -f webmail-ingress.yaml + kubectl create -f ingress.yaml Create the first admin account diff --git a/docs/kubernetes/mailu/security-ingress.yaml b/docs/kubernetes/mailu/ingress.yaml similarity index 57% rename from docs/kubernetes/mailu/security-ingress.yaml rename to docs/kubernetes/mailu/ingress.yaml index 74ced47e..85b4375d 100644 --- a/docs/kubernetes/mailu/security-ingress.yaml +++ b/docs/kubernetes/mailu/ingress.yaml @@ -1,20 +1,15 @@ apiVersion: extensions/v1beta1 kind: Ingress metadata: - name: mailu-antispam-ingress + name: mailu-ingress namespace: mailu-mailserver annotations: kubernetes.io/tls-acme: "true" certmanager.k8s.io/cluster-issuer: letsencrypt-stage - ingress.kubernetes.io/configuration-snippet: | - rewrite ^/admin/antispam/(.*) /$1 break; - auth_request /internal/auth/admin; - proxy_set_header X-Real-IP ""; - proxy_set_header X-Forwarded-For ""; labels: app: mailu role: mail - tier: frontend + tier: backend spec: tls: - hosts: @@ -24,7 +19,7 @@ spec: - host: "mail.example.com" http: paths: - - path: "/admin/antispam" + - path: "/" backend: - serviceName: antispam - servicePort: 11334 \ No newline at end of file + serviceName: front + servicePort: 80 diff --git a/docs/kubernetes/mailu/webdav-ingress.yaml b/docs/kubernetes/mailu/webdav-ingress.yaml deleted file mode 100644 index 3498eb02..00000000 --- a/docs/kubernetes/mailu/webdav-ingress.yaml +++ /dev/null @@ -1,46 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: mailu-webdav-ingress - namespace: mailu-mailserver - annotations: - kubernetes.io/tls-acme: "true" - nginx.ingress.kubernetes.io/proxy-body-size: "0" - certmanager.k8s.io/cluster-issuer: letsencrypt-stage - #ingress.kubernetes.io/auth-url: http://admin.mailu-mailserver.svc.cluster.local/internal/auth/basic - ingress.kubernetes.io/configuration-snippet: | - rewrite ^/webdav/(.*) /$1 break; - auth_request /internal/auth/basic; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - auth_request_set $user $upstream_http_x_user; - proxy_set_header X-Remote-User $user; - proxy_set_header X-Script-Name /webdav; - ingress.kubernetes.io/server-snippet: | - location /internal { - internal; - - proxy_set_header Authorization $http_authorization; - proxy_pass_header Authorization; - proxy_pass http://admin.mailu-mailserver.svc.cluster.local; - proxy_pass_request_body off; - proxy_set_header Content-Length ""; - } - labels: - app: mailu - role: mail - tier: frontend -spec: - tls: - - hosts: - - "mail.example.com" - secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt - rules: - - host: "mail.example.com" - http: - paths: - - path: "/webdav" - backend: - serviceName: webdav - servicePort: 5232 \ No newline at end of file diff --git a/docs/kubernetes/mailu/webmail-ingress.yaml b/docs/kubernetes/mailu/webmail-ingress.yaml deleted file mode 100644 index 40655ca2..00000000 --- a/docs/kubernetes/mailu/webmail-ingress.yaml +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: mailu-webmail-ingress - namespace: mailu-mailserver - annotations: - kubernetes.io/tls-acme: "true" - nginx.ingress.kubernetes.io/proxy-body-size: "0" - certmanager.k8s.io/cluster-issuer: letsencrypt-stage - nginx.ingress.kubernetes.io/configuration-snippet: | - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; - labels: - app: mailu - role: mail - tier: backend -spec: - tls: - - hosts: - - "webmail.example.com" - secretName: letsencrypt-webmail # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt - rules: - - host: "webmail.example.com" - http: - paths: - - path: "/" - backend: - serviceName: webmail - servicePort: 80 \ No newline at end of file diff --git a/towncrier/newsfragments/1158.feature b/towncrier/newsfragments/1158.feature new file mode 100644 index 00000000..12f9c049 --- /dev/null +++ b/towncrier/newsfragments/1158.feature @@ -0,0 +1 @@ +- Use nginx as http endpoint on kubernetes to simplify ingress