mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-12-01 13:53:55 +00:00
498 lines
14 KiB
Go
498 lines
14 KiB
Go
/*
|
|
Copyright 2020 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package netpol
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"k8s.io/apimachinery/pkg/util/intstr"
|
|
|
|
v1 "k8s.io/api/core/v1"
|
|
networkingv1 "k8s.io/api/networking/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
)
|
|
|
|
// GetDenyIngress returns a default deny ingress policy.
|
|
func GetDenyIngress(name string) *networkingv1.NetworkPolicy {
|
|
return &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{},
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeIngress},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetDenyEgressForTarget returns a default deny egress policy.
|
|
func GetDenyEgressForTarget(name string, targetSelector metav1.LabelSelector) *networkingv1.NetworkPolicy {
|
|
return &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: targetSelector,
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress},
|
|
Egress: []networkingv1.NetworkPolicyEgressRule{},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetRandomIngressPolicies returns "num" random policies that allow a unique:n label, i.e.
|
|
// unique:1, unique:2, and so on. Used for creating a 'background' set of policies.
|
|
func GetRandomIngressPolicies(num int) []*networkingv1.NetworkPolicy {
|
|
policies := []*networkingv1.NetworkPolicy{}
|
|
|
|
for i := 0; i < num; i++ {
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: fmt.Sprintf("allow-all-%v", i),
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"unique": fmt.Sprintf("%v", i),
|
|
},
|
|
},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{{}},
|
|
},
|
|
}
|
|
policies = append(policies, policy)
|
|
}
|
|
return policies
|
|
}
|
|
|
|
// GetAllowIngress allows all ingress
|
|
func GetAllowIngress(name string) *networkingv1.NetworkPolicy {
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{},
|
|
},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{
|
|
{},
|
|
},
|
|
},
|
|
}
|
|
return policy
|
|
}
|
|
|
|
// GetAllowIngressByPort allows ingress by port
|
|
func GetAllowIngressByPort(name string, port *intstr.IntOrString) *networkingv1.NetworkPolicy {
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{},
|
|
},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{
|
|
{
|
|
Ports: []networkingv1.NetworkPolicyPort{
|
|
{Port: port},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
return policy
|
|
}
|
|
|
|
// GetAllowEgressByPort allows egress by port
|
|
func GetAllowEgressByPort(name string, port *intstr.IntOrString) *networkingv1.NetworkPolicy {
|
|
protocolUDP := v1.ProtocolUDP
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{},
|
|
},
|
|
Egress: []networkingv1.NetworkPolicyEgressRule{
|
|
{
|
|
Ports: []networkingv1.NetworkPolicyPort{
|
|
{Port: port},
|
|
{
|
|
Protocol: &protocolUDP,
|
|
Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress},
|
|
},
|
|
}
|
|
return policy
|
|
}
|
|
|
|
// GetDenyAll denies ingress traffic, AS WELL as egress traffic.
|
|
// - BOTH policy types must be specified
|
|
// - The Egress rule must (like the ingress default rule) be a array with 0 values.
|
|
func GetDenyAll(name string) *networkingv1.NetworkPolicy {
|
|
policy := GetDenyIngress(name)
|
|
policy.Spec.PolicyTypes = []networkingv1.PolicyType{networkingv1.PolicyTypeEgress, networkingv1.PolicyTypeIngress}
|
|
policy.Spec.Egress = []networkingv1.NetworkPolicyEgressRule{}
|
|
policy.Spec.Ingress = []networkingv1.NetworkPolicyIngressRule{}
|
|
return policy
|
|
}
|
|
|
|
// GetDenyAllWithEgressDNS deny all egress traffic, besides DNS/UDP port
|
|
func GetDenyAllWithEgressDNS() *networkingv1.NetworkPolicy {
|
|
protocolUDP := v1.ProtocolUDP
|
|
return &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deny-all-tcp-allow-dns",
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress, networkingv1.PolicyTypeIngress},
|
|
PodSelector: metav1.LabelSelector{},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{},
|
|
Egress: []networkingv1.NetworkPolicyEgressRule{
|
|
{
|
|
Ports: []networkingv1.NetworkPolicyPort{
|
|
{
|
|
Protocol: &protocolUDP,
|
|
Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetAllowIngressByPod allows ingress by pod labels
|
|
func GetAllowIngressByPod(name string, targetLabels map[string]string, peerPodSelector *metav1.LabelSelector) *networkingv1.NetworkPolicy {
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: targetLabels,
|
|
},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{{
|
|
From: []networkingv1.NetworkPolicyPeer{{
|
|
PodSelector: peerPodSelector,
|
|
}},
|
|
}},
|
|
},
|
|
}
|
|
return policy
|
|
}
|
|
|
|
// GetAllowIngressForTarget allows ingress for target
|
|
func GetAllowIngressForTarget(name string, targetLabels map[string]string) *networkingv1.NetworkPolicy {
|
|
return &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: targetLabels,
|
|
},
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeIngress},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{
|
|
{
|
|
From: []networkingv1.NetworkPolicyPeer{
|
|
{
|
|
PodSelector: &metav1.LabelSelector{},
|
|
NamespaceSelector: &metav1.LabelSelector{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetDenyIngressForTarget denies all ingress for target
|
|
func GetDenyIngressForTarget(targetSelector metav1.LabelSelector) *networkingv1.NetworkPolicy {
|
|
return &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deny-ingress-via-label-selector",
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: targetSelector,
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeIngress},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetAllowIngressByNamespace allows ingress for namespace
|
|
func GetAllowIngressByNamespace(name string, targetLabels map[string]string, peerNamespaceSelector *metav1.LabelSelector) *networkingv1.NetworkPolicy {
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: targetLabels,
|
|
},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{{
|
|
From: []networkingv1.NetworkPolicyPeer{{
|
|
NamespaceSelector: peerNamespaceSelector,
|
|
}},
|
|
}},
|
|
},
|
|
}
|
|
return policy
|
|
}
|
|
|
|
// GetAllowIngressByNamespaceAndPort allows ingress for namespace AND port AND protocol
|
|
func GetAllowIngressByNamespaceAndPort(name string, targetLabels map[string]string, peerNamespaceSelector *metav1.LabelSelector, port *intstr.IntOrString, protocol *v1.Protocol) *networkingv1.NetworkPolicy {
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: targetLabels,
|
|
},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{{
|
|
From: []networkingv1.NetworkPolicyPeer{{
|
|
NamespaceSelector: peerNamespaceSelector,
|
|
}},
|
|
Ports: []networkingv1.NetworkPolicyPort{
|
|
{
|
|
Port: port,
|
|
Protocol: protocol,
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
}
|
|
return policy
|
|
}
|
|
|
|
// GetAllowIngressByNamespaceOrPod allows ingress for pods with matching namespace OR pod labels
|
|
func GetAllowIngressByNamespaceOrPod(name string, targetLabels map[string]string, peerNamespaceSelector *metav1.LabelSelector, peerPodSelector *metav1.LabelSelector) *networkingv1.NetworkPolicy {
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: targetLabels,
|
|
},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{{
|
|
From: []networkingv1.NetworkPolicyPeer{
|
|
{
|
|
NamespaceSelector: peerNamespaceSelector,
|
|
},
|
|
{
|
|
PodSelector: peerPodSelector,
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
}
|
|
return policy
|
|
}
|
|
|
|
// GetAllowIngressByNamespaceAndPod allows ingress for pods with matching namespace AND pod labels
|
|
func GetAllowIngressByNamespaceAndPod(name string, targetLabels map[string]string, peerNamespaceSelector *metav1.LabelSelector, peerPodSelector *metav1.LabelSelector) *networkingv1.NetworkPolicy {
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: targetLabels,
|
|
},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{{
|
|
From: []networkingv1.NetworkPolicyPeer{{
|
|
NamespaceSelector: peerNamespaceSelector,
|
|
PodSelector: peerPodSelector,
|
|
}},
|
|
}},
|
|
},
|
|
}
|
|
return policy
|
|
}
|
|
|
|
// GetAllowEgressByNamespaceAndPod allows egress for pods with matching namespace AND pod labels
|
|
func GetAllowEgressByNamespaceAndPod(name string, targetLabels map[string]string, peerNamespaceSelector *metav1.LabelSelector, peerPodSelector *metav1.LabelSelector) *networkingv1.NetworkPolicy {
|
|
protocolUDP := v1.ProtocolUDP
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: targetLabels,
|
|
},
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress},
|
|
Egress: []networkingv1.NetworkPolicyEgressRule{
|
|
{
|
|
To: []networkingv1.NetworkPolicyPeer{
|
|
{
|
|
NamespaceSelector: peerNamespaceSelector,
|
|
PodSelector: peerPodSelector,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Ports: []networkingv1.NetworkPolicyPort{
|
|
{
|
|
Protocol: &protocolUDP,
|
|
Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
return policy
|
|
}
|
|
|
|
// GetAllowEgress allows all egress
|
|
func GetAllowEgress() *networkingv1.NetworkPolicy {
|
|
return &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "allow-egress",
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{},
|
|
},
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress},
|
|
Egress: []networkingv1.NetworkPolicyEgressRule{{}},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetAllowEgressForTarget allows all egress for a target
|
|
func GetAllowEgressForTarget(targetSelector metav1.LabelSelector) *networkingv1.NetworkPolicy {
|
|
return &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "allow-egress-for-target",
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: targetSelector,
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress},
|
|
Egress: []networkingv1.NetworkPolicyEgressRule{{}},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetAllowEgressByCIDR creates an egress netpol with an ipblock
|
|
func GetAllowEgressByCIDR(podname string, podserverCIDR string) *networkingv1.NetworkPolicy {
|
|
protocolUDP := v1.ProtocolUDP
|
|
return &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "allow-client-a-via-cidr-egress-rule",
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"pod": podname,
|
|
},
|
|
},
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress},
|
|
// Allow traffic to only one CIDR block.
|
|
Egress: []networkingv1.NetworkPolicyEgressRule{
|
|
{
|
|
To: []networkingv1.NetworkPolicyPeer{
|
|
{
|
|
IPBlock: &networkingv1.IPBlock{
|
|
CIDR: podserverCIDR,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Ports: []networkingv1.NetworkPolicyPort{
|
|
{
|
|
Protocol: &protocolUDP,
|
|
Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetAllowEgressByCIDRExcept creates an egress netpol with an ipblock and except
|
|
func GetAllowEgressByCIDRExcept(podname string, podserverCIDR string, except []string) *networkingv1.NetworkPolicy {
|
|
protocolUDP := v1.ProtocolUDP
|
|
return &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "allow-client-a-via-cidr-egress-rule",
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"pod": podname,
|
|
},
|
|
},
|
|
PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress},
|
|
// Allow traffic to only one CIDR block.
|
|
Egress: []networkingv1.NetworkPolicyEgressRule{
|
|
{
|
|
To: []networkingv1.NetworkPolicyPeer{
|
|
{
|
|
IPBlock: &networkingv1.IPBlock{
|
|
CIDR: podserverCIDR,
|
|
Except: except,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Ports: []networkingv1.NetworkPolicyPort{
|
|
{
|
|
Protocol: &protocolUDP,
|
|
Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GetAllowIngressOnProtocolByPort is a base network policy template which distinguishes between the types of v1.Protocol available in v1 core
|
|
func GetAllowIngressOnProtocolByPort(name string, protocol v1.Protocol, targetLabels map[string]string, portNum *intstr.IntOrString) *networkingv1.NetworkPolicy {
|
|
policy := &networkingv1.NetworkPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: name,
|
|
},
|
|
Spec: networkingv1.NetworkPolicySpec{
|
|
PodSelector: metav1.LabelSelector{
|
|
MatchLabels: targetLabels,
|
|
},
|
|
Ingress: []networkingv1.NetworkPolicyIngressRule{{
|
|
Ports: []networkingv1.NetworkPolicyPort{{
|
|
Port: portNum,
|
|
Protocol: &protocol,
|
|
}},
|
|
}},
|
|
},
|
|
}
|
|
return policy
|
|
}
|