github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/config/flags_node.go (about)

     1  /*
     2   * Copyright (C) 2019 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package config
    19  
    20  import (
    21  	"fmt"
    22  	"strings"
    23  	"time"
    24  
    25  	"github.com/pkg/errors"
    26  	"github.com/rs/zerolog"
    27  	"github.com/rs/zerolog/log"
    28  	"github.com/urfave/cli/v2"
    29  
    30  	"github.com/mysteriumnetwork/node/metadata"
    31  )
    32  
    33  var (
    34  	// Alphabetically sorted list of node flags
    35  	// Some of the flags are location in separate source files: flags_*.go
    36  
    37  	// FlagDiscoveryType proposal discovery adapter.
    38  	FlagDiscoveryType = cli.StringSliceFlag{
    39  		Name:  "discovery.type",
    40  		Usage: `Proposal discovery adapter(s) separated by comma. Options: { "api", "broker", "api,broker,dht" }`,
    41  		Value: cli.NewStringSlice("api"),
    42  	}
    43  	// FlagDiscoveryPingInterval proposal ping interval in seconds.
    44  	FlagDiscoveryPingInterval = cli.DurationFlag{
    45  		Name:  "discovery.ping",
    46  		Usage: `Proposal update interval { "30s", "3m", "1h20m30s" }`,
    47  		Value: 180 * time.Second,
    48  	}
    49  	// FlagDiscoveryFetchInterval proposal fetch interval in seconds.
    50  	FlagDiscoveryFetchInterval = cli.DurationFlag{
    51  		Name:  "discovery.fetch",
    52  		Usage: `Proposal fetch interval { "30s", "3m", "1h20m30s" }`,
    53  		Value: 180 * time.Second,
    54  	}
    55  	// FlagDHTAddress IP address of interface to listen for DHT connections.
    56  	FlagDHTAddress = cli.StringFlag{
    57  		Name:  "discovery.dht.address",
    58  		Usage: "IP address to bind DHT to",
    59  		Value: "0.0.0.0",
    60  	}
    61  	// FlagDHTPort listens DHT connections on the specified port.
    62  	FlagDHTPort = cli.IntFlag{
    63  		Name:  "discovery.dht.port",
    64  		Usage: "The port to bind DHT to (by default, random port will be used)",
    65  		Value: 0,
    66  	}
    67  	// FlagDHTProtocol protocol for DHT to use.
    68  	FlagDHTProtocol = cli.StringFlag{
    69  		Name:  "discovery.dht.proto",
    70  		Usage: "Protocol to use with DHT. Options: { udp, tcp }",
    71  		Value: "tcp",
    72  	}
    73  	// FlagDHTBootstrapPeers DHT bootstrap peer nodes list.
    74  	FlagDHTBootstrapPeers = cli.StringSliceFlag{
    75  		Name:  "discovery.dht.peers",
    76  		Usage: `Peer URL(s) for DHT bootstrap (e.g. /ip4/127.0.0.1/tcp/1234/p2p/QmNUZRp1zrk8i8TpfyeDZ9Yg3C4PjZ5o61yao3YhyY1TE8") separated by comma. They will tell us about the other nodes in the network.`,
    77  		Value: cli.NewStringSlice(),
    78  	}
    79  
    80  	// FlagBindAddress IP address to bind to.
    81  	FlagBindAddress = cli.StringFlag{
    82  		Name:  "bind.address",
    83  		Usage: "IP address to bind provided services to",
    84  		Value: "0.0.0.0",
    85  	}
    86  	// FlagFeedbackURL URL of Feedback API.
    87  	FlagFeedbackURL = cli.StringFlag{
    88  		Name:  "feedback.url",
    89  		Usage: "URL of Feedback API",
    90  		Value: "https://feedback.mysterium.network",
    91  	}
    92  	// FlagFirewallKillSwitch always blocks non-tunneled outgoing consumer traffic.
    93  	FlagFirewallKillSwitch = cli.BoolFlag{
    94  		Name:  "firewall.killSwitch.always",
    95  		Usage: "Always block non-tunneled outgoing consumer traffic",
    96  	}
    97  	// FlagFirewallProtectedNetworks protects provider's networks from access via VPN
    98  	FlagFirewallProtectedNetworks = cli.StringFlag{
    99  		Name:  "firewall.protected.networks",
   100  		Usage: "List of comma separated (no spaces) subnets to be protected from access via VPN",
   101  		Value: "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.0/8",
   102  	}
   103  	// FlagShaperEnabled enables bandwidth limitation.
   104  	FlagShaperEnabled = cli.BoolFlag{
   105  		Name:  "shaper.enabled",
   106  		Usage: "Limit service bandwidth",
   107  	}
   108  	// FlagShaperBandwidth set the bandwidth limit.
   109  	FlagShaperBandwidth = cli.Uint64Flag{
   110  		Name:  "shaper.bandwidth",
   111  		Usage: "Set the bandwidth limit in Kbytes",
   112  		Value: 6250,
   113  	}
   114  	// FlagKeystoreLightweight determines the scrypt memory complexity.
   115  	FlagKeystoreLightweight = cli.BoolFlag{
   116  		Name:  "keystore.lightweight",
   117  		Usage: "Determines the scrypt memory complexity. If set to true, will use 4MB blocks instead of the standard 256MB ones",
   118  		Value: true,
   119  	}
   120  	// FlagLogHTTP enables HTTP payload logging.
   121  	FlagLogHTTP = cli.BoolFlag{
   122  		Name:  "log.http",
   123  		Usage: "Enable HTTP payload logging",
   124  	}
   125  	// FlagLogLevel logger level.
   126  	FlagLogLevel = cli.StringFlag{
   127  		Name: "log-level",
   128  		Usage: func() string {
   129  			allLevels := []string{
   130  				zerolog.TraceLevel.String(),
   131  				zerolog.DebugLevel.String(),
   132  				zerolog.InfoLevel.String(),
   133  				zerolog.WarnLevel.String(),
   134  				zerolog.FatalLevel.String(),
   135  				zerolog.PanicLevel.String(),
   136  				zerolog.Disabled.String(),
   137  			}
   138  			return fmt.Sprintf("Set the logging level (%s)", strings.Join(allLevels, "|"))
   139  		}(),
   140  		Value: zerolog.DebugLevel.String(),
   141  	}
   142  	// FlagVerbose enables verbose logging.
   143  	FlagVerbose = cli.BoolFlag{
   144  		Name:  "verbose",
   145  		Usage: "Enable verbose logging",
   146  		Value: false,
   147  	}
   148  	// FlagOpenvpnBinary openvpn binary to use for OpenVPN connections.
   149  	FlagOpenvpnBinary = cli.StringFlag{
   150  		Name:  "openvpn.binary",
   151  		Usage: "openvpn binary to use for OpenVPN connections",
   152  		Value: "openvpn",
   153  	}
   154  	// FlagQualityType quality oracle adapter.
   155  	FlagQualityType = cli.StringFlag{
   156  		Name:  "quality.type",
   157  		Usage: "Quality Oracle adapter. Options:  (elastic, morqa, none - opt-out from sending quality metrics)",
   158  		Value: "morqa",
   159  	}
   160  	// FlagQualityAddress quality oracle URL.
   161  	FlagQualityAddress = cli.StringFlag{
   162  		Name: "quality.address",
   163  		Usage: fmt.Sprintf(
   164  			"Address of specific Quality Oracle adapter given in '--%s'",
   165  			FlagQualityType.Name,
   166  		),
   167  		Value: "https://quality.mysterium.network/api/v3",
   168  	}
   169  	// FlagTequilapiAddress IP address of interface to listen for incoming connections.
   170  	FlagTequilapiAddress = cli.StringFlag{
   171  		Name:  "tequilapi.address",
   172  		Usage: "IP address to bind API to",
   173  		Value: "127.0.0.1",
   174  	}
   175  	// FlagTequilapiAllowedHostnames Restrict hostnames in requests' Host header to following domains.
   176  	FlagTequilapiAllowedHostnames = cli.StringFlag{
   177  		Name:  "tequilapi.allowed-hostnames",
   178  		Usage: "Comma separated list of allowed domains. Prepend value with dot for wildcard mask",
   179  		Value: ".localhost, localhost, .localdomain",
   180  	}
   181  	// FlagTequilapiPort port for listening for incoming API requests.
   182  	FlagTequilapiPort = cli.IntFlag{
   183  		Name:  "tequilapi.port",
   184  		Usage: "Port for listening incoming API requests",
   185  		Value: 4050,
   186  	}
   187  	// FlagTequilapiDebugMode debug mode for tequilapi.
   188  	FlagTequilapiDebugMode = cli.BoolFlag{
   189  		Name:  "tequilapi.debug",
   190  		Usage: "Starts tequilapi in debug mode",
   191  		Value: false,
   192  	}
   193  	// FlagTequilapiUsername username for API authentication.
   194  	FlagTequilapiUsername = cli.StringFlag{
   195  		Name:  "tequilapi.auth.username",
   196  		Usage: "Default username for API authentication",
   197  		Value: "myst",
   198  	}
   199  	// FlagTequilapiPassword username for API authentication.
   200  	FlagTequilapiPassword = cli.StringFlag{
   201  		Name:  "tequilapi.auth.password",
   202  		Usage: "Default password for API authentication",
   203  		Value: "mystberry",
   204  	}
   205  	// FlagPProfEnable enables pprof via TequilAPI.
   206  	FlagPProfEnable = cli.BoolFlag{
   207  		Name:  "pprof.enable",
   208  		Usage: "Enables pprof",
   209  		Value: false,
   210  	}
   211  	// FlagUserMode allows running node under current user without sudo.
   212  	FlagUserMode = cli.BoolFlag{
   213  		Name:  "usermode",
   214  		Usage: "Run as a regular user. Delegate elevated commands to the supervisor.",
   215  		Value: false,
   216  	}
   217  
   218  	// FlagDVPNMode allows running node in a kernelspace without establishing system-wite tunnels.
   219  	FlagDVPNMode = cli.BoolFlag{
   220  		Name:  "dvpnmode",
   221  		Usage: "Run in a kernelspace without establishing system-wite tunnels",
   222  		Value: false,
   223  	}
   224  
   225  	// FlagProxyMode allows running node under current user as a proxy.
   226  	FlagProxyMode = cli.BoolFlag{
   227  		Name:  "proxymode",
   228  		Usage: "Run as a regular user as a proxy",
   229  		Value: false,
   230  	}
   231  
   232  	// FlagUserspace allows running a node without privileged permissions.
   233  	FlagUserspace = cli.BoolFlag{
   234  		Name:  "userspace",
   235  		Usage: "Run a node without privileged permissions",
   236  		Value: false,
   237  	}
   238  
   239  	// FlagVendorID identifies 3rd party vendor (distributor) of Mysterium node.
   240  	FlagVendorID = cli.StringFlag{
   241  		Name: "vendor.id",
   242  		Usage: "Marks vendor (distributor) of the node for collecting statistics. " +
   243  			"3rd party vendors may use their own identifier here.",
   244  	}
   245  	// FlagLauncherVersion is used for reporting the version of a Launcher.
   246  	FlagLauncherVersion = cli.StringFlag{
   247  		Name:  "launcher.ver",
   248  		Usage: "Report the version of a launcher for statistics",
   249  	}
   250  
   251  	// FlagP2PListenPorts sets manual ports for p2p connections.
   252  	// TODO: remove the deprecated flag once all users stop to use it.
   253  	FlagP2PListenPorts = cli.StringFlag{
   254  		Name:  "p2p.listen.ports",
   255  		Usage: "Deprecated flag, use --udp.ports to set range of listen ports",
   256  		Value: "0:0",
   257  	}
   258  
   259  	// FlagConsumer sets to run as consumer only which allows to skip bootstrap for some of the dependencies.
   260  	FlagConsumer = cli.BoolFlag{
   261  		Name:  "consumer",
   262  		Usage: "Run in consumer mode only.",
   263  		Value: false,
   264  	}
   265  
   266  	// FlagDefaultCurrency sets the default currency used in node
   267  	FlagDefaultCurrency = cli.StringFlag{
   268  		Name:   metadata.FlagNames.DefaultCurrency,
   269  		Usage:  "Default currency used in node and apps that depend on it",
   270  		Value:  metadata.DefaultNetwork.DefaultCurrency,
   271  		Hidden: true, // Users are not meant to touch or see this.
   272  	}
   273  
   274  	// FlagDocsURL sets the URL which leads to node documentation.
   275  	FlagDocsURL = cli.StringFlag{
   276  		Name:   "docs-url",
   277  		Usage:  "URL leading to node documentation",
   278  		Value:  "https://docs.mysterium.network",
   279  		Hidden: true,
   280  	}
   281  
   282  	// FlagDNSResolutionHeadstart sets the dns resolution head start for swarm dialer.
   283  	FlagDNSResolutionHeadstart = cli.DurationFlag{
   284  		Name:   "dns-resolution-headstart",
   285  		Usage:  "the headstart we give DNS lookups versus IP lookups",
   286  		Value:  time.Millisecond * 1500,
   287  		Hidden: true,
   288  	}
   289  
   290  	// FlagResidentCountry sets the resident country
   291  	FlagResidentCountry = cli.StringFlag{
   292  		Name:  "resident-country",
   293  		Usage: "set resident country. If not set initially a default country will be resolved.",
   294  	}
   295  
   296  	// FlagWireguardMTU sets Wireguard myst interface MTU.
   297  	FlagWireguardMTU = cli.IntFlag{
   298  		Name:  "wireguard.mtu",
   299  		Usage: "Wireguard interface MTU",
   300  	}
   301  )
   302  
   303  // RegisterFlagsNode function register node flags to flag list
   304  func RegisterFlagsNode(flags *[]cli.Flag) error {
   305  	if err := RegisterFlagsDirectory(flags); err != nil {
   306  		return err
   307  	}
   308  
   309  	RegisterFlagsLocation(flags)
   310  	RegisterFlagsNetwork(flags)
   311  	RegisterFlagsTransactor(flags)
   312  	RegisterFlagsAffiliator(flags)
   313  	RegisterFlagsPayments(flags)
   314  	RegisterFlagsPolicy(flags)
   315  	RegisterFlagsMMN(flags)
   316  	RegisterFlagsPilvytis(flags)
   317  	RegisterFlagsChains(flags)
   318  	RegisterFlagsUI(flags)
   319  	RegisterFlagsBlockchainNetwork(flags)
   320  	RegisterFlagsSSE(flags)
   321  
   322  	*flags = append(*flags,
   323  		&FlagBindAddress,
   324  		&FlagDiscoveryType,
   325  		&FlagDiscoveryPingInterval,
   326  		&FlagDiscoveryFetchInterval,
   327  		&FlagDHTAddress,
   328  		&FlagDHTPort,
   329  		&FlagDHTProtocol,
   330  		&FlagDHTBootstrapPeers,
   331  		&FlagFeedbackURL,
   332  		&FlagFirewallKillSwitch,
   333  		&FlagFirewallProtectedNetworks,
   334  		&FlagShaperEnabled,
   335  		&FlagShaperBandwidth,
   336  		&FlagKeystoreLightweight,
   337  		&FlagLogHTTP,
   338  		&FlagLogLevel,
   339  		&FlagVerbose,
   340  		&FlagOpenvpnBinary,
   341  		&FlagQualityType,
   342  		&FlagQualityAddress,
   343  		&FlagTequilapiAddress,
   344  		&FlagTequilapiAllowedHostnames,
   345  		&FlagTequilapiPort,
   346  		&FlagTequilapiUsername,
   347  		&FlagTequilapiPassword,
   348  		&FlagPProfEnable,
   349  		&FlagUserMode,
   350  		&FlagDVPNMode,
   351  		&FlagProxyMode,
   352  		&FlagUserspace,
   353  		&FlagVendorID,
   354  		&FlagLauncherVersion,
   355  		&FlagP2PListenPorts,
   356  		&FlagConsumer,
   357  		&FlagDefaultCurrency,
   358  		&FlagDocsURL,
   359  		&FlagDNSResolutionHeadstart,
   360  		&FlagResidentCountry,
   361  		&FlagWireguardMTU,
   362  	)
   363  
   364  	return nil
   365  }
   366  
   367  // ParseFlagsNode function fills in node options from CLI context
   368  func ParseFlagsNode(ctx *cli.Context) {
   369  	ParseFlagsDirectory(ctx)
   370  
   371  	ParseFlagsLocation(ctx)
   372  	ParseFlagsNetwork(ctx)
   373  	ParseFlagsTransactor(ctx)
   374  	ParseFlagsAffiliator(ctx)
   375  	ParseFlagsPayments(ctx)
   376  	ParseFlagsPolicy(ctx)
   377  	ParseFlagsMMN(ctx)
   378  	ParseFlagPilvytis(ctx)
   379  	ParseFlagsChains(ctx)
   380  	ParseFlagsUI(ctx)
   381  	ParseFlagsSSE(ctx)
   382  	//it is important to have this one at the end so it overwrites defaults correctly
   383  	ParseFlagsBlockchainNetwork(ctx)
   384  
   385  	Current.ParseStringFlag(ctx, FlagBindAddress)
   386  	Current.ParseStringSliceFlag(ctx, FlagDiscoveryType)
   387  	Current.ParseDurationFlag(ctx, FlagDiscoveryPingInterval)
   388  	Current.ParseDurationFlag(ctx, FlagDiscoveryFetchInterval)
   389  	Current.ParseStringFlag(ctx, FlagDHTAddress)
   390  	Current.ParseIntFlag(ctx, FlagDHTPort)
   391  	Current.ParseStringFlag(ctx, FlagDHTProtocol)
   392  	Current.ParseStringSliceFlag(ctx, FlagDHTBootstrapPeers)
   393  	Current.ParseStringFlag(ctx, FlagFeedbackURL)
   394  	Current.ParseBoolFlag(ctx, FlagFirewallKillSwitch)
   395  	Current.ParseStringFlag(ctx, FlagFirewallProtectedNetworks)
   396  	Current.ParseBoolFlag(ctx, FlagShaperEnabled)
   397  	Current.ParseUInt64Flag(ctx, FlagShaperBandwidth)
   398  	Current.ParseBoolFlag(ctx, FlagKeystoreLightweight)
   399  	Current.ParseBoolFlag(ctx, FlagLogHTTP)
   400  	Current.ParseBoolFlag(ctx, FlagVerbose)
   401  	Current.ParseStringFlag(ctx, FlagLogLevel)
   402  	Current.ParseStringFlag(ctx, FlagOpenvpnBinary)
   403  	Current.ParseStringFlag(ctx, FlagQualityAddress)
   404  	Current.ParseStringFlag(ctx, FlagQualityType)
   405  	Current.ParseStringFlag(ctx, FlagTequilapiAddress)
   406  	Current.ParseStringFlag(ctx, FlagTequilapiAllowedHostnames)
   407  	Current.ParseIntFlag(ctx, FlagTequilapiPort)
   408  	Current.ParseStringFlag(ctx, FlagTequilapiUsername)
   409  	Current.ParseStringFlag(ctx, FlagTequilapiPassword)
   410  	Current.ParseBoolFlag(ctx, FlagPProfEnable)
   411  	Current.ParseBoolFlag(ctx, FlagUserMode)
   412  	Current.ParseBoolFlag(ctx, FlagDVPNMode)
   413  	Current.ParseBoolFlag(ctx, FlagProxyMode)
   414  	Current.ParseBoolFlag(ctx, FlagUserspace)
   415  	Current.ParseStringFlag(ctx, FlagVendorID)
   416  	Current.ParseStringFlag(ctx, FlagLauncherVersion)
   417  	Current.ParseStringFlag(ctx, FlagP2PListenPorts)
   418  	Current.ParseBoolFlag(ctx, FlagConsumer)
   419  	Current.ParseStringFlag(ctx, FlagDefaultCurrency)
   420  	Current.ParseStringFlag(ctx, FlagDocsURL)
   421  	Current.ParseDurationFlag(ctx, FlagDNSResolutionHeadstart)
   422  	Current.ParseIntFlag(ctx, FlagWireguardMTU)
   423  
   424  	ValidateAddressFlags(FlagTequilapiAddress)
   425  }
   426  
   427  // ValidateAddressFlags validates given address flags for public exposure
   428  func ValidateAddressFlags(flags ...cli.StringFlag) {
   429  	for _, flag := range flags {
   430  		if flag.Value == "localhost" || flag.Value == "127.0.0.1" {
   431  			return
   432  		}
   433  		log.Warn().Msgf("Possible security vulnerability by flag `%s`, `%s` might be reachable from outside! "+
   434  			"Ensure its set to localhost or protected by firewall.", flag.Name, flag.Value)
   435  	}
   436  }
   437  
   438  // ValidateWireguardMTUFlag validates given mtu flag
   439  func ValidateWireguardMTUFlag() error {
   440  
   441  	v := Current.GetInt(FlagWireguardMTU.Name)
   442  	if v == 0 {
   443  		return nil
   444  	}
   445  	if v < 68 || v > 1500 {
   446  		msg := "Wireguard MTU value is out of possible range: 68..1500"
   447  		log.Error().Msg(msg)
   448  		return errors.Errorf("Flag validation error: %s", msg)
   449  	}
   450  	return nil
   451  }