---
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

## 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