-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[docker-1.12] Signature verification on pull #200
[docker-1.12] Signature verification on pull #200
Conversation
What happens if the policy file does not exist? Do we default succeed? |
we default fail since this is going to be part of the docker package we'll ship a default policy.json and if it doesn't exists in /etc/containers/policy.json we badly bail out |
"type": "insecureAcceptAnything" | ||
} | ||
] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I‘d rather not have two RPMs owning policy.json
in the distribution at the same time… but I don’t have a strong opinion on which one should own it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I don't think docker should own it. Probably best if owned by skopeo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lsm5, Miloslav suggested to have a "skopeo-container-policy" package which just ships the policy.json file under /etc/containers/. This package will be Required by both skopeo and docker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM
@@ -85,9 +92,51 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named) (err error) { | |||
return err | |||
} | |||
|
|||
func (p *v2Puller) checkTrusted(ref reference.Named) (reference.Named, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK on this function; didn’t look at the rest in too much detail.
2cd2234
to
30cdf42
Compare
670365c
to
7481164
Compare
@@ -94,12 +95,24 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named) (err error) { | |||
|
|||
func (p *v2Puller) checkTrusted(ref reference.Named) (reference.Named, error) { | |||
p.originalRef = ref | |||
imgRef, err := docker.NewReference(ref) | |||
dockerRef, err := containersImageRef.ParseNamed(ref.String()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mtrmac PTAL at this since in projectatomic/docker it's the only way to have a consistent reference parsing for signatures. It's working like this, pinging you to understand if I'm missing something. (this is related to containers/image#123).
Without this change, ref
is parsed using projectatomic/docker's reference and contains the hostname and makes the signatures check fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK. It is a bit horrible, but that’s what we get with Golang’s interface-as-collection-of-method-signatures type system instead of an interface-as-a-name-and-explicitly-committed-to-protocol.
Please make sure to add a comment explaining why we can't use docker.NewReference
without the ParseNamed(ref.String())
roundtrip so that this isn’t “cleaned up” later when we forget or a new maintainer comes.
08b2f4d
to
75e6672
Compare
75e6672
to
fe7686d
Compare
@rhatdan @mtrmac alright, integration tests are green locally (finally), I need only containers/image#126 merged and a revendor here and this seems really in a good shape. The last blocker I have is containers/image#99 which I'm working on right now but I feel we can start building rpms (in Fedora at least) so people can start testing this out. |
fe7686d
to
5ada5fe
Compare
OK I see checks are still failing? |
@rhatdan nah, those are related to the RH CI which has been always broken for various reasons like the current one:
which is unrelated to this PR |
5ada5fe
to
06825df
Compare
alright, containers/image#126 got merged, now we're only missing containers/image#99 which I'm working on but it's not a total blocker so I'd say we can start testing this out /cc @lsm5 @ddarrah @rhatdan |
bf404d5
to
691ce93
Compare
407a421
to
967b10c
Compare
967b10c
to
8ad06e4
Compare
@mtrmac PTAL - This is based on containers/image master code so, in order to pull-by-digest AND verify with GPG one must use https://github.com/containers/image/blob/master/docs/policy.json.md#a-temporary-work-around-to-allow-accessing-any-image-by-digest. Please ack on this. @jwhonce @rhatdan @imcleod I'm running integration tests locally, after that, ready to merge! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A possible improvement, but LGTM.
DockerAuthConfig: &dockerAuthConfig, | ||
DockerRegistryUserAgent: dockerversion.DockerUserAgent(c), | ||
} | ||
img, err := imgRef.NewImage(ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could now be more secure with a imgRef.NewImageSource
→image.UnparsedFromSource
, the way copy.Image
does it; it would skip all of the risky manifest parsing image.FromUnparsedImage
is doing which nothing here seems to need. (AFAICT this change wouldn’t affect the behavior with manifest lists, but that would be worth checking).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack, will fix it if it's not totally breaking manifest lists.
ref, err = p.checkTrusted(ctx, ref) | ||
if err != nil { | ||
return allowV1Fallback(err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, what happens on the v1 fallback? Do we just accept any unsigned image on that path? So all the attacker needs to do is to DoS the signature fetch/verification so that we fall back?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot about this but meant to ping you, what do we do here? I'm ok not falling back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can even add a flag on the daemon which explicitly allow v1 fallback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alright, v1 fallback is now disabled if there's any error checking the image's signature
8ad06e4
to
556d579
Compare
1519241
to
8fc3c69
Compare
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
8fc3c69
to
918c0a7
Compare
"finger crossed" lol |
This patch implements signature verification through containers/image directly into the daemon.
Depends on containers/image#99 (you can workaround that by following containers/image#99 (comment))
/cc @mtrmac @rhatdan @ddarrah