Add logging filter token

The token is used to filter out request logs when the user agent matches a randomly generated string.
This commit is contained in:
Maximilian Paß
2024-01-24 12:43:27 +01:00
committed by Sebastian Serth
parent 221a6ff1b2
commit 57590457a8
5 changed files with 52 additions and 3 deletions

View File

@ -16,6 +16,7 @@ import (
"github.com/openHPI/poseidon/internal/environment"
"github.com/openHPI/poseidon/internal/nomad"
"github.com/openHPI/poseidon/internal/runner"
"github.com/openHPI/poseidon/pkg/dto"
"github.com/openHPI/poseidon/pkg/logging"
"github.com/openHPI/poseidon/pkg/monitoring"
"golang.org/x/sys/unix"
@ -40,7 +41,7 @@ var (
pgoEnabled = "false"
)
func getVcsRevision() string {
func getVcsRevision(short bool) string {
vcsRevision := "unknown"
vcsModified := false
@ -59,6 +60,10 @@ func getVcsRevision() string {
}
}
if short {
vcsRevision = vcsRevision[:7]
}
if vcsModified {
return vcsRevision + "-modified"
} else {
@ -66,9 +71,15 @@ func getVcsRevision() string {
}
}
func initializeUserAgent() {
dto.UserAgentOut = strings.ReplaceAll(dto.UserAgentOut, dto.UserAgentVCSPlaceholder, getVcsRevision(true))
dto.UserAgentFiltered = strings.ReplaceAll(dto.UserAgentFiltered, dto.UserAgentVCSPlaceholder, getVcsRevision(true))
dto.UserAgentFiltered = strings.ReplaceAll(dto.UserAgentFiltered, dto.UserAgentFilterTokenPlaceholder, config.Config.Server.LoggingFilterToken)
}
func initSentry(options *sentry.ClientOptions, profilingEnabled bool) {
if options.Release == "" {
commit := getVcsRevision()
commit := getVcsRevision(false)
options.Release = commit
}
@ -278,6 +289,8 @@ func notifySystemdWatchdog(ctx context.Context, healthURL string, client *http.C
if err != nil {
return
}
req.Header.Set("User-Agent", dto.UserAgentFiltered)
resp, err := client.Do(req)
if err != nil {
log.WithError(err).Debug("Failed watchdog health check")
@ -425,6 +438,7 @@ func main() {
if err := config.InitConfig(); err != nil {
log.WithError(err).Warn("Could not initialize configuration")
}
initializeUserAgent()
logging.InitializeLogging(config.Config.Logger.Level, config.Config.Logger.Formatter)
initSentry(&config.Config.Sentry, config.Config.Profiling.CPUEnabled)

View File

@ -25,6 +25,11 @@ server:
interactivestderr: true
# If set, the file at the given path overwrites the default Nomad job file in internal/environment/template-environment-job.hcl
# templatejobfile: ./poseidon.hcl
# The LoggingFilterToken filters out Systemd Watchdog requests from the logs and is preconfigured with a random value.
# It can also be manually configured to hide additional requests from the logs, such as those from monitoring systems.
# To use this feature, the respective user agent must be set according to `dto.UserAgentFiltered`.
# However, it is important to consider the security implications of using this expert-level setting for manual values.
# loggingfiltertoken: secret
# alert defines how poseidon should handle specific risks.
alert:
# The prewarming pool threshold [0, 1) defines which part of the prewarming pool should always be filled.

View File

@ -1,7 +1,9 @@
package config
import (
"crypto/rand"
"crypto/tls"
"encoding/base64"
"errors"
"flag"
"fmt"
@ -37,6 +39,7 @@ var (
PrewarmingPoolThreshold: 0,
PrewarmingPoolReloadTimeout: 0,
},
LoggingFilterToken: randomFilterToken(),
},
Nomad: Nomad{
Enabled: true,
@ -100,6 +103,7 @@ type server struct {
InteractiveStderr bool
TemplateJobFile string
Alert alert
LoggingFilterToken string
}
// URL returns the URL of the Poseidon webserver.
@ -280,3 +284,14 @@ func loadValue(prefix string, value reflect.Value, logEntry *logrus.Entry) {
Warn("Setting configuration option via environment variables is not supported")
}
}
func randomFilterToken() string {
const tokenLength = 32
randomBytes := make([]byte, tokenLength) //nolint:all // length required to be filled by rand.Read.
n, err := rand.Read(randomBytes)
if n != tokenLength || err != nil {
log.WithError(err).WithField("byteCount", n).Fatal("Failed to generate random token")
}
return base64.URLEncoding.EncodeToString(randomBytes)
}

View File

@ -9,6 +9,17 @@ import (
"strings"
)
var (
// UserAgentOut for outgoing requests (without libraries). The Git Hash will be replaced by main.go.
UserAgentOut = "Poseidon/" + UserAgentVCSPlaceholder + " Go-http-client/1.1"
UserAgentFiltered = "Poseidon/" + UserAgentVCSPlaceholder + " (" + UserAgentFilterTokenPlaceholder + ") Go-http-client/1.1"
)
const (
UserAgentVCSPlaceholder = "<7 Git Hash>"
UserAgentFilterTokenPlaceholder = "FilterToken"
)
// RunnerRequest is the expected json structure of the request body for the ProvideRunner function.
type RunnerRequest struct {
ExecutionEnvironmentID int `json:"executionEnvironmentId"`

View File

@ -93,7 +93,11 @@ func HTTPLoggingMiddleware(next http.Handler) http.Handler {
"duration": latency,
"user_agent": RemoveNewlineSymbol(r.UserAgent()),
})
logEntry.Debug()
if r.UserAgent() == dto.UserAgentFiltered {
logEntry.Trace()
} else {
logEntry.Debug()
}
})
}