-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Improve the external authorization concept from opt-in to secure-by-default #3506
Improve the external authorization concept from opt-in to secure-by-default #3506
Conversation
Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please follow instructions at https://git.k8s.io/community/CLA.md#the-contributor-license-agreement to sign the CLA. It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
CLA signed |
1 similar comment
CLA signed |
/assign @antoineco |
/shrug |
PR raised from issue #3276 |
/unassign @antoineco |
@haassConnyun: ¯\_(ツ)_/¯ In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
@aledbf sorry to bump this - is there something we should do to get a review or a comment? |
Sorry for delay, I'll try to review this by the end of this week. |
@haassConnyun no-auth-locations is a global setting, it won't let users to whitelist a path for a given service. Do you have any plan to implement something so that users can opt out of this global auth setting per ingress? Maybe something like |
glog.Warningf("Global auth location denied, reason: url scheme is empty") | ||
} else if authURL.Host == "" { | ||
glog.Warningf("Global auth location denied, reason: url host is empty") | ||
} else if strings.Contains(authURL.Host, "..") { |
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.
Is this some kind of edge case where url.Parse
does not 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.
This was taken from auth-url annotation parser.
https://github.com/kubernetes/ingress-nginx/blob/master/internal/ingress/annotations/authreq/main.go#L137
The idea behind was to follow the syntax and style of the existing solution
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, it is the case url.Parse
does not catch.
|
||
authURL, err := url.Parse(val) | ||
if err != nil { | ||
glog.Warningf("Global auth location denied, reason: url is not") |
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.
The log message seems incomplete. Also can you include the err
in the message as well?
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 assume it should be ".. is not valid"))
Yes, will append the err
to the end.
@@ -150,6 +152,25 @@ func ReadConfig(src map[string]string) config.Configuration { | |||
} | |||
} | |||
|
|||
// Verify that the configured global auth is parsable as URL. if not, set the default value |
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.
Also can you extract this verification logic into a helper/util function and reuse it both here and in auth-url annotation parsing?
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.
Done.
rootfs/etc/nginx/template/nginx.tmpl
Outdated
@@ -1163,6 +1164,18 @@ stream { | |||
{{- end }} | |||
{{ end }} | |||
|
|||
{{ if not (isLocationInLocationList $location $all.Cfg.NoAuthLocations) }} |
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.
What if both auth-url annotation and global setting is set? If I read this correctly it'll have duplicate auth request setup. We should make sure annotation overrides global setting.
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.
Okay, can do it. Was not sure about the priorities. Now it is clear.
@haassConnyun thanks for the PR! I've made few inline comments. On top of them I think Nginx template should not have separate rendering for global and annotation settings. When the setting is set you can create the annotation manually in the controller and make sure every (except the whitelisted ones) ingress has it. That way you'd not need to touch |
Hi @ElvinEfendi, As requested changes were made:
To assist you, I have drawn 2 tables:
|
b4c8c26
to
e786a47
Compare
Hi @ElvinEfendi Rebased, tested, green. |
baff365
to
53713fe
Compare
Hi @ElvinEfendi , I hope the change is not too dramatic.
The switch between 2 solutions is full, so or you are using location specific external auth, or go with global external auth (including all addons in both cases). For example, it is not possible to have Modification of Can I get another feedback round? P.S. I am working on rebase. |
28366dc
to
a16a12d
Compare
@aledbf any reason why do you not wanna merge this? (I saw you added do-not-merge above) |
Hi @ElvinEfendi and @aledbf |
@okryvoshapka-connyun apologies for the delay. Please squash the commits. |
d7800f8
to
1aae430
Compare
1aae430
to
edc66f0
Compare
edc66f0
to
8cc9afe
Compare
@aledbf , rebased and squashed. |
@@ -389,6 +390,14 @@ nginx.ingress.kubernetes.io/auth-snippet: | | |||
!!! example | |||
Please check the [external-auth](../../examples/auth/external-auth/README.md) example. | |||
|
|||
#### Global External Authentication | |||
|
|||
By default the controller redirects all requests to an existing service that provides authentication if `global-auth-url` is set in the NGINX ConfigMap. If you want to disable this behavior for that ingress, you can use ssl-redirect: "false" in the NGINX ConfigMap. |
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.
What does ssl-redirect
has to do with global-auth-url
?
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.
Fixed.
|
||
defIPCIDR = append(defIPCIDR, "0.0.0.0/0") | ||
defNginxStatusIpv4Whitelist = append(defNginxStatusIpv4Whitelist, "127.0.0.1") | ||
defNginxStatusIpv6Whitelist = append(defNginxStatusIpv6Whitelist, "::1") | ||
defProxyDeadlineDuration := time.Duration(5) * time.Second | ||
degGlobalExternalAuth := GlobalExternalAuth{"", "", "", "", append(defResponseHeaders, ""), "", ""} |
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.
s/deg/def
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.
Fixed.
The PR is looking good! I still think we can avoid touching The location objects are built in controller.go, and when building we assign the annotations, including external auth. In the code path why can you not check global external auth and set external auth of location to the global one if the annotation is not set? Or even better in the external auth annotation, why don't you set default value to the global external auth value from the configmap? For an example you can check
proxy-connect-timeout is given as annotation then it will be used, otherwise its default/fallback value will be taken from configmap (you can trace GetDefaultBackend function to see that).
|
@ElvinEfendi , thank you for feedback.
As you have pointed to an example of "proxy-connect-timeout", I can change it, but it will take some time as I am a bit busy with another project. P.S. After simply typos fixes, e2e tests have failed for an unclear reason |
/approve |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: aledbf, ElvinEfendi, haassConnyun The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What this PR does / why we need it:
Assuming the cluster uses an external authorization service,
currently activation of external authorization is per ingress rule, that means the annotation
auth-url
needs to be added to every service that is publicly available. We call this security by opt-in.To improve this concept to security-by-default be propose to add a parameter to the configmap which takes care of authorizing every request automatically.
The existing
no-auth-locations
is used to manually whitelist services, the new code creates the needed internallocation
and adds a sub-auth request to every regular location, just as happens with theauth-url
annotation