Skip to content

Conversation

aanm
Copy link
Member

@aanm aanm commented Jul 29, 2020

Deny rules will be configured with ingressDeny and egressDeny.

Policy example:

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "guestbook-web"
spec:
  endpointSelector:
    matchLabels:
      k8s-app.guestbook: web
  ingress:
  - fromEndpoints:
    - matchLabels:
        k8s-app.guestbook: redis
  ingressDeny:
  - fromEndpoints:
    - matchLabels:
        k8s-app.guestbook: redis

Since in the datapath the denies take priority over the allow rules, this rule will drop all packets from any pod running with the label k8s-app.guestbook=redis in the default namespace that tries to reach any pod running with the label k8s-app.guestbook=web.

The ingressDeny differs from the ingress as the L7 rules are not available in the L4 section. For example:
ingress:

...
  ingress:
  - fromEndpoints:
    - matchLabels:
        env: prod
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/public"
...

vs
ingressDeny:

...
  ingressDeny:
  - fromEndpoints:
    - matchLabels:
        env: prod
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP
...

And in egressDeny vs egress the toFQDNs are not available as well as, similar to the ingressDeny, the L7 Rules.

egress:

...
  egress:
  - toEndpoints:
    - matchLabels:
       "k8s:io.kubernetes.pod.namespace": kube-system
       "k8s:k8s-app": kube-dns
    toPorts:
      - ports:
         - port: "53"
           protocol: ANY
        rules:
          dns:
            - matchPattern: "*"
  - toFQDNs:
      - matchName: "cilium.io"
      - matchName: "sub.cilium.io"
      - matchPattern: "*.sub.cilium.io"
...

egressDeny:

...
  egressDeny:
  - toEndpoints:
    - matchLabels:
       "k8s:io.kubernetes.pod.namespace": kube-system
       "k8s:k8s-app": kube-dns
    toPorts:
      - ports:
         - port: "53"
           protocol: ANY
...

TODO:

  • Fix tests
  • Add tests
  • Documentation
  • Change the slightly the exposed API to the users since deny policies won't have L7 policies initially.
    This was done in the last commit if we don't like it we can always revert it.

Fixes #7111

@aanm aanm added release-note/major This PR introduces major new functionality to Cilium. dont-merge/preview-only Only for preview or testing, don't merge it. labels Jul 29, 2020
@aanm aanm requested a review from jrajahalme July 29, 2020 21:17
@aanm aanm requested a review from a team as a code owner July 29, 2020 21:17
@aanm aanm requested a review from a team July 29, 2020 21:17
@aanm aanm requested review from a team as code owners July 29, 2020 21:17
@aanm aanm requested review from a team July 29, 2020 21:17
@aanm aanm requested a review from a team as a code owner July 29, 2020 21:17
@aanm
Copy link
Member Author

aanm commented Jul 29, 2020

test-me-please

@aanm aanm force-pushed the pr/denypolicies branch from c81e2e8 to ce2d451 Compare July 29, 2020 21:21
@aanm
Copy link
Member Author

aanm commented Jul 29, 2020

test-me-please

Copy link
Member

@jrajahalme jrajahalme left a comment

Choose a reason for hiding this comment

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

Looking good, some minor comments only so far. Overall one would hope that most of the code duplication for the deny case could be avoided by refactoring code.

@aanm aanm force-pushed the pr/denypolicies branch from ce2d451 to 01a7374 Compare August 3, 2020 20:34
@aanm aanm requested a review from a team August 3, 2020 20:34
@aanm aanm force-pushed the pr/denypolicies branch from 01a7374 to e6441ca Compare August 3, 2020 20:38
@aanm aanm requested a review from jrajahalme August 3, 2020 20:40
Copy link
Member

@jrajahalme jrajahalme left a comment

Choose a reason for hiding this comment

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

Some questions for clarification. Also, it's a pity that the last commit makes code less readable :-(

}
}
} else if len(ingressPolicy) > 0 {
verdict = ingressPolicy.IngressCoversContext(ctx)
Copy link
Member

Choose a reason for hiding this comment

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

Normal policy should still be considered if verdict after checking deny policies is not api.Denied, so this can not be in an else block.

Copy link
Member Author

Choose a reason for hiding this comment

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

nice catch!

found += cnt
}
}

Copy link
Member

Choose a reason for hiding this comment

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

I wonder if SetDeny(true) needs to be called before this block as well?

found += cnt
}
}

Copy link
Member

Choose a reason for hiding this comment

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

I wonder if SetDeny(true) needs to be called before this block as well?

@aanm aanm force-pushed the pr/denypolicies branch from e6441ca to 041834a Compare August 4, 2020 01:29
@aanm
Copy link
Member Author

aanm commented Aug 4, 2020

test-me-please

@coveralls
Copy link

coveralls commented Aug 4, 2020

Coverage Status

Coverage increased (+0.04%) to 37.173% when pulling 94b466831133a88a11499dd369be30de3170fa28 on aanm:pr/denypolicies into bd89e83 on cilium:master.

@aanm aanm force-pushed the pr/denypolicies branch from 041834a to 65f448e Compare August 5, 2020 19:57
@aanm
Copy link
Member Author

aanm commented Aug 5, 2020

test-me-please

Copy link
Member

@pchaigno pchaigno left a comment

Choose a reason for hiding this comment

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

LGTM overall. My only concern is around handling of AlwaysAllowLocalhost when deny policy rules are loaded, in particular with L4-only deny rules (see comment below). I think all other comments can be addressed as follow ups.

Since L7 rules are not supported in deny rules, should we reject them during validation?

That last commit is really hard to review. Couldn't it be broken up in several commits?

@aanm
Copy link
Member Author

aanm commented Aug 6, 2020

@pchaigno thanks for the review

Since L7 rules are not supported in deny rules, should we reject them during validation?

How? I mean, there isn't any L7 field in deny rules, so how could even be validated (or where)?

That last commit is really hard to review. Couldn't it be broken up in several commits?

Unfortunately it couldn't, the unit tests would have been broken if that would be the case.

@aanm aanm force-pushed the pr/denypolicies branch from 65f448e to a20c16d Compare August 6, 2020 17:25
@aanm aanm force-pushed the pr/denypolicies branch 2 times, most recently from 288cfb7 to 65e3463 Compare October 2, 2020 17:22
@aanm
Copy link
Member Author

aanm commented Oct 2, 2020

test-me-please

Copy link
Member

@christarazi christarazi left a comment

Choose a reason for hiding this comment

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

🎉 Mainly looked over CI code changes this time around.

@aanm aanm force-pushed the pr/denypolicies branch from 65e3463 to c54d8f1 Compare October 2, 2020 19:00
@aanm
Copy link
Member Author

aanm commented Oct 2, 2020

test-focus K8sPolicyTest*

@aanm aanm force-pushed the pr/denypolicies branch from c54d8f1 to ade5689 Compare October 2, 2020 19:56
@aanm
Copy link
Member Author

aanm commented Oct 2, 2020

test-focus K8sPolicyTest*

Copy link
Member

@joestringer joestringer left a comment

Choose a reason for hiding this comment

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

I did another brief pass particularly looking at the docs, I think there's some improvements we can make before release but I'm OK to push those out to a subsequent PR.

Given the level of review we've done between Jarno, you and I across the core logic + eyes on the overall k8s API behaviour from a broader set of folks, I think we have nailed down the desired behaviour. Furthermore we've caught a bunch of issues and added testing for several areas that were previously ambiguous so I'm getting towards diminishing returns on spending more time staring at the code in this PR. Given the beta tag I think we're safe to get this in, and push it out for broader exposure, testing, and iteration on top of this base.

Are there any remaining areas you feel could do with more eyes/attention?

Comment on lines 1135 to 1136
The current known limitation is a deny policy with ``toEntities`` "world" for
which a ``toFQDNs`` can bypass it.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should file an issue for this and reference it here so if users are concerned about it, they can 👍 and/or investigate?

Comment on lines +116 to +119
Flags uint8 `align:"deny"`
Pad0 uint8 `align:"pad0"`
Copy link
Member

Choose a reason for hiding this comment

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

My comment was not about the naming, it was about the content of the values we populate. I think if we declare the PolicyEntry in Go, it will auto-zero the fields like Pad0 so we should be good.

aanm added 14 commits October 3, 2020 00:13
This will allow to reuse functions.

Signed-off-by: André Martins <andre@cilium.io>
This function can be refactored out of the pkg/endpoint. With this
change it is also possible to unit test this function.

Signed-off-by: André Martins <andre@cilium.io>
Create function to de-duplicate code and have the ability to re-use
code.

Signed-off-by: André Martins <andre@cilium.io>
Signed-off-by: André Martins <andre@cilium.io>
Signed-off-by: André Martins <andre@cilium.io>
With these changes users will have the ability to dump deny
policy maps using 'cilium bpf policy map'.

Signed-off-by: André Martins <andre@cilium.io>
This change adds the deny policy enforcement in the datapath. When
checking the entry of the policy map, we will check the dedicated bit
for policy denies. If that bit is set, which we will consider unlikely
to avoid performance penalties for the allow case, the traffic will be
dropped.

Signed-off-by: André Martins <andre@cilium.io>
These changes only add the fields into the API for both Cilium and
Kubernetes interactions.

Signed-off-by: André Martins <andre@cilium.io>
Signed-off-by: André Martins <andre@cilium.io>
Since not all functionalities will be available in the IngressDeny and
EgressDeny fields of Rule, it was necessary to create a new structure,
IngressDeny and EgressDeny. These 2 structures share common fields with
the Ingress and Egress except the implementation of L7 Policies, which
is part of the PortRule but not of the PortDenyRules. This requirement
requires the introduction of some interfaces to avoid code duplication
in the policy calculation.

Signed-off-by: André Martins <andre@cilium.io>
These changes introduce automatic capability of performing unit tests
by adding an algorithm used to derive map states and test cases. This
commit keeps the same behavior used in the manually unit tests to
check if the new algorithm used to derive map states breaks the old
expectations. In follow up changes the manual tests will be removed.

Signed-off-by: André Martins <andre@cilium.io>
Signed-off-by: André Martins <andre@cilium.io>
Signed-off-by: André Martins <andre@cilium.io>
Add documentation and examples for policy denies.

Signed-off-by: André Martins <andre@cilium.io>
@aanm aanm force-pushed the pr/denypolicies branch from ade5689 to 3dca900 Compare October 2, 2020 22:40
@aanm
Copy link
Member Author

aanm commented Oct 2, 2020

test-me-please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-note/major This PR introduces major new functionality to Cilium.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CIDR-based deny security policies
7 participants