rancher-sandbox / rancher-desktop

Container Management and Kubernetes on the Desktop
https://rancherdesktop.io
Apache License 2.0
6.04k stars 285 forks source link

Bring back iptable scanning #7723

Closed Nino-K closed 2 weeks ago

Nino-K commented 3 weeks ago

Previously, the guestAgent in Rancher Desktop was picking up port mappings from iptables using the GetPorts function from Lima, as seen here. However, since the iptables scanning package was removed from the guestAgent, it no longer retrieves these port mappings.

An example of such a rule in iptables is as follows:

CNI-HOSTPORT-SETMARK  tcp  --  10.42.0.0/24         anywhere             tcp dpt:12345
CNI-HOSTPORT-SETMARK  tcp  --  localhost            anywhere             tcp dpt:12345
DNAT       tcp  --  anywhere             anywhere             tcp dpt:12345 to:10.42.0.100:80
CNI-DN-6ef6bede9244615191a81  tcp  --  anywhere             anywhere             /* dnat name: "cbr0" id: "0344293f74a8790f54a73bdd10f97bfaf98b3fb80b8e88c610f2da8ddf1c241a" */ multiport dports 12345

These rules are generated by the CNI (Container Network Interface) plugin for pod-to-pod communication. They are part of Kubernetes' networking and ensure that traffic on specific host ports (e.g., port 12345) is correctly routed to the appropriate pod, with the CNI plugin managing the handling of that traffic.

Given their role in routing traffic correctly within Kubernetes, it is important that these rules are not overlooked by the guestAgent.

TCP Repro Steps

  1. Download echo-server.yaml from https://gist.github.com/mikeseese/cca62f2dba7a453ebe172031a9490760
  2. Using Rancher Desktop v1.16.0, K8s v1.30.5, CE: moby, start up the cluster
  3. kubectl apply -f echo-server.yaml
  4. curl <hostIP>:12345/param?query=demo
  5. See that curl can't reach the host
    • It should have returned a JSON object, i.e.:
      {"host":{"hostname":"127.0.0.1","ip":"::ffff:127.0.0.1","ips":[]},"http":{"method":"GET","baseUrl":"","originalUrl":"/param?query=demo","protocol":"http"},"request":{"params":{"0":"/param"},"query":{"query":"demo"},"cookies":{},"body":{},"headers":{"host":"127.0.0.1:12345","user-agent":"curl/8.1.2","accept":"*/*"}},"environment":{"PATH":"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","HOSTNAME":"echo-server","INGRESS_NGINX_CONTROLLER_ADMISSION_SERVICE_PORT_HTTPS_WEBHOOK":"443","INGRESS_NGINX_CONTROLLER_ADMISSION_PORT_443_TCP_ADDR":"10.43.14.22","INGRESS_NGINX_CONTROLLER_SERVICE_PORT_HTTP":"80","INGRESS_NGINX_CONTROLLER_PORT_443_TCP_PORT":"443","KUBERNETES_PORT_443_TCP_ADDR":"10.43.0.1","INGRESS_NGINX_CONTROLLER_ADMISSION_SERVICE_PORT":"443","INGRESS_NGINX_CONTROLLER_PORT_443_TCP":"tcp://10.43.38.178:443","KUBERNETES_SERVICE_PORT":"443","KUBERNETES_SERVICE_PORT_HTTPS":"443","INGRESS_NGINX_CONTROLLER_SERVICE_HOST":"10.43.38.178","INGRESS_NGINX_CONTROLLER_SERVICE_PORT":"80","INGRESS_NGINX_CONTROLLER_PORT_80_TCP_ADDR":"10.43.38.178","INGRESS_NGINX_CONTROLLER_PORT_443_TCP_PROTO":"tcp","INGRESS_NGINX_CONTROLLER_ADMISSION_PORT_443_TCP_PORT":"443","INGRESS_NGINX_CONTROLLER_PORT_80_TCP":"tcp://10.43.38.178:80","INGRESS_NGINX_CONTROLLER_PORT_80_TCP_PROTO":"tcp","KUBERNETES_SERVICE_HOST":"10.43.0.1","KUBERNETES_PORT_443_TCP":"tcp://10.43.0.1:443","KUBERNETES_PORT_443_TCP_PORT":"443","INGRESS_NGINX_CONTROLLER_ADMISSION_SERVICE_HOST":"10.43.14.22","INGRESS_NGINX_CONTROLLER_ADMISSION_PORT":"tcp://10.43.14.22:443","INGRESS_NGINX_CONTROLLER_ADMISSION_PORT_443_TCP":"tcp://10.43.14.22:443","INGRESS_NGINX_CONTROLLER_SERVICE_PORT_HTTPS":"443","INGRESS_NGINX_CONTROLLER_PORT_80_TCP_PORT":"80","KUBERNETES_PORT_443_TCP_PROTO":"tcp","INGRESS_NGINX_CONTROLLER_ADMISSION_PORT_443_TCP_PROTO":"tcp","INGRESS_NGINX_CONTROLLER_PORT":"tcp://10.43.38.178:80","INGRESS_NGINX_CONTROLLER_PORT_443_TCP_ADDR":"10.43.38.178","KUBERNETES_PORT":"tcp://10.43.0.1:443","NODE_VERSION":"16.16.0","YARN_VERSION":"1.22.19","HOME":"/root"}}
  6. To see what you should have seen, you can forward the port manually: kubectl port-forward pods/echo-server 12345:80 -n default and change the curl command to use the localhost IP curl 127.0.0.1:12345/param?query=demo

Fixes: https://github.com/rancher-sandbox/rancher-desktop/issues/7722

jandubois commented 3 weeks ago

Previously, the guestAgent in Lima was picking up port mappings from iptables using the GetPorts function, as seen here. However, since the iptables scanning package was removed from the guestAgent, it no longer retrieves these port mappings.

The iptables scanning code was never removed from Lima; it is still there. Did you mean the code in Rancher Desktop was removed from the WSL2 code?

Nino-K commented 3 weeks ago

The iptables scanning code was never removed from Lima; it is still there. Did you mean the code in Rancher Desktop was removed from the WSL2 code?

Thanks, I corrected it now. I meant Rancher Desktop.

Nino-K commented 3 weeks ago

Mostly comments, but I do think the blocking sleep must be replaced by something cancellable.

I agree. To be honest, I just revived the old code with a minor modification to make it work for our current needs, but I didn't change any of the old pars, assuming that it was previously doing the right thing. However, I agree with removing the time.Sleep. Also, the comparePorts code naming is terrible.