Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose non-HTTP services via NodePorts #72

Closed
asoltesz opened this issue Oct 5, 2020 · 5 comments
Closed

Expose non-HTTP services via NodePorts #72

asoltesz opened this issue Oct 5, 2020 · 5 comments
Labels
enhancement New feature or request

Comments

@asoltesz
Copy link

asoltesz commented Oct 5, 2020

Is your feature request related to a problem? Please describe.

Currently, non-HTTP services like SMTP (25) and SMTPS (465) are exposed via hostPort definitions on the Kubernetes node (host) that runs the "front" pod. By default there is 1 replica of the "front" pod.

The administrator needs to know which node/host runs the "front" pod and set the MX/DNS record(s) to that node directly.

This is inherently problematic and results in low availability. The node can die unexpectedly, and as a Kubernetes best-practice, there shouldn't be any assumption for a service running on a specific node. When the "front" pod is moved to another node (after the crash of the og node), the mail services stop immediately since the "front" pod will open the ports on an other IP address and traffic will not come to that until the DNS records are updated and refreshed to clients (TTL).

Currently, the administrator needs to lock the deployment's pod scheduling to a specific node with a nodeSelector.

Describe the solution you'd like

Add the option to expose non-HTTP services on NodePorts.

NodePorts are in a range (e.g.: 30000-32600) but the administrator knows this beforehand (attribute of the cluster) and it can assign a specific nodeport to each service (e.g.: 30025 to SMTP) via the Helm chart variables.

The administrator then sets up local port-forwards on all cluster nodes as needed (e.g.: 25 >> 30025). Cluster nodes are typically automatically provisioned, so this shouldn't be a problem.

Kubernetes will automatically accept mail-related traffic on any of the nodes and internally route it to the "front" container.

From this point the MX/DNS record can be assigned to something like a simple Floating IP which moves automatically to another node when its owner node crashes (I use Hetzner and their fip-controller).

Describe alternatives you've considered

Deploy "front" as DaemonSet (#46)

#46 would result in the "front" container running on all of the cluster nodes which feels like an overkill, even if the "front" container is lightweight.

Additional context

@asoltesz asoltesz added the enhancement New feature or request label Oct 5, 2020
@micw
Copy link
Contributor

micw commented Jan 10, 2021

I merged #46 - does this fix the issue for you? With port forwarding there's always the risk that all requests seems to come from localhost, making mailu an open relay.

@asoltesz
Copy link
Author

asoltesz commented Jan 12, 2021

I further investigated the issues around NodePorts and it seems that it is NOT possible to preserve the Source IP when NodePorts are used the way I described them in my enhancement request. (as of Kubernetes v1.19)

https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-type-nodeport

To avoid this, Kubernetes has a feature to preserve the client source IP. If you set service.spec.externalTrafficPolicy to the value Local, kube-proxy only proxies proxy requests to local endpoints, and does not forward traffic to other nodes. This approach preserves the original source IP address. If there are no local endpoints, packets sent to the node are dropped, so you can rely on the correct source-ip in any packet processing rules you might apply a packet that make it through to the endpoint.

So, I think my original request would create an open-relay.

@asoltesz
Copy link
Author

NOTE:

I have solved my original issue (that prompted the enhancement request) by creating/updating DNS entries dynamically with External-DNS and a small Mailu-specific operator that I wrote for this purpose.

The managed DNS entry always points to the exact Kubernetes node that is running the Mailu Front pod. It the Front pod is migrated to another Kubernetes node, the DNS entry gets updated.

See the operator on GitHUB.

@tbscode
Copy link

tbscode commented Oct 24, 2023

Very old issue, a lot has changed in the chart.

What is the recommended way to connect to the smtp tcp port externally?

I have a basic installation of the chart working on my cluster.
I can login, send and receive emails use the admin interface and webmailer.
I'm using microk8s + metallb and have tested for open relays.

But I was not yet able to send emails from another machine though smtp.

So-far I tried

  1. using the default hostPort.enabed: true and exposing 465 port.
  2. Configuring values.yaml
front:
  externalService:
    type: LoadBalancer
    enabled: true
    loadBalancerIP: <server-ip>

And then exposing the port that the load balancer get mapped for 465.

Both without success.

@tbscode
Copy link

tbscode commented Oct 24, 2023

Whoops ok both approaches work totally fine, when trying the correct port 587.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants