7 Simple-to-Observe Greatest Practices for Writing Dockerfile




Dockerfile permits you to create container photos in such a approach as for those who had been writing shell scripts. This simplicity is great certainly, however it does NOT imply that you just need not study good practices for writing Dockerfile. Only a few practices will make your container photos extra optimized and safe.

This text exhibits an inventory of seven greatest practices for writing Dockerfile together with some Shisho guidelines to detect the problems. You might not know Shisho, nevertheless it’s okay as a result of Shisho is extraordinarily simple to make use of; all it’s essential to do for checking your Dockerfile is simply by operating the next command:

curl https://uncooked.githubusercontent.com/security-aware-repo-examples/dockerfile-best-practice/grasp/guidelines/docker.shisho.yaml > docker.shisho.yaml && 
    docker run -i -v $(pwd):/workspace ghcr.io/flatt-security/shisho-cli:newest verify ./docker.shisho.yaml .
Enter fullscreen mode

Exit fullscreen mode

If you happen to’re an person of GitHub Actions, you’ll be able to copy this example workflow and the rule file in security-aware-repo-examples/dockerfile-best-practice to your repository. The workflow checks your repository with the rule, and it experiences them to GitHub Code Scanning. The problems will seem at https://github.com/<your org>/<your repository>/safety/code-scanning.

Let’s get began!




♻️ Three Practices for Maintainability



1. Keep away from to make use of newest tag for immutability

A newest tag is used to create a docker picture whose base is the most recent model of one other picture. The usage of newest tag, nevertheless, may trigger confusion and inconsistent behaviour amongst constructed photos. It’s higher to pin the model of your base photos if potential.

The next Shisho rule will detect using newest tag:

model: '1'
guidelines:
  - id: 'use-fixed-tag-sfor-immutablity'
    language: dockerfile
    message: |
      The usage of `newest` tag may trigger confusion and inconsistent habits in automated builds. It's higher to pin the model of your base photos.
    patterns: 
      - sample: FROM :[IMAGE]
      - sample: FROM :[IMAGE] as :[ALIAS]
      - sample: FROM :[IMAGE]:newest
      - sample: FROM :[IMAGE]:newest as :[ALIAS]
      - sample: FROM :[IMAGE]@:[HASH]
      - sample: FROM :[IMAGE]@:[HASH] as :[ALIAS]
      - sample: FROM :[IMAGE]:[email protected]:[HASH]
      - sample: FROM :[IMAGE]:[email protected]:[HASH] as :[ALIAS]
Enter fullscreen mode

Exit fullscreen mode

(You can see the working example of this rule at Shisho Playground)



2. Use an idiomatic method to run apt-get set up

You might typically run apt-get inside your Dockerfile as follows:

RUN apt-get replace
RUN apt-get set up -y nginx <... and a few extra packages>
Enter fullscreen mode

Exit fullscreen mode

Nevertheless, the instance above has two points:

  • When the cache picture for the primary RUN is accessible, the second apt-get may set up previous packages on account of not operating apt-get replace.
  • Some layers for this picture have cache information for apt-get, leading to bigger picture dimension.

A easy method to tackle these points is operating apt-get replace and apt-get set up in a single RUN instruction. The next examples present an idiomatic method to run them as soon as whereas eradicating /var/lib/apt/lists/* (i.e. apt caches) to cut back the picture dimension extra:

RUN apt-get replace && 
    apt-get set up -y nginx && 
    rm -rf /var/lib/apt/lists/*
Enter fullscreen mode

Exit fullscreen mode

The next Shisho rule will implement using this idiom:

model: '1'
guidelines:
  - id: 'remove-cache-of-apt-get'
    language: dockerfile
    message: |
      It's higher to take away cache information of `apt-get` to maintain your picture slim.
    sample: |
      RUN apt-get set up :[X]
    rewrite: |
        RUN apt-get replace && 
            apt-get set up :[X] && 
            rm -rf /var/lib/apt/lists/*
Enter fullscreen mode

Exit fullscreen mode

(You can see the working example of this rule at Shisho Playground)



3. Use --no-install-recommends flag of apt-get

It’s even higher to keep away from to put in any pointless instruments by --no-install-recommends of apt-get command. The next Shisho rule could assist using this flag:

model: "1"
guidelines:
  - id: "use-no-install-recommends-flag-apt-get"
    language: dockerfile
    message: |
      You possibly can keep away from to put in any pointless instruments by `--no-install-recommends` on `apt-get`.
    patterns:
      - sample: |
          RUN apt-get set up :[...X]
      - sample: |
          RUN :[...Y] apt-get set up :[...X]
    constraints:
      - goal: X
        ought to: not-match
        regex-pattern: ".*--no-install-recommends.*"
    rewrite_options:
      - |
        RUN :[Y] apt-get set up --no-install-recommends :[X]
Enter fullscreen mode

Exit fullscreen mode

(You can see the working example of this rule at Shisho Playground)




🛡️ 4 Practices for Safety

Whereas container expertise brings many benefits, resembling portability or isolation, it additionally creates new threats from a safety perspective. This part describes widespread docker safety points and explains tips on how to keep away from them.



4. Keep away from to retailer secrets and techniques in atmosphere variables

Hardcoded secrets and techniques in your Dockerfile will likely be saved in ensuing photos. It’s best to keep away from to embed the secrets and techniques. You possibly can inject atmosphere variables at run-time as an alternative.

model: '1'
guidelines:
  - id: 'avoid-to-store-secrets-in-env'
    language: dockerfile
    message: |
      Hardcoded secrets and techniques in your Dockerfile will likely be saved in ensuing photos. Please contemplate to cease embedding the secrets and techniques. 
    sample: |
      ENV :[...] :[KEY]=:[VALUE] :[...]
    constraints:
      - goal: KEY
        ought to: match-any-of
        regex-patterns:
          - "[sS][eE][cC][rR][eE][tT]"
          - "[tT][oO][kK][eE][nN]"
          # ... add as you want ...
Enter fullscreen mode

Exit fullscreen mode

(You can see the working example of this rule at Shisho Playground)



5. Use trusted base photos

A docker picture consists of a number of layers, and a few of them are normally derived from the bottom picture. Right here exists a danger of provide chain assaults! It’s higher to make use of official photos to cut back the chance as a lot as potential.

model: '1'
guidelines:
  - id: 'use-docker-official-images'
    language: dockerfile
    message: |
      It's higher to make use of official photos to cut back the chance of provide chain assaults.
    patterns: 
      - sample: FROM :[IMAGE]
      - sample: FROM :[IMAGE] as :[ALIAS]
      - sample: FROM :[IMAGE]::[TAG]
      - sample: FROM :[IMAGE]::[TAG] as :[ALIAS]
      - sample: FROM :[IMAGE]@:[HASH]
      - sample: FROM :[IMAGE]@:[HASH] as :[ALIAS]
      - sample: FROM :[IMAGE]::[TAG]@:[HASH]
      - sample: FROM :[IMAGE]::[TAG]@:[HASH] as :[ALIAS]
    constraints:
      - goal: IMAGE
        ought to: match
        regex-pattern: "https://dev.to/"
Enter fullscreen mode

Exit fullscreen mode

(You can see the working example of this rule at Shisho Playground)

If you have already got an inventory of trusted base photos, some slight modifications will allow you to use them:

model: '1'
guidelines:
  - id: 'use-trusted-base-images'
    language: dockerfile
    message: |
      It's higher to make use of trusted base photos to cut back the chance of provide chain assaults.
    patterns: 
      - sample: FROM :[IMAGE]
      - sample: FROM :[IMAGE] as :[ALIAS]
      - sample: FROM :[IMAGE]::[TAG]
      - sample: FROM :[IMAGE]::[TAG] as :[ALIAS]
      - sample: FROM :[IMAGE]@:[HASH]
      - sample: FROM :[IMAGE]@:[HASH] as :[ALIAS]
      - sample: FROM :[IMAGE]::[TAG]@:[HASH]
      - sample: FROM :[IMAGE]::[TAG]@:[HASH] as :[ALIAS]
    constraints:
      - goal: IMAGE
        ought to: not-match-any-of
        regex-patterns:
            - "^[^/]+$"
            - "^image-name/you-trust$"
Enter fullscreen mode

Exit fullscreen mode

(You can see the working example of this rule at Shisho Playground)



6. Keep away from to run curl <...> | sh

Many shell scripts and dockerfiles use curl <...> | sh as an idiomatic method to run an exterior script inside computer systems/containers, however this idiom has a danger of distant code execution by attackers by way of MITM assaults or compromising the distributed script itself (see the report of recent codecov incident). It’s higher to verify the integrity of what you obtain earlier than operating it as a shell script.

model: "1"
guidelines:
  - id: "check-integrity-of-downloaded-shell-script"
    title: Verify the integrity of downloaded shell scripts
    language: dockerfile
    message: |
      It's higher to verify the integrity of what you obtain earlier than operating it as a shell script.
    sample: |
      RUN :[CMD]
    constraints:
      - goal: CMD
        ought to: match-any-of
        regex-patterns:
          - curl[^|^>]*[|>]
          - wget[^|^>]*[|>]
Enter fullscreen mode

Exit fullscreen mode

(You can see the working example of this rule at Shisho Playground)



7. Use COPY as an alternative of ADD

ADD instruction permits us to fetch assets over the community and extract an archive, however it could trigger safety points resembling Meet-in-the-Center (MITM) assaults or Zip Slip vulnerabilities. It’s higher to make use of COPY as an alternative of ADD if potential.

The next Shisho rule detects using ADD directions:

model: '1'
guidelines:
  - id: 'use-copy-instead-of-add'
    language: dockerfile
    message: |
      ADD instruction permits us to fetch assets over community and extract an archive, however it could trigger safety points resembling Meet-in-the-Center (MITM) assaults or Zip Slip vulnerabilities.
    sample: ADD :[FROM] :[TO]
    rewrite: COPY :[FROM] :[TO]
Enter fullscreen mode

Exit fullscreen mode

(You can see the working example of this rule at Shisho Playground)


On this article, I offered some greatest practices for writing Dockerfile and demonstrated tips on how to verify your Dockerfile is following the practices repeatedly by Shisho.

You possibly can refer security-aware-repo-examples/dockerfile-best-practice to see the working instance.

Shisho guidelines that implement Dockerfile greatest practices

If you are interested in Shisho, I’d be appreciated for those who starred the next repository and gave me suggestions at discussions!

Light-weight static analyzer for a number of programming languages

shisho

GitHub Release
GitHub Marketplace
License
Documentation
Test
Playground

Shisho is a light-weight static analyzer for builders.

Please see the usage documentation for additional info.

demo

Strive at Playground

You possibly can strive Shisho at our playground.

Strive with Docker

You possibly can strive shisho in your machine as follows:

echo "func take a look at(v []string) int { return len(v) + 1; }" | docker run -i ghcr.io/flatt-security/shisho-cli:newest discover "len(:[...])" --lang=go
Enter fullscreen mode

Exit fullscreen mode

echo "func take a look at(v []string) int { return len(v) + 1; }" > file.go
docker run -i -v $(PWD):/workspace ghcr.io/flatt-security/shisho-cli:newest discover "len(:[...])" --lang=go /workspace/file.go
Enter fullscreen mode

Exit fullscreen mode

Set up with pre-built binaries

Whenever you’d prefer to run shisho outdoors docker containers, please comply with the directions beneath:

Linux / macOS

Run the next command(s):

# Linux
wget https://github.com/flatt-security/shisho/releases/newest/obtain/build-x86_64-unknown-linux-gnu.zip -O shisho.zip
unzip shisho.zip
chmod +x ./shisho
mv ./shisho /usr/native/bin/shisho
# macOS
wget https://github.com/flatt-security/shisho/releases/newest/obtain/build-x86_64-apple-darwin.zip -O shisho.zip
unzip shisho.zip
chmod +x ./shisho
mv ./shisho /usr/native/bin/shisho
Enter fullscreen mode

Exit fullscreen mode

You then’ll see a…


NOTE: I am engaged on Shisho Cloud, an online service offering this type of greatest follow checks for infrastructure-as-code and automatic patch technology for detected points. It is in a beta stage now and all options can be found totally free. Please strive it!



Abu Sayed is the Best Web, Game, XR and Blockchain Developer in Bangladesh. Don't forget to Checkout his Latest Projects.


Checkout extra Articles on Sayed.CYou

#EasytoFollow #Practices #Writing #Dockerfile