crd

package
v0.0.0-...-056dfb2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 16, 2020 License: MIT Imports: 9 Imported by: 0

README

Network policies: experimental CRD

Model

Traffic

"Traffic" is a request from a Source to a Destination, over a specified port and protocol. Sources and Destinations are both Peers. If a Peer is internal to the Kubernetes cluster, its data includes both names and labels from the Pod, Node, and Namespace. If a peer is external, this data will not be included. Peers also have IP addresses.

TrafficEdge

"TrafficEdge"s match (or don't match) Traffic requests, based on a variety of attributes. TrafficEdges are the heart of network policies, as they give policies the ability to accept or reject Traffic based on attributes of the Traffic.

One big difference between Kubernetes network policies and this experimental model is that Kubernetes privileges a "target", which is treated differently than the other Peer. On the other hand, this model is symmetrical between source and destination, and ingress and egress.

Policy

A policy is a TrafficEdge -- used to match traffic -- and a directive, along with compatibility hints to aid in translation into kubernetes network policies. If a policy matches traffic, it can choose to allow or deny the traffic. If multiple policies match traffic, the policy priority is taken into account.

Code

Examples: practical uses of the experimental network policy API to:

  • flush out corner cases
  • compare to Kubernetes network policies
  • test accuracy of Builder/Reducer conversions

Builder: convert Kubernetes network policies to experimental model (reverse of Reducer)

Reducer: convert experimental network policies to Kubernetes model (reverse of Builder)

TODOs:

  • add more test cases
  • fix translation bugs
  • add support for priority

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AllSourcesAllDests = &Policy{
	ObjectMeta: metav1.ObjectMeta{
		Name: "allow-all-sources-all-dests",
	},
	Spec: PolicySpec{
		Compatibility:  []networkingv1.PolicyType{networkingv1.PolicyTypeIngress, networkingv1.PolicyTypeEgress},
		TrafficMatcher: EverythingMatcher,
		Directive:      DirectiveAllow,
	},
}

All/All

View Source
var AllSourcesExternalDests = &Policy{
	ObjectMeta: metav1.ObjectMeta{
		Name: "all-sources-external-dests",
	},
	Spec: PolicySpec{
		Compatibility: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress},
		TrafficMatcher: &TrafficEdge{
			Type: TrafficMatchTypeAll,
			Dest: &PeerMatcher{
				RelativeLocation: &PeerLocationExternal,
			},
		},
		Directive: DirectiveAllow,
	},
}

All/External

View Source
var AllSourcesInternalDests = &Policy{
	ObjectMeta: metav1.ObjectMeta{
		Name: "all-sources-internal-dests",
	},
	Spec: PolicySpec{
		Compatibility: []networkingv1.PolicyType{networkingv1.PolicyTypeIngress},
		TrafficMatcher: &TrafficEdge{
			Type: TrafficMatchTypeAll,
			Dest: &PeerMatcher{
				RelativeLocation: &PeerLocationInternal,
			},
		},
		Directive: DirectiveAllow,
	},
}

All/Internal

View Source
var AnthosAllowKubeDNSEgressNetworkPolicy = &networkingv1.NetworkPolicy{
	ObjectMeta: metav1.ObjectMeta{
		Name:      "allow-kube-dns-egress",
		Namespace: "kube-system",
	},
	Spec: networkingv1.NetworkPolicySpec{
		PodSelector: metav1.LabelSelector{
			MatchLabels: map[string]string{
				"k8s-app": "kube-dns",
			},
		},
		Egress: []networkingv1.NetworkPolicyEgressRule{
			{
				Ports: []networkingv1.NetworkPolicyPort{
					{Protocol: &tcp, Port: &port53},
					{Protocol: &udp, Port: &port53},
				},
				To: []networkingv1.NetworkPolicyPeer{
					{
						IPBlock: &networkingv1.IPBlock{
							CIDR: "169.254.169.254/32",
						},
					},
				},
			},
			{
				Ports: []networkingv1.NetworkPolicyPort{
					{Protocol: &tcp, Port: &port443},
				},
				To: []networkingv1.NetworkPolicyPeer{
					{
						IPBlock: &networkingv1.IPBlock{
							CIDR: "${APISERVER_IP}/32",
						},
					},
				},
			},
			{
				Ports: []networkingv1.NetworkPolicyPort{
					{Protocol: &tcp, Port: &port443},
				},
				To: []networkingv1.NetworkPolicyPeer{
					{
						IPBlock: &networkingv1.IPBlock{
							CIDR: "${GOOGLEAPIS_CIDR}/32",
						},
					},
				},
			},
			{
				Ports: []networkingv1.NetworkPolicyPort{
					{Protocol: &tcp, Port: &port80},
				},
				To: []networkingv1.NetworkPolicyPeer{
					{
						IPBlock: &networkingv1.IPBlock{
							CIDR: "169.254.169.254/32",
						},
					},
				},
			},
			{
				Ports: []networkingv1.NetworkPolicyPort{
					{Protocol: &tcp, Port: &port988},
				},
				To: []networkingv1.NetworkPolicyPeer{
					{
						IPBlock: &networkingv1.IPBlock{
							CIDR: "127.0.0.1/32",
						},
					},
				},
			},
		},
		PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress},
	},
}
View Source
var AnthosAllowKubeDNSIngressNetworkPolicy = &networkingv1.NetworkPolicy{
	ObjectMeta: metav1.ObjectMeta{
		Name:      "allow-kube-dns-egress",
		Namespace: "kube-system",
	},
	Spec: networkingv1.NetworkPolicySpec{
		PodSelector: metav1.LabelSelector{
			MatchLabels: map[string]string{
				"k8s-app": "kube-dns",
			},
		},
		Ingress: []networkingv1.NetworkPolicyIngressRule{
			{
				Ports: []networkingv1.NetworkPolicyPort{
					{Protocol: &tcp, Port: &port53},
					{Protocol: &udp, Port: &port53},
				},
				From: []networkingv1.NetworkPolicyPeer{
					{
						PodSelector:       &metav1.LabelSelector{},
						NamespaceSelector: &metav1.LabelSelector{},
					},
				},
			},
		},
		PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeIngress},
	},
}

See: https://github.com/GoogleCloudPlatform/anthos-security-blueprints/blob/master/restricting-traffic/kube-system/allow-kubedns-egress.yaml

View Source
var DenyAll = &Policy{
	ObjectMeta: metav1.ObjectMeta{
		Name: "deny-all",
	},
	Spec: PolicySpec{
		Compatibility:  []networkingv1.PolicyType{networkingv1.PolicyTypeEgress, networkingv1.PolicyTypeIngress},
		TrafficMatcher: EverythingMatcher,
		Directive:      DirectiveDeny,
	},
}
View Source
var EverythingMatcher = &TrafficEdge{Type: TrafficMatchTypeAll}

EverythingMatcher matches everything

View Source
var NothingMatcher = &TrafficEdge{Type: TrafficMatchTypeAny}

NothingMatcher matches nothing

Functions

func BuildPortsFromSlice

func BuildPortsFromSlice(npPorts []networkingv1.NetworkPolicyPort) ([]*PortMatcher, []*ProtocolMatcher)

func BuildTrafficPeersFromEgress

func BuildTrafficPeersFromEgress(netpol *networkingv1.NetworkPolicy) ([]*TrafficEdge, Directive)

func BuildTrafficPeersFromIngress

func BuildTrafficPeersFromIngress(netpol *networkingv1.NetworkPolicy) ([]*TrafficEdge, Directive)

func Reduce

func Reduce(np *Policy) []*networkingv1.NetworkPolicy

func ReduceAll

func ReduceAll(np []*Policy) []*networkingv1.NetworkPolicy

func ReducePeerMatcher

func ReducePeerMatcher(peer *PeerMatcher) []networkingv1.NetworkPolicyPeer

func ReducePortProtocol

func ReducePortProtocol(portMatcher *PortMatcher, protocolMatcher *ProtocolMatcher) []networkingv1.NetworkPolicyPort

Types

type Blackduck

type Blackduck struct {
	Namespace string
	KBAddress string
}

func (*Blackduck) AllowBDNamespaceCommunication

func (bd *Blackduck) AllowBDNamespaceCommunication() *Policy

func (*Blackduck) AllowDNSOnTCP

func (bd *Blackduck) AllowDNSOnTCP() *Policy

func (*Blackduck) AllowEgressToKB

func (bd *Blackduck) AllowEgressToKB() *Policy

func (*Blackduck) DenyAll

func (bd *Blackduck) DenyAll() *Policy

type Directive

type Directive string
const (
	DirectiveAllow Directive = "Allow"
	DirectiveDeny  Directive = "Deny"
)

type IPMatcher

type IPMatcher struct {
	Value *string
	Block *networkingv1.IPBlock
}

IPMatcher matches an IP address using a cidr

func (*IPMatcher) Matches

func (ipm *IPMatcher) Matches(ip string) bool

type InternalPeer

type InternalPeer struct {
	PodLabels       map[string]string
	Pod             string
	NamespaceLabels map[string]string
	Namespace       string
	NodeLabels      map[string]string
	Node            string
}

type InternalPeerMatcher

type InternalPeerMatcher struct {
	Namespace       *StringMatcher
	NamespaceLabels *metav1.LabelSelector
	Node            *StringMatcher
	NodeLabels      *metav1.LabelSelector
	Pod             *StringMatcher
	PodLabels       *metav1.LabelSelector
}

func (*InternalPeerMatcher) Matches

func (ipm *InternalPeerMatcher) Matches(i *InternalPeer) bool

type NetpolServer

type NetpolServer struct {
	Name string
}

func (*NetpolServer) SimpleDaemonSet

func (ns *NetpolServer) SimpleDaemonSet() *appsv1.DaemonSet

func (*NetpolServer) SimpleService

func (ns *NetpolServer) SimpleService() *v1.Service

type Peer

type Peer struct {
	Internal *InternalPeer
	IP       string
}

func (*Peer) IsExternal

func (tc *Peer) IsExternal() bool

type PeerLocation

type PeerLocation string
var (
	PeerLocationInternal PeerLocation = "internal"
	PeerLocationExternal PeerLocation = "external"
)

type PeerMatcher

type PeerMatcher struct {
	IP               *IPMatcher
	RelativeLocation *PeerLocation
	Internal         *InternalPeerMatcher
}

func BuildSourceDest

func BuildSourceDest(policyNamespace string, peer networkingv1.NetworkPolicyPeer) *PeerMatcher

func BuildSourceDestsFromSlice

func BuildSourceDestsFromSlice(policyNamespace string, peers []networkingv1.NetworkPolicyPeer) []*PeerMatcher

func (*PeerMatcher) Matches

func (pm *PeerMatcher) Matches(p *Peer) bool

type Policies

type Policies struct {
	Policies []*Policy
}

func BuildNetworkPolicy

func BuildNetworkPolicy(policy *networkingv1.NetworkPolicy) *Policies

func BuildPolicies

func BuildPolicies(netpols []*networkingv1.NetworkPolicy) *Policies

func (*Policies) Allows

func (ps *Policies) Allows(t *Traffic) bool

Allows searches through policies for matches, from which it takes directives. Some corner cases: - no matches => allowed (traffic must be explicitly denied) - allows take precedence over denies (TODO maybe rules need precedence?)

type Policy

type Policy struct {
	metav1.ObjectMeta
	Spec PolicySpec
}

func AllowIngressToNamespace

func AllowIngressToNamespace(nsLabels map[string]string) *Policy

func BuildTarget

func BuildTarget(netpol *networkingv1.NetworkPolicy) []*Policy

func DenyEgressFromNamespace

func DenyEgressFromNamespace(ns string) *Policy

type PolicySpec

type PolicySpec struct {
	Compatibility  []networkingv1.PolicyType
	Priority       int
	TrafficMatcher *TrafficEdge
	Directive      Directive
}

func (*PolicySpec) Allows

func (ps *PolicySpec) Allows(tm *Traffic) (bool, Directive)

Allows returns: - false, "" if no match - true, Deny if matched and denies - true, Allow if matched and allowed

type PortMatcher

type PortMatcher struct {
	Range *struct {
		Low  int
		High int
	}
	Value *intstr.IntOrString
}

func NamedPortMatcher

func NamedPortMatcher(port string) *PortMatcher

func NumberedPortMatcher

func NumberedPortMatcher(port int) *PortMatcher

func (*PortMatcher) Matches

func (pm *PortMatcher) Matches(port intstr.IntOrString) bool

type ProtocolMatcher

type ProtocolMatcher struct {
	Values []v1.Protocol
}

func (*ProtocolMatcher) Matches

func (pm *ProtocolMatcher) Matches(protocol v1.Protocol) bool

type StringMatcher

type StringMatcher struct {
	Value string
}

func (*StringMatcher) Matches

func (sm *StringMatcher) Matches(v string) bool

type Traffic

type Traffic struct {
	Source      *Peer
	Destination *Peer

	Protocol v1.Protocol
	Port     intstr.IntOrString
}

type TrafficEdge

type TrafficEdge struct {
	Type     TrafficMatchType
	Source   *PeerMatcher
	Dest     *PeerMatcher
	Port     *PortMatcher
	Protocol *ProtocolMatcher
}

func BuildSourceDestAndPorts

func BuildSourceDestAndPorts(isIngress bool, targetPodSelector metav1.LabelSelector, policyNamespace string, npPorts []networkingv1.NetworkPolicyPort, peers []networkingv1.NetworkPolicyPeer) []*TrafficEdge

func (*TrafficEdge) Matches

func (m *TrafficEdge) Matches(t *Traffic) bool

type TrafficMatchType

type TrafficMatchType string
const (
	TrafficMatchTypeAll TrafficMatchType = "all"
	TrafficMatchTypeAny TrafficMatchType = "any"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL