Просмотр исходного кода

More logging changes
* Remove syslog support
* Add file logging support
* Revert to independent logger for fail2ban

Rod Hynes 9 лет назад
Родитель
Сommit
24e9088916
3 измененных файлов с 52 добавлено и 67 удалено
  1. 9 13
      psiphon/server/config.go
  2. 40 50
      psiphon/server/log.go
  3. 3 4
      psiphon/server/tunnelServer.go

+ 9 - 13
psiphon/server/config.go

@@ -66,16 +66,9 @@ type Config struct {
 	// panic, fatal, error, warn, info, debug
 	LogLevel string
 
-	// SyslogFacility specifies the syslog facility to log to.
-	// When set, the local syslog service is used for message
-	// logging.
-	// Valid values include: "user", "local0", "local1", etc.
-	SyslogFacility string
-
-	// SyslogTag specifies an optional tag for syslog log
-	// messages. The default tag is "psiphon-server". The
-	// fail2ban logs, if enabled, also use this tag.
-	SyslogTag string
+	// LogFilename specifies the path of the file to log
+	// to. When blank, logs are written to stderr.
+	LogFilename string
 
 	// Fail2BanFormat is a string format specifier for the
 	// log message format to use for fail2ban integration for
@@ -88,6 +81,11 @@ type Config struct {
 	// "Authentication failure for psiphon-client from %s".
 	Fail2BanFormat string
 
+	// LogFilename specifies the path of the file to log
+	// fail2ban messages to. When blank, logs are written to
+	// stderr.
+	Fail2BanLogFilename string
+
 	// DiscoveryValueHMACKey is the network-wide secret value
 	// used to determine a unique discovery strategy.
 	DiscoveryValueHMACKey string
@@ -224,7 +222,7 @@ func (config *Config) RunLoadMonitor() bool {
 }
 
 // UseFail2Ban indicates whether to log client IP addresses, in authentication
-// failure cases, to the local syslog service AUTH facility for use by fail2ban.
+// failure cases, for use by fail2ban.
 func (config *Config) UseFail2Ban() bool {
 	return config.Fail2BanFormat != ""
 }
@@ -461,8 +459,6 @@ func GenerateConfig(params *GenerateConfigParams) ([]byte, []byte, []byte, error
 
 	config := &Config{
 		LogLevel:                       "info",
-		SyslogFacility:                 "user",
-		SyslogTag:                      "psiphon-server",
 		Fail2BanFormat:                 "Authentication failure for psiphon-client from %s",
 		GeoIPDatabaseFilename:          "",
 		HostID:                         "example-host-id",

+ 40 - 50
psiphon/server/log.go

@@ -20,12 +20,11 @@
 package server
 
 import (
+	"fmt"
 	"io"
-	"log/syslog"
 	"os"
 
 	"github.com/Psiphon-Inc/logrus"
-	logrus_syslog "github.com/Psiphon-Inc/logrus/hooks/syslog"
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon"
 )
 
@@ -68,7 +67,18 @@ func NewLogWriter() *io.PipeWriter {
 	return log.Writer()
 }
 
+// LogFail2Ban logs a message using the format specified by
+// config.Fail2BanFormat and the given client IP address. This
+// is for integration with fail2ban for blocking abusive
+// clients by source IP address.
+func LogFail2Ban(clientIPAddress string) {
+	fail2BanLogger.Info(
+		fmt.Sprintf(fail2BanFormat, clientIPAddress))
+}
+
 var log *ContextLogger
+var fail2BanFormat string
+var fail2BanLogger *logrus.Logger
 
 // InitLogging configures a logger according to the specified
 // config params. If not called, the default logger set by the
@@ -84,76 +94,56 @@ func InitLogging(config *Config) error {
 		return psiphon.ContextError(err)
 	}
 
-	hooks := make(logrus.LevelHooks)
-
-	var syslogHook *logrus_syslog.SyslogHook
-
-	if config.SyslogFacility != "" {
+	logWriter := os.Stderr
 
-		syslogHook, err = logrus_syslog.NewSyslogHook(
-			"", "", getSyslogPriority(config), config.SyslogTag)
+	if config.LogFilename != "" {
+		logWriter, err = os.OpenFile(
+			config.LogFilename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
 		if err != nil {
 			return psiphon.ContextError(err)
 		}
-
-		hooks.Add(syslogHook)
 	}
 
 	log = &ContextLogger{
 		&logrus.Logger{
-			Out:       os.Stderr,
-			Formatter: new(logrus.JSONFormatter),
-			Hooks:     hooks,
+			Out:       logWriter,
+			Formatter: &logrus.JSONFormatter{},
 			Level:     level,
 		},
 	}
 
-	return nil
-}
+	if config.Fail2BanFormat != "" {
 
-// getSyslogPriority determines golang's syslog "priority" value
-// based on the provided config.
-func getSyslogPriority(config *Config) syslog.Priority {
-
-	// TODO: assumes log.Level filter applies?
-	severity := syslog.LOG_DEBUG
-
-	facilityCodes := map[string]syslog.Priority{
-		"kern":     syslog.LOG_KERN,
-		"user":     syslog.LOG_USER,
-		"mail":     syslog.LOG_MAIL,
-		"daemon":   syslog.LOG_DAEMON,
-		"auth":     syslog.LOG_AUTH,
-		"syslog":   syslog.LOG_SYSLOG,
-		"lpr":      syslog.LOG_LPR,
-		"news":     syslog.LOG_NEWS,
-		"uucp":     syslog.LOG_UUCP,
-		"cron":     syslog.LOG_CRON,
-		"authpriv": syslog.LOG_AUTHPRIV,
-		"ftp":      syslog.LOG_FTP,
-		"local0":   syslog.LOG_LOCAL0,
-		"local1":   syslog.LOG_LOCAL1,
-		"local2":   syslog.LOG_LOCAL2,
-		"local3":   syslog.LOG_LOCAL3,
-		"local4":   syslog.LOG_LOCAL4,
-		"local5":   syslog.LOG_LOCAL5,
-		"local6":   syslog.LOG_LOCAL6,
-		"local7":   syslog.LOG_LOCAL7,
-	}
+		fail2BanFormat = config.Fail2BanFormat
 
-	facility, ok := facilityCodes[config.SyslogFacility]
-	if !ok {
-		facility = syslog.LOG_USER
+		fail2BanLogWriter := os.Stderr
+
+		if config.Fail2BanLogFilename != "" {
+			logWriter, err = os.OpenFile(
+				config.Fail2BanLogFilename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
+			if err != nil {
+				return psiphon.ContextError(err)
+			}
+		}
+
+		fail2BanLogger = &logrus.Logger{
+			Out: fail2BanLogWriter,
+			Formatter: &logrus.TextFormatter{
+				DisableColors: true,
+				FullTimestamp: true,
+			},
+			Level: level,
+		}
 	}
 
-	return severity | facility
+	return nil
 }
 
 func init() {
 	log = &ContextLogger{
 		&logrus.Logger{
 			Out:       os.Stderr,
-			Formatter: new(logrus.JSONFormatter),
+			Formatter: &logrus.JSONFormatter{},
 			Hooks:     make(logrus.LevelHooks),
 			Level:     logrus.DebugLevel,
 		},

+ 3 - 4
psiphon/server/tunnelServer.go

@@ -618,15 +618,14 @@ func (sshClient *sshClient) authLogCallback(conn ssh.ConnMetadata, method string
 			return
 		}
 
-		logFields := LogFields{"error": err, "method": method}
 		if sshClient.sshServer.support.Config.UseFail2Ban() {
 			clientIPAddress := psiphon.IPAddressFromAddr(conn.RemoteAddr())
 			if clientIPAddress != "" {
-				logFields["fail2ban"] = fmt.Sprintf(
-					sshClient.sshServer.support.Config.Fail2BanFormat, clientIPAddress)
+				LogFail2Ban(clientIPAddress)
 			}
 		}
-		log.WithContextFields(logFields).Error("authentication failed")
+
+		log.WithContextFields(LogFields{"error": err, "method": method}).Error("authentication failed")
 
 	} else {