Skip to content

Commit

Permalink
Add ToServices feature
Browse files Browse the repository at this point in the history
This PR adds ToServices feature, which allows users to apply an ACNP/ANP
on a Service.

This PR uses groupID assigned to the Service by AntreaProxy to match
traffic, which means that ToServices can only be used when AntreaProxy
is enabled and this Service must have at least one clusterIP.

Also, this PR use groupID to match traffic, thus the policies will not
be enforced when appliedTo workloads connect to Service Endpoints
directly. In order to enforce policies on directly Endpoints traffic,
one fallback is using ClusterGroup with ServiceReference added in
PR #1797.

What this PR did:
1. Add ToServices field in ACNP and ANP.
2. In ServiceLBTable, load OVS groupID to reg7.
3. Use OVS groupID of Service to do the conj match in the egress table.
4. Add a channel between proxier and networkpolicy controller for
Service groupID update events.

Signed-off-by: wgrayson <wgrayson@vmware.com>
  • Loading branch information
GraysonWu committed Oct 20, 2021
1 parent 8336f7a commit d955364
Show file tree
Hide file tree
Showing 41 changed files with 968 additions and 185 deletions.
23 changes: 23 additions & 0 deletions build/yamls/antrea-aks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,18 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
type: array
required:
- action
type: object
Expand Down Expand Up @@ -1918,6 +1930,17 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
type: object
type: array
required:
- action
type: object
Expand Down
23 changes: 23 additions & 0 deletions build/yamls/antrea-eks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,18 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
type: array
required:
- action
type: object
Expand Down Expand Up @@ -1918,6 +1930,17 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
type: object
type: array
required:
- action
type: object
Expand Down
23 changes: 23 additions & 0 deletions build/yamls/antrea-gke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,18 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
type: array
required:
- action
type: object
Expand Down Expand Up @@ -1918,6 +1930,17 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
type: object
type: array
required:
- action
type: object
Expand Down
23 changes: 23 additions & 0 deletions build/yamls/antrea-ipsec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,18 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
type: array
required:
- action
type: object
Expand Down Expand Up @@ -1918,6 +1930,17 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
type: object
type: array
required:
- action
type: object
Expand Down
23 changes: 23 additions & 0 deletions build/yamls/antrea.yml
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,18 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
- namespace
type: object
type: array
required:
- action
type: object
Expand Down Expand Up @@ -1918,6 +1930,17 @@ spec:
type: object
type: object
type: array
toServices:
items:
properties:
name:
type: string
namespace:
type: string
required:
- name
type: object
type: array
required:
- action
type: object
Expand Down
23 changes: 23 additions & 0 deletions build/yamls/base/crds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,18 @@ spec:
type: string
fqdn:
type: string
toServices:
type: array
items:
type: object
required:
- name
- namespace
properties:
name:
type: string
namespace:
type: string
name:
type: string
enableLogging:
Expand Down Expand Up @@ -1364,6 +1376,17 @@ spec:
format: cidr
fqdn:
type: string
toServices:
type: array
items:
type: object
required:
- name
properties:
name:
type: string
namespace:
type: string
name:
type: string
enableLogging:
Expand Down
17 changes: 14 additions & 3 deletions cmd/antrea-agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
npl "antrea.io/antrea/pkg/agent/nodeportlocal"
"antrea.io/antrea/pkg/agent/openflow"
"antrea.io/antrea/pkg/agent/proxy"
proxytypes "antrea.io/antrea/pkg/agent/proxy/types"
"antrea.io/antrea/pkg/agent/querier"
"antrea.io/antrea/pkg/agent/route"
"antrea.io/antrea/pkg/agent/stats"
Expand Down Expand Up @@ -199,6 +200,11 @@ func run(o *Options) error {
agentInitializer.GetWireGuardClient(),
o.config.AntreaProxy.ProxyAll)

var groupCounters []proxytypes.GroupCounter
groupIDUpdates := make(chan string, 100)
v4GroupCounter := proxytypes.NewGroupCounter(false, groupIDUpdates)
v6GroupCounter := proxytypes.NewGroupCounter(true, groupIDUpdates)

var proxier proxy.Proxier
if features.DefaultFeatureGate.Enabled(features.AntreaProxy) {
v4Enabled := config.IsIPv4Enabled(nodeConfig, networkConfig.TrafficEncapMode)
Expand All @@ -208,11 +214,14 @@ func run(o *Options) error {

switch {
case v4Enabled && v6Enabled:
proxier = proxy.NewDualStackProxier(nodeConfig.Name, informerFactory, ofClient, routeClient, nodePortAddressesIPv4, nodePortAddressesIPv6, proxyAll, skipServices)
proxier = proxy.NewDualStackProxier(nodeConfig.Name, informerFactory, ofClient, routeClient, nodePortAddressesIPv4, nodePortAddressesIPv6, proxyAll, skipServices, v4GroupCounter, v6GroupCounter)
groupCounters = append(groupCounters, v4GroupCounter, v6GroupCounter)
case v4Enabled:
proxier = proxy.NewProxier(nodeConfig.Name, informerFactory, ofClient, false, routeClient, nodePortAddressesIPv4, proxyAll, skipServices)
proxier = proxy.NewProxier(nodeConfig.Name, informerFactory, ofClient, false, routeClient, nodePortAddressesIPv4, proxyAll, skipServices, v4GroupCounter)
groupCounters = append(groupCounters, v4GroupCounter)
case v6Enabled:
proxier = proxy.NewProxier(nodeConfig.Name, informerFactory, ofClient, true, routeClient, nodePortAddressesIPv6, proxyAll, skipServices)
proxier = proxy.NewProxier(nodeConfig.Name, informerFactory, ofClient, true, routeClient, nodePortAddressesIPv6, proxyAll, skipServices, v6GroupCounter)
groupCounters = append(groupCounters, v6GroupCounter)
default:
return fmt.Errorf("at least one of IPv4 or IPv6 should be enabled")
}
Expand Down Expand Up @@ -247,6 +256,8 @@ func run(o *Options) error {
ifaceStore,
nodeConfig.Name,
entityUpdates,
groupCounters,
groupIDUpdates,
antreaPolicyEnabled,
statusManagerEnabled,
loggingEnabled,
Expand Down
47 changes: 46 additions & 1 deletion docs/antrea-network-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- [ACNP with ClusterGroup reference](#acnp-with-clustergroup-reference)
- [ACNP for complete Pod isolation in selected Namespaces](#acnp-for-complete-pod-isolation-in-selected-namespaces)
- [ACNP for default Namespace isolation](#acnp-for-default-namespace-isolation)
- [ACNP for toServices rule](#acnp-for-toservices-rule)
- [Behavior of <em>to</em> and <em>from</em> selectors](#behavior-of-to-and-from-selectors)
- [Key differences from K8s NetworkPolicy](#key-differences-from-k8s-networkpolicy)
- [kubectl commands for Antrea ClusterNetworkPolicy](#kubectl-commands-for-antrea-clusternetworkpolicy)
Expand All @@ -32,6 +33,7 @@
- [K8s clusters with version 1.21 and above](#k8s-clusters-with-version-121-and-above)
- [K8s clusters with version 1.20 and below](#k8s-clusters-with-version-120-and-below)
- [FQDN based filtering](#fqdn-based-filtering)
- [toServices instruction](#toservices-instruction)
- [RBAC](#rbac)
- [Notes](#notes)
<!-- /toc -->
Expand Down Expand Up @@ -331,6 +333,32 @@ spec:
enableLogging: true
```

#### ACNP for toServices rule

```yaml
apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
name: acnp-drop-to-services
spec:
priority: 5
tier: securityops
appliedTo:
- podSelector:
matchLabels:
role: client
namespaceSelector:
matchLabels:
env: prod
egress:
- action: Drop
toServices:
- name: svcName
namespace: svcNamespace
name: DropToServices
enableLogging: true
```

**spec**: The ClusterNetworkPolicy `spec` has all the information needed to
define a cluster-wide security policy.

Expand Down Expand Up @@ -408,14 +436,20 @@ a rule, it will be auto-generated by Antrea. The rule name auto-generation proce
is the same as ingress rules.
A ClusterGroup name can be set in the `group` field of a egress `to` section in place
of stand-alone selectors to allow traffic to workloads/ipBlocks set in the ClusterGroup.
`toServices` field contains a list of combinations of Service Namespace and Service Name to match traffic to this Service.
More details can be found in the [toServices](#toservices-instruction) section.
The [first example](#acnp-with-stand-alone-selectors) policy contains a single rule, which drops matched traffic on a
single port, to the 10.0.10.0/24 subnet specified by the `ipBlock` field.
The [second example](#acnp-with-clustergroup-reference) policy contains a single rule, which drops matched traffic on
TCP port 5978 to all network endpoints selected by the "test-cg-with-ip-block"
ClusterGroup.
The [third example](#acnp-for-complete-pod-isolation-in-selected-namespaces) policy contains a single rule,
which drops all egress traffic initiated by any Pod in Namespaces that have `app` set to
`no-network-access-required`. Note that an empty `To` in the egress rule means that
`no-network-access-required`.
The [fifth example](#acnp-for-toservices-rule) policy contains a single rule,
which drops traffic from "role: client" labeled Pods from "env: prod" labeled Namespaces to Service svcNamespace/svcName
via ClusterIP.
Note that an empty `to` + an empty `toServices` in the egress rule means that
this rule matches all egress destinations.
Egress `To` section also supports FQDN based filtering. This can be applied to exact FQDNs or
wildcard expressions. More details can be found in the [FQDN](#fqdn-based-filtering) section.
Expand Down Expand Up @@ -1021,6 +1055,17 @@ spec:
- fqdn: "svcA.default.svc.cluster.local"
```

## toServices instruction

A combination of Service name and Service Namespace can be used in `toServices` to refer to a Service.
`toServices` match traffic based on the clusterIP, port and protocol of Services. So headless Service is not supported.
Since `toServices` represents a combination of IP+port, it can't be used with `to` or `ports`. Also, this match process
relies on the groupID assigned to the Service by AntreaProxy. So it can only be used when AntreaProxy is enabled.
This clusterIP based match has one caveat: directly access to the Endpoints of this Service is not controlled by
`toServices`. To control the access to the backend Endpoints, you could use `ClusterGroup` with `ServiceReference`.
Because `ClusterGroup` with `ServiceReference` is equivalent to a podSelector that selects all backend Endpoints Pods of
the Service referred in `ServiceReference`.

## RBAC

Antrea-native policy CRDs are meant for admins to manage the security of their
Expand Down
Loading

0 comments on commit d955364

Please sign in to comment.