--- tags: OWASP cloud-native-application-security --- # OWASP cloud-native-application-security CNAS 01 Container Runs as Root ** CNAS-0.1: Insecure cloud, container or orchestration configuration ** | Risk | Result of Successful Exploit Execution | Aqua Demo | | -------- | -------- | -------- | | Insecure cloud, container or orchestration configuration | Container runs as root | Demo Container best practice and aqua policy Demo | # Container Security Best Practice Demo **Table of Contents** [TOC] ## Container best practices Demo will cover the following best practices and configuration. ## Container Hardening Demo Goals: 1. Multi-Stage Build 2. Use Specific package version 3. Dont run as root 4. make filesystem read only 5. remove shell access Install the GO app -- Create go package using vim CMD`vim app.go` ```go= package main import ( "fmt" "time" "os/user" ) func main () { user, err := user.Current() if err != nil { panic(err) } for { fmt.Println("user: " + user.Username + " id: " + user.Uid) time.Sleep(1 * time.Second) } } ``` Install the dockerfile -- CMD `vim Dockerfile` ```dockerfile= FROM ubuntu ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y golang-go COPY app.go . RUN CGO_ENABLED=0 go build app.go CMD ["./app"] ``` run the command `docker build -t app .` `docker run app` **`docker image list | grep app`** check out the size ### Time to reduce the size of the image, run the following: **`docker image list | grep app`** > note this will be around 658mb go back into the dockerfile --- `vim Dockerfile` ## 1. First Goal - Reduce the image via a multi-Stage Build ```dockerfile= # build container stage 1 FROM ubuntu ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y golang-go COPY app.go . RUN CGO_ENABLED=0 go build app.go # app container stage 2 FROM alpine COPY --from=0 /app . CMD ["./app"] ``` `docker build -t app .` ## Lets now see how much smaller the image is. > It should be around 7mb `docker image list | grep app` ## 2. Second Goal - Use specific package version `vim Dockerfile` ### Build container stage 1 ```dockerfile= FROM ubuntu ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y golang-go COPY app.go . RUN CGO_ENABLED=0 go build app.go # app container stage 2 FROM alpine:3.11.6 COPY --from=0 /app . CMD ["./app"] ``` `docker build -t app .` `docker run app` `docker image list | grep app` docker image list | grep app ## 3. Third Goal - Dont run as root `vim Dockerfile` ### Build container stage 1 ```dockerfile= FROM ubuntu:20.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y golang-go=2:1.13~1ubuntu2 COPY app.go . RUN pwd RUN CGO_ENABLED=0 go build app.go ### App container stage 2 FROM alpine:3.12.0 RUN addgroup -S appgroup && adduser -S appuser -G appgroup -h /home/appuser COPY --from=0 /app /home/appuser/ USER appuser CMD ["/home/appuser/app"] ``` `docker build -t app .` `docker run app` `docker image list | grep app` Aqua Policy check ![](https://i.imgur.com/wk3kdz2.png) ## 4. Fourth Goal - make filesystem read only `vim Dockerfile` ### Build container stage 1 ```dockerfile= FROM ubuntu:20.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y golang-go=2:1.13~1ubuntu2 COPY app.go . RUN pwd RUN CGO_ENABLED=0 go build app.go ### App container stage 2 FROM alpine:3.12.0 RUN chmod a-w /etc RUN addgroup -S appgroup && adduser -S appuser -G appgroup -h /home/appuser COPY --from=0 /app /home/appuser/ USER appuser CMD ["/home/appuser/app"] ``` `docker build -t app .` `docker run app` `docker image list | grep app` ## 5. remove shell access ### Build container stage 1 ```dockerfile= FROM ubuntu:20.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y golang-go=2:1.13~1ubuntu2 COPY app.go . RUN pwd RUN CGO_ENABLED=0 go build app.go ### App container stage 2 FROM alpine:3.12.0 RUN addgroup -S appgroup && adduser -S appuser -G appgroup -h /home/appuser RUN rm -rf /bin/* COPY --from=0 /app /home/appuser/ USER appuser CMD ["/home/appuser/app"] ``` `docker build -t app .` `docker run app` `docker image list | grep app` ## Prove the authority now run as follows ```docker run -d app``` 9c891a484441e85ba578035c599842d35b246d0e45770ae4c7a3a972ac0b3c41 ```docker exec -it 9c891a484441e85ba578035c599842d35b246d0e45770ae4c7a3a972ac0b3c41 sh``` ``` > / $ ls -lh total 60K drwxr-xr-x 2 root root 4.0K May 29 2020 bin drwxr-xr-x 5 root root 340 Mar 31 17:09 dev drwxr-xr-x 1 root root 4.0K Mar 31 17:09 etc drwxr-xr-x 1 root root 4.0K Mar 31 17:05 home drwxr-xr-x 7 root root 4.0K May 29 2020 lib drwxr-xr-x 5 root root 4.0K May 29 2020 media drwxr-xr-x 2 root root 4.0K May 29 2020 mnt drwxr-xr-x 2 root root 4.0K May 29 2020 opt dr-xr-xr-x 220 root root 0 Mar 31 17:09 proc drwx------ 2 root root 4.0K May 29 2020 root drwxr-xr-x 2 root root 4.0K May 29 2020 run drwxr-xr-x 2 root root 4.0K May 29 2020 sbin drwxr-xr-x 2 root root 4.0K May 29 2020 srv dr-xr-xr-x 13 root root 0 Mar 31 17:09 sys drwxrwxrwt 2 root root 4.0K May 29 2020 tmp drwxr-xr-x 7 root root 4.0K May 29 2020 usr drwxr-xr-x 12 root root 4.0K May 29 2020 var / $ ``` ### Add the folowing after the run in stage 2 RUN `rm -rf /bin/*` ### Once done rebuild the image ```docker build -t app .``` ```docker run -d app``` * docker exec -it 9c891a484441e85ba578035c599842d35b246d0e45770ae4c7a3a972ac0b3c41 sh * docker exec -it 9c891a484441e85ba578035c599842d35b246d0e45770ae4c7a3a972ac0b3c41 bash