Best Practices and Ways to Safeguard Your Docker Image

Best Practices and Ways to Safeguard Your Docker Image

In today's rapidly evolving software development landscape, containerisation has become a cornerstone for deploying applications efficiently and consistently. Docker, a leading containerization platform, allows developers to package applications and their dependencies into a single, portable container. However, with the convenience of Docker comes the responsibility of ensuring that these containers are secure. Safeguarding your Docker images is crucial to protect sensitive data, maintain application integrity, and prevent unauthorized access. This article delves into the best practices and strategies to secure your Docker images, from managing secrets and minimizing vulnerabilities to implementing robust security measures. By following these guidelines, you can enhance the security of your Dockerized applications and maintain a resilient deployment environment.

So, let's dive in to explore the best actions and steps to implement in our containerisation world.

Make your token accessible through an argument or environment variable.

  • Using Arguments:

    Pass the token as a command-line argument when running your Docker container.

    • Example: docker run -e TOKEN=my_secret_token my_docker_image
  • Using Environment Variables:

    Set the token as an environment variable in your Dockerfile or Docker Compose file.

    • In Dockerfile: ENV TOKEN=my_secret_token

    • In Docker Compose file:

    •   services:
          my_service:
            image: my_docker_image
            environment:
              - TOKEN=my_secret_token
      

Following above steps, you can securely pass and access tokens in your Docker containers.

Prevent access to bash or SSH into your container.

  1. Use Minimal Base Images:

    Choose minimal base images that do not include unnecessary tools like bash or SSH.

    • Example: Use alpine or scratch as your base image.
  2. Remove Unnecessary Packages:

    If you are using a larger base image, ensure you remove any unnecessary packages that could be used to gain shell access.

    • Example in Dockerfile:

        FROM ubuntu:latest
        RUN apt-get update && apt-get remove -y bash openssh-server
      
  3. Set a Non-Root User:

    Run your application as a non-root user to limit the permissions available within the container.

    • Example in Dockerfile:

        RUN useradd -m myuser
        USER myuser
      
  4. Use Docker Security Options:

    Use Docker security options to restrict access and capabilities.

    • Example: docker run --security-opt no-new-privileges my_docker_image

By implementing these practices, you can significantly reduce the risk of unauthorized access to bash or SSH within your Docker containers.

Scan the base image for any vulnerabilities

  1. Trivy:

    Trivy is a comprehensive and easy-to-use vulnerability scanner for containers.

    • Example: trivy image my_docker_image
  2. Snyk:

    Snyk provides container security scanning and monitoring.

    • Example: snyk container test my_docker_image

By using these tools, you can effectively scan your Docker base images for vulnerabilities and ensure that your containers are secure.

Create secrets for the Docker registry and use your private registry.

  1. Create Docker Registry Secrets:

    • Use Docker's docker login command to create a secret for your private registry.

    • Example:

        docker login myprivateregistry.com
      
    • This command will prompt you for your username and password, and store the credentials in ~/.docker/config.json.

  2. Using Docker Secrets in Docker Swarm:

    • Create a secret in Docker Swarm.

    • Example:

        echo "my_secret_password" | docker secret create my_registry_secret -
      
    • Use the secret in your Docker service.

    • Example in Docker Compose file:

        version: '3.1'
      
        services:
          my_service:
            image: myprivateregistry.com/my_image:latest
            secrets:
              - my_registry_secret
      
        secrets:
          my_registry_secret:
            external: true
      
  3. Using Docker Secrets in Kubernetes:

    • Create a Kubernetes secret for your Docker registry.

    • Example:

        kubectl create secret docker-registry my-registry-secret \
          --docker-server=myprivateregistry.com \
          --docker-username=myusername \
          --docker-password=mypassword \
          --docker-email=myemail@example.com
      

      Use the secret in your Kubernetes deployment.

    • Example in Kubernetes YAML file:

        apiVersion: v1
        kind: Pod
        metadata:
          name: mypod
        spec:
          containers:
          - name: mycontainer
            image: myprivateregistry.com/my_image:latest
          imagePullSecrets:
          - name: my-registry-secret
      

So now, you can securely create and use secrets for your Docker registry and ensure that your private registry is properly integrated with your Docker or Kubernetes environment.

Sign your image before deployment.

We will use the cosign tool to sign the Docker image before deploying it to the cloud hub.

  1. Install Cosign:

    • You can install cosign using the following command:

        go install github.com/sigstore/cosign/cmd/cosign@latest
      
  2. Generate a Key Pair:

    • Generate a key pair for signing your images.

        cosign generate-key-pair
      
    • This will create two files: cosign.key (private key) and cosign.pub (public key).

  3. Sign the Docker Image:

    • Use the generated private key to sign your Docker image.

        cosign sign --key cosign.key myprivateregistry.com/my_image:latest
      
  4. Verify the Signed Image:

    • Use the public key to verify the signed image.

        cosign verify --key cosign.pub myprivateregistry.com/my_image:latest
      
  5. Store the Public Key:

    • Store the public key in a secure location or share it with others who need to verify the image.
  6. Using Sigstore for Keyless Signing (Optional):

    • Sigstore offers keyless signing using OIDC (OpenID Connect) for authentication.

    • Authenticate using your OIDC provider (e.g., GitHub, Google).

        cosign sign --keyless myprivateregistry.com/my_image:latest
      
    • Verify the keyless signed image.

        cosign verify myprivateregistry.com/my_image:latest
      

With that, you can sign your Docker images using cosign along with sigstore, ensuring their integrity and authenticity before deployment.

Conclusion

Securing your Docker images is not just a best practice but a necessity in today's digital age. By implementing the strategies discussed, such as managing secrets, minimising vulnerabilities, and using robust security measures, you can significantly enhance the security of your Dockerized applications. Remember, the goal is to create a resilient deployment environment that protects sensitive data and maintains application integrity. As you continue to leverage the power of Docker, always prioritise security to ensure your applications remain safe and reliable.

Happy containerising!