Remove mounts for /etc/passwd and others by creating accounts within container

master
Hugo Thunnissen 2 years ago
parent 718f92e8f8
commit 2ab3d88f1a

@ -1,5 +1,7 @@
FROM ubuntu:21.10 FROM ubuntu:21.10
RUN yes | unminimize
RUN apt-get -y update && apt-get -y install locales RUN apt-get -y update && apt-get -y install locales
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \ RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
@ -21,7 +23,6 @@ ENV LC_MEASUREMENT=en_US.UTF-8
ENV LC_IDENTIFICATION=en_US.UTF-8 ENV LC_IDENTIFICATION=en_US.UTF-8
ENV TZ=Europe/Amsterdam ENV TZ=Europe/Amsterdam
RUN apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install \ RUN apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install \
man-db jq curl git pwgen build-essential libjansson-dev \ man-db jq curl git pwgen build-essential libjansson-dev \
libtiff-dev libgif-dev ffmpeg libffi-dev xutils-dev \ libtiff-dev libgif-dev ffmpeg libffi-dev xutils-dev \

@ -3,6 +3,7 @@ package main
import ( import (
"bufio" "bufio"
_ "embed" _ "embed"
"errors"
"flag" "flag"
"fmt" "fmt"
"os" "os"
@ -29,6 +30,51 @@ var customLisp string
//go:embed bash/bash_aliases //go:embed bash/bash_aliases
var bashAliases string var bashAliases string
var ErrAddUserFailExit = errors.New("useradd command returned no-zero exit code")
var ErrAddGroupFailExit = errors.New("groupadd command returned no-zero exit code")
func AddUser(username string, uid string) error {
cmd := exec.Command(
"useradd",
"--no-create-home",
"--uid", uid,
"--user-group",
username,
)
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf(
"Error adding user: %w. Process error: %w. Process output: %s",
ErrAddUserFailExit,
err,
output,
)
}
return nil
}
func AddGroup(name string, gid string) error {
cmd := exec.Command(
"groupadd",
"--gid", gid,
name,
)
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf(
"Error adding group: %w. Process error: %w. Process output: %s",
ErrAddGroupFailExit,
err,
output,
)
}
return nil
}
func EntryPoint(command []string) error { func EntryPoint(command []string) error {
if len(command) == 0 { if len(command) == 0 {
command = []string{"/bin/bash", "-i"} command = []string{"/bin/bash", "-i"}
@ -44,7 +90,8 @@ func EntryPoint(command []string) error {
) )
} }
dockerGid, err := strconv.Atoi(os.Getenv("WORKSPACE_DOCKER_GID")) dockerGidString := os.Getenv("WORKSPACE_DOCKER_GID")
dockerGid, err := strconv.Atoi(dockerGidString)
if err != nil { if err != nil {
return fmt.Errorf( return fmt.Errorf(
"Failed to parse GID from WORKSPACE_DOCKER_GID env var with contents \"%s\". Error: %w", "Failed to parse GID from WORKSPACE_DOCKER_GID env var with contents \"%s\". Error: %w",
@ -53,17 +100,27 @@ func EntryPoint(command []string) error {
) )
} }
err = AddUser(os.Getenv("WORKSPACE_USERNAME"), uidString)
if err != nil {
return err
}
err = AddGroup("docker", dockerGidString)
if err != nil {
return err
}
err = syscall.Setgroups([]int{dockerGid}) err = syscall.Setgroups([]int{dockerGid})
if err != nil { if err != nil {
return err return err
} }
err = syscall.Setgid(uid) err = syscall.Setgid(int(uid))
if err != nil { if err != nil {
return err return err
} }
err = syscall.Setuid(uid) err = syscall.Setuid(int(uid))
if err != nil { if err != nil {
return err return err
} }
@ -78,7 +135,7 @@ func EntryPoint(command []string) error {
return syscall.Exec(path, command, os.Environ()) return syscall.Exec(path, command, os.Environ())
} }
func Run(detach bool, command []string) error { func Run(detach bool, mounts []string, command []string) error {
workDir, err := os.Getwd() workDir, err := os.Getwd()
if err != nil { if err != nil {
return err return err
@ -100,18 +157,13 @@ func Run(detach bool, command []string) error {
"--workdir=" + workDir, "--workdir=" + workDir,
"-e", "DISPLAY=" + os.Getenv("DISPLAY"), "-e", "DISPLAY=" + os.Getenv("DISPLAY"),
"-e", "WORKSPACE_USER=" + curUser.Uid, "-e", "WORKSPACE_USER=" + curUser.Uid,
"-e", "WORKSPACE_USERNAME=" + curUser.Name, "-e", "WORKSPACE_USERNAME=" + curUser.Username,
"-e", "WORKSPACE_DOCKER_GID=" + dockerGroup.Gid, "-e", "WORKSPACE_DOCKER_GID=" + dockerGroup.Gid,
"-e", "HOME=" + home, "-e", "HOME=" + home,
"-h", os.Getenv("HOSTNAME"), "-h", os.Getenv("HOSTNAME"),
"-v", "/var/run/docker.sock:/var/run/docker.sock", "-v", "/var/run/docker.sock:/var/run/docker.sock",
"-v", "/etc/subuid:/etc/subuid:ro",
"-v", "/etc/subgid:/etc/subgid:ro",
"-v", "/etc/hosts:/etc/hosts:ro", "-v", "/etc/hosts:/etc/hosts:ro",
"-v", "/etc/passwd:/etc/passwd:ro",
"-v", "/etc/resolv.conf:/etc/resolv.conf:ro", "-v", "/etc/resolv.conf:/etc/resolv.conf:ro",
"-v", "/etc/sudoers:/etc/sudoers:ro",
"-v", "/etc/group:/etc/group:ro",
"-v", home + ":" + home, "-v", home + ":" + home,
"-e", "SSH_AGENT_LAUNCHER=" + os.Getenv("SSH_AGENT_LAUNCHER"), "-e", "SSH_AGENT_LAUNCHER=" + os.Getenv("SSH_AGENT_LAUNCHER"),
"-e", "SSH_AUTH_SOCK=" + os.Getenv("SSH_AUTH_SOCK"), "-e", "SSH_AUTH_SOCK=" + os.Getenv("SSH_AUTH_SOCK"),
@ -131,6 +183,10 @@ func Run(detach bool, command []string) error {
dockerCommand = append(dockerCommand, "-ti") dockerCommand = append(dockerCommand, "-ti")
} }
for _, mount := range mounts {
dockerCommand = append(dockerCommand, "-v", mount+":"+mount)
}
fileInfo, err := os.Lstat(home) fileInfo, err := os.Lstat(home)
if err != nil { if err != nil {
return fmt.Errorf( return fmt.Errorf(
@ -216,6 +272,9 @@ func main() {
"Whether or not to detach from the container after running the command", "Whether or not to detach from the container after running the command",
) )
var mounts arrayFlag
run.Var(&mounts, "mount", "Directory to mount inside the workspace container")
switch cmd { switch cmd {
case "entrypoint": case "entrypoint":
err := EntryPoint(os.Args[2:]) err := EntryPoint(os.Args[2:])
@ -231,7 +290,7 @@ func main() {
os.Exit(1) os.Exit(1)
} }
err = Run(detach, run.Args()) err = Run(detach, mounts, run.Args())
if err != nil { if err != nil {
fmt.Println("error running command in container", err) fmt.Println("error running command in container", err)
os.Exit(1) os.Exit(1)

@ -0,0 +1,16 @@
package main
import (
"strings"
)
type arrayFlag []string
func (f *arrayFlag) String() string {
return strings.Join(*f, ",")
}
func (f *arrayFlag) Set(value string) error {
*f = append(*f, value)
return nil
}
Loading…
Cancel
Save