Add --add-user to write UID/GID to passwd

This commit is contained in:
Tim Hockin 2020-01-03 16:16:15 -08:00
parent fbdeead461
commit 5154ace66d
3 changed files with 41 additions and 0 deletions

View File

@ -22,7 +22,11 @@ RUN apt-get update \
openssh-client \ openssh-client \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# By default we will run as this user...
RUN echo "git-sync:x:65533:65533::/tmp:/sbin/nologin" >> /etc/passwd RUN echo "git-sync:x:65533:65533::/tmp:/sbin/nologin" >> /etc/passwd
# ...but the user might choose a different UID and pass --add-user
# which needs to be able to write to /etc/passwd.
RUN chmod 0666 /etc/passwd
ADD bin/{ARG_OS}_{ARG_ARCH}/{ARG_BIN} /{ARG_BIN} ADD bin/{ARG_OS}_{ARG_ARCH}/{ARG_BIN} /{ARG_BIN}

View File

@ -94,6 +94,8 @@ var flSSHKnownHosts = flag.Bool("ssh-known-hosts", envBool("GIT_KNOWN_HOSTS", tr
"enable SSH known_hosts verification") "enable SSH known_hosts verification")
var flSSHKnownHostsFile = flag.String("ssh-known-hosts-file", envString("GIT_SSH_KNOWN_HOSTS_FILE", "/etc/git-secret/known_hosts"), var flSSHKnownHostsFile = flag.String("ssh-known-hosts-file", envString("GIT_SSH_KNOWN_HOSTS_FILE", "/etc/git-secret/known_hosts"),
"the known_hosts file to use") "the known_hosts file to use")
var flAddUser = flag.Bool("add-user", envBool("GIT_SYNC_ADD_USER", false),
"add a record to /etc/passwd for the current UID/GID (needed to use SSH with a different UID)")
var flCookieFile = flag.Bool("cookie-file", envBool("GIT_COOKIE_FILE", false), var flCookieFile = flag.Bool("cookie-file", envBool("GIT_COOKIE_FILE", false),
"use git cookiefile") "use git cookiefile")
@ -241,6 +243,13 @@ func main() {
os.Exit(1) os.Exit(1)
} }
if *flAddUser {
if err := addUser(); err != nil {
fmt.Fprintf(os.Stderr, "ERROR: can't write to /etc/passwd: %v\n", err)
os.Exit(1)
}
}
// This context is used only for git credentials initialization. There are no long-running operations like // This context is used only for git credentials initialization. There are no long-running operations like
// `git clone`, so initTimeout set to 30 seconds should be enough. // `git clone`, so initTimeout set to 30 seconds should be enough.
ctx, cancel := context.WithTimeout(context.Background(), initTimeout) ctx, cancel := context.WithTimeout(context.Background(), initTimeout)
@ -390,6 +399,29 @@ func sleepForever() {
os.Exit(0) os.Exit(0)
} }
// Put the current UID/GID into /etc/passwd so SSH can look it up. This
// assumes that we have the permissions to write to it.
func addUser() error {
home := os.Getenv("HOME")
if home == "" {
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("can't get current working directory: %v", err)
}
home = cwd
}
f, err := os.OpenFile("/etc/passwd", os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer f.Close()
str := fmt.Sprintf("git-sync:x:%d:%d::%s:/sbin/nologin\n", os.Getuid(), os.Getgid(), home)
_, err = f.WriteString(str)
return err
}
// updateSymlink atomically swaps the symlink to point at the specified // updateSymlink atomically swaps the symlink to point at the specified
// directory and cleans up the previous worktree. If there was a previous // directory and cleans up the previous worktree. If there was a previous
// worktree, this returns the path to it. // worktree, this returns the path to it.

View File

@ -103,6 +103,11 @@ that this is a Pod-wide setting, unlike the container `securityContext` above.
# ... # ...
``` ```
If you want git-sync to run as a different (non-root) UID and GID, you can
change these last blocks to any UID/GID you like. SSH demands that the current
UID be present in /etc/passwd, so in this case you will need to add the
`--add-user` flag to git-sync's args array.
**Note:** Kubernetes mounts the Secret with permissions 0444 by default (not **Note:** Kubernetes mounts the Secret with permissions 0444 by default (not
restrictive enough to be used as an SSH key), so make sure you set the restrictive enough to be used as an SSH key), so make sure you set the
`defaultMode`. `defaultMode`.