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 Load-balancer port through uPNP #58

Closed
thebsdbox opened this issue Jul 20, 2020 · 6 comments · Fixed by #96
Closed

Expose Load-balancer port through uPNP #58

thebsdbox opened this issue Jul 20, 2020 · 6 comments · Fixed by #96
Labels
enhancement New feature or request services in-cluster

Comments

@thebsdbox
Copy link
Collaborator

This is technically possible to expose the port mapping to a commercial router so we could:

  • Create VIP
  • Create Load-balancer
  • Expose VIP:Port to router:port through uPNP

kubectl expose deployment nginx-deployment --port=18080 --type=LoadBalancer --name=nginx-loadbalancer

The --port=xxx will need to be considered for the uPNP endpoint (router)

Errors will be hard to handle as it's not something that Kubernetes load-balancers are designed to handle, errors would exist the kube-vip pod in the namespace the load-balancer is created in. This is where an end-user would find that the exposed port hasn't made it to the router (such as having an already existing port-mapping created).

cc / @displague

@thebsdbox thebsdbox added this to the 0.1.7 release milestone Jul 20, 2020
@thebsdbox thebsdbox added enhancement New feature or request services in-cluster labels Jul 20, 2020
@thebsdbox
Copy link
Collaborator Author

package main

import "fmt"
import "github.com/yanzay/upnp"

func main() {

upnpMan := new(upnp.Upnp)
err := upnpMan.SearchGateway()
if err != nil {
        fmt.Println(err.Error())
} else {
        fmt.Println("local ip address: ", upnpMan.LocalHost)
        fmt.Println("gateway ip address: ", upnpMan.Gateway.Host)
}

err = upnpMan.ExternalIPAddr()
if err != nil {
        fmt.Println(err.Error())
} else {
        fmt.Println("internet ip address: ", upnpMan.GatewayOutsideIP)
}

>  cat main.go                                                      upnp-master
package main

import "fmt"
import "github.com/yanzay/upnp"

func main() {

upnpMan := new(upnp.Upnp)
err := upnpMan.SearchGateway()
if err != nil {
	fmt.Println(err.Error())
} else {
	fmt.Println("local ip address: ", upnpMan.LocalHost)
	fmt.Println("gateway ip address: ", upnpMan.Gateway.Host)
}

err = upnpMan.ExternalIPAddr()
if err != nil {
	fmt.Println(err.Error())
} else {
	fmt.Println("internet ip address: ", upnpMan.GatewayOutsideIP)
}

mapping := new(upnp.Upnp)
if err := mapping.AddPortMapping(22, 55789, "TCP"); err == nil {
	fmt.Println("success !")
	// remove port mapping in gatway
//	mapping.Reclaim()
} else {
	fmt.Println("fail !")
}

}

^ earlier testing (needs to put it somewhere)

@displague
Copy link
Contributor

I'm adding relevant keywords so this can be better found in Google searches:
https://tools.ietf.org/html/rfc6970
Universal Plug and Play (UPnP), Internet Gateway Device - Port Control Protocol Interworking Function, (IGD-PCP IWF)

@displague
Copy link
Contributor

displague commented Jul 21, 2020

I ran this PoC code (with the router port 22 and a 100s port removal). This is awesome!

@displague
Copy link
Contributor

A uPNP CCM could query the network (SSDP) to find out if a node is no longer available (to remove it from the cluster), https://www.electricmonk.nl/log/2016/07/05/exploring-upnp-with-python/

@thebsdbox
Copy link
Collaborator Author

Attempted to implement this only to be hit with a brick wall ->
VIP 192.168.0.201
Host 192.168.0.45

image

I can't advertise the VIP to the router, only the address of the host itself

@thebsdbox
Copy link
Collaborator Author

Merged as of #96

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

Successfully merging a pull request may close this issue.

2 participants