Merge pull request #5063 from Crypt-iQ/pprof_patch_03022021

lnd: optionally serve pprof on localhost for better security
This commit is contained in:
Olaoluwa Osuntokun 2021-04-05 20:20:39 -07:00 committed by GitHub
commit 1ccf6ed7d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 11 deletions

@ -239,7 +239,7 @@ type Config struct {
CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"` CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"`
Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65535"` Profile string `long:"profile" description:"Enable HTTP profiling on either a port or host:port"`
UnsafeDisconnect bool `long:"unsafe-disconnect" description:"DEPRECATED: Allows the rpcserver to intentionally disconnect from peers with open channels. THIS FLAG WILL BE REMOVED IN 0.10.0"` UnsafeDisconnect bool `long:"unsafe-disconnect" description:"DEPRECATED: Allows the rpcserver to intentionally disconnect from peers with open channels. THIS FLAG WILL BE REMOVED IN 0.10.0"`
UnsafeReplay bool `long:"unsafe-replay" description:"Causes a link to replay the adds on its commitment txn after starting up, this enables testing of the sphinx replay logic."` UnsafeReplay bool `long:"unsafe-replay" description:"Causes a link to replay the adds on its commitment txn after starting up, this enables testing of the sphinx replay logic."`
@ -1086,15 +1086,34 @@ func ValidateConfig(cfg Config, usageMessage string,
cfg.Autopilot.MaxChannelSize = int64(MaxFundingAmount) cfg.Autopilot.MaxChannelSize = int64(MaxFundingAmount)
} }
// Validate profile port number. // Validate profile port or host:port.
if cfg.Profile != "" { if cfg.Profile != "" {
profilePort, err := strconv.Atoi(cfg.Profile) str := "%s: The profile port must be between 1024 and 65535"
if err != nil || profilePort < 1024 || profilePort > 65535 {
str := "%s: The profile port must be between 1024 and 65535" // Try to parse Profile as a host:port.
err := fmt.Errorf(str, funcName) _, hostPort, err := net.SplitHostPort(cfg.Profile)
_, _ = fmt.Fprintln(os.Stderr, err) if err == nil {
_, _ = fmt.Fprintln(os.Stderr, usageMessage) // Determine if the port is valid.
return nil, err profilePort, err := strconv.Atoi(hostPort)
if err != nil || profilePort < 1024 || profilePort > 65535 {
err = fmt.Errorf(str, funcName)
_, _ = fmt.Fprintln(os.Stderr, err)
_, _ = fmt.Fprintln(os.Stderr, usageMessage)
return nil, err
}
} else {
// Try to parse Profile as a port.
profilePort, err := strconv.Atoi(cfg.Profile)
if err != nil || profilePort < 1024 || profilePort > 65535 {
err = fmt.Errorf(str, funcName)
_, _ = fmt.Fprintln(os.Stderr, err)
_, _ = fmt.Fprintln(os.Stderr, usageMessage)
return nil, err
}
// Since the user just set a port, we will serve debugging
// information over localhost.
cfg.Profile = net.JoinHostPort("127.0.0.1", cfg.Profile)
} }
} }

4
lnd.go

@ -227,11 +227,11 @@ func Main(cfg *Config, lisCfg ListenerCfg, interceptor signal.Interceptor) error
// Enable http profiling server if requested. // Enable http profiling server if requested.
if cfg.Profile != "" { if cfg.Profile != "" {
go func() { go func() {
listenAddr := net.JoinHostPort("", cfg.Profile)
profileRedirect := http.RedirectHandler("/debug/pprof", profileRedirect := http.RedirectHandler("/debug/pprof",
http.StatusSeeOther) http.StatusSeeOther)
http.Handle("/", profileRedirect) http.Handle("/", profileRedirect)
fmt.Println(http.ListenAndServe(listenAddr, nil)) ltndLog.Infof("Pprof listening on %v", cfg.Profile)
fmt.Println(http.ListenAndServe(cfg.Profile, nil))
}() }()
} }