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

Cilium non-deterministically classifies CIDR policy matches for range with node IPs #16308

Closed
olemarkus opened this issue May 25, 2021 · 9 comments · Fixed by #25298
Closed
Assignees
Labels
kind/bug This is a bug in the Cilium logic. kind/community-report This was reported by a user in the Cilium community, eg via Slack. needs/triage This issue requires triaging to establish severity and next steps. pinned These issues are not marked stale by our issue bot. sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. sig/policy Impacts whether traffic is allowed or denied based on user-defined policies.

Comments

@olemarkus
Copy link

Bug report

General Information

  • Cilium version: cilium 1.9.4
  • Kernel version: Linux ip-10-29-109-25 5.4.0-1045-aws Adding labels to ui #47-Ubuntu SMP Tue Apr 13 07:02:25 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
  • Orchestration system version in use: kubernetes v1.20.6

How to reproduce the issue

Run node-local-dns --setupiptables=false and kubelet --cluster-dns=169.254.20.10

Add a CNP that looks like this:

spec:
  egress:
  - toCIDR:
    - 169.254.20.10/32
    toPorts:
    - ports:
      - port: "53"
        protocol: ANY
  endpointSelector: {}

On first cilium run, cilium will deny traffic to node-local-dns. If the pod is deleted, the second cilium run will accept traffic.

First cilium run

cilium ip list:

169.254.20.10/32    host

cilium monitor -t policy-verdict:

Policy verdict log: flow 0xaaa04ad local EP ID 1762, remote ID 1, proto 17, egress, action deny, match none, 100.71.181.66:53076 -> 169.254.20.10:53 udp
Policy verdict log: flow 0xaaa04ad local EP ID 1762, remote ID 1, proto 17, egress, action deny, match none, 100.71.181.66:53076 -> 169.254.20.10:53 udp
Policy verdict log: flow 0x0 local EP ID 481, remote ID 17956, proto 6, ingress, action deny, match none, 100.71.139.54:45062 -> 100.71.181.177:6943 tcp SYN
Policy verdict log: flow 0xaaa04ad local EP ID 1762, remote ID 1, proto 17, egress, action deny, match none, 100.71.181.66:53076 -> 169.254.20.10:53 udp
Policy verdict log: flow 0xaaa04ad local EP ID 1762, remote ID 1, proto 17, egress, action deny, match none, 100.71.181.66:53076 -> 169.254.20.10:53 udp
Policy verdict log: flow 0x897b78c4 local EP ID 1762, remote ID 1, proto 17, egress, action deny, match none, 100.71.181.66:56843 -> 169.254.20.10:53 udp
Policy verdict log: flow 0x897b78c4 local EP ID 1762, remote ID 1, proto 17, egress, action deny, match none, 100.71.181.66:56843 -> 169.254.20.10:53 udp

Second cilium run

169.254.20.10/32     cidr:169.254.0.0/16                                                                                       
                     cidr:169.254.0.0/19                                                                                       
                     cidr:169.254.20.10/31                                                                                     
                     cidr:168.0.0.0/5                                                                                          
                     cidr:168.0.0.0/7                                                                                          
                     cidr:169.254.0.0/17                                                                                       
                     cidr:169.254.20.0/23                                                                                      
                     reserved:world                                                                                            
                     cidr:169.254.20.0/22                                                                                      
                     cidr:169.254.20.10/32                                                                                     
                     cidr:169.254.20.0/25                                                                                      
                     cidr:169.254.20.0/27                                                                                      
                     cidr:169.0.0.0/8                                                                                          
                     cidr:169.128.0.0/9                                                                                        
                     cidr:169.254.0.0/15                                                                                       
                     cidr:169.224.0.0/11                                                                                       
                     cidr:168.0.0.0/6                                                                                          
                     cidr:169.254.20.0/26                                                                                      
                     cidr:160.0.0.0/3                                                                                          
                     cidr:169.254.16.0/20                                                                                      
                     cidr:0.0.0.0/0                                                                                            
                     cidr:169.254.16.0/21                                                                                      
                     cidr:128.0.0.0/2                                                                                          
                     cidr:169.248.0.0/13                                                                                       
                     cidr:169.192.0.0/10                                                                                       
                     cidr:169.254.20.8/30                                                                                      
                     cidr:169.254.0.0/18                                                                                       
                     cidr:160.0.0.0/4                                                                                          
                     cidr:169.254.20.0/28                                                                                      
                     cidr:169.254.20.8/29                                                                                      
                     cidr:169.240.0.0/12                                                                                       
                     cidr:169.252.0.0/14                                                                                       
                     cidr:169.254.20.0/24                                                                                      
                     cidr:128.0.0.0/1  

cilium monitor -t policy-verdict:

Policy verdict log: flow 0x5f42acab local EP ID 1109, remote ID 16777221, proto 17, egress, action allow, match L3-L4, 100.71.139.123:38685 -> 169.254.20.10:53 udp
Policy verdict log: flow 0xbe339248 local EP ID 1109, remote ID 16777221, proto 17, egress, action allow, match L3-L4, 100.71.139.123:54033 -> 169.254.20.10:53 udp
Policy verdict log: flow 0x3a516849 local EP ID 1109, remote ID 16777221, proto 17, egress, action allow, match L3-L4, 100.71.139.123:40686 -> 169.254.20.10:53 udp
Policy verdict log: flow 0x656356b6 local EP ID 1109, remote ID 16777221, proto 17, egress, action allow, match L3-L4, 100.71.139.123:41152 -> 169.254.20.10:53 udp
Policy verdict log: flow 0x978580ec local EP ID 1109, remote ID 16777221, proto 17, egress, action allow, match L3-L4, 100.71.139.123:53109 -> 169.254.20.10:53 udp
Policy verdict log: flow 0x45c1e6c1 local EP ID 1109, remote ID 16777221, proto 17, egress, action allow, match L3-L4, 100.71.139.123:50593 -> 169.254.20.10:53 udp
Policy verdict log: flow 0x9cd850d5 local EP ID 1109, remote ID 16777221, proto 17, egress, action allow, match L3-L4, 100.71.139.123:37507 -> 169.254.20.10:53 udp

Slack thread https://cilium.slack.com/archives/C1MATJ5U5/p1621963201289500

@olemarkus olemarkus added the kind/bug This is a bug in the Cilium logic. label May 25, 2021
@pchaigno pchaigno added kind/community-report This was reported by a user in the Cilium community, eg via Slack. needs/triage This issue requires triaging to establish severity and next steps. labels May 25, 2021
@christarazi
Copy link
Member

We determined on Slack that the proper policy would be to use toEntities: [host], as toCIDRs aren't supported for host IPs. Would the appropriate action here be that we clarify this in the documentation?

/cc @pchaigno

@olemarkus
Copy link
Author

Unfortunately, that isn't enough. As sometimes the traffic will match the host entity, sometimes it matches the CIDR. So to make this work you actually need to have a policy that allows for both of those.

This really feels like a largish gap in the flows that Cilium policies can match.

There is a similar issue with pod -> host networking (e.g if you have kube API servers on host network, which is very common). Here, there is no policy that can match if remove identities are enabled.

@christarazi christarazi added the sig/policy Impacts whether traffic is allowed or denied based on user-defined policies. label Jun 4, 2021
@joestringer
Copy link
Member

Interesting report. When Cilium detects that the IP address is associated with the host, for example assigned to a local interface, then it is expected to map that IP address to the "host" identity and avoid matching via IPs. Usually this would exclude the IP from the CIDR portion of the policy engine. The background to this is that label-based and entity-based policies are semantically richer ways of describing the connectivity that you wish to allow. So host would take precedence.

Reading from the IP/CIDR-based policies docs, the relevant text is:

CIDR rules apply if Cilium cannot map the source or destination to an identity derived from endpoint labels, ie the Special Identities.

Curiously though, there's a bit of a conflict in the docs. Above it talks about how "special identities" (including "host") are excluded from CIDR policy. Following that paragraph we have the following list of peers that CIDR policies may apply to:

  • A network endpoint outside the cluster
  • The host network namespace where the pod is running.
  • Within the cluster prefix but the IP’s networking is not provided by Cilium.

I actually think that The host network namespace where the pod is running. is a bug in the docs. I would expect that the host network namespace is expected to be handled as "host" identity, not by CIDR policy.

We probably need to investigate a little bit closer the ipcache precedence rules in pkg/ipcache to get to the bottom of this. Is it that the ipcache is informed about potentially two different identities for the same IP (host vs. CIDR 16xxxxx identity?) and the ordering of those events somehow governs which identity ends up being used? Or is the IP not being consistenly associated with the host, in which case Cilium falls back to using the CIDR identity when the IP is not assigned to a network interface?

@stale
Copy link

stale bot commented Aug 28, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the stale The stale bot thinks this issue is old. Add "pinned" label to prevent this from becoming stale. label Aug 28, 2021
@olemarkus
Copy link
Author

Still a pretty big important issue to us

@stale stale bot removed the stale The stale bot thinks this issue is old. Add "pinned" label to prevent this from becoming stale. label Aug 28, 2021
@eddycharly
Copy link
Contributor

eddycharly commented Oct 14, 2021

We face the same issue today using a regular NetworkPolicy.

Some trafic went to world endpoint and we could allow the trafic by adding an ip block in the policy while some trafic went to the host endpoint and the ip block didn't make it in this case.

@aanm aanm added the sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. label Jan 6, 2022
@kruczjak
Copy link

Hello, we've experienced same issue with regular NetworkPolicy.

Same policy worked on different CNI and broke after we've migrated to cilium.

@github-actions
Copy link

github-actions bot commented Jul 9, 2022

This issue has been automatically marked as stale because it has not
had recent activity. It will be closed if no further activity occurs.

@github-actions github-actions bot added the stale The stale bot thinks this issue is old. Add "pinned" label to prevent this from becoming stale. label Jul 9, 2022
@olemarkus
Copy link
Author

This is still an issue.

@sayboras sayboras removed the stale The stale bot thinks this issue is old. Add "pinned" label to prevent this from becoming stale. label Jul 9, 2022
@pchaigno pchaigno added the pinned These issues are not marked stale by our issue bot. label Jul 9, 2022
@joestringer joestringer changed the title Cilium non-deterministically classifies 169.254.20.10/32 Cilium non-deterministically classifies CIDR policy matches for range with node IPs Apr 14, 2023
asauber added a commit that referenced this issue May 5, 2023
This is a fix for a regression in the local addresses logic, introduced
in 080857b as part of the
implementation for AddressScopeMax. Addresses with the form of
link-local unicast addresses began to be filtered out of the local
address aggregation, causing them to labeled with the "world" identity
for the sake of policy enforcement. Examples of such addresses include:

169.254.10.10
fe80::1234

This caused issues for a variety of users, whose policies allowing
"host" traffic would no longer allow traffic to these addresses, forcing
the use of workarounds involving CIDR policies, which is not the
intended behavior for this type of address. This was a regression as of
Cilium 1.12.0-rc2. One reason for this regression was that logic prior
to the change looked at the address scope, whereas logic after the
change looked at the address bytes, and it was found that many users had
assigned addresses of the forms above but with scope global, causing
them to again be filtered unconditionally.

This patch factors out the local address filtering logic into a
function, removes the skip over IsLinkLocalUnicast(), and adds a variety
of unit tests for that function.

fixes: #25242
fixes: #23910
fixes: #16308
fixes: #20055

Signed-off-by: Andrew Sauber <andrew.sauber@isovalent.com>
asauber added a commit that referenced this issue May 10, 2023
This is a fix for a regression in the local addresses logic, introduced
in 080857b as part of the
implementation for AddressScopeMax. Addresses with the form of
link-local unicast addresses began to be filtered out of the local
address aggregation, causing them to labeled with the "world" identity
for the sake of policy enforcement. Examples of such addresses include:

169.254.10.10
fe80::1234

This caused issues for a variety of users, whose policies allowing
"host" traffic would no longer allow traffic to these addresses, forcing
the use of workarounds involving CIDR policies, which is not the
intended behavior for this type of address. This was a regression as of
Cilium 1.12.0-rc2. One reason for this regression was that logic prior
to the change looked at the address scope, whereas logic after the
change looked at the address bytes, and it was found that many users had
assigned addresses of the forms above but with scope global, causing
them to again be filtered unconditionally.

This patch factors out the local address filtering logic into a
function, removes the skip over IsLinkLocalUnicast(), and adds a variety
of unit tests for that function.

fixes: #25242
fixes: #23910
fixes: #16308
fixes: #20055

Signed-off-by: Andrew Sauber <andrew.sauber@isovalent.com>
michi-covalent pushed a commit that referenced this issue May 10, 2023
This is a fix for a regression in the local addresses logic, introduced
in 080857b as part of the
implementation for AddressScopeMax. Addresses with the form of
link-local unicast addresses began to be filtered out of the local
address aggregation, causing them to labeled with the "world" identity
for the sake of policy enforcement. Examples of such addresses include:

169.254.10.10
fe80::1234

This caused issues for a variety of users, whose policies allowing
"host" traffic would no longer allow traffic to these addresses, forcing
the use of workarounds involving CIDR policies, which is not the
intended behavior for this type of address. This was a regression as of
Cilium 1.12.0-rc2. One reason for this regression was that logic prior
to the change looked at the address scope, whereas logic after the
change looked at the address bytes, and it was found that many users had
assigned addresses of the forms above but with scope global, causing
them to again be filtered unconditionally.

This patch factors out the local address filtering logic into a
function, removes the skip over IsLinkLocalUnicast(), and adds a variety
of unit tests for that function.

fixes: #25242
fixes: #23910
fixes: #16308
fixes: #20055

Signed-off-by: Andrew Sauber <andrew.sauber@isovalent.com>
thorn3r pushed a commit to thorn3r/cilium that referenced this issue May 15, 2023
[ upstream commit 05b6d82 ]

This is a fix for a regression in the local addresses logic, introduced
in 080857b as part of the
implementation for AddressScopeMax. Addresses with the form of
link-local unicast addresses began to be filtered out of the local
address aggregation, causing them to labeled with the "world" identity
for the sake of policy enforcement. Examples of such addresses include:

169.254.10.10
fe80::1234

This caused issues for a variety of users, whose policies allowing
"host" traffic would no longer allow traffic to these addresses, forcing
the use of workarounds involving CIDR policies, which is not the
intended behavior for this type of address. This was a regression as of
Cilium 1.12.0-rc2. One reason for this regression was that logic prior
to the change looked at the address scope, whereas logic after the
change looked at the address bytes, and it was found that many users had
assigned addresses of the forms above but with scope global, causing
them to again be filtered unconditionally.

This patch factors out the local address filtering logic into a
function, removes the skip over IsLinkLocalUnicast(), and adds a variety
of unit tests for that function.

fixes: cilium#25242
fixes: cilium#23910
fixes: cilium#16308
fixes: cilium#20055

Signed-off-by: Andrew Sauber <andrew.sauber@isovalent.com>
Signed-off-by: Tim Horner <timothy.horner@isovalent.com>
aditighag pushed a commit that referenced this issue May 16, 2023
[ upstream commit 05b6d82 ]

This is a fix for a regression in the local addresses logic, introduced
in 080857b as part of the
implementation for AddressScopeMax. Addresses with the form of
link-local unicast addresses began to be filtered out of the local
address aggregation, causing them to labeled with the "world" identity
for the sake of policy enforcement. Examples of such addresses include:

169.254.10.10
fe80::1234

This caused issues for a variety of users, whose policies allowing
"host" traffic would no longer allow traffic to these addresses, forcing
the use of workarounds involving CIDR policies, which is not the
intended behavior for this type of address. This was a regression as of
Cilium 1.12.0-rc2. One reason for this regression was that logic prior
to the change looked at the address scope, whereas logic after the
change looked at the address bytes, and it was found that many users had
assigned addresses of the forms above but with scope global, causing
them to again be filtered unconditionally.

This patch factors out the local address filtering logic into a
function, removes the skip over IsLinkLocalUnicast(), and adds a variety
of unit tests for that function.

fixes: #25242
fixes: #23910
fixes: #16308
fixes: #20055

Signed-off-by: Andrew Sauber <andrew.sauber@isovalent.com>
Signed-off-by: Tim Horner <timothy.horner@isovalent.com>
@asauber asauber self-assigned this May 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug This is a bug in the Cilium logic. kind/community-report This was reported by a user in the Cilium community, eg via Slack. needs/triage This issue requires triaging to establish severity and next steps. pinned These issues are not marked stale by our issue bot. sig/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. sig/policy Impacts whether traffic is allowed or denied based on user-defined policies.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants