mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-04 19:55:09 -04:00
Add migration from legacy tcp to named pipes
This commit is contained in:
@@ -144,7 +144,7 @@ func init() {
|
||||
|
||||
defaultDaemonAddr := "unix:///var/run/netbird.sock"
|
||||
if runtime.GOOS == "windows" {
|
||||
defaultDaemonAddr = "npipe://netbird"
|
||||
defaultDaemonAddr = windowsPipeDaemonAddr
|
||||
}
|
||||
|
||||
rootCmd.PersistentFlags().StringVar(&daemonAddr, "daemon-addr", defaultDaemonAddr, "Daemon service address to serve CLI requests [unix|tcp|npipe]://[path|host:port|name]")
|
||||
|
||||
@@ -62,6 +62,15 @@ func (p *program) Start(svc service.Service) error {
|
||||
// Collect static system and platform information
|
||||
system.UpdateStaticInfoAsync()
|
||||
|
||||
// A daemon installed before named-pipe support uses the old loopback-TCP
|
||||
// address as the daemon address. We migrate to a named pipe so an
|
||||
// upgraded daemon enforces per-caller authorization instead of silently
|
||||
// running on identity-less TCP.
|
||||
if migrated, ok := migrateLegacyDaemonAddr(daemonAddr); ok {
|
||||
log.Infof("legacy daemon address %q predates named-pipe support. listening on %q so per-caller authorization is enforced", daemonAddr, migrated)
|
||||
daemonAddr = migrated
|
||||
}
|
||||
|
||||
network, _, err := parseListenAddress(daemonAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parse daemon address: %w", err)
|
||||
|
||||
@@ -125,6 +125,10 @@ func applyServiceParams(cmd *cobra.Command, params *serviceParams) {
|
||||
|
||||
if !rootCmd.PersistentFlags().Changed("daemon-addr") && params.DaemonAddr != "" {
|
||||
daemonAddr = params.DaemonAddr
|
||||
if migrated, ok := migrateLegacyDaemonAddr(daemonAddr); ok {
|
||||
cmd.Printf("Migrating saved daemon address %q to %q so per-caller authorization can be enforced\n", daemonAddr, migrated)
|
||||
daemonAddr = migrated
|
||||
}
|
||||
}
|
||||
|
||||
if !serviceCmd.PersistentFlags().Changed("json-socket") && params.JSONSocket != "" {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -14,6 +15,31 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
windowsPipeDaemonAddr = "npipe://netbird"
|
||||
|
||||
// legacyWindowsDaemonAddr is the loopback-TCP address the Windows daemon used
|
||||
// before named-pipe support. TCP exposes no peer-identity primitive, so the
|
||||
// authorization interceptor cannot run over it.
|
||||
legacyWindowsDaemonAddr = "tcp://127.0.0.1:41731"
|
||||
)
|
||||
|
||||
// migrateLegacyDaemonAddr upgrades the pre-named-pipe Windows daemon address to
|
||||
// the pipe. Existing installs persist daemon addr, so on upgrade the daemon
|
||||
// would otherwise keep listening on TCP and silently run without IPC
|
||||
// authorization. Only the exact legacy default is rewritten, while a
|
||||
// deliberately-chosen custom TCP address is left alone.
|
||||
func migrateLegacyDaemonAddr(addr string) (string, bool) {
|
||||
return migrateLegacyDaemonAddrForOS(runtime.GOOS, addr)
|
||||
}
|
||||
|
||||
func migrateLegacyDaemonAddrForOS(goos, addr string) (string, bool) {
|
||||
if goos == "windows" && addr == legacyWindowsDaemonAddr {
|
||||
return windowsPipeDaemonAddr, true
|
||||
}
|
||||
return addr, false
|
||||
}
|
||||
|
||||
type socketListener struct {
|
||||
net.Listener
|
||||
network string
|
||||
|
||||
63
client/cmd/service_socket_test.go
Normal file
63
client/cmd/service_socket_test.go
Normal file
@@ -0,0 +1,63 @@
|
||||
//go:build !ios && !android
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMigrateLegacyDaemonAddrForOS(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
goos string
|
||||
addr string
|
||||
want string
|
||||
migrate bool
|
||||
}{
|
||||
{
|
||||
name: "windows legacy tcp migrates to pipe",
|
||||
goos: "windows",
|
||||
addr: legacyWindowsDaemonAddr,
|
||||
want: windowsPipeDaemonAddr,
|
||||
migrate: true,
|
||||
},
|
||||
{
|
||||
name: "windows pipe already migrated stays",
|
||||
goos: "windows",
|
||||
addr: windowsPipeDaemonAddr,
|
||||
want: windowsPipeDaemonAddr,
|
||||
migrate: false,
|
||||
},
|
||||
{
|
||||
name: "windows custom tcp left alone",
|
||||
goos: "windows",
|
||||
addr: "tcp://127.0.0.1:9999",
|
||||
want: "tcp://127.0.0.1:9999",
|
||||
migrate: false,
|
||||
},
|
||||
{
|
||||
name: "linux legacy-looking tcp not migrated",
|
||||
goos: "linux",
|
||||
addr: legacyWindowsDaemonAddr,
|
||||
want: legacyWindowsDaemonAddr,
|
||||
migrate: false,
|
||||
},
|
||||
{
|
||||
name: "linux unix socket untouched",
|
||||
goos: "linux",
|
||||
addr: "unix:///var/run/netbird.sock",
|
||||
want: "unix:///var/run/netbird.sock",
|
||||
migrate: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got, ok := migrateLegacyDaemonAddrForOS(tc.goos, tc.addr)
|
||||
assert.Equal(t, tc.want, got)
|
||||
assert.Equal(t, tc.migrate, ok)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user