cloudflared
cloudflared copied to clipboard
The default Access config is ignored
Describe the bug The default Access config (the one at the root, not the per-ingress one) is ignored, causing JWT validation to not occur.
To Reproduce
Here's a config we're using (with redacted values):
{
"connectTimeout": "2s",
"credentials-file": "/tmp/17a15b6e-ccf2-47bb-9417-ff08fd8ed38d",
"ingress": [
{
"service": "http://ingress.ingress-nginx.svc.cluster.local"
}
],
"keepAliveTimeout": "30s",
"metrics": "0.0.0.0:28282",
"no-autoupdate": true,
"originRequest": {
"access": {
"audTag": ["REDACTED"],
"required": true,
"teamName": "REDACTED"
}
},
"retries": 3,
"tlsTimeout": "3s",
"tunnel": "REDACTED"
}
Tunnel is up and running, so I know the tunnel ID, credential files, and ingress service configuration themselves are correct.
Expected behavior
I expected the Access configuration to be enforced, i.e., JWT token and audience tag to be validated.
For example, I can point a different subdomain (with its own Access Application, which has a different audience tag not in the config) to the same Tunnel, and cloudflared accepts the request anyway (expected a 403).
In fact, I can remove the team name, and cloudflared tunnel run
doesn't even complain about the team name being blank.
Environment and versions
- OS: linux
- Architecture: amd64
- Version: 2022.10.1 (latest at time of writing)
Logs and errors
Unfortunately, there are no logs or errors. It would be nice for cloudflared to also let us know whether Access enforcement is enabled or not when starting up.
Additional context
It seems this problem only occurs on the default Access config. If I specify the Access config on the ingress level (i.e., move originRequest
from top-level and down to under ingress
, it works.
{
"connectTimeout": "2s",
"credentials-file": "/tmp/17a15b6e-ccf2-47bb-9417-ff08fd8ed38d",
"ingress": [
{
"originRequest": {
"access": {
"audTag": ["REDACTED"],
"required": true,
"teamName": "REDACTED"
}
},
"service": "http://ingress.ingress-nginx.svc.cluster.local"
}
],
"keepAliveTimeout": "30s",
"metrics": "0.0.0.0:28282",
"no-autoupdate": true,
"retries": 3,
"tlsTimeout": "3s",
"tunnel": "REDACTED"
}
In fact, when I remove teamName
, cloudflared tunnel run
now correctly complains:
2022-10-19T04:05:49Z ERR Couldn't start tunnel error="access.TeamName cannot be blank"
access.TeamName cannot be blank
Doing it this way does work as expected: attempting to point a different Access Application to the tunnel returns a 403 when its audience tag is not included in the config.
Hey @ripta . This is largely intended. Access rules are currently tied to the ingress rules only because we want them to be tied to a hostname.
Any reason why you want this to be global?
@sudarshan-reddy — Because I don't want anything to be unprotected by default.
If it's part of a design to not support a global originRequest.access, that's fine, but this behavior should be made clear, preferably with a loud error message. Whe I specify that global setting (as of v2022.10.1), it's just ignored, which is surprising, because I expected all my ingresses automatically protected.
Looking at the code, it also seemed like the intention is to in fact support global setting, because there's support for per-ingress override in setAccess
:
https://github.com/cloudflare/cloudflared/blob/c3c050aa792ebefb1a4e67930cfa19fd7e445333/ingress/config.go#L430-L434
which is called when evaluating per-ingress:
https://github.com/cloudflare/cloudflared/blob/c3c050aa792ebefb1a4e67930cfa19fd7e445333/ingress/ingress.go#L198
but then the overridden values (that take into account global settings) are summarily ignored by checking r.OriginRequest.Access
instead of cfg.Access
here:
https://github.com/cloudflare/cloudflared/blob/c3c050aa792ebefb1a4e67930cfa19fd7e445333/ingress/ingress.go#L265