slackhq / nebula

A scalable overlay networking tool with a focus on performance, simplicity and security

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

πŸ› BUG: Stoping Nebula does not free up port :4242

azukaar opened this issue Β· comments

What version of nebula are you using?

1.7.12

What operating system are you using?

all

Describe the Bug

When running Nebula programmatically, it does not free up port :4242
This is causing some issues, for example re-connecting on the Android app requires restarting the app completely to bypass the error complaining about the port being already busy.

You can test this easily like this:

package main

import (
	"github.com/slackhq/nebula"
	"github.com/slackhq/nebula/config"
	"github.com/sirupsen/logrus"
	"os"
	"fmt"
	"time"
)

func startNebula(configRaw []byte) *nebula.Control {
	logrus := logrus.New()
        logrus.Out = os.Stdout	 
	logrus.Info("## Starting nebula")
	
	c := config.NewC(logrus)
	err := c.LoadString(string(configRaw))
	if err != nil {
		fmt.Println(err)
		return nil
	}

	// Adjust PKI paths to be absolute
	
	l, err := nebula.Main(c, false, "", logrus, nil)

	if err != nil {
		fmt.Println(err)
		return nil
	}

	l.Start()
	
	logrus.Info("## Started Nebula")

	return l
}

func main() {
	// read config from test.yml
	config, err := os.ReadFile("test.yml")
	if err != nil {
		fmt.Printf("Failed to read config: %v", err)
		return
	}
	
	l := startNebula(config)

	time.Sleep(2 * time.Second)

	l.Stop()

	time.Sleep(2 * time.Second)

	startNebula(config)
}

Logs from affected hosts

No response

Config files from affected hosts

No response

Hi @azukaar -

AFAIK, calling nebula.Main multiple times is unsupported and listen.port is not a reloadable setting. In other words, this is expected behavior. Maybe you can describe more clearly what you're trying to achieve?

This is causing some issues, for example re-connecting on the Android app requires restarting the app completely to bypass the error complaining about the port being already busy.

If you're experiencing a bug with Mobile Nebula, please file a ticket at https://github.com/DefinedNet/mobile_nebula. This isn't something I've seen reports of, nor do I experience myself. In the mobile app, IIRC, we kill the Nebula process and create a new one when restarting. Although we also tend to use an ephemeral port...

I was writing a OS service was a desktop application connecting to Nebula
Having to restart the service on every disconnection is a little overkill in what you would normally expect to be doing (just stop() and start() the service)
Feel free to close the ticket if that's not something you plan on improving

Hi @azukaar -

Nebula was written as an application first and so the code was written in such a way that it expects a systemctl stop nebula (for example), shutting the entire process down and bringing it back up.

Some initial support for using Nebula like a library was first added in order to support Mobile Nebula, IIRC.

Some configuration can be reloaded via the reload() call. Does this achieve what you're looking for? Another option might be to run Nebula in a disposable sub-process.

Thanks for your input!
I will just restart the service for now (reload() does not work as I would like to possibly change the config)

@azukaar I think that's the best option at the moment...

But I didn't mean to imply this isn't something we would like to support. Just not something we seem to have tackled yet.

Can you share which platform you're running on?

I was mistaken. This should be doing what you want already...

In interface.go we do try to close all listeners:

nebula/interface.go

Lines 410 to 415 in 280fa02

for _, u := range f.writers {
err := u.Close()
if err != nil {
f.l.WithError(err).Error("Error while closing udp socket")
}
}

The UDP listener is passed to Interface here:

nebula/main.go

Line 299 in 280fa02

ifce.writers = udpConns

The Interface should be closed when the Control is closed:

nebula/control.go

Lines 82 to 84 in 280fa02

if err := c.f.Close(); err != nil {
c.l.WithError(err).Error("Close interface failed")
}

Yes I saw this code that is why I was confused and marked it as a bug,
if you try the code I sent earlier you will see that the port is indeed not closed (tested on both Android and Windows with 1.7.2)
I closed the ticket after your previous comment but if you agree it is actually a bug it can be re-opened

@azukaar It looks like this issue was fixed in a3e59a3. Can you re-test with your code pointed at master instead of v1.7.2?

@azukaar Were you able to re-test with master?

Sorry for delay @johnmaguire the issue cannot be reproduced on @master branch

No worries, thanks for checking. Closing as fixed by a3e59a3