-
Notifications
You must be signed in to change notification settings - Fork 78
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
Error retrieving OAuth token from repositories that do not support it #51
Comments
Hey there, thanks for the report. We do have Regarding your self-signed certificate issue, Portieris uses a system certificate pool that's defined at build time, so if it has the CA for your Artifactory in its |
With the self-signed certificates I am mounting a file with certs for both Notary and Artifactory to I don't think an override feature for specific servers is quite necessary for this one since adding an arbitrary CA for Notary operations at runtime is already a feature. An extension of that for registry operations is probably all that's needed. |
Interesting. The OAuth helper does use a custom http.Client, but it doesn't set the We'll need to dig into that a bit more to find out what's going on there. Incidentally, Portieris shouldn't need to interact with the Registry at all - it should only be talking to Notary (and the oauth server), hence my comment above about needing to change the hostname that the OAuth helper thinks it's going to before we can use that to find out where to go for auth. Perhaps fixing the fact that we're going to the wrong place for the OAuth token would resolve both symptoms here... cc @bainsy88 |
@molepigeon @bainsy88 I can fix it using your suggestion of hitting the v2 endpoint and code would look something like this
If the above changes look good I will create test cases, run them and satisfy all the requirements for a pull request? |
@jerrinss5 Thanks for the code! That's pretty much on the lines that I was thinking. I misspoke before though, there's a couple of things that we should be careful about to be properly compliant with the spec from RFC 2617. In essence, rather than making the initial call to There are some cases where Notary wants auth for some requests and not others. Notary lets you configure a list of repositories that you can store trust data for. We use this in the IBM registry to prevent someone from using us as the source of trust for Docker Hub images, for example. If the repo doesn't match the list, it will 404 even without auth, at which point we know that the server doesn't have it - and going and getting an auth token won't change that so we needn't do it. We should only go for auth if we get a 401 when we ask for the resource without auth. The RFC isn't entirely clear on whether we can assume that Please do open a pull request once it's ready for that! |
@molepigeon thanks for the feedback. Agree with defensive coding of using maps to extract the www-authenticate header, will make the necessary changes referring from docker/distribution.
If the above flow is expected, for azure registry when I try to GET call to https://abc.azurecr.io, I get back a 404, but there is auth required to access this registry. |
So, if I wanted to access, for example, https://abc.azurecr.io/v2/foo/bar, the flow would be:
|
Makes sense, this is lot more clearer I will implement the above mentioned changes and send a pull request. Thanks @molepigeon |
@molepigeon I was trying out your suggestion of hitting https://abc.azurecr.io/v2/foo/bar - but it leads to a 404. |
@jerrinss5 I think you're going to the registry to get responses on those APIs. We should use the Notary API to be sure that we get the correct data back. Notary's API is a little different to Registry's, but in short a sensible URL to call would be: For example:
Don't forget that the API could return something other than a 401 - for example, if you make an unauthenticated request to IBM's notary asking for a Docker Hub image, you'll get a 404 even without auth:
|
ok so I did implement the way you mentioned above to hit the tuf/root.json endpoint for respective endpoints and it is working fine for authenticated calls. changes I tried stepping through the docker client code but was getting confused on how they are implementing. |
@jerrinss5 I get 401 from that call, too. I don't have access to my laptop right now to confirm this, but I'd guess that you could go to Docker's oauth server (by following the realm) and ask for those scopes without supplying a username and password and you'd get a token back that would work for that request. |
@jerrinss5 Just had a play with Docker Hub's auth server. I was struggling to get a valid token until I remembered that when you do Also, Docker Hub seems to want you to use the GET (Registry V2 token) method for authenticating: https://docs.docker.com/registry/spec/auth/jwt/ ... Rather than the POST (Oauth2) method: https://docs.docker.com/registry/spec/auth/oauth/. When I try to POST to This worked for me using the GET endpoint, without supplying credentials:
|
so I did make changes to the code to fetch token from auth.docker.io with the required scopes and it is working fine with curl as you showed it above. I will try to debug further to understand if the token I am fetching is correct in code. |
@molepigeon I have tried this but running into |
It could be a bunch of things. I'd suggest putting some extra logging in so that you can tell which call returned 401 - whether it's the call to the oauth server or the call to the notary server. If you get a token back from oauth, and then notary returns 401, your token might not have all the scopes you asked for. If you log the token, you can paste it into jwt.io to decode it and see what scopes you've been authorized for. If your token doesn't contain the scopes you asked for, the oauth server decided you're not allowed those for some reason, so it's worth double checking the oauth request. |
@molepigeon the GetAllTargetMetadataByName call refers to the vendor tuf/notary call |
You can remove the So - you used your code to get a token, then that token works for a curl but not for the request that the code makes? If that's right, there must be something different about the request that the code makes compared to your curl. I notice your code put a special case in for library... Looks like that would make the challenge contain library, which is correct for docker hub public images. But does the code then go and ask Notary for the image with library in it? If not, that might be why you're getting a 401. |
Yes, when it is an image from docker.
Do you mean this part - Calling: https://auth.docker.io/token?service=notary.docker.io&scope=repository:docker.io/library/nginx:pull |
I mean once we have a token, we use it by adding it to the Authorization header in a call to the notary server, right? I think that bit is handled by the notary client. Does that call include the library part? |
That's a good point, I think i missed that part. |
@molepigeon it started working when I added the library for notary client.
|
@molepigeon - So I got it working as such with these changes. Handled official part as follows:
Do let me know if these look good, I have yet to create test cases though. |
@molepigeon can we have portieris with image pull secrets assigned to it, so in case of pods without any image pull secrets we can try image pull secrets of the portieris app as the default one. This is so that we can handle scenarios where images are pulled using the docker config within the host of the worker nodes? |
so go it working.. still working on helm charts and test cases |
@molepigeon @jerrinss5 - I'm running Portieris in an EKS Cluster with a Harbor Registry and got everything working until the query to oauth/token which obviously is not a valid endpoint. |
i have sent a PR @mistermania |
Thanks @josephdrichard That seems to be the issue - where do you need to include ?. Can you explain a bit more - Sorry being stupid |
I added a line in https://github.com/IBM/portieris/blob/master/helm/portieris/templates/secret.yaml after defining serverCert.pem and serverKey.pem, to also include my ca.pem. |
Error from server (InternalError): error when creating "****.yaml": Internal error occurred: failed calling webhook "trust.hooks.securityenforcement.admission.cloud.ibm.com": Post https://portieris.authentic.svc:443/admit?timeout=30s: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "portieris_ca") |
Can you check your logs again? Do you still see this? Do you have this commit in your code? |
Why the above cant be done ? Shouldnt Portieris shoud only be worried about notary as the Imagepull secret is used by kube api to pull image ? |
It can - and as I suggested in your quote I suspect that that the PR that exists already will resolve this since the Notary server should tell Portieris where the oauth server is. The imagepullsecret is used to authenticate with Notary to access the signature, so Portieris will still need to use it. |
Thanks @molepigeon , what's preventing PR to be approved ? Is it just waiting for the test mentioned by @josephdrichard ? I am about to finalize a solution and thought this is the best rather than implementing on admission web hook (either mutating of validating) . The next bet could be Open Policy Agent. |
My attempt to rebase #82 went really poorly and I'll need to start over when I have time. The blocker is resolving the merge conflicts and getting it to pass CI. |
@molepigeon - should i send a PR for this minus few test cases i am struggling with? https://github.com/jerrinss5/portieris/commits/master |
Sure. Please make sure that your branch is up to date with master though, #82 cherry picked your commits but it's way behind master and has merge conflicts. Regarding those tests, I'm not sure if the extra commits that the author of #82 added to that PR would help to resolve your test issues. Maybe worth a look. |
Rebased and tested this. Requires a change in order to handle registries on non-default port. |
@josephdrichard - can you help me with the test cases? I haven't looked at it yet! |
Okay. I am looking at those 5 test cases now. |
I got them all to pass here: Most were just failing because it was detecting the notary was invalid sooner. Also one failure with us.icr.io/hello being treated as official, and then being changed to docker.io/library/hello. Can you look and see if there is anything else before your fix can be merged? |
thank you so much @josephdrichard - i will have a look at it tomorrow evening and merge your changes. Will keep you posted. |
Okay thanks. Is there anything else blocking this fix from going into master? |
@josephdrichard - i have added your changes to my code. (jerrinss5@9d081ee) and the merge request updated out here (#139) Previously it was mentioned that we should use fake registry for test cases, but lets see on review if the authors have additional comments on the test cases. Let me know if something is off with my commits. Thanks. |
Looks good to me. In my opinion there isn't any need to block this on using a fake registry for the test cases, so I hope that it can merge soon. |
Specifically, these two issues are blocking using portieris app with starlingx: * IBM/portieris#51 * IBM/portieris#59 Once these fixes are included in a published release of portieris, drop this patch and rebase to the latest release. Story: 2007348 Task: 40434 Change-Id: I14d0e5664333c5080440b9fd156c66a317444563 Signed-off-by: Joseph Richard <joseph.richard@windriver.com>
Any news on this in 2021? Compatibility of Portieris with Docker Hub and Harbor would be great! |
@sr258 no specific commitments, but it is on the radar |
fixed in v0.13.0 |
What commit ID of Portieris did you experience the problem with?
939c65b4e121c778d97f5dd1384484f5fcb078f1
What went wrong?
I am unable to deploy images from Docker Hub or a self-hosted Artifactory. When deploying an image from either registry Portieris queries
https://<registry>/oauth/token
. As far as I am aware this endpoint only exists for IBM Container Registry. So when Docker Hub is queried a 404 and large amount of HTML (probably the Docker 404 page) is returned. For Artifactory we receive an x509 error from our self-signed cert. This causes both deployments to fail despite being signed images with correct registry credentials.These errors happen when querying the registry, before it gets as far as communicating with our self-hosted Notary.
We can deploy images hosted in IBM Container Registry just fine. Even when we host the signing information in our self-hosted Notary.
What should have happened differently?
Portieris should not query
https://<registry>/oauth/token
for non-IBM registries.Portieris should be able to handle registries using self-signed TLS certificates.
How can it be reproduced?
Install Portieris and attempt to any Docker Hub pod with a valid pull secret.
Any other relevant information
We are running Portieris on an EKS cluster so we have deployed with the
IBMContainerService
option set tofalse
.The text was updated successfully, but these errors were encountered: