Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Skip TLS check when using insecure host #1526

Merged
merged 5 commits into from
Feb 4, 2019

Conversation

Timer
Copy link
Contributor

@Timer Timer commented Nov 17, 2018

Fixes #1497

Copy link
Member

@squaremo squaremo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it'll work! May I request that we put this behaviour behind another flag, so it is opt-in, to avoid surprises: I suggest --registry-insecure-tls-skip-verify.

@squaremo
Copy link
Member

@Timer I added that flag -- mind seeing if it works for your setup, when you have a sec?

I was thinking maybe the right thing to do is to act like docker, that is, for an insecure host:

  • try HTTPS, but with TLS insecure skip verify
  • if that fails, use HTTP but don't send credentials

I wonder if that would break some private registry setups ...

@donifer
Copy link

donifer commented Dec 27, 2018

Any updates on this? I think I'm hitting this issue using an insecure registry when polling images.

err="Get https://registry.internal.mydomain.com/v2/: x509: certificate is valid for ingress.local, not registry.internal.mydomain.com

@squaremo
Copy link
Member

@donifer Mayyyybe -- that looks more like you're using a registry host with HTTPS, and it has an invalid certificate. That's a closely related problem, but not solved by this PR as it stands -- it would need the alternate formulation I posted above (that is: for insecure hosts, try https:// with TLS_INSECURE_SKIP_VERIFY first, and fall back to HTTP if that doesn't connect).

Nonetheless, I've pushed a build from this branch to quay.io/squaremo/flux:insecure-host-behavior-ad833b9, if you want to try it out. (NB you need to supply the new flag to fluxd: --registry-tls-insecure-skip-verify)

@cazzoo
Copy link

cazzoo commented Jan 7, 2019

Looking to this fix

@squaremo
Copy link
Member

squaremo commented Jan 8, 2019

@Timer @donifer @cazzoo I've implemented this idea:

  • try HTTPS, but with TLS insecure skip verify
  • if that fails, use HTTP but don't send credentials

i.e., to use your own registry, you now have the option of using a self-signed certificate (or HTTP but no authentication!) so long as you supply the hostname with --registry-insecure-host.

If you have the chance to test this out in a controlled environment, I would appreciate feedback. I've pushed a build from this branch to quay.io/squaremo/flux:insecure-host-behavior-096bd47.

@squaremo squaremo dismissed their stale review January 9, 2019 11:11

We've since made more changes

tx = transport.NewTransport(tx, auth.NewAuthorizer(manager, tokenHandler, basicauthHandler))
authHandlers := []auth.AuthenticationHandler{}
// only send creds over HTTPS
if registryURL.Scheme == "https" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is too restrictive and opinionated. For instance, one may intentionally want to use http in a sealed environment in which the registry just happens to require credentials for reasons beyond your control.

Also, it is almost equally unsafe to send the creds over HTTPS when the certificate verification is being skipped

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah those two points are fair. So I guess the recommendation would be to

  1. only fall back to http if the domain is flagged as insecure
  2. only use TLS_INSECURE_SKIP_VERIFY if the domain is flagged as insecure
  3. always use credentials if you have them

on the basis that cases 1. and 2. are basically equivalent, and if you've flagged the domain as insecure, you are accepting the risk of a MitM attack in either situation -- ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that sounds good

Copy link
Member

@squaremo squaremo Jan 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^ @Timer @donifer @cazzoo Just to bring this significant change to your attention, since you've indicated this PR may be of interest to you (e.g., by creating it)

insecure = true
break
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The size of this function is getting out of hand. I would suggest factoring out the challenge obtention (or part of it at least)

Host: repo.Domain,
Path: "/v2/",
}

// Before we know how to authorise, need to establish which
// authorisation challenges the host will send. See if we've been
// here before.
attemptInsecureFallback := insecure
attempt:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make the label more descriptive? (e.g. schemeAttempt or attemptScheme)

registryPollInterval = fs.Duration("registry-poll-interval", 5*time.Minute, "period at which to check for updated images")
registryRPS = fs.Float64("registry-rps", 50, "maximum registry requests per second per host")
registryBurst = fs.Int("registry-burst", defaultRemoteConnections, "maximum number of warmer connections to remote and memcache")
registryTrace = fs.Bool("registry-trace", false, "output trace of image registry requests to log")
registryInsecure = fs.StringSlice("registry-insecure-host", []string{}, "use HTTP for this image registry domain (e.g., registry.cluster.local), instead of HTTPS")
registryInsecure = fs.StringSlice("registry-insecure-host", []string{}, "let these registry hosts skip TLS host verification, and fall back to HTTP (without basic auth) instead of HTTPS; this allows man-in-the-middle attacks, so use with extreme caution")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something we could break in existing installations using the flag by changing its behavior?

We are attempting http if https doesn't work, so, I don't think so, but it's worth giving it some further thought.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, there is something which can break: we are now skipping auth, which I am against, but if we really want to skip basic auth with http, we should at least create a new flag and deprecate this one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: if we're not skipping auth (as agreed above), I don't think this will be a breaking or even surprising change; if you already had a domain listed as insecure, it's because you wanted it to use HTTP (including sending credentials); instead, it will attempt HTTPS and fallback to HTTP, still sending creds. The change is now you can also use it if you want it to use HTTPS with a self-signed cert.

@cazzoo
Copy link

cazzoo commented Jan 22, 2019

That kind of solution will be enough for my case, I'm actually using self-signed certificate and would like to use HTTPS anyway. Actually using http as hotfix but this is unwanted here.
Looking for merge to next release

@squaremo
Copy link
Member

@2opremio I've implemented the "always send creds" scheme we discussed, and split the long method up. PTAL!

Timer and others added 5 commits February 4, 2019 11:05
We accept a list of image registry hosts for which to use HTTP; in
some cases, people also want to switch off TLS host certificate
verification, e.g., they have a setup in which the image manifests are
on a host using TLS but with a self-signed cert.

This extra flag allows people to switch TLS host cert verification off
(it's a bad idea to do that by default) explicitly, when the registry
is listed as an insecure host.
This commit changes the meaning of --registry-insecure-host to match
what Docker considers an insecure host:

 - the TLS host certificate is not verified
 - if it can't connect with HTTPS, it'll fall back to HTTP
 - no credentials are sent over HTTP

This gives a better path to using a local registry, since it's
relatively easy to set things up so it can use TLS; just a pain to set
TLS up with a valid host certificate.

Not sending credentials over HTTP is also a little more secure by
default -- previously, an insecure host would have used HTTP straight
away, _and_ sent credentials over it.
HTTPS without host cert verification is vulnerable to MitM attacks as
HTTP; so, accept that marking a host as insecure is just a risk, and
send credentials unconditionally.
This mainly just to keep method length a little more managable.
@squaremo squaremo merged commit 737815d into fluxcd:master Feb 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants