jcmoraisjr / haproxy-ingress

HAProxy Ingress
https://haproxy-ingress.github.io
Apache License 2.0
1.03k stars 269 forks source link

Switch default TCP Backend for unknown SNIs #966

Open hans-fischer opened 1 year ago

hans-fischer commented 1 year ago

Hello. I just found this nice project and already managed to run it outside the K8S-Cluster.

It is much more customisable then the hatech-implementation and I realy want to use it in our K8S-Cluster.

What are you trying to do

TL;DR: A default TCP Backend if SNI is unknown for HA-PROXY-INGRESS.

We are currently using NGINX inside the k8s-cluster with HA-Proxy outside in TCP mode. My Team does not known, if they need NGINX capabilities and don't want to switch in a BIGBANG manner. It would be nice if I could send Traffic for unknown SNIs to the currently working NGINX if the IngressClass of Ha-Proxy-Ingress don't know the SNI because the NGINX could know the SNI.

What HAProxy Ingress should do or how it should behave differently

A parameter to set a different TCP-Backend to a K8S-Service with Port-Parameter and a Parameter to set proxy-protocol.

jcmoraisjr commented 1 year ago

Hi thanks for evaluating this humble controller! Please have a look at tcp-services documentation, maybe it already does what you want. It should work pretty much like its HTTP counterpart, so configure an ingress without hostname or path in order to create a "default backend" for tcp mode.

I don't remember to use it in that way, so please let me know if you have any problem. You can use this same issue or even reach us on slack if you prefer.

hans-fischer commented 1 year ago

Hello jcmoraisjr, thank you for your reply.

I know the tcp-service-config already. Its fine for all kinds of other services.

I'am looking for a change in the section: TCP/TLS frontend

listen _fronttls mode tcp bind :443 tcp-request inspect-delay 5s tcp-request content set-var(req.sslpassback) req.ssl_sni,lower,map_str(/etc/haproxy/maps/_front_sslpassthroughexact.map) tcp-request content accept if { req.ssl_hello_type 1 } use_backend %[var(req.sslpassback)] if { var(req.sslpassback) -m found } use_backend _default_server_https_socket unix@/var/run/haproxy/_https_socket.sock send-proxy-v2 if { [IN_HTTP_S_SNI_LIST] -m found } server [K8S-NGINX-SVC-PODS] send-proxy-v2

Last two lines have changed. Code in brackets[] is pseudo-code. I don't know how to implement jet.

I don't know if that is technical possible but I see a good chance.

Kind regards Hans Fischer

jcmoraisjr commented 1 year ago

Maybe this is what you're looking for:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: haproxy
    haproxy-ingress.github.io/ssl-passthrough: "true"
  name: someing
  namespace: default
spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: somesvc
            port:
              number: 8443
        path: /
        pathType: Prefix
hans-fischer commented 1 year ago

Thank you for your effort.

Unfortunately this redirects all traffic from 443 to the "nginx backend". Because this TCP-rule kicks first and everytime when the HAPORXY:443 is called.

My goal is to establish this new HA-Proxy-Ingress aside to the old NGINX. So I have a Ingress Class for NGINX and HAPORXY. HAPROXY evaluate first, thats clear. So the goal would be HAPROXY checks if he knows the an Ingress-Object with SNI example.com than redirects to the HA-PROXY-https-backend, if NOT redirects to NGINX.

The reason is, we could still use the nginx and slowly migrate the HAPORXY-INGRESS.

The current implementation is HAPROXY checks TCP-SNI against a list and if found, redirects to specific TCP Backend. If you put a *-wildcard on that list. Its not possible to use, test or migrate slowly to the new IngressClass.

Kind regards Hans Fischer

jcmoraisjr commented 1 year ago

I see, the tcp frontend evaluates before the http one have a chance to identify if a request belongs to haproxy or not. I can see the big picture here and I'm going to tag it as backlog and give it a chance for a future version. In the short term I cannot see a way to accomplish that without fronting both controllers with another proxy that chooses the right ingress based on incoming hdr(host) (if http) or SNI (https).

hans-fischer commented 1 year ago

Hey jcmoraisjr, thank you very much for accepting my concern. I understand that you put it in Backlog. I might provide a MR when I have the time to implement it myself.

Kind regards Hans Fischer