History

Deprecate auto detection of container user (#7930)

There is no reliable way to handle fallbacks for MinIO deployments, due to various command line options and multiple locations which require access inside container. Parsing command line options is tricky to figure out which is the backend disk etc, we did try to fix this in implementations of check-user.go but it wasn't complete and introduced more bugs. This PR simplifies the entire approach to rather than running Docker container as non-root by default always, it allows users to opt-in. Such that they are aware that that is what they are planning to do. In-fact there are other ways docker containers can be run as regular users, without modifying our internal behavior and adding more complexities.

Harshavardhana committed 7 years ago

Commit 55dd0171 parent 12353ca8 files · +21 −185Browse files

Unified · Split

8 files
  1. .gitignore +0 −1
  2. Dockerfile +1 −3
  3. Dockerfile.dev +2 −3
  4. Dockerfile.release +2 −5
  5. Makefile +0 −1
  6. dockerscripts/check-user.go +0 −135
  7. dockerscripts/docker-entrypoint.sh +9 −28
  8. docs/docker/README.md +7 −9
.gitignore+0−1
@@ -22,5 +22,4 @@ prime/ · 21 unmodified lines
22stage/22stage/
23.sia_temp/23.sia_temp/
24config.json24config.json
25dockerscripts/check-user
26dockerscripts/healthcheck25dockerscripts/healthcheck
Dockerfile+1−3
@@ -10,8 +10,7 @@ RUN \ · 9 unmodified lines
10 apk add --no-cache git && \10 apk add --no-cache git && \
11 git clone https://github.com/minio/minio && cd minio && \11 git clone https://github.com/minio/minio && cd minio && \
12 go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \12 go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \
13 cd dockerscripts; go build -tags kqueue -ldflags "-s -w" -o /usr/bin/healthcheck healthcheck.go && \13 cd dockerscripts; go build -tags kqueue -ldflags "-s -w" -o /usr/bin/healthcheck healthcheck.go
14 go build -tags kqueue -ldflags "-s -w" -o /usr/bin/check-user check-user.go
15 14
16FROM alpine:3.915FROM alpine:3.9
17 16
@@ -23,7 +22,6 @@ EXPOSE 9000 · 5 unmodified lines
23 22
24COPY --from=0 /go/bin/minio /usr/bin/minio23COPY --from=0 /go/bin/minio /usr/bin/minio
25COPY --from=0 /usr/bin/healthcheck /usr/bin/healthcheck24COPY --from=0 /usr/bin/healthcheck /usr/bin/healthcheck
26COPY --from=0 /usr/bin/check-user /usr/bin/check-user
27COPY dockerscripts/docker-entrypoint.sh /usr/bin/25COPY dockerscripts/docker-entrypoint.sh /usr/bin/
28 26
29RUN \27RUN \
Dockerfile.dev+2−3
@@ -2,7 +2,7 @@ FROM alpine:3.9 · 1 unmodified line
2 2
3LABEL maintainer="MinIO Inc <dev@min.io>"3LABEL maintainer="MinIO Inc <dev@min.io>"
4 4
5COPY dockerscripts/docker-entrypoint.sh dockerscripts/healthcheck dockerscripts/check-user /usr/bin/5COPY dockerscripts/docker-entrypoint.sh dockerscripts/healthcheck /usr/bin/
6COPY minio /usr/bin/6COPY minio /usr/bin/
7 7
8ENV MINIO_UPDATE off8ENV MINIO_UPDATE off
@@ -14,8 +14,7 @@ RUN \ · 5 unmodified lines
14 echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \14 echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && \
15 chmod +x /usr/bin/minio && \15 chmod +x /usr/bin/minio && \
16 chmod +x /usr/bin/docker-entrypoint.sh && \16 chmod +x /usr/bin/docker-entrypoint.sh && \
17 chmod +x /usr/bin/healthcheck && \17 chmod +x /usr/bin/healthcheck
18 chmod +x /usr/bin/check-user
19 18
20EXPOSE 900019EXPOSE 9000
21 20
Dockerfile.release+2−5
@@ -7,15 +7,13 @@ ENV GO111MODULE on · 6 unmodified lines
7RUN \7RUN \
8 apk add --no-cache git && \8 apk add --no-cache git && \
9 git clone https://github.com/minio/minio && cd minio/dockerscripts && \9 git clone https://github.com/minio/minio && cd minio/dockerscripts && \
10 go build -tags kqueue -ldflags "-s -w" -o /usr/bin/healthcheck healthcheck.go && \10 go build -tags kqueue -ldflags "-s -w" -o /usr/bin/healthcheck healthcheck.go
11 go build -tags kqueue -ldflags "-s -w" -o /usr/bin/check-user check-user.go
12 11
13FROM alpine:3.912FROM alpine:3.9
14 13
15LABEL maintainer="MinIO Inc <dev@min.io>"14LABEL maintainer="MinIO Inc <dev@min.io>"
16 15
17COPY --from=0 /usr/bin/healthcheck /usr/bin/healthcheck16COPY --from=0 /usr/bin/healthcheck /usr/bin/healthcheck
18COPY --from=0 /usr/bin/check-user /usr/bin/check-user
19COPY dockerscripts/docker-entrypoint.sh /usr/bin/17COPY dockerscripts/docker-entrypoint.sh /usr/bin/
20 18
21ENV MINIO_UPDATE off19ENV MINIO_UPDATE off
@@ -28,8 +26,7 @@ RUN \ · 6 unmodified lines
28 curl https://dl.min.io/server/minio/release/linux-amd64/minio > /usr/bin/minio && \26 curl https://dl.min.io/server/minio/release/linux-amd64/minio > /usr/bin/minio && \
29 chmod +x /usr/bin/minio && \27 chmod +x /usr/bin/minio && \
30 chmod +x /usr/bin/docker-entrypoint.sh && \28 chmod +x /usr/bin/docker-entrypoint.sh && \
31 chmod +x /usr/bin/healthcheck && \29 chmod +x /usr/bin/healthcheck
32 chmod +x /usr/bin/check-user
33 30
34EXPOSE 900031EXPOSE 9000
35 32
Makefile+0−1
@@ -73,7 +73,6 @@ build: checks · 72 unmodified lines
73 @echo "Building minio binary to './minio'"73 @echo "Building minio binary to './minio'"
74 @GO111MODULE=on GOFLAGS="" CGO_ENABLED=0 go build -tags kqueue --ldflags $(BUILD_LDFLAGS) -o $(PWD)/minio 1>/dev/null74 @GO111MODULE=on GOFLAGS="" CGO_ENABLED=0 go build -tags kqueue --ldflags $(BUILD_LDFLAGS) -o $(PWD)/minio 1>/dev/null
75 @GO111MODULE=on GOFLAGS="" CGO_ENABLED=0 go build -tags kqueue --ldflags $(BUILD_LDFLAGS) -o $(PWD)/dockerscripts/healthcheck $(PWD)/dockerscripts/healthcheck.go 1>/dev/null75 @GO111MODULE=on GOFLAGS="" CGO_ENABLED=0 go build -tags kqueue --ldflags $(BUILD_LDFLAGS) -o $(PWD)/dockerscripts/healthcheck $(PWD)/dockerscripts/healthcheck.go 1>/dev/null
76 @GO111MODULE=on GOFLAGS="" CGO_ENABLED=0 go build -tags kqueue --ldflags $(BUILD_LDFLAGS) -o $(PWD)/dockerscripts/check-user $(PWD)/dockerscripts/check-user.go 1>/dev/null
77 76
78docker: build77docker: build
79 @docker build -t $(TAG) . -f Dockerfile.dev78 @docker build -t $(TAG) . -f Dockerfile.dev
dockerscripts/check-user.go+0−135
@@ -1,135 +0,0 @@
1// +build ignore
2
3/*
4 * MinIO Cloud Storage, (C) 2019 MinIO, Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19package main
20
21import (
22 "fmt"
23 "log"
24 "os"
25 "os/user"
26 "syscall"
27
28 "github.com/minio/cli"
29 minio "github.com/minio/minio/cmd"
30)
31
32var defaultUserGroup string
33
34func init() {
35 username := os.Getenv("MINIO_USERNAME")
36 groupname := os.Getenv("MINIO_GROUPNAME")
37 defaultUserGroup = username + ":" + groupname
38}
39
40func getUserGroup(path string) (string, error) {
41 fi, err := os.Stat(minio.PathJoin(path, ".minio.sys"))
42 if err != nil {
43 // Fresh directory we should default to what was requested by user.
44 if os.IsNotExist(err) {
45 fi, err = os.Stat(path)
46 if err != nil {
47 return "", err
48 }
49 } else {
50 return "", err
51 }
52 }
53 stat, ok := fi.Sys().(*syscall.Stat_t)
54 if !ok {
55 // Unable to figure out uid/gid, default to defaultUserGroup
56 return defaultUserGroup, nil
57 }
58 u, err := user.LookupId(fmt.Sprintf("%d", stat.Uid))
59 if err != nil {
60 return fmt.Sprintf("%d:%d", stat.Uid, stat.Gid), nil
61 }
62 g, err := user.LookupGroupId(fmt.Sprintf("%d", stat.Gid))
63 if err != nil {
64 return fmt.Sprintf("%d:%d", stat.Uid, stat.Gid), nil
65 }
66 return fmt.Sprintf("%s:%s", u.Username, g.Name), nil
67}
68
69func main() {
70 app := cli.NewApp()
71 app.Flags = append(minio.ServerFlags, minio.GlobalFlags...)
72 app.Action = func(ctx *cli.Context) {
73 // Fetch address option
74 serverAddr := ctx.GlobalString("address")
75 if serverAddr == "" || serverAddr == ":9000" {
76 serverAddr = ctx.String("address")
77 }
78 if ctx.Args().First() == "help" {
79 cli.ShowCommandHelpAndExit(ctx, "check-user", 1)
80 }
81 if ctx.Args().First() != "minio" {
82 cli.ShowCommandHelpAndExit(ctx, "check-user", 1)
83 }
84 args := cli.Args(ctx.Args().Tail())
85 if !args.Present() {
86 cli.ShowCommandHelpAndExit(ctx, "check-user", 1)
87 }
88 var ug string
89 var err error
90 switch args.First() {
91 case "gateway":
92 args = cli.Args(args.Tail())
93 if args.First() != "nas" {
94 fmt.Println(defaultUserGroup)
95 return
96 }
97 args = cli.Args(args.Tail())
98 if args.First() == "" {
99 fmt.Println("")
100 return
101 }
102 ug, err = getUserGroup(args.First())
103 if err != nil {
104 log.Fatalln(err)
105 }
106 case "server":
107 var setArgs [][]string
108 setArgs, err = minio.GetAllSets(args.Tail()...)
109 if err != nil {
110 log.Fatalln(err)
111 }
112 var endpoints minio.EndpointList
113 _, endpoints, _, err = minio.CreateEndpoints(serverAddr, setArgs...)
114 if err != nil {
115 log.Fatalln(err)
116 }
117 for _, endpoint := range endpoints {
118 if !endpoint.IsLocal {
119 continue
120 }
121 ug, err = getUserGroup(endpoint.Path)
122 if err != nil {
123 log.Fatalln(err)
124 }
125 break
126 }
127 default:
128 cli.ShowCommandHelpAndExit(ctx, "check-user", 1)
129 }
130 fmt.Println(ug)
131 }
132 if err := app.Run(os.Args); err != nil {
133 log.Fatalln(err)
134 }
135}
dockerscripts/docker-entrypoint.sh+9−28
@@ -15,9 +15,6 @@ · 14 unmodified lines
15# limitations under the License.15# limitations under the License.
16#16#
17 17
18export MINIO_USERNAME=${MINIO_USERNAME:-"minio"}
19export MINIO_GROUPNAME=${MINIO_GROUPNAME:-"minio"}
20
21# If command starts with an option, prepend minio.18# If command starts with an option, prepend minio.
22if [ "${1}" != "minio" ]; then19if [ "${1}" != "minio" ]; then
23 if [ -n "${1}" ]; then20 if [ -n "${1}" ]; then
@@ -42,37 +39,21 @@ docker_secrets_env() { · 18 unmodified lines
42 fi39 fi
43}40}
44 41
45## Create UID/GID based on available environment variables.42# su-exec to requested user, if service cannot run exec will fail.
46docker_set_uid_gid() {
47 addgroup -S "$MINIO_GROUPNAME" >/dev/null 2>&1 && \
48 adduser -S -G "$MINIO_GROUPNAME" "$MINIO_USERNAME" >/dev/null 2>&1
49}
50
51# su-exec to requested user, if user cannot be requested
52# existing user is used automatically.
53docker_switch_user() {43docker_switch_user() {
54 owner=$(check-user "$@")44 if [ -z "${MINIO_USERNAME}" ] || [ -z "${MINIO_GROUPNAME}" ]; then
55 if [ "${owner}" != "${MINIO_USERNAME}:${MINIO_GROUPNAME}" ]; then45 addgroup -S "$MINIO_GROUPNAME" >/dev/null 2>&1 && \
56 ## Print the message only if we are not using non-default username:groupname.46 adduser -S -G "$MINIO_GROUPNAME" "$MINIO_USERNAME" >/dev/null 2>&1
57 if [ "${MINIO_USERNAME}:${MINIO_GROUPNAME}" != "minio:minio" ]; then47
58 echo "Requested username/group ${MINIO_USERNAME}:${MINIO_GROUPNAME} cannot be used"48 exec su-exec "${MINIO_USERNAME}:${MINIO_GROUPNAME}" "$@"
59 echo "Found existing data with user ${owner}, we will continue and use ${owner} instead."49 else
60 return50 # fallback
61 fi51 exec "$@"
62 fi
63 # check if su-exec is allowed, if yes proceed proceed.
64 if su-exec "${owner}" "/bin/ls" >/dev/null 2>&1; then
65 exec su-exec "${owner}" "$@"
66 fi52 fi
67 # fallback
68 exec "$@"
69}53}
70 54
71## Set access env from secrets if necessary.55## Set access env from secrets if necessary.
72docker_secrets_env56docker_secrets_env
73 57
74## User Input UID and GID
75docker_set_uid_gid
76
77## Switch to user if applicable.58## Switch to user if applicable.
78docker_switch_user "$@"59docker_switch_user "$@"
docs/docker/README.md+7−9
@@ -58,20 +58,19 @@ docker run -p 9000:9000 --name minio1 \ · 57 unmodified lines
58 minio/minio server /data58 minio/minio server /data
59```59```
60 60
61### Run MinIO Docker as non root user61### Run MinIO Docker as regular user
62MinIO server runs as non-root within the container by default. However, this is applicable only if you're deploying new MinIO instance (not upgrading from older releases). Deployments upgrading from older MinIO deployments, will continue to run as the user previously used if any.62MinIO server doesn't run as a regular user by default in docker containers. To run MinIO container as regular user use environment variables `MINIO_USERNAME` and `MINIO_GROUPNAME`.
63 63
64By default `minio` is username and groupname. Use environment variables `MINIO_USERNAME` and `MINIO_GROUPNAME` to override these default values.64> NOTE: If you are upgrading from existing deployments, you need to make sure this user has write access to previous persistent volumes. MinIO will not migrate the content automatically.
65 65
66#### GNU/Linux and macOS66#### GNU/Linux and macOS
67```sh67```sh
68docker run -p 9000:9000 --name minio1 \68docker run -p 9000:9000 --name minio1 \
69 -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \69 -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
70 -e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \70 -e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
71 -e "MINIO_USERNAME=custom" \71 -e "MINIO_USERNAME=minio-user" \
72 -e "MINIO_GROUPNAME=custom" \72 -e "MINIO_GROUPNAME=minio-user" \
73 -v /mnt/data:/data \73 -v /mnt/data:/data \
74 -v /mnt/config:/root/.minio \
75 minio/minio server /data74 minio/minio server /data
76```75```
77 76
@@ -80,10 +79,9 @@ docker run -p 9000:9000 --name minio1 \ · 2 unmodified lines
80docker run -p 9000:9000 --name minio1 \79docker run -p 9000:9000 --name minio1 \
81 -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \80 -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
82 -e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \81 -e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
83 -e "MINIO_USERNAME=custom" \82 -e "MINIO_USERNAME=minio-user" \
84 -e "MINIO_GROUPNAME=custom" \83 -e "MINIO_GROUPNAME=minio-user" \
85 -v D:\data:/data \84 -v D:\data:/data \
86 -v D:\minio\config:/root/.minio \
87 minio/minio server /data85 minio/minio server /data
88```86```
89 87

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t