Skip to content
This repository has been archived by the owner on Sep 12, 2024. It is now read-only.

Add a proxy for wsl integration #15

Merged
merged 3 commits into from
Jan 31, 2024
Merged

Add a proxy for wsl integration #15

merged 3 commits into from
Jan 31, 2024

Conversation

Nino-K
Copy link
Member

@Nino-K Nino-K commented Jan 23, 2024

This commit introduces a proxy server that actively listens in the default network, capturing all incoming requests destined for the Kubernetes API server within the network namespace.

Related to: rancher-sandbox/rancher-desktop#6245
Fixes: rancher-sandbox/rancher-desktop#6359

@Nino-K Nino-K requested a review from mook-as January 23, 2024 21:30
Copy link
Contributor

@mook-as mook-as left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear why this is scoped as it is (and it's not clearly documented).

README.md Outdated
```
## wsl-proxy
Its primary function comes into play when WSL integration is activated alongside the network tunnel. The purpose is to actively listen on `127.0.0.1:6443` and reroute all incoming requests to the upstream Kubernetes API server residing within the network namespace. The proxy achieves this by directing the incoming traffic through a Virtual Ethernet pair. Specifically, `veth-rd0` serves as the originating end listening in the default network, while `veth-rd1` acts as the terminating end within the network namespace.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and reroute all incoming requests to the upstream Kubernetes API server residing within the network namespace

It also routes non-Kubernetes things, right? (Think random containers)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It routes anything that is destined for K8s API server at 127.0.0.1:6443.

README.md Outdated
```
## wsl-proxy
Its primary function comes into play when WSL integration is activated alongside the network tunnel. The purpose is to actively listen on `127.0.0.1:6443` and reroute all incoming requests to the upstream Kubernetes API server residing within the network namespace. The proxy achieves this by directing the incoming traffic through a Virtual Ethernet pair. Specifically, `veth-rd0` serves as the originating end listening in the default network, while `veth-rd1` acts as the terminating end within the network namespace.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to somehow document what is doing work on veth-rd1, since wsl-proxy sounds like it runs within the default namespace (and needs something on the other end to help it).

cmd/proxy/wsl_integration_linux.go Outdated Show resolved Hide resolved
Copy link
Contributor

@mook-as mook-as left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slight doc changes.

README.md Outdated
@@ -47,7 +47,7 @@ portForwarding["Port Forwarding"]
`host-switch` runs on the Windows host and acts as a receiver for all traffic originating from the network namespace within the WSL VM. It performs a handshake to find the right VM to talk to over `AF_VSOCK`. Once a correct VM is found, it then listens for the incoming traffic from that VM. In additon to this, it can provide a DNS resolver that runs in the user space network along with an API that allows for dynamic port forwarding.

## network-setup
Its main responsibility is to respond to the handshake request from the `host-switch.exe`, create a network namespace and start the `vm-switch` subprocess in the newly created network namespace. In addition, it also calls unshare with provided arguments through `--unshare-args`. Below is a sequence diagram demonstrating the process.
Its main responsibility is to respond to the handshake request from the `host-switch.exe`, create a network namespace and start the `vm-switch` subprocess in the newly created network namespace. In addition, it also calls unshare with provided arguments through `--unshare-args`. Below is a sequence diagram demonstrating the process. The process also establishes a Virtual Ethernet pair consisting of two endpoints: veth-rd0 and `veth-rd1`. `veth-rd0` resides within the default namespace and is configured to listen on the IP address `192.168.1.1`. Conversely, `veth-rd1` is located within a network namespace and is assigned the IP address `192.168.1.2`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Its main responsibility is to respond to the handshake request from the `host-switch.exe`, create a network namespace and start the `vm-switch` subprocess in the newly created network namespace. In addition, it also calls unshare with provided arguments through `--unshare-args`. Below is a sequence diagram demonstrating the process. The process also establishes a Virtual Ethernet pair consisting of two endpoints: veth-rd0 and `veth-rd1`. `veth-rd0` resides within the default namespace and is configured to listen on the IP address `192.168.1.1`. Conversely, `veth-rd1` is located within a network namespace and is assigned the IP address `192.168.1.2`.
Its main responsibility is to respond to the handshake request from the `host-switch.exe`, create a network namespace and start the `vm-switch` subprocess in the newly created network namespace. In addition, it also calls unshare with provided arguments through `--unshare-args`. Below is a sequence diagram demonstrating the process. The process also establishes a Virtual Ethernet pair consisting of two endpoints: `veth-rd0` and `veth-rd1`. `veth-rd0` resides within the default namespace and is configured to listen on the IP address `192.168.1.1`. Conversely, `veth-rd1` is located within a network namespace and is assigned the IP address `192.168.1.2`.

README.md Outdated
```
## wsl-proxy
Its primary function comes into play when WSL integration is activated alongside the network tunnel. The purpose is to actively listen on `127.0.0.1:6443` and reroute all incoming requests to the upstream Kubernetes API server residing within the network namespace. Although, in the future this coponent will expand to proxy non k8s API traffic (e.g container traffic into the namespace) The proxy achieves this by directing the incoming traffic through a Virtual Ethernet pair. Specifically, `veth-rd0` serves as the originating end listening in the default network, while `veth-rd1` acts as the terminating end within the network namespace.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the last bit is better phrased as

The proxy uses 192.168.1.2:6443 as its upstream, which is the veth-rd1 interface created by network-setup.

Nothing in the wsl-proxy process actually deals with veth.

cmd/proxy/wsl_integration_linux.go Outdated Show resolved Hide resolved
Comment on lines +24 to +25
bin/wsl-proxy:
GOOS=linux go build $(LDFLAGS) -o $@ ./cmd/proxy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it's kind of odd that the directory named proxy produces a binary named wsl-proxy (instead of proxy). But that's an issue we also have with all the other commands…

TargetURL *url.URL
}

// handleRequestAndRedirect Copies the original request headers to the new request,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// handleRequestAndRedirect Copies the original request headers to the new request,
// handleRequestAndRedirect copies the original request headers to the new request,

}

// handleRequestAndRedirect Copies the original request headers to the new request,
// and updates the request URL to the target URL. It then Performs the request to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// and updates the request URL to the target URL. It then Performs the request to
// and updates the request URL to the target URL. It then performs the request to

}
}

type requestHandler struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we're not using httputil.ReverseProxy? I'm mostly thinking about annoying bits like websocket / upgrade support (which ends up being used for logs and things, I think).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we're not using httputil.ReverseProxy? I'm mostly thinking about annoying bits like websocket / upgrade support (which ends up being used for logs and things, I think).

Is there going to be websocket? this proxy is meant to only talk to k8s API endpoint and I think that is mostly https. However, it wouldn't hurt to use httputil.ReverseProxy.

Comment on lines 53 to 55
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
proxy.ServeHTTP(writer, request)
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this isn't just

	http.ListenAndServe(listenAddr, proxy)

This commit introduces a proxy server that actively listens
in the default network, capturing all incoming requests
destined for the Kubernetes API server within the network namespace.

Signed-off-by: Nino Kodabande <[email protected]>
Signed-off-by: Nino Kodabande <[email protected]>
Signed-off-by: Nino Kodabande <[email protected]>
Comment on lines +55 to +57
if err != nil {
logrus.Error("Error starting server:", err)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, the docs says:

ListenAndServe always returns a non-nil error.

But I don't think that's an issue here.

@Nino-K Nino-K merged commit 7853cfc into main Jan 31, 2024
2 checks passed
@Nino-K Nino-K deleted the add-wsl-integration-proxy branch January 31, 2024 18:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create a proxy exposing the API server on 127.0.0.1:6443 in the shared namespace
2 participants