Container Images
Supply Chain Security and Container Images
Containers & Docker
- review of previous info on containers vs vm
- app / kernel group / host kernel / OS
continers build in layers
FROM ubuntu
RUN apt update -y && apt get install -y curl
CMD ["sh"]
Reduce Footprint (Multistage)
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"]
app.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)
}
}
look at the size of the image
docker image list | grep app
app latest 095865436e26 4 minutes ago 693MB
lets reduce using multi-stage build
# build stage (0)
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
# runtime stage
FROM alpine
COPY /app .
CMD ["./app"]
check size
docker image list | grep app
app latest 8ed877429a72 15 seconds ago 7.73MB
Secure Images
- use specific verions of images (not default/latest) e.g.
FROM alpine:3.12.1
- dont run as root, create a user e.g.
RUN addgroup -S appgroup && adduser -G appgroup -h /home/appuser
(see below) - make filesystem read-only e.g.
RUN chmod a-w /etc
or any other folders - remove shell access e.g.
RUN rm -fr /bin/*
AFTER allRUN
is complete that might need apps under/bin/*
final solution:
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
# runtime stage
FROM alpine:3.12.1
RUN chmod a-w /etc
RUN addgroup -S appgroup && adduser -G appgroup -h /home/appuser
RUN rm -fr /bin/*
COPY /app /home/appuser/
USER appuser
CMD ["/home/appuser/app"]
Layers
note look at layers in docker best practice on best way to use them.
Image Vulnerability Scanning
examples
- buffer overflows in vuln apache images
- the app itself
- the dependencies inside the container
result
- privesc
- info leak
- ddos
check each layer of the image, where bins may be installed on those layers e.g. curl, nginx, base image.
when to check?
- during build time
- during run time
during code->commit, build (scan the registry when image pushed), enforce at deploy time using OPA
image scanning tools
look at Clair (complex) and Trivy (simple) for image scanning