To me, one of the requirements for putting docker into production use would be the ability to verify that any images we use as base images are in fact the official "ubuntu" or "busybox" images. I'm not seeing any obvious evidence that images on the public repository are cryptographically signed so that it may be verified that they haven't been tampered with. Am I missing something?
(As an alternative, I suppose it would be possible to start from scratch with our own base images in our own private registry, but even then I'd want to put some checks in place that we don't accidentally pull anything from the public repo.)
Currently, apparently no useful validation is done.
As Adrian Mouat says, docker 1.3 added "something" to do with image verification.
However, findings in this post indicate that only the manifest rather than the image itself is currently verified. That is, the manifest is signed and checked, but the checksum it contains for the image doesn't appear to be used correctly to check the image itself hasn't been tampered with. It is worrying that the apparently broken checksum verification slipped through to a release.
Docker does do "Digital Signature Verification" as of release 1.3, although it is still in very early stages. This verification ensures that any official image you download has not been tampered with in transit. At the time of writing, some official images need to do more work with regards to ensuring files downloaded during the image building process are properly checked against stored hashes.
You may also want to look at this post on container provenance.
Related
This question already has answers here:
Encrypted and secure docker containers
(6 answers)
Closed 2 months ago.
I'm looking for a solution where I can run an app to an device in an ecrypted way, I mean user of that laptop should not be able to see the source code, just the running app. But it should be run on their device.
Is there any way to encrypt app running and use a key with expiration date, like windiws with licence? In my case is a little bit different, they should be much more limmited .
Thank you very much for the answers.
I didn't find any tool/framework for that.
Docker cannot solve the issue, since everything in the container must be readable by the underlying OS.
With the command docker save the user can export the images content into a tar file. See: https://docs.docker.com/engine/reference/commandline/save/
So you have to protect your app the same way you would protect it without docker.
First of all you should use a compiled language so the user cannot see the code directly. But even compiled code is not protected againts modification etc. To take it one step futher you could try to obfuscate the compiled binary.
I'm writing a tool to sync container image from any container registry. In order to sync images, I need a way to check if local image:tag is different from remote image:tag, possibly through comparing image sha ID (as image sha digest is registry-based). Due to the nature of my tool, pulling image first then compare using docker inspect will not be suitable.
I was able to find some post like this or this. They either tell me to use docker v2 API to fetch remote metadata (which contains image ID) and then compare with local image ID or use container-diff (which seems like it was made for a more complicated problem, comparing packages in package management systems inside images). The docker v2 API method is not universal because each registry (docker.io, grc.io, ecr) requires different headers, authentications, etc. Therefore, container-diff seems to be the most suitable choice for me, but I have yet to figure out a way to simply output true/false if local and remote image are different. Also, it seems like this tool does pull images before diffing them.
Is there anyway to do this universally for all registries? I see that there are tools that already implemented this feature like fluxcd for kubernetes which can sync remote image to local pod image but is yet to know their technical details.
On a high level your approach is correct to compare the SHA values, however you need to dive deeper into the container spec, as there is more to it. (layer and blobs)
There are already tools out there that can copy images from one registry to another. The tools by default don't copy the data if the image already exist in the target. Skopeo is a good starting point.
If you plan to copy images from different registries, you need to cope with each registry individually. I would also recommend you to take a look at Harbor. The Harbor Container Registry has the capability to copy images from and to various registries built in. You can use Harbor as your solution or starting point for your endeavor.
Since DockerHub will implement rate limiting on Nov 1, we will probably tell our engineers to create (free) DockerHub accounts in order to each individually enjoy 200 pulls per 6 hours.
We are however worried that an engineer might somehow accidentally push an image to DockerHub from their laptop.
Is there some way we can block our developers from accidentally pushing to DockerHub?
It's possible that Docker will provide the ability to create more limited tokens before the rate limits start, either pull only, or perhaps limited to specific repos. This functionality is needed for CI users that are running builds in the cloud and don't want to give out full access.
Otherwise, I'd recommend not tagging your local images with something that you can push to Docker Hub. The image reference includes the repository name, and can be prefixed with a registry. If they tag with a local registry name, or specify a repository they don't have access to push to, then they will not push anything to Hub.
Even better is if you create a local registry which removes the need to pull from Hub. Mirror the base images your developers need, and have them perform their builds against your internal registry. There are lots of implementations of the docker registry including Docker's image or for an enterprise environment, that's been extended in the Harbor Project which is part of the CNCF. Both are free and open source.
As an extreme measure, you can block the ability to run any POST /v2/*/blobs/upload (see the registry API spec) on an http proxy that all developers use to access the internet, but you may find this breaks many legitimate use cases.
Let's say I have the following layers of docker:
Os
jre
application server
application.
The customer is running an image containing all the above.
What is the best practice in case there is an urgent security or any other urgent update on one of the layers.
For example:
there is an urgent security update required on the os layer, and the customer can't wait until we finish the entire CI/CD and certify the change by another docker image.
My assumption was to provide the customer an option to update by his own, and update on his local docker repo the image with updated os, and where all the rest remains the same.
It seems to be very demanding request , is there any alternative or any best practices?
General advises would be to make sure the containers you provide are stateless (you can use volumes to store data). This makes the process of updating the images a question of stopping the old containers and starting the updated ones.
Your clients could use docker exec on the target containers to apply a quick fix until you provide them with the new image or you can host a link with the new image that they can pull and update themselves.
Outside of that, I don't think there is a standard for this process.
Suppose I have a private Docker repository at myrepo.myhost.com.
I now build an image off of a very large public Docker Registry image. Assume it's called bandwidthguy/five-gigabyte-image:latest.
I have a Dockerfile that does one simple thing, for example:
FROM bandwidthguy/five-gigabyte-image
COPY some-custom-file /etc/bigstuff
I build the image:
docker build -t myversionof-five-gigabyte-image .
and tag it.
docker tag myversionof-five-gigabyte-image:latest myrepo.myhost.com/myversions/five-gigabyte-image:latest
Now I push to my repo.
docker push myrepo.myhost.com/myversions/five-gigabyte-image
I noticed that when doing this, the entire large source image gets pushed to my repository.
What I'm wondering is if there is any way to somehow have Docker only push a difference image, and then pull the other layers from their respective sources when the image is pulled. Pushing the entire image to my private repo can have problems:
If the private repo is hosted on my home ISP, my limited upstream can cause major lag when pulling the image while out and about.
If the private repo is on a hosted service, it might have a disk quota and I am using 5GB of that quota needlessly.
It takes a long time to push the image, especially if I have slow upload speed at the time.
It may just be the case that you can't put the parts on different servers, but I figured it's worth an ask to see if it can be done. It would make sense that you could store all the layers on your own host for the purposes of running an air-gapped server, but it seems a bit of an oversight that you can't pull the source images from the Registry.
This question showcased my early misunderstanding of Docker. There is no current mechanism for storing different layers of an image on different repositories. While there's no theoretical reason this couldn't be implemented, I'm guessing it's just not worth the extra effort.
So, the answer to my question is no, you can't store only image differences in a private repo - you'll be storing all layers, including those that were pulled from the public repo, in your private repo. However, since layers are represented by their hashes, clients that have already pulled the image from the public repo won't need to re-download those layers again from the private repo. This leads to the possibility that perhaps the hashes of the very large layers could be kicked out of the private repo manually, and then users could be required to first pull the source image from public manually. (Pulling fresh from the private repo only would error out.) I haven't looked into this, but it might be a possible hacky solution.
Luckily, there aren't too many Docker images that actually need multiple gigabytes of space. Even so, layers are stored compressed and deduplicated in the registry.