Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfeistel <6742251-feistel@users.noreply.gitlab.com>2021-08-10 19:44:16 +0300
committerfeistel <6742251-feistel@users.noreply.gitlab.com>2021-10-07 16:40:43 +0300
commitdc7d694f00eadd078a05991bff7c78cb29efeff4 (patch)
treeca2c07cc40a46e67623c598a6735d49458a2e157
parent64f914a804a4da8a521c5cbe7df1b8cb73f45a4f (diff)
refactor: stop running gitlab-pages as root
We have now disabled chroot by default since %14.1, and recently removed support for disk-based configuration coming in %14.3. And we've also removed the chroot completely from Pages. Since nginx can do TCP proxying and there's no need to use privileged ports, Pages has been confirmed to run as non-root in k8s environment without any issues. This MR removes support for the gitlab-pages daemon completely. Changelog: removed
-rw-r--r--daemon.go189
-rw-r--r--internal/config/config.go13
-rw-r--r--internal/config/flags.go4
-rw-r--r--main.go16
-rw-r--r--test/acceptance/helpers_test.go4
5 files changed, 2 insertions, 224 deletions
diff --git a/daemon.go b/daemon.go
deleted file mode 100644
index 86ede6be..00000000
--- a/daemon.go
+++ /dev/null
@@ -1,189 +0,0 @@
-package main
-
-import (
- "encoding/json"
- "os"
- "os/exec"
- "os/signal"
- "path/filepath"
- "strings"
- "syscall"
-
- "github.com/sirupsen/logrus"
-
- "gitlab.com/gitlab-org/gitlab-pages/internal/config"
-)
-
-const (
- daemonRunProgram = "gitlab-pages-unprivileged"
-)
-
-func daemonMain() {
- if os.Args[0] != daemonRunProgram {
- return
- }
-
- // Validate that a working directory is valid
- // https://man7.org/linux/man-pages/man2/getcwd.2.html
- wd, err := os.Getwd()
- if err != nil {
- fatal(err, "could not get current working directory")
- } else if strings.HasPrefix(wd, "(unreachable)") {
- fatal(os.ErrPermission, "could not get current working directory")
- }
-
- logrus.WithFields(logrus.Fields{
- "uid": syscall.Getuid(),
- "gid": syscall.Getgid(),
- "wd": wd,
- }).Info("starting the daemon as unprivileged user")
-
- // read the configuration from the pipe "ExtraFiles"
- var config config.Config
- if err := json.NewDecoder(os.NewFile(3, "options")).Decode(&config); err != nil {
- fatal(err, "could not decode app config")
- }
- runApp(&config)
- os.Exit(0)
-}
-
-func daemonReexec(uid, gid uint, args ...string) (cmd *exec.Cmd, err error) {
- path, err := os.Executable()
- if err != nil {
- return
- }
-
- cmd = &exec.Cmd{
- Path: path,
- Args: args,
- Env: os.Environ(),
- Stdin: os.Stdin,
- Stdout: os.Stdout,
- Stderr: os.Stderr,
- SysProcAttr: &syscall.SysProcAttr{
- Credential: &syscall.Credential{
- Uid: uint32(uid),
- Gid: uint32(gid),
- },
- Setsid: true,
- },
- }
- return
-}
-
-func daemonUpdateFd(cmd *exec.Cmd, fd uintptr) (childFd uintptr) {
- file := os.NewFile(fd, "[socket]")
-
- // we add 3 since, we have a 3 predefined FDs
- childFd = uintptr(3 + len(cmd.ExtraFiles))
- cmd.ExtraFiles = append(cmd.ExtraFiles, file)
-
- return
-}
-
-func daemonUpdateFds(cmd *exec.Cmd, fds []uintptr) {
- for idx, fd := range fds {
- fds[idx] = daemonUpdateFd(cmd, fd)
- }
-}
-
-func killProcess(cmd *exec.Cmd) {
- if cmd.Process != nil {
- cmd.Process.Kill()
- }
- cmd.Wait()
- for _, file := range cmd.ExtraFiles {
- file.Close()
- }
-}
-
-func passSignals(cmd *exec.Cmd) {
- if cmd.Process == nil {
- return
- }
-
- s := make(chan os.Signal, 1)
- signal.Notify(s, syscall.SIGTERM, os.Interrupt, os.Kill)
-
- go func() {
- for cmd.Process != nil {
- cmd.Process.Signal(<-s)
- }
- }()
-}
-
-func daemonize(config *config.Config) error {
- uid := config.Daemon.UID
- gid := config.Daemon.GID
- pagesRoot := config.General.RootDir
-
- // Ensure pagesRoot is an absolute path. This will produce a different path
- // if any component of pagesRoot is a symlink (not likely). For example,
- // -pages-root=/some-path where ln -s /other-path /some-path
- // pagesPath will become: /other-path and we will fail to serve files from /some-path.
- // GitLab Rails also resolves the absolute path for `pages_path`
- // https://gitlab.com/gitlab-org/gitlab/blob/981ad651d8bd3690e28583eec2363a79f775af89/config/initializers/1_settings.rb#L296
- pagesRoot, err := filepath.Abs(pagesRoot)
- if err != nil {
- return err
- }
-
- logrus.WithFields(logrus.Fields{
- "uid": uid,
- "gid": gid,
- "pages-root": pagesRoot,
- }).Info("running the daemon as unprivileged user")
-
- cmd, err := daemonReexec(uid, gid, daemonRunProgram)
- if err != nil {
- return err
- }
- defer killProcess(cmd)
-
- // Create a pipe to pass the configuration
- configReader, configWriter, err := os.Pipe()
- if err != nil {
- return err
- }
- defer configWriter.Close()
- cmd.ExtraFiles = append(cmd.ExtraFiles, configReader)
-
- updateFds(config, cmd)
-
- // Start the process
- if err := cmd.Start(); err != nil {
- logrus.WithError(err).Error("start failed")
- return err
- }
-
- // Write the configuration
- if err := json.NewEncoder(configWriter).Encode(config); err != nil {
- return err
- }
- configWriter.Close()
-
- // Pass through signals
- passSignals(cmd)
-
- // Wait for process to exit
- return cmd.Wait()
-}
-
-func updateFds(config *config.Config, cmd *exec.Cmd) {
- for _, fds := range [][]uintptr{
- config.Listeners.HTTP,
- config.Listeners.HTTPS,
- config.Listeners.Proxy,
- config.Listeners.HTTPSProxyv2,
- } {
- daemonUpdateFds(cmd, fds)
- }
-
- for _, fdPtr := range []*uintptr{
- &config.ListenMetrics,
- } {
- if *fdPtr != 0 {
- *fdPtr = daemonUpdateFd(cmd, *fdPtr)
- }
- }
-}
diff --git a/internal/config/config.go b/internal/config/config.go
index 71ff0eed..860ea4be 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -18,7 +18,6 @@ type Config struct {
General General
ArtifactsServer ArtifactsServer
Authentication Auth
- Daemon Daemon
GitLab GitLab
Listeners Listeners
Log Log
@@ -80,12 +79,6 @@ type Auth struct {
Scope string
}
-// Daemon groups settings related to configuring GitLab Pages daemon
-type Daemon struct {
- UID uint
- GID uint
-}
-
// Cache configuration for GitLab API
type Cache struct {
CacheExpiry time.Duration
@@ -215,10 +208,6 @@ func loadConfig() (*Config, error) {
RedirectURI: *redirectURI,
Scope: *authScope,
},
- Daemon: Daemon{
- UID: *daemonUID,
- GID: *daemonGID,
- },
Log: Log{
Format: *logFormat,
Verbose: *logVerbose,
@@ -281,8 +270,6 @@ func LogConfig(config *Config) {
log.WithFields(log.Fields{
"artifacts-server": *artifactsServer,
"artifacts-server-timeout": *artifactsServerTimeout,
- "daemon-gid": *daemonGID,
- "daemon-uid": *daemonUID,
"default-config-filename": flag.DefaultConfigFlagname,
"disable-cross-origin-requests": *disableCrossOriginRequests,
"domain": config.General.Domain,
diff --git a/internal/config/flags.go b/internal/config/flags.go
index aa5bf1c5..6523c20a 100644
--- a/internal/config/flags.go
+++ b/internal/config/flags.go
@@ -21,8 +21,8 @@ var (
metricsAddress = flag.String("metrics-address", "", "The address to listen on for metrics requests")
sentryDSN = flag.String("sentry-dsn", "", "The address for sending sentry crash reporting to")
sentryEnvironment = flag.String("sentry-environment", "", "The environment for sentry crash reporting")
- daemonUID = flag.Uint("daemon-uid", 0, "Drop privileges to this user")
- daemonGID = flag.Uint("daemon-gid", 0, "Drop privileges to this group")
+ _ = flag.Uint("daemon-uid", 0, "Drop privileges to this user")
+ _ = flag.Uint("daemon-gid", 0, "Drop privileges to this group")
_ = flag.Bool("daemon-enable-jail", false, "DEPRECATED and ignored, will be removed in 15.0")
_ = flag.Bool("daemon-inplace-chroot", false, "DEPRECATED and ignored, will be removed in 15.0") // TODO: https://gitlab.com/gitlab-org/gitlab-pages/-/issues/599
propagateCorrelationID = flag.Bool("propagate-correlation-id", false, "Reuse existing Correlation-ID from the incoming request header `X-Request-ID` if present")
diff --git a/main.go b/main.go
index 042e5974..f89d10fa 100644
--- a/main.go
+++ b/main.go
@@ -5,7 +5,6 @@ import (
"io"
"math/rand"
"os"
- "strings"
"time"
"github.com/sirupsen/logrus"
@@ -82,20 +81,6 @@ func appMain() {
defer closeAll(cs)
}
- if config.Daemon.UID != 0 || config.Daemon.GID != 0 {
- if err := daemonize(config); err != nil {
- if strings.Contains(err.Error(), "signal:") {
- log.WithField("signal", err.Error()).Info("daemon received signal")
- return
- }
-
- errortracking.Capture(err)
- fatal(err, "could not create pages daemon")
- }
-
- return
- }
-
runApp(config)
}
@@ -202,6 +187,5 @@ func main() {
metrics.MustRegister()
- daemonMain()
appMain()
}
diff --git a/test/acceptance/helpers_test.go b/test/acceptance/helpers_test.go
index b8181dca..8ad0166f 100644
--- a/test/acceptance/helpers_test.go
+++ b/test/acceptance/helpers_test.go
@@ -381,10 +381,6 @@ func getPagesDaemonArgs(t *testing.T) []string {
t.Log("Running pages as a daemon")
- // This triggers the drop-privileges-and-chroot code in the pages daemon
- out = append(out, "-daemon-uid", "0")
- out = append(out, "-daemon-gid", "65534")
-
return out
}