mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-22 02:06:39 +00:00
Compare commits
3 Commits
logs/peerl
...
set-cmd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0c3818e06 | ||
|
|
6922826919 | ||
|
|
56a1a75e3f |
210
client/cmd/flags.go
Normal file
210
client/cmd/flags.go
Normal file
@@ -0,0 +1,210 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/netbirdio/netbird/client/iface"
|
||||
"github.com/netbirdio/netbird/client/internal"
|
||||
"github.com/netbirdio/netbird/management/domain"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// SharedFlags contains all configuration flags that are common between up and set commands
|
||||
type SharedFlags struct {
|
||||
// Network configuration
|
||||
InterfaceName string
|
||||
WireguardPort uint16
|
||||
NATExternalIPs []string
|
||||
CustomDNSAddress string
|
||||
ExtraIFaceBlackList []string
|
||||
DNSLabels []string
|
||||
DNSRouteInterval time.Duration
|
||||
|
||||
// Feature flags
|
||||
RosenpassEnabled bool
|
||||
RosenpassPermissive bool
|
||||
ServerSSHAllowed bool
|
||||
AutoConnectDisabled bool
|
||||
NetworkMonitor bool
|
||||
LazyConnEnabled bool
|
||||
|
||||
// System flags
|
||||
DisableClientRoutes bool
|
||||
DisableServerRoutes bool
|
||||
DisableDNS bool
|
||||
DisableFirewall bool
|
||||
BlockLANAccess bool
|
||||
BlockInbound bool
|
||||
|
||||
// Login-specific (only for up command)
|
||||
NoBrowser bool
|
||||
}
|
||||
|
||||
// AddSharedFlags adds all shared configuration flags to the given command
|
||||
func AddSharedFlags(cmd *cobra.Command, flags *SharedFlags) {
|
||||
// Network configuration flags
|
||||
cmd.PersistentFlags().StringVar(&flags.InterfaceName, interfaceNameFlag, iface.WgInterfaceDefault,
|
||||
"Wireguard interface name")
|
||||
cmd.PersistentFlags().Uint16Var(&flags.WireguardPort, wireguardPortFlag, iface.DefaultWgPort,
|
||||
"Wireguard interface listening port")
|
||||
cmd.PersistentFlags().StringSliceVar(&flags.NATExternalIPs, externalIPMapFlag, nil,
|
||||
`Sets external IPs maps between local addresses and interfaces. `+
|
||||
`You can specify a comma-separated list with a single IP and IP/IP or IP/Interface Name. `+
|
||||
`An empty string "" clears the previous configuration. `+
|
||||
`E.g. --external-ip-map 12.34.56.78/10.0.0.1 or --external-ip-map 12.34.56.200,12.34.56.78/10.0.0.1,12.34.56.80/eth1 `+
|
||||
`or --external-ip-map ""`)
|
||||
cmd.PersistentFlags().StringVar(&flags.CustomDNSAddress, dnsResolverAddress, "",
|
||||
`Sets a custom address for NetBird's local DNS resolver. `+
|
||||
`If set, the agent won't attempt to discover the best ip and port to listen on. `+
|
||||
`An empty string "" clears the previous configuration. `+
|
||||
`E.g. --dns-resolver-address 127.0.0.1:5053 or --dns-resolver-address ""`)
|
||||
cmd.PersistentFlags().StringSliceVar(&flags.ExtraIFaceBlackList, extraIFaceBlackListFlag, nil,
|
||||
"Extra list of default interfaces to ignore for listening")
|
||||
cmd.PersistentFlags().StringSliceVar(&flags.DNSLabels, dnsLabelsFlag, nil,
|
||||
`Sets DNS labels. `+
|
||||
`You can specify a comma-separated list of up to 32 labels. `+
|
||||
`An empty string "" clears the previous configuration. `+
|
||||
`E.g. --extra-dns-labels vpc1 or --extra-dns-labels vpc1,mgmt1 `+
|
||||
`or --extra-dns-labels ""`)
|
||||
cmd.PersistentFlags().DurationVar(&flags.DNSRouteInterval, dnsRouteIntervalFlag, time.Minute,
|
||||
"DNS route update interval")
|
||||
|
||||
// Feature flags
|
||||
cmd.PersistentFlags().BoolVar(&flags.RosenpassEnabled, enableRosenpassFlag, false,
|
||||
"[Experimental] Enable Rosenpass feature. If enabled, the connection will be post-quantum secured via Rosenpass.")
|
||||
cmd.PersistentFlags().BoolVar(&flags.RosenpassPermissive, rosenpassPermissiveFlag, false,
|
||||
"[Experimental] Enable Rosenpass in permissive mode to allow this peer to accept WireGuard connections without requiring Rosenpass functionality from peers that do not have Rosenpass enabled.")
|
||||
cmd.PersistentFlags().BoolVar(&flags.ServerSSHAllowed, serverSSHAllowedFlag, false,
|
||||
"Allow SSH server on peer. If enabled, the SSH server will be permitted")
|
||||
cmd.PersistentFlags().BoolVar(&flags.AutoConnectDisabled, disableAutoConnectFlag, false,
|
||||
"Disables auto-connect feature. If enabled, then the client won't connect automatically when the service starts.")
|
||||
cmd.PersistentFlags().BoolVarP(&flags.NetworkMonitor, networkMonitorFlag, "N", networkMonitor,
|
||||
`Manage network monitoring. Defaults to true on Windows and macOS, false on Linux and FreeBSD. `+
|
||||
`E.g. --network-monitor=false to disable or --network-monitor=true to enable.`)
|
||||
cmd.PersistentFlags().BoolVar(&flags.LazyConnEnabled, enableLazyConnectionFlag, false,
|
||||
"[Experimental] Enable the lazy connection feature. If enabled, the client will establish connections on-demand.")
|
||||
|
||||
// System flags (from system.go)
|
||||
cmd.PersistentFlags().BoolVar(&flags.DisableClientRoutes, disableClientRoutesFlag, false,
|
||||
"Disable client routes. If enabled, the client won't process client routes received from the management service.")
|
||||
cmd.PersistentFlags().BoolVar(&flags.DisableServerRoutes, disableServerRoutesFlag, false,
|
||||
"Disable server routes. If enabled, the client won't act as a router for server routes received from the management service.")
|
||||
cmd.PersistentFlags().BoolVar(&flags.DisableDNS, disableDNSFlag, false,
|
||||
"Disable DNS. If enabled, the client won't configure DNS settings.")
|
||||
cmd.PersistentFlags().BoolVar(&flags.DisableFirewall, disableFirewallFlag, false,
|
||||
"Disable firewall configuration. If enabled, the client won't modify firewall rules.")
|
||||
cmd.PersistentFlags().BoolVar(&flags.BlockLANAccess, blockLANAccessFlag, false,
|
||||
"Block access to local networks (LAN) when using this peer as a router or exit node")
|
||||
cmd.PersistentFlags().BoolVar(&flags.BlockInbound, blockInboundFlag, false,
|
||||
"Block inbound connections. If enabled, the client will not allow any inbound connections to the local machine nor routed networks.\n"+
|
||||
"This overrides any policies received from the management service.")
|
||||
}
|
||||
|
||||
// AddUpOnlyFlags adds flags that are specific to the up command
|
||||
func AddUpOnlyFlags(cmd *cobra.Command, flags *SharedFlags) {
|
||||
cmd.PersistentFlags().BoolVar(&flags.NoBrowser, noBrowserFlag, false, noBrowserDesc)
|
||||
}
|
||||
|
||||
// BuildConfigInput creates an internal.ConfigInput from SharedFlags with Changed() checks
|
||||
func BuildConfigInput(cmd *cobra.Command, flags *SharedFlags, customDNSAddressConverted []byte) (*internal.ConfigInput, error) {
|
||||
ic := internal.ConfigInput{
|
||||
ManagementURL: managementURL,
|
||||
AdminURL: adminURL,
|
||||
ConfigPath: configPath,
|
||||
CustomDNSAddress: customDNSAddressConverted,
|
||||
}
|
||||
|
||||
// Handle PreSharedKey from root command
|
||||
if rootCmd.PersistentFlags().Changed(preSharedKeyFlag) {
|
||||
ic.PreSharedKey = &preSharedKey
|
||||
}
|
||||
|
||||
if cmd.Flag(enableRosenpassFlag).Changed {
|
||||
ic.RosenpassEnabled = &flags.RosenpassEnabled
|
||||
}
|
||||
|
||||
if cmd.Flag(rosenpassPermissiveFlag).Changed {
|
||||
ic.RosenpassPermissive = &flags.RosenpassPermissive
|
||||
}
|
||||
|
||||
if cmd.Flag(serverSSHAllowedFlag).Changed {
|
||||
ic.ServerSSHAllowed = &flags.ServerSSHAllowed
|
||||
}
|
||||
|
||||
if cmd.Flag(interfaceNameFlag).Changed {
|
||||
if err := parseInterfaceName(flags.InterfaceName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ic.InterfaceName = &flags.InterfaceName
|
||||
}
|
||||
|
||||
if cmd.Flag(wireguardPortFlag).Changed {
|
||||
p := int(flags.WireguardPort)
|
||||
ic.WireguardPort = &p
|
||||
}
|
||||
|
||||
if cmd.Flag(networkMonitorFlag).Changed {
|
||||
ic.NetworkMonitor = &flags.NetworkMonitor
|
||||
}
|
||||
|
||||
if cmd.Flag(disableAutoConnectFlag).Changed {
|
||||
ic.DisableAutoConnect = &flags.AutoConnectDisabled
|
||||
|
||||
if flags.AutoConnectDisabled {
|
||||
cmd.Println("Autoconnect has been disabled. The client won't connect automatically when the service starts.")
|
||||
} else {
|
||||
cmd.Println("Autoconnect has been enabled. The client will connect automatically when the service starts.")
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.Flag(dnsRouteIntervalFlag).Changed {
|
||||
ic.DNSRouteInterval = &flags.DNSRouteInterval
|
||||
}
|
||||
|
||||
if cmd.Flag(disableClientRoutesFlag).Changed {
|
||||
ic.DisableClientRoutes = &flags.DisableClientRoutes
|
||||
}
|
||||
|
||||
if cmd.Flag(disableServerRoutesFlag).Changed {
|
||||
ic.DisableServerRoutes = &flags.DisableServerRoutes
|
||||
}
|
||||
|
||||
if cmd.Flag(disableDNSFlag).Changed {
|
||||
ic.DisableDNS = &flags.DisableDNS
|
||||
}
|
||||
|
||||
if cmd.Flag(disableFirewallFlag).Changed {
|
||||
ic.DisableFirewall = &flags.DisableFirewall
|
||||
}
|
||||
|
||||
if cmd.Flag(blockLANAccessFlag).Changed {
|
||||
ic.BlockLANAccess = &flags.BlockLANAccess
|
||||
}
|
||||
|
||||
if cmd.Flag(blockInboundFlag).Changed {
|
||||
ic.BlockInbound = &flags.BlockInbound
|
||||
}
|
||||
|
||||
if cmd.Flag(enableLazyConnectionFlag).Changed {
|
||||
ic.LazyConnectionEnabled = &flags.LazyConnEnabled
|
||||
}
|
||||
|
||||
if cmd.Flag(externalIPMapFlag).Changed {
|
||||
ic.NATExternalIPs = flags.NATExternalIPs
|
||||
}
|
||||
|
||||
if cmd.Flag(extraIFaceBlackListFlag).Changed {
|
||||
ic.ExtraIFaceBlackList = flags.ExtraIFaceBlackList
|
||||
}
|
||||
|
||||
if cmd.Flag(dnsLabelsFlag).Changed {
|
||||
var err error
|
||||
ic.DNSLabels, err = domain.FromStringList(flags.DNSLabels)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid DNS labels: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return &ic, nil
|
||||
}
|
||||
@@ -149,6 +149,7 @@ func init() {
|
||||
rootCmd.AddCommand(loginCmd)
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
rootCmd.AddCommand(sshCmd)
|
||||
rootCmd.AddCommand(setCmd)
|
||||
rootCmd.AddCommand(networksCMD)
|
||||
rootCmd.AddCommand(forwardingRulesCmd)
|
||||
rootCmd.AddCommand(debugCmd)
|
||||
@@ -167,24 +168,6 @@ func init() {
|
||||
debugCmd.AddCommand(forCmd)
|
||||
debugCmd.AddCommand(persistenceCmd)
|
||||
|
||||
upCmd.PersistentFlags().StringSliceVar(&natExternalIPs, externalIPMapFlag, nil,
|
||||
`Sets external IPs maps between local addresses and interfaces.`+
|
||||
`You can specify a comma-separated list with a single IP and IP/IP or IP/Interface Name. `+
|
||||
`An empty string "" clears the previous configuration. `+
|
||||
`E.g. --external-ip-map 12.34.56.78/10.0.0.1 or --external-ip-map 12.34.56.200,12.34.56.78/10.0.0.1,12.34.56.80/eth1 `+
|
||||
`or --external-ip-map ""`,
|
||||
)
|
||||
upCmd.PersistentFlags().StringVar(&customDNSAddress, dnsResolverAddress, "",
|
||||
`Sets a custom address for NetBird's local DNS resolver. `+
|
||||
`If set, the agent won't attempt to discover the best ip and port to listen on. `+
|
||||
`An empty string "" clears the previous configuration. `+
|
||||
`E.g. --dns-resolver-address 127.0.0.1:5053 or --dns-resolver-address ""`,
|
||||
)
|
||||
upCmd.PersistentFlags().BoolVar(&rosenpassEnabled, enableRosenpassFlag, false, "[Experimental] Enable Rosenpass feature. If enabled, the connection will be post-quantum secured via Rosenpass.")
|
||||
upCmd.PersistentFlags().BoolVar(&rosenpassPermissive, rosenpassPermissiveFlag, false, "[Experimental] Enable Rosenpass in permissive mode to allow this peer to accept WireGuard connections without requiring Rosenpass functionality from peers that do not have Rosenpass enabled.")
|
||||
upCmd.PersistentFlags().BoolVar(&serverSSHAllowed, serverSSHAllowedFlag, false, "Allow SSH server on peer. If enabled, the SSH server will be permitted")
|
||||
upCmd.PersistentFlags().BoolVar(&autoConnectDisabled, disableAutoConnectFlag, false, "Disables auto-connect feature. If enabled, then the client won't connect automatically when the service starts.")
|
||||
upCmd.PersistentFlags().BoolVar(&lazyConnEnabled, enableLazyConnectionFlag, false, "[Experimental] Enable the lazy connection feature. If enabled, the client will establish connections on-demand.")
|
||||
|
||||
debugCmd.PersistentFlags().BoolVarP(&debugSystemInfoFlag, systemInfoFlag, "S", true, "Adds system information to the debug bundle")
|
||||
debugCmd.PersistentFlags().BoolVarP(&debugUploadBundle, uploadBundle, "U", false, fmt.Sprintf("Uploads the debug bundle to a server from URL defined by %s", uploadBundleURL))
|
||||
|
||||
161
client/cmd/set.go
Normal file
161
client/cmd/set.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
setFlags = &SharedFlags{}
|
||||
|
||||
setCmd = &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "Update NetBird client configuration",
|
||||
Long: `Update NetBird client configuration without connecting. Uses the same flags as 'netbird up' but only updates the configuration file.`,
|
||||
RunE: setFunc,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Add all shared flags to the set command
|
||||
AddSharedFlags(setCmd, setFlags)
|
||||
// Note: We don't add up-only flags like --no-browser to set command
|
||||
}
|
||||
|
||||
func setFunc(cmd *cobra.Command, _ []string) error {
|
||||
SetFlagsFromEnvVars(rootCmd)
|
||||
SetFlagsFromEnvVars(cmd)
|
||||
|
||||
cmd.SetOut(cmd.OutOrStdout())
|
||||
|
||||
// Validate inputs (reuse validation logic from up.go)
|
||||
if err := validateNATExternalIPs(setFlags.NATExternalIPs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.Flag(dnsLabelsFlag).Changed {
|
||||
if _, err := validateDnsLabels(setFlags.DNSLabels); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var customDNSAddressConverted []byte
|
||||
if cmd.Flag(dnsResolverAddress).Changed {
|
||||
var err error
|
||||
customDNSAddressConverted, err = parseCustomDNSAddress(cmd.Flag(dnsResolverAddress).Changed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Connect to daemon
|
||||
ctx := cmd.Context()
|
||||
conn, err := DialClientGRPCServer(ctx, daemonAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("connect to daemon: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if closeErr := conn.Close(); closeErr != nil {
|
||||
fmt.Printf("Warning: failed to close connection: %v\n", closeErr)
|
||||
}
|
||||
}()
|
||||
|
||||
client := proto.NewDaemonServiceClient(conn)
|
||||
req := &proto.SetConfigRequest{}
|
||||
|
||||
// Set fields based on changed flags
|
||||
if cmd.Flag(enableRosenpassFlag).Changed {
|
||||
req.RosenpassEnabled = &setFlags.RosenpassEnabled
|
||||
}
|
||||
|
||||
if cmd.Flag(rosenpassPermissiveFlag).Changed {
|
||||
req.RosenpassPermissive = &setFlags.RosenpassPermissive
|
||||
}
|
||||
|
||||
if cmd.Flag(serverSSHAllowedFlag).Changed {
|
||||
req.ServerSSHAllowed = &setFlags.ServerSSHAllowed
|
||||
}
|
||||
|
||||
if cmd.Flag(disableAutoConnectFlag).Changed {
|
||||
req.DisableAutoConnect = &setFlags.AutoConnectDisabled
|
||||
}
|
||||
|
||||
if cmd.Flag(networkMonitorFlag).Changed {
|
||||
req.NetworkMonitor = &setFlags.NetworkMonitor
|
||||
}
|
||||
|
||||
if cmd.Flag(interfaceNameFlag).Changed {
|
||||
if err := parseInterfaceName(setFlags.InterfaceName); err != nil {
|
||||
return err
|
||||
}
|
||||
req.InterfaceName = &setFlags.InterfaceName
|
||||
}
|
||||
|
||||
if cmd.Flag(wireguardPortFlag).Changed {
|
||||
port := int64(setFlags.WireguardPort)
|
||||
req.WireguardPort = &port
|
||||
}
|
||||
|
||||
if cmd.Flag(dnsResolverAddress).Changed {
|
||||
customAddr := string(customDNSAddressConverted)
|
||||
req.CustomDNSAddress = &customAddr
|
||||
}
|
||||
|
||||
if cmd.Flag(extraIFaceBlackListFlag).Changed {
|
||||
req.ExtraIFaceBlacklist = setFlags.ExtraIFaceBlackList
|
||||
}
|
||||
|
||||
if cmd.Flag(dnsLabelsFlag).Changed {
|
||||
req.DnsLabels = setFlags.DNSLabels
|
||||
req.CleanDNSLabels = &[]bool{setFlags.DNSLabels != nil && len(setFlags.DNSLabels) == 0}[0]
|
||||
}
|
||||
|
||||
if cmd.Flag(externalIPMapFlag).Changed {
|
||||
req.NatExternalIPs = setFlags.NATExternalIPs
|
||||
req.CleanNATExternalIPs = &[]bool{setFlags.NATExternalIPs != nil && len(setFlags.NATExternalIPs) == 0}[0]
|
||||
}
|
||||
|
||||
if cmd.Flag(dnsRouteIntervalFlag).Changed {
|
||||
req.DnsRouteInterval = durationpb.New(setFlags.DNSRouteInterval)
|
||||
}
|
||||
|
||||
if cmd.Flag(disableClientRoutesFlag).Changed {
|
||||
req.DisableClientRoutes = &setFlags.DisableClientRoutes
|
||||
}
|
||||
|
||||
if cmd.Flag(disableServerRoutesFlag).Changed {
|
||||
req.DisableServerRoutes = &setFlags.DisableServerRoutes
|
||||
}
|
||||
|
||||
if cmd.Flag(disableDNSFlag).Changed {
|
||||
req.DisableDns = &setFlags.DisableDNS
|
||||
}
|
||||
|
||||
if cmd.Flag(disableFirewallFlag).Changed {
|
||||
req.DisableFirewall = &setFlags.DisableFirewall
|
||||
}
|
||||
|
||||
if cmd.Flag(blockLANAccessFlag).Changed {
|
||||
req.BlockLanAccess = &setFlags.BlockLANAccess
|
||||
}
|
||||
|
||||
if cmd.Flag(blockInboundFlag).Changed {
|
||||
req.BlockInbound = &setFlags.BlockInbound
|
||||
}
|
||||
|
||||
if cmd.Flag(enableLazyConnectionFlag).Changed {
|
||||
req.LazyConnectionEnabled = &setFlags.LazyConnEnabled
|
||||
}
|
||||
|
||||
// Send the request
|
||||
if _, err := client.SetConfig(ctx, req); err != nil {
|
||||
return fmt.Errorf("update configuration: %w", err)
|
||||
}
|
||||
|
||||
cmd.Println("Configuration updated successfully")
|
||||
return nil
|
||||
}
|
||||
110
client/cmd/set_test.go
Normal file
110
client/cmd/set_test.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func TestParseBoolArg(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected bool
|
||||
hasError bool
|
||||
}{
|
||||
{"true", true, false},
|
||||
{"True", true, false},
|
||||
{"1", true, false},
|
||||
{"yes", true, false},
|
||||
{"on", true, false},
|
||||
{"false", false, false},
|
||||
{"False", false, false},
|
||||
{"0", false, false},
|
||||
{"no", false, false},
|
||||
{"off", false, false},
|
||||
{"invalid", false, true},
|
||||
{"maybe", false, true},
|
||||
{"", false, true},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.input, func(t *testing.T) {
|
||||
result, err := parseBoolArg(test.input)
|
||||
|
||||
if test.hasError {
|
||||
if err == nil {
|
||||
t.Errorf("Expected error for input %q, but got none", test.input)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error for input %q: %v", test.input, err)
|
||||
}
|
||||
if result != test.expected {
|
||||
t.Errorf("For input %q, expected %v but got %v", test.input, test.expected, result)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetCommandStructure(t *testing.T) {
|
||||
// Test that the set command has the expected subcommands
|
||||
expectedSubcommands := []string{
|
||||
"autoconnect",
|
||||
"ssh-server",
|
||||
"network-monitor",
|
||||
"rosenpass",
|
||||
"dns",
|
||||
"dns-interval",
|
||||
}
|
||||
|
||||
actualSubcommands := make([]string, 0, len(setCmd.Commands()))
|
||||
for _, cmd := range setCmd.Commands() {
|
||||
actualSubcommands = append(actualSubcommands, cmd.Name())
|
||||
}
|
||||
|
||||
if len(actualSubcommands) != len(expectedSubcommands) {
|
||||
t.Errorf("Expected %d subcommands, got %d", len(expectedSubcommands), len(actualSubcommands))
|
||||
}
|
||||
|
||||
for _, expected := range expectedSubcommands {
|
||||
found := false
|
||||
for _, actual := range actualSubcommands {
|
||||
if actual == expected {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected subcommand %q not found", expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetCommandUsage(t *testing.T) {
|
||||
if setCmd.Use != "set" {
|
||||
t.Errorf("Expected command use to be 'set', got %q", setCmd.Use)
|
||||
}
|
||||
|
||||
if setCmd.Short != "Set NetBird client configuration" {
|
||||
t.Errorf("Expected short description to be 'Set NetBird client configuration', got %q", setCmd.Short)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubcommandArgRequirements(t *testing.T) {
|
||||
// Test that all subcommands except dns-interval require exactly 1 argument
|
||||
subcommands := []*cobra.Command{
|
||||
setAutoconnectCmd,
|
||||
setSSHServerCmd,
|
||||
setNetworkMonitorCmd,
|
||||
setRosenpassCmd,
|
||||
setDNSCmd,
|
||||
setDNSIntervalCmd,
|
||||
}
|
||||
|
||||
for _, cmd := range subcommands {
|
||||
if cmd.Args == nil {
|
||||
t.Errorf("Command %q should have Args validation", cmd.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func getStatus(ctx context.Context) (*proto.StatusResponse, error) {
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
resp, err := proto.NewDaemonServiceClient(conn).Status(ctx, &proto.StatusRequest{GetFullPeerStatus: true})
|
||||
resp, err := proto.NewDaemonServiceClient(conn).Status(ctx, &proto.StatusRequest{GetFullPeerStatus: true, ShouldRunProbes: true})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("status failed: %v", status.Convert(err).Message())
|
||||
}
|
||||
|
||||
@@ -19,24 +19,3 @@ var (
|
||||
blockInbound bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Add system flags to upCmd
|
||||
upCmd.PersistentFlags().BoolVar(&disableClientRoutes, disableClientRoutesFlag, false,
|
||||
"Disable client routes. If enabled, the client won't process client routes received from the management service.")
|
||||
|
||||
upCmd.PersistentFlags().BoolVar(&disableServerRoutes, disableServerRoutesFlag, false,
|
||||
"Disable server routes. If enabled, the client won't act as a router for server routes received from the management service.")
|
||||
|
||||
upCmd.PersistentFlags().BoolVar(&disableDNS, disableDNSFlag, false,
|
||||
"Disable DNS. If enabled, the client won't configure DNS settings.")
|
||||
|
||||
upCmd.PersistentFlags().BoolVar(&disableFirewall, disableFirewallFlag, false,
|
||||
"Disable firewall configuration. If enabled, the client won't modify firewall rules.")
|
||||
|
||||
upCmd.PersistentFlags().BoolVar(&blockLANAccess, blockLANAccessFlag, false,
|
||||
"Block access to local networks (LAN) when using this peer as a router or exit node")
|
||||
|
||||
upCmd.PersistentFlags().BoolVar(&blockInbound, blockInboundFlag, false,
|
||||
"Block inbound connections. If enabled, the client will not allow any inbound connections to the local machine nor routed networks.\n"+
|
||||
"This overrides any policies received from the management service.")
|
||||
}
|
||||
|
||||
124
client/cmd/up.go
124
client/cmd/up.go
@@ -7,7 +7,6 @@ import (
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -15,7 +14,6 @@ import (
|
||||
gstatus "google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"github.com/netbirdio/netbird/client/iface"
|
||||
"github.com/netbirdio/netbird/client/internal"
|
||||
"github.com/netbirdio/netbird/client/internal/peer"
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
@@ -42,6 +40,7 @@ var (
|
||||
dnsLabels []string
|
||||
dnsLabelsValidated domain.List
|
||||
noBrowser bool
|
||||
upFlags = &SharedFlags{}
|
||||
|
||||
upCmd = &cobra.Command{
|
||||
Use: "up",
|
||||
@@ -51,26 +50,12 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Add shared flags to up command
|
||||
AddSharedFlags(upCmd, upFlags)
|
||||
|
||||
// Add up-specific flags
|
||||
upCmd.PersistentFlags().BoolVarP(&foregroundMode, "foreground-mode", "F", false, "start service in foreground")
|
||||
upCmd.PersistentFlags().StringVar(&interfaceName, interfaceNameFlag, iface.WgInterfaceDefault, "Wireguard interface name")
|
||||
upCmd.PersistentFlags().Uint16Var(&wireguardPort, wireguardPortFlag, iface.DefaultWgPort, "Wireguard interface listening port")
|
||||
upCmd.PersistentFlags().BoolVarP(&networkMonitor, networkMonitorFlag, "N", networkMonitor,
|
||||
`Manage network monitoring. Defaults to true on Windows and macOS, false on Linux and FreeBSD. `+
|
||||
`E.g. --network-monitor=false to disable or --network-monitor=true to enable.`,
|
||||
)
|
||||
upCmd.PersistentFlags().StringSliceVar(&extraIFaceBlackList, extraIFaceBlackListFlag, nil, "Extra list of default interfaces to ignore for listening")
|
||||
upCmd.PersistentFlags().DurationVar(&dnsRouteInterval, dnsRouteIntervalFlag, time.Minute, "DNS route update interval")
|
||||
|
||||
upCmd.PersistentFlags().StringSliceVar(&dnsLabels, dnsLabelsFlag, nil,
|
||||
`Sets DNS labels`+
|
||||
`You can specify a comma-separated list of up to 32 labels. `+
|
||||
`An empty string "" clears the previous configuration. `+
|
||||
`E.g. --extra-dns-labels vpc1 or --extra-dns-labels vpc1,mgmt1 `+
|
||||
`or --extra-dns-labels ""`,
|
||||
)
|
||||
|
||||
upCmd.PersistentFlags().BoolVar(&noBrowser, noBrowserFlag, false, noBrowserDesc)
|
||||
|
||||
AddUpOnlyFlags(upCmd, upFlags)
|
||||
}
|
||||
|
||||
func upFunc(cmd *cobra.Command, args []string) error {
|
||||
@@ -118,7 +103,16 @@ func runInForegroundMode(ctx context.Context, cmd *cobra.Command) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ic, err := setupConfig(customDNSAddressConverted, cmd)
|
||||
// Handle DNS labels validation and assignment to SharedFlags
|
||||
if cmd.Flag(dnsLabelsFlag).Changed {
|
||||
var err error
|
||||
dnsLabelsValidated, err = validateDnsLabels(upFlags.DNSLabels)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ic, err := BuildConfigInput(cmd, upFlags, customDNSAddressConverted)
|
||||
if err != nil {
|
||||
return fmt.Errorf("setup config: %v", err)
|
||||
}
|
||||
@@ -235,92 +229,6 @@ func runInDaemonMode(ctx context.Context, cmd *cobra.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupConfig(customDNSAddressConverted []byte, cmd *cobra.Command) (*internal.ConfigInput, error) {
|
||||
ic := internal.ConfigInput{
|
||||
ManagementURL: managementURL,
|
||||
AdminURL: adminURL,
|
||||
ConfigPath: configPath,
|
||||
NATExternalIPs: natExternalIPs,
|
||||
CustomDNSAddress: customDNSAddressConverted,
|
||||
ExtraIFaceBlackList: extraIFaceBlackList,
|
||||
DNSLabels: dnsLabelsValidated,
|
||||
}
|
||||
|
||||
if cmd.Flag(enableRosenpassFlag).Changed {
|
||||
ic.RosenpassEnabled = &rosenpassEnabled
|
||||
}
|
||||
|
||||
if cmd.Flag(rosenpassPermissiveFlag).Changed {
|
||||
ic.RosenpassPermissive = &rosenpassPermissive
|
||||
}
|
||||
|
||||
if cmd.Flag(serverSSHAllowedFlag).Changed {
|
||||
ic.ServerSSHAllowed = &serverSSHAllowed
|
||||
}
|
||||
|
||||
if cmd.Flag(interfaceNameFlag).Changed {
|
||||
if err := parseInterfaceName(interfaceName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ic.InterfaceName = &interfaceName
|
||||
}
|
||||
|
||||
if cmd.Flag(wireguardPortFlag).Changed {
|
||||
p := int(wireguardPort)
|
||||
ic.WireguardPort = &p
|
||||
}
|
||||
|
||||
if cmd.Flag(networkMonitorFlag).Changed {
|
||||
ic.NetworkMonitor = &networkMonitor
|
||||
}
|
||||
|
||||
if rootCmd.PersistentFlags().Changed(preSharedKeyFlag) {
|
||||
ic.PreSharedKey = &preSharedKey
|
||||
}
|
||||
|
||||
if cmd.Flag(disableAutoConnectFlag).Changed {
|
||||
ic.DisableAutoConnect = &autoConnectDisabled
|
||||
|
||||
if autoConnectDisabled {
|
||||
cmd.Println("Autoconnect has been disabled. The client won't connect automatically when the service starts.")
|
||||
}
|
||||
|
||||
if !autoConnectDisabled {
|
||||
cmd.Println("Autoconnect has been enabled. The client will connect automatically when the service starts.")
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.Flag(dnsRouteIntervalFlag).Changed {
|
||||
ic.DNSRouteInterval = &dnsRouteInterval
|
||||
}
|
||||
|
||||
if cmd.Flag(disableClientRoutesFlag).Changed {
|
||||
ic.DisableClientRoutes = &disableClientRoutes
|
||||
}
|
||||
if cmd.Flag(disableServerRoutesFlag).Changed {
|
||||
ic.DisableServerRoutes = &disableServerRoutes
|
||||
}
|
||||
if cmd.Flag(disableDNSFlag).Changed {
|
||||
ic.DisableDNS = &disableDNS
|
||||
}
|
||||
if cmd.Flag(disableFirewallFlag).Changed {
|
||||
ic.DisableFirewall = &disableFirewall
|
||||
}
|
||||
|
||||
if cmd.Flag(blockLANAccessFlag).Changed {
|
||||
ic.BlockLANAccess = &blockLANAccess
|
||||
}
|
||||
|
||||
if cmd.Flag(blockInboundFlag).Changed {
|
||||
ic.BlockInbound = &blockInbound
|
||||
}
|
||||
|
||||
if cmd.Flag(enableLazyConnectionFlag).Changed {
|
||||
ic.LazyConnectionEnabled = &lazyConnEnabled
|
||||
}
|
||||
return &ic, nil
|
||||
}
|
||||
|
||||
func setupLoginRequest(providedSetupKey string, customDNSAddressConverted []byte, cmd *cobra.Command) (*proto.LoginRequest, error) {
|
||||
loginRequest := proto.LoginRequest{
|
||||
SetupKey: providedSetupKey,
|
||||
|
||||
@@ -319,10 +319,6 @@ func (config *Config) apply(input ConfigInput) (updated bool, err error) {
|
||||
*input.WireguardPort, config.WgPort)
|
||||
config.WgPort = *input.WireguardPort
|
||||
updated = true
|
||||
} else if config.WgPort == 0 {
|
||||
config.WgPort = iface.DefaultWgPort
|
||||
log.Infof("using default Wireguard port %d", config.WgPort)
|
||||
updated = true
|
||||
}
|
||||
|
||||
if input.InterfaceName != nil && *input.InterfaceName != config.WgIface {
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
gstatus "google.golang.org/grpc/status"
|
||||
|
||||
"github.com/netbirdio/netbird/client/iface"
|
||||
"github.com/netbirdio/netbird/client/iface/device"
|
||||
"github.com/netbirdio/netbird/client/internal/dns"
|
||||
"github.com/netbirdio/netbird/client/internal/listener"
|
||||
@@ -526,17 +525,13 @@ func statusRecorderToSignalConnStateNotifier(statusRecorder *peer.Status) signal
|
||||
|
||||
// freePort attempts to determine if the provided port is available, if not it will ask the system for a free port.
|
||||
func freePort(initPort int) (int, error) {
|
||||
addr := net.UDPAddr{}
|
||||
if initPort == 0 {
|
||||
initPort = iface.DefaultWgPort
|
||||
}
|
||||
|
||||
addr.Port = initPort
|
||||
addr := net.UDPAddr{Port: initPort}
|
||||
|
||||
conn, err := net.ListenUDP("udp", &addr)
|
||||
if err == nil {
|
||||
returnPort := conn.LocalAddr().(*net.UDPAddr).Port
|
||||
closeConnWithLog(conn)
|
||||
return initPort, nil
|
||||
return returnPort, nil
|
||||
}
|
||||
|
||||
// if the port is already in use, ask the system for a free port
|
||||
|
||||
@@ -13,10 +13,10 @@ func Test_freePort(t *testing.T) {
|
||||
shouldMatch bool
|
||||
}{
|
||||
{
|
||||
name: "not provided, fallback to default",
|
||||
name: "when port is 0 use random port",
|
||||
port: 0,
|
||||
want: 51820,
|
||||
shouldMatch: true,
|
||||
want: 0,
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
name: "provided and available",
|
||||
@@ -31,7 +31,7 @@ func Test_freePort(t *testing.T) {
|
||||
shouldMatch: false,
|
||||
},
|
||||
}
|
||||
c1, err := net.ListenUDP("udp", &net.UDPAddr{Port: 51830})
|
||||
c1, err := net.ListenUDP("udp", &net.UDPAddr{Port: 0})
|
||||
if err != nil {
|
||||
t.Errorf("freePort error = %v", err)
|
||||
}
|
||||
@@ -39,6 +39,14 @@ func Test_freePort(t *testing.T) {
|
||||
_ = c1.Close()
|
||||
}(c1)
|
||||
|
||||
if tests[1].port == c1.LocalAddr().(*net.UDPAddr).Port {
|
||||
tests[1].port++
|
||||
tests[1].want++
|
||||
}
|
||||
|
||||
tests[2].port = c1.LocalAddr().(*net.UDPAddr).Port
|
||||
tests[2].want = c1.LocalAddr().(*net.UDPAddr).Port
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -67,6 +67,9 @@ service DaemonService {
|
||||
rpc SubscribeEvents(SubscribeRequest) returns (stream SystemEvent) {}
|
||||
|
||||
rpc GetEvents(GetEventsRequest) returns (GetEventsResponse) {}
|
||||
|
||||
// SetConfig updates daemon configuration without reconnecting
|
||||
rpc SetConfig(SetConfigRequest) returns (SetConfigResponse) {}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +161,7 @@ message UpResponse {}
|
||||
|
||||
message StatusRequest{
|
||||
bool getFullPeerStatus = 1;
|
||||
bool shouldRunProbes = 2;
|
||||
}
|
||||
|
||||
message StatusResponse{
|
||||
@@ -495,3 +499,29 @@ message GetEventsRequest {}
|
||||
message GetEventsResponse {
|
||||
repeated SystemEvent events = 1;
|
||||
}
|
||||
|
||||
message SetConfigRequest {
|
||||
optional bool rosenpassEnabled = 1;
|
||||
optional bool rosenpassPermissive = 2;
|
||||
optional bool serverSSHAllowed = 3;
|
||||
optional bool disableAutoConnect = 4;
|
||||
optional bool networkMonitor = 5;
|
||||
optional google.protobuf.Duration dnsRouteInterval = 6;
|
||||
optional bool disable_client_routes = 7;
|
||||
optional bool disable_server_routes = 8;
|
||||
optional bool disable_dns = 9;
|
||||
optional bool disable_firewall = 10;
|
||||
optional bool block_lan_access = 11;
|
||||
optional bool lazyConnectionEnabled = 12;
|
||||
optional bool block_inbound = 13;
|
||||
optional string interfaceName = 14;
|
||||
optional int64 wireguardPort = 15;
|
||||
optional string customDNSAddress = 16;
|
||||
repeated string extraIFaceBlacklist = 17;
|
||||
repeated string dns_labels = 18;
|
||||
optional bool cleanDNSLabels = 19;
|
||||
repeated string natExternalIPs = 20;
|
||||
optional bool cleanNATExternalIPs = 21;
|
||||
}
|
||||
|
||||
message SetConfigResponse {}
|
||||
|
||||
@@ -55,6 +55,8 @@ type DaemonServiceClient interface {
|
||||
TracePacket(ctx context.Context, in *TracePacketRequest, opts ...grpc.CallOption) (*TracePacketResponse, error)
|
||||
SubscribeEvents(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (DaemonService_SubscribeEventsClient, error)
|
||||
GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (*GetEventsResponse, error)
|
||||
// SetConfig updates daemon configuration without reconnecting
|
||||
SetConfig(ctx context.Context, in *SetConfigRequest, opts ...grpc.CallOption) (*SetConfigResponse, error)
|
||||
}
|
||||
|
||||
type daemonServiceClient struct {
|
||||
@@ -268,6 +270,15 @@ func (c *daemonServiceClient) GetEvents(ctx context.Context, in *GetEventsReques
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *daemonServiceClient) SetConfig(ctx context.Context, in *SetConfigRequest, opts ...grpc.CallOption) (*SetConfigResponse, error) {
|
||||
out := new(SetConfigResponse)
|
||||
err := c.cc.Invoke(ctx, "/daemon.DaemonService/SetConfig", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// DaemonServiceServer is the server API for DaemonService service.
|
||||
// All implementations must embed UnimplementedDaemonServiceServer
|
||||
// for forward compatibility
|
||||
@@ -309,6 +320,8 @@ type DaemonServiceServer interface {
|
||||
TracePacket(context.Context, *TracePacketRequest) (*TracePacketResponse, error)
|
||||
SubscribeEvents(*SubscribeRequest, DaemonService_SubscribeEventsServer) error
|
||||
GetEvents(context.Context, *GetEventsRequest) (*GetEventsResponse, error)
|
||||
// SetConfig updates daemon configuration without reconnecting
|
||||
SetConfig(context.Context, *SetConfigRequest) (*SetConfigResponse, error)
|
||||
mustEmbedUnimplementedDaemonServiceServer()
|
||||
}
|
||||
|
||||
@@ -376,6 +389,9 @@ func (UnimplementedDaemonServiceServer) SubscribeEvents(*SubscribeRequest, Daemo
|
||||
func (UnimplementedDaemonServiceServer) GetEvents(context.Context, *GetEventsRequest) (*GetEventsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetEvents not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) SetConfig(context.Context, *SetConfigRequest) (*SetConfigResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetConfig not implemented")
|
||||
}
|
||||
func (UnimplementedDaemonServiceServer) mustEmbedUnimplementedDaemonServiceServer() {}
|
||||
|
||||
// UnsafeDaemonServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
@@ -752,6 +768,24 @@ func _DaemonService_GetEvents_Handler(srv interface{}, ctx context.Context, dec
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DaemonService_SetConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SetConfigRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DaemonServiceServer).SetConfig(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/daemon.DaemonService/SetConfig",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DaemonServiceServer).SetConfig(ctx, req.(*SetConfigRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// DaemonService_ServiceDesc is the grpc.ServiceDesc for DaemonService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -835,6 +869,10 @@ var DaemonService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GetEvents",
|
||||
Handler: _DaemonService_GetEvents_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetConfig",
|
||||
Handler: _DaemonService_SetConfig_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
||||
@@ -707,7 +707,9 @@ func (s *Server) Status(
|
||||
s.statusRecorder.UpdateRosenpass(s.config.RosenpassEnabled, s.config.RosenpassPermissive)
|
||||
|
||||
if msg.GetFullPeerStatus {
|
||||
s.runProbes()
|
||||
if msg.ShouldRunProbes {
|
||||
s.runProbes()
|
||||
}
|
||||
|
||||
fullStatus := s.statusRecorder.GetFullStatus()
|
||||
pbFullStatus := toProtoFullStatus(fullStatus)
|
||||
@@ -797,6 +799,133 @@ func (s *Server) GetConfig(_ context.Context, _ *proto.GetConfigRequest) (*proto
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetConfig updates daemon configuration without reconnecting
|
||||
func (s *Server) SetConfig(ctx context.Context, req *proto.SetConfigRequest) (*proto.SetConfigResponse, error) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
if s.config == nil {
|
||||
return nil, gstatus.Errorf(codes.FailedPrecondition, "daemon is not configured")
|
||||
}
|
||||
|
||||
configChanged := false
|
||||
|
||||
if req.RosenpassEnabled != nil && s.config.RosenpassEnabled != *req.RosenpassEnabled {
|
||||
s.config.RosenpassEnabled = *req.RosenpassEnabled
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.RosenpassPermissive != nil && s.config.RosenpassPermissive != *req.RosenpassPermissive {
|
||||
s.config.RosenpassPermissive = *req.RosenpassPermissive
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.ServerSSHAllowed != nil && s.config.ServerSSHAllowed != nil && *s.config.ServerSSHAllowed != *req.ServerSSHAllowed {
|
||||
*s.config.ServerSSHAllowed = *req.ServerSSHAllowed
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.DisableAutoConnect != nil && s.config.DisableAutoConnect != *req.DisableAutoConnect {
|
||||
s.config.DisableAutoConnect = *req.DisableAutoConnect
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.NetworkMonitor != nil && s.config.NetworkMonitor != nil && *s.config.NetworkMonitor != *req.NetworkMonitor {
|
||||
*s.config.NetworkMonitor = *req.NetworkMonitor
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.DnsRouteInterval != nil {
|
||||
duration := req.DnsRouteInterval.AsDuration()
|
||||
if s.config.DNSRouteInterval != duration {
|
||||
s.config.DNSRouteInterval = duration
|
||||
configChanged = true
|
||||
}
|
||||
}
|
||||
|
||||
if req.DisableClientRoutes != nil && s.config.DisableClientRoutes != *req.DisableClientRoutes {
|
||||
s.config.DisableClientRoutes = *req.DisableClientRoutes
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.DisableServerRoutes != nil && s.config.DisableServerRoutes != *req.DisableServerRoutes {
|
||||
s.config.DisableServerRoutes = *req.DisableServerRoutes
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.DisableDns != nil && s.config.DisableDNS != *req.DisableDns {
|
||||
s.config.DisableDNS = *req.DisableDns
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.DisableFirewall != nil && s.config.DisableFirewall != *req.DisableFirewall {
|
||||
s.config.DisableFirewall = *req.DisableFirewall
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.BlockLanAccess != nil && s.config.BlockLANAccess != *req.BlockLanAccess {
|
||||
s.config.BlockLANAccess = *req.BlockLanAccess
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.LazyConnectionEnabled != nil && s.config.LazyConnectionEnabled != *req.LazyConnectionEnabled {
|
||||
s.config.LazyConnectionEnabled = *req.LazyConnectionEnabled
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.BlockInbound != nil && s.config.BlockInbound != *req.BlockInbound {
|
||||
s.config.BlockInbound = *req.BlockInbound
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.InterfaceName != nil && s.config.WgIface != *req.InterfaceName {
|
||||
s.config.WgIface = *req.InterfaceName
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.WireguardPort != nil && s.config.WgPort != int(*req.WireguardPort) {
|
||||
s.config.WgPort = int(*req.WireguardPort)
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if req.CustomDNSAddress != nil && s.config.CustomDNSAddress != *req.CustomDNSAddress {
|
||||
s.config.CustomDNSAddress = *req.CustomDNSAddress
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if len(req.ExtraIFaceBlacklist) > 0 {
|
||||
s.config.IFaceBlackList = req.ExtraIFaceBlacklist
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if len(req.DnsLabels) > 0 || (req.CleanDNSLabels != nil && *req.CleanDNSLabels) {
|
||||
if req.CleanDNSLabels != nil && *req.CleanDNSLabels {
|
||||
s.config.DNSLabels = domain.List{}
|
||||
} else {
|
||||
var err error
|
||||
s.config.DNSLabels, err = domain.FromStringList(req.DnsLabels)
|
||||
if err != nil {
|
||||
return nil, gstatus.Errorf(codes.InvalidArgument, "invalid DNS labels: %v", err)
|
||||
}
|
||||
}
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if len(req.NatExternalIPs) > 0 || (req.CleanNATExternalIPs != nil && *req.CleanNATExternalIPs) {
|
||||
s.config.NATExternalIPs = req.NatExternalIPs
|
||||
configChanged = true
|
||||
}
|
||||
|
||||
if configChanged {
|
||||
if err := internal.WriteOutConfig(s.latestConfigInput.ConfigPath, s.config); err != nil {
|
||||
return nil, gstatus.Errorf(codes.Internal, "write config: %v", err)
|
||||
}
|
||||
log.Debug("Configuration updated successfully")
|
||||
}
|
||||
|
||||
return &proto.SetConfigResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *Server) onSessionExpire() {
|
||||
if runtime.GOOS != "windows" {
|
||||
isUIActive := internal.CheckUIApp()
|
||||
|
||||
Reference in New Issue
Block a user