Skip to content
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

endpoint: Do not override deny entries with proxy redirects #26344

Merged
merged 2 commits into from Jul 6, 2023

Conversation

jrajahalme
Copy link
Member

@jrajahalme jrajahalme commented Jun 19, 2023

Use DenyPreferredInsert instead of directly manipulating policy map state to make sure deny entries are not overridden by new proxy redirect entries.

Prior to this fix it was possible for a proxy redirect to be pushed onto the policy map when it should have been overridden by a deny at least in these cases:

  • L3-only deny with L3/L4 redirect: No redirect should be added as the L3 is denied, the new test case verifies this
  • L3-only deny with L4-only redirect: L4-only redirect should be added and an L3/L4 deny should also be added, but the L3/L4 deny is only added by deny preferred insert, and is missed when the map is manipulated directly.

It is clear that in the latter case the addition of the redirect can not be completely blocked, so we can't fix this by making AllowsL4 more restrictive. But also in the former case it is possible that the deny rule only covers a subset of security identities, while the redirect rule covers some of the same security identities, but also some more that should not be blocked. Hence the correct fix here is to leave AllowsL4 to be L3-independent, and cover these cases with deny preferred insert instead of adding redirect entries to the map directly.

This PR also contains a related change that allows a redirect entry to be updated, maybe with a changed proxy port. I've not seen evidence that this is currently fixing a bug, but it feels like a real possibility.

Fixes: #12716

Fixed proxy redirect policy implementation when any deny rule prevents them.

@jrajahalme jrajahalme added kind/bug This is a bug in the Cilium logic. area/proxy Impacts proxy components, including DNS, Kafka, Envoy and/or XDS servers. release-note/bug This PR fixes an issue in a previous release of Cilium. sig/policy Impacts whether traffic is allowed or denied based on user-defined policies. labels Jun 19, 2023
@jrajahalme jrajahalme requested review from a team as code owners June 19, 2023 08:48
@jrajahalme
Copy link
Member Author

/test

@jrajahalme
Copy link
Member Author

jrajahalme commented Jun 19, 2023

This is a bug in the Cilium redirect creation logic that needs to be fixed for both deny and auth rules to be properly handled. This current form of the PR seems to break Agent restart FQDN tests, so some more investigation is needed on why that happens.

Update: Figured out that it is natural for new L3-specific DNS proxy redirects to generate no MapState as the proxy has yet to allocate any identities. Removed the check for the number of entries generated and removed the removal of redirects that do not generate any MapState (earlier I had assumed that would only happen if deny entry overrides all the MapState for the new redirect).

@jrajahalme jrajahalme force-pushed the policy-deny-override-redirect branch from 7ba5878 to c0cf2dc Compare June 19, 2023 14:49
@jrajahalme jrajahalme added needs-backport/1.13 This PR / issue needs backporting to the v1.13 branch release-blocker/1.14 This issue will prevent the release of the next version of Cilium. labels Jun 19, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from main in 1.13.5 Jun 19, 2023
@jrajahalme jrajahalme self-assigned this Jun 20, 2023
@jrajahalme jrajahalme requested review from nathanjsweet and removed request for aditighag June 20, 2023 05:53
@jrajahalme jrajahalme force-pushed the policy-deny-override-redirect branch 2 times, most recently from 827b53b to fc3fe4c Compare June 20, 2023 06:26
@jrajahalme
Copy link
Member Author

Removed unrelated change/cleanup to make both reviews and backports easier.

@jrajahalme jrajahalme force-pushed the policy-deny-override-redirect branch from fc3fe4c to 1d0fc87 Compare June 20, 2023 06:49
@jrajahalme
Copy link
Member Author

Fixed commit message.

@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from main in 1.11.19 Jun 20, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from main in 1.12.12 Jun 20, 2023
@jrajahalme
Copy link
Member Author

Added additional needs-backport labels

@jrajahalme
Copy link
Member Author

/test

}
if entry.IsRedirectEntry() {
entry.ProxyPort = redirectPort
}
e.desiredPolicy.PolicyMapState[keyFromFilter] = entry
e.desiredPolicy.PolicyMapState.DenyPreferredInsertWithChanges(keyFromFilter, entry, insertedDesiredMapState, nil, idLookup)
Copy link
Member

Choose a reason for hiding this comment

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

Is it expected that DenyPreferredInsertWithChanges will insert into insertedDesiredMapState?

Copy link
Member Author

Choose a reason for hiding this comment

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

Previously we were inserting into insertedDesiredMapState only when the key/entry did not exist previously, now DenyPreferredInsertWithChanges inserts into insertedDesiredMapState also when the there was a previous entry with the same key. This does not matter, as where these are used in the revert code below, we first delete all inserted keys, then add back the old values, if they existed, from updatedDesiredMapState. End result is that same before and after, previously the revert code directly replaced the new value with the old one, now the new value is deleted first, and the old one added back after.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm. if there were old values also for (e.g., L3L4) entries created by DenyPreferredInsertWithChanges then the old values of those can not be reverted back in case of a failure with the current code in the PR. I may have to change adds and deletes arguments to DenyPreferredInsertWithChanges to be MapState instead of just Keys to make DenyPreferredInsertWithChanges revertible. Let me try that!

// Merging owners from the new entry to the existing one has no datapath impact so we skip
// adding anything to 'adds' here.
if oldEntry, exists := keys[key]; exists && (oldEntry.IsRedirectEntry() || oldEntry.IsDeny) {
// Merging owners has the effect of keeping the shered entry alive as long as one of the owners exists.
Copy link
Member

Choose a reason for hiding this comment

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

typo:

Suggested change
// Merging owners has the effect of keeping the shered entry alive as long as one of the owners exists.
// Merging owners has the effect of keeping the shared entry alive as long as one of the owners exists.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed, thanks!

if oldEntry, exists := keys[key]; exists && (oldEntry.IsRedirectEntry() || oldEntry.IsDeny) {
// Merging owners has the effect of keeping the shered entry alive as long as one of the owners exists.
if oldEntry, exists := keys[key]; exists &&
(!entry.IsRedirectEntry() && oldEntry.IsRedirectEntry() || oldEntry.IsDeny) {
Copy link
Member

Choose a reason for hiding this comment

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

IIUC, this is not changing functional behavior and we are just adding an extra condition for explicitness for the if-statement, correct?

Copy link
Member Author

Choose a reason for hiding this comment

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

Right now I think that is the case, yes. I was thinking that if the proxy port of an existing entry needs to be updated, then this code path should allow for that. I think this is currently not happening, but we are replacing direct manipulation of the redirect entry in bpf.go with the DenyPreferredInsertWithChanges that will end up here for a non-deny entry, so I thought it would be best to allow for proxy port to be updated by that call, if it ever needs to happen.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated with a new 1st commit that exports DenyPreferredInsertWithChanges() and makes it revertible, including unit testing.

@jrajahalme jrajahalme added backport-pending/1.12 backport-pending/1.13 The backport for Cilium 1.13.x for this PR is in progress. and removed needs-backport/1.11 needs-backport/1.13 This PR / issue needs backporting to the v1.13 branch labels Jul 11, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Needs backport from main to Backport pending to v1.11 in 1.11.19 Jul 11, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Needs backport from main to Backport pending to v1.13 in 1.13.5 Jul 11, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Needs backport from main to Backport pending to v1.12 in 1.12.12 Jul 11, 2023
@julianwiedmann julianwiedmann added backport-done/1.13 The backport for Cilium 1.13.x for this PR is done. and removed backport-pending/1.13 The backport for Cilium 1.13.x for this PR is in progress. labels Jul 11, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Backport pending to v1.13 to Backport done to v1.13 in 1.13.5 Jul 11, 2023
@jrajahalme jrajahalme added backport-pending/1.14 The backport for Cilium 1.14.x for this PR is in progress. and removed needs-backport/1.14 This PR / issue needs backporting to the v1.14 branch labels Jul 11, 2023
@julianwiedmann julianwiedmann added backport-done/1.12 The backport for Cilium 1.12.x for this PR is done. and removed backport-pending/1.12 labels Jul 14, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Backport pending to v1.12 to Backport done to v1.12 in 1.12.12 Jul 14, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Backport pending to v1.12 to Backport done to v1.12 in 1.12.12 Jul 14, 2023
@aanm aanm added backport-done/1.14 The backport for Cilium 1.14.x for this PR is done. and removed backport-pending/1.14 The backport for Cilium 1.14.x for this PR is in progress. labels Jul 14, 2023
@aanm aanm added backport-done/1.11 The backport for Cilium 1.11.x for this PR is done. and removed backport-pending/1.11 labels Jul 26, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Backport pending to v1.11 to Backport done to v1.11 in 1.11.19 Jul 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects/v1.14 This issue affects v1.14 branch area/proxy Impacts proxy components, including DNS, Kafka, Envoy and/or XDS servers. backport/author The backport will be carried out by the author of the PR. backport-done/1.11 The backport for Cilium 1.11.x for this PR is done. backport-done/1.12 The backport for Cilium 1.12.x for this PR is done. backport-done/1.13 The backport for Cilium 1.13.x for this PR is done. backport-done/1.14 The backport for Cilium 1.14.x for this PR is done. kind/bug This is a bug in the Cilium logic. ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-blocker/1.14 This issue will prevent the release of the next version of Cilium. release-note/bug This PR fixes an issue in a previous release of Cilium. sig/policy Impacts whether traffic is allowed or denied based on user-defined policies.
Projects
No open projects
1.11.19
Backport done to v1.11
1.12.12
Backport done to v1.12
1.13.5
Backport done to v1.13
Development

Successfully merging this pull request may close these issues.

None yet

8 participants