From 0a700b63cd3bb721a8679212a406f168f89e89d2 Mon Sep 17 00:00:00 2001 From: Eswar Rajan Subramanian Date: Wed, 2 Nov 2022 16:49:34 +0530 Subject: [PATCH 1/8] K8s Net pol -- UDP handling Signed-off-by: Eswar Rajan Subramanian --- src/networkpolicy/deduplicator.go | 6 +- src/networkpolicy/helperFunctions.go | 4 +- src/networkpolicy/networkPolicy.go | 169 ++++++++++++++++++++++----- src/plugin/k8sNetwork.go | 80 +++++++++---- src/plugin/kubearmor.go | 24 +++- 5 files changed, 221 insertions(+), 62 deletions(-) diff --git a/src/networkpolicy/deduplicator.go b/src/networkpolicy/deduplicator.go index b45ebbb9..8535f63f 100644 --- a/src/networkpolicy/deduplicator.go +++ b/src/networkpolicy/deduplicator.go @@ -974,13 +974,15 @@ func UpdateDuplicatedPolicy(existingPolicies []types.KnoxNetworkPolicy, discover for _, policy := range existIngressPolicies { if policy.Metadata["status"] == "updated" { - delete(policy.Metadata, "status") + policy.Metadata["status"] = "latest" + //delete(policy.Metadata, "status") updatedPolicies = append(updatedPolicies, policy) } } for _, policy := range existEgressPolicies { if policy.Metadata["status"] == "updated" { - delete(policy.Metadata, "status") + policy.Metadata["status"] = "latest" + //delete(policy.Metadata, "status") updatedPolicies = append(updatedPolicies, policy) } } diff --git a/src/networkpolicy/helperFunctions.go b/src/networkpolicy/helperFunctions.go index 9675d6df..54aaee4a 100644 --- a/src/networkpolicy/helperFunctions.go +++ b/src/networkpolicy/helperFunctions.go @@ -13,6 +13,7 @@ import ( "github.com/clarketm/json" "github.com/accuknox/auto-policy-discovery/src/cluster" + "github.com/accuknox/auto-policy-discovery/src/config" "github.com/accuknox/auto-policy-discovery/src/libs" "github.com/accuknox/auto-policy-discovery/src/plugin" wpb "github.com/accuknox/auto-policy-discovery/src/protobuf/v1/worker" @@ -797,7 +798,8 @@ func GetNetPolicy(cluster, namespace, policyType string) *wpb.WorkerResponse { } response.K8SNetworkpolicy = nil } else if strings.Contains(policyType, "generic") { - policies := plugin.ConvertKnoxNetPolicyToK8sNetworkPolicy(cluster, namespace) + knoxNetPolicies := libs.GetNetworkPolicies(config.CurrentCfg.ConfigDB, cluster, namespace, "latest", "", "") + policies := plugin.ConvertKnoxNetPolicyToK8sNetworkPolicy(cluster, namespace, knoxNetPolicies) for i := range policies { genericNetPol := wpb.Policy{} diff --git a/src/networkpolicy/networkPolicy.go b/src/networkpolicy/networkPolicy.go index ecadfba7..9d7afa6a 100644 --- a/src/networkpolicy/networkPolicy.go +++ b/src/networkpolicy/networkPolicy.go @@ -1598,13 +1598,31 @@ func mergeIngressPolicies(existPolicy types.KnoxNetworkPolicy, policies []types. } } } + } else if len(newIngress.FromCIDRs) > 0 && len(newIngress.ToPorts) > 0 { + newCIDR := newIngress.FromCIDRs[0].CIDRs[0] + newToPort := newIngress.ToPorts[0] + + for _, existIngress := range mergedPolicy.Spec.Ingress { + if len(existIngress.FromCIDRs) == 0 || len(existIngress.ToPorts) == 0 { + continue + } + existCIDR := existIngress.FromCIDRs[0].CIDRs[0] + existToPort := existIngress.ToPorts[0] + + if existCIDR == newCIDR && existToPort == newToPort { + ingressMatched = true + break + } + } } + if !ingressMatched { mergedPolicy.Spec.Ingress = append(mergedPolicy.Spec.Ingress, newIngress) updated = true } } } + return mergedPolicy, updated } @@ -1668,7 +1686,24 @@ func mergeEgressPolicies(existPolicy types.KnoxNetworkPolicy, policies []types.K } } } + } else if len(newEgress.ToCIDRs) > 0 && len(newEgress.ToPorts) > 0 { + newCIDR := newEgress.ToCIDRs[0].CIDRs[0] + newToPort := newEgress.ToPorts[0] + + for _, existEgress := range mergedPolicy.Spec.Egress { + if len(existEgress.ToCIDRs) == 0 || len(existEgress.ToPorts) == 0 { + continue + } + existCIDR := existEgress.ToCIDRs[0].CIDRs[0] + existToPort := existEgress.ToPorts[0] + + if existCIDR == newCIDR && existToPort == newToPort { + egressMatched = true + break + } + } } + if !egressMatched { mergedPolicy.Spec.Egress = append(mergedPolicy.Spec.Egress, newEgress) updated = true @@ -1858,6 +1893,49 @@ func convertKnoxNetworkLogToKnoxNetworkPolicy(log *types.KnoxNetworkLog, pods [] ePolicy.Metadata["namespace"] = log.SrcNamespace egressPolicy = &ePolicy } + } else if log.DstPodName == "" && len(log.DstReservedLabels) == 0 && log.Direction == "EGRESS" { + // Egress Policy + ePolicy := buildNewKnoxEgressPolicy() + egress := types.Egress{} + + ePolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) + + var cidrs []string + cidrs = append(cidrs, "0.0.0.0/32") + + egress.ToCIDRs = append(egress.ToCIDRs, types.SpecCIDR{ + CIDRs: cidrs, + }) + + egress.ToPorts = append(egress.ToPorts, types.SpecPort{ + Port: strconv.Itoa(log.DstPort), + Protocol: libs.GetProtocol(log.Protocol), + }) + + ePolicy.Spec.Egress = append(ePolicy.Spec.Egress, egress) + ePolicy.Metadata["namespace"] = log.SrcNamespace + egressPolicy = &ePolicy + } else if log.DstPodName == "" && len(log.DstReservedLabels) == 0 && log.Direction == "INGRESS" { + iPolicy := buildNewKnoxIngressPolicy() + ingress := types.Ingress{} + + iPolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) + + var cidrs []string + cidrs = append(cidrs, "0.0.0.0/32") + + ingress.FromCIDRs = append(ingress.FromCIDRs, types.SpecCIDR{ + CIDRs: cidrs, + }) + + ingress.ToPorts = append(ingress.ToPorts, types.SpecPort{ + Port: strconv.Itoa(log.DstPort), + Protocol: libs.GetProtocol(log.Protocol), + }) + + iPolicy.Spec.Ingress = append(iPolicy.Spec.Ingress, ingress) + iPolicy.Metadata["namespace"] = log.SrcNamespace + ingressPolicy = &iPolicy } if !isValidPolicy(ingressPolicy) { @@ -2134,47 +2212,78 @@ func PopulateNetworkPoliciesFromNetworkLogs(networkLogs []types.KnoxNetworkLog) func writeNetworkPoliciesYamlToDB(policies []types.KnoxNetworkPolicy) { clusters := []string{} + res := []types.PolicyYaml{} for _, pol := range policies { clusters = append(clusters, pol.Metadata["cluster_name"]) } - // convert knoxPolicy to CiliumPolicy - ciliumPolicies := plugin.ConvertKnoxPoliciesToCiliumPolicies(policies) + if cfg.CurrentCfg.ConfigNetPolicy.NetworkLogFrom == "kubearmor" { + k8sNetPolicies := plugin.ConvertKnoxNetPolicyToK8sNetworkPolicy("", "", policies) - res := []types.PolicyYaml{} + for i, np := range k8sNetPolicies { + jsonBytes, err := json.Marshal(np) + if err != nil { + log.Error().Msg(err.Error()) + continue + } + yamlBytes, err := yaml.JSONToYAML(jsonBytes) + if err != nil { + log.Error().Msg(err.Error()) + continue + } - for i, ciliumPolicy := range ciliumPolicies { - jsonBytes, err := json.Marshal(ciliumPolicy) - if err != nil { - log.Error().Msg(err.Error()) - continue - } - yamlBytes, err := yaml.JSONToYAML(jsonBytes) - if err != nil { - log.Error().Msg(err.Error()) - continue - } + policyYaml := types.PolicyYaml{ + Type: types.PolicyTypeNetwork, + Kind: np.Kind, + Name: np.Name, + Namespace: np.Namespace, + Cluster: clusters[i], + Labels: np.Labels, + Yaml: yamlBytes, + } + res = append(res, policyYaml) - var labels types.LabelMap - if ciliumPolicy.Kind == cu.ResourceTypeCiliumNetworkPolicy { - labels = ciliumPolicy.Spec.EndpointSelector.MatchLabels - } else { - labels = ciliumPolicy.Spec.NodeSelector.MatchLabels + PolicyStore.Publish(&policyYaml) } - policyYaml := types.PolicyYaml{ - Type: types.PolicyTypeNetwork, - Kind: ciliumPolicy.Kind, - Name: ciliumPolicy.Metadata["name"], - Namespace: ciliumPolicy.Metadata["namespace"], - Cluster: clusters[i], - Labels: labels, - Yaml: yamlBytes, - } - res = append(res, policyYaml) + } else { - PolicyStore.Publish(&policyYaml) + // convert knoxPolicy to CiliumPolicy + ciliumPolicies := plugin.ConvertKnoxPoliciesToCiliumPolicies(policies) + + for i, ciliumPolicy := range ciliumPolicies { + jsonBytes, err := json.Marshal(ciliumPolicy) + if err != nil { + log.Error().Msg(err.Error()) + continue + } + yamlBytes, err := yaml.JSONToYAML(jsonBytes) + if err != nil { + log.Error().Msg(err.Error()) + continue + } + + var labels types.LabelMap + if ciliumPolicy.Kind == cu.ResourceTypeCiliumNetworkPolicy { + labels = ciliumPolicy.Spec.EndpointSelector.MatchLabels + } else { + labels = ciliumPolicy.Spec.NodeSelector.MatchLabels + } + + policyYaml := types.PolicyYaml{ + Type: types.PolicyTypeNetwork, + Kind: ciliumPolicy.Kind, + Name: ciliumPolicy.Metadata["name"], + Namespace: ciliumPolicy.Metadata["namespace"], + Cluster: clusters[i], + Labels: labels, + Yaml: yamlBytes, + } + res = append(res, policyYaml) + + PolicyStore.Publish(&policyYaml) + } } if err := libs.UpdateOrInsertPolicyYamls(CfgDB, res); err != nil { diff --git a/src/plugin/k8sNetwork.go b/src/plugin/k8sNetwork.go index ffb629e6..0e0422a6 100644 --- a/src/plugin/k8sNetwork.go +++ b/src/plugin/k8sNetwork.go @@ -3,8 +3,6 @@ package plugin import ( "strconv" - "github.com/accuknox/auto-policy-discovery/src/config" - "github.com/accuknox/auto-policy-discovery/src/libs" "github.com/accuknox/auto-policy-discovery/src/types" v1 "k8s.io/api/core/v1" nv1 "k8s.io/api/networking/v1" @@ -12,9 +10,8 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) -func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string) []nv1.NetworkPolicy { +func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string, knoxNetPolicies []types.KnoxNetworkPolicy) []nv1.NetworkPolicy { - knoxNetPolicies := libs.GetNetworkPolicies(config.CurrentCfg.ConfigDB, clustername, namespace, "latest", "", "") log.Info().Msgf("No. of knox network policies - %d", len(knoxNetPolicies)) if len(knoxNetPolicies) <= 0 { @@ -31,11 +28,14 @@ func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string) []nv1 k8NetPol.Name = knp.Metadata["name"] k8NetPol.Namespace = knp.Metadata["namespace"] k8NetPol.ClusterName = knp.Metadata["cluster_name"] + k8NetPol.Labels = knp.Spec.Selector.MatchLabels if len(knp.Spec.Egress) > 0 { for _, eg := range knp.Spec.Egress { var egressRule nv1.NetworkPolicyEgressRule + port := nv1.NetworkPolicyPort{} + to := nv1.NetworkPolicyPeer{} var protocol v1.Protocol if eg.ToPorts[0].Protocol == string(v1.ProtocolTCP) { @@ -43,20 +43,35 @@ func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string) []nv1 } else if eg.ToPorts[0].Protocol == string(v1.ProtocolUDP) { protocol = v1.ProtocolUDP } + portVal, _ := strconv.ParseInt(eg.ToPorts[0].Port, 10, 32) - port := nv1.NetworkPolicyPort{ - Port: &intstr.IntOrString{ - Type: intstr.Int, - IntVal: int32(portVal), - }, - Protocol: &protocol, + if portVal != 0 { + port = nv1.NetworkPolicyPort{ + Port: &intstr.IntOrString{ + Type: intstr.Int, + IntVal: int32(portVal), + }, + Protocol: &protocol, + } + } else { + port = nv1.NetworkPolicyPort{ + Protocol: &protocol, + } } - to := nv1.NetworkPolicyPeer{ - PodSelector: &metav1.LabelSelector{ - MatchLabels: eg.MatchLabels, - }, + if len(eg.ToCIDRs) == 0 { + to = nv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: eg.MatchLabels, + }, + } + } else { + to = nv1.NetworkPolicyPeer{ + IPBlock: &nv1.IPBlock{ + CIDR: eg.ToCIDRs[0].CIDRs[0], + }, + } } egressRule.Ports = append(egressRule.Ports, port) @@ -71,27 +86,44 @@ func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string) []nv1 if len(knp.Spec.Ingress) > 0 { for _, ing := range knp.Spec.Ingress { var ingressRule nv1.NetworkPolicyIngressRule + port := nv1.NetworkPolicyPort{} var protocol v1.Protocol + from := nv1.NetworkPolicyPeer{} if ing.ToPorts[0].Protocol == string(v1.ProtocolTCP) { protocol = v1.ProtocolTCP } else if ing.ToPorts[0].Protocol == string(v1.ProtocolUDP) { protocol = v1.ProtocolUDP } + portVal, _ := strconv.ParseInt(ing.ToPorts[0].Port, 10, 32) - port := nv1.NetworkPolicyPort{ - Port: &intstr.IntOrString{ - Type: intstr.Int, - IntVal: int32(portVal), - }, - Protocol: &protocol, + if portVal != 0 { + port = nv1.NetworkPolicyPort{ + Port: &intstr.IntOrString{ + Type: intstr.Int, + IntVal: int32(portVal), + }, + Protocol: &protocol, + } + } else { + port = nv1.NetworkPolicyPort{ + Protocol: &protocol, + } } - from := nv1.NetworkPolicyPeer{ - PodSelector: &metav1.LabelSelector{ - MatchLabels: ing.MatchLabels, - }, + if len(ing.FromCIDRs) == 0 { + from = nv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: ing.MatchLabels, + }, + } + } else { + from = nv1.NetworkPolicyPeer{ + IPBlock: &nv1.IPBlock{ + CIDR: ing.FromCIDRs[0].CIDRs[0], + }, + } } ingressRule.Ports = append(ingressRule.Ports, port) diff --git a/src/plugin/kubearmor.go b/src/plugin/kubearmor.go index 1f12a9eb..dc408ca1 100644 --- a/src/plugin/kubearmor.go +++ b/src/plugin/kubearmor.go @@ -431,7 +431,7 @@ func StartKubeArmorRelay(StopChan chan struct{}, cfg types.ConfigKubeArmorRelay) } if config.CurrentCfg.ConfigNetPolicy.NetworkLogFrom == "kubearmor" { - if res.Operation == "Network" && strings.Contains(res.Data, "tcp_") { + if res.Operation == "Network" { KubeArmorNetworkLogs = append(KubeArmorNetworkLogs, res) } } @@ -494,8 +494,7 @@ func StartKubeArmorRelay(StopChan chan struct{}, cfg types.ConfigKubeArmorRelay) } if config.CurrentCfg.ConfigNetPolicy.NetworkLogFrom == "kubearmor" { - if log.Operation == "Network" && (strings.Contains(log.Data, "tcp_") || - strings.Contains(log.Resource, "UDP")) { + if log.Operation == "Network" { KubeArmorNetworkLogs = append(KubeArmorNetworkLogs, &log) } } @@ -575,7 +574,7 @@ func ConvertKubeArmorNetLogToKnoxNetLog(kaNwLogs []*pb.Log) []types.KnoxNetworkL } } - if ip == "127.0.0.1" { + if net.ParseIP(ip).IsLoopback() { // ignore adding policies with pod IP pointing to localhost continue } @@ -590,8 +589,23 @@ func ConvertKubeArmorNetLogToKnoxNetLog(kaNwLogs []*pb.Log) []types.KnoxNetworkL locKnoxLog.DstIP = ip locKnoxLog.DstPort, _ = strconv.Atoi(port) locKnoxLog.SynFlag = true - } else { + } else if strings.Contains(kalog.Data, "SYS_BIND") { + var port string + locKnoxLog.Protocol = libs.IPProtocolUDP + + resSlice := strings.Split(kalog.Resource, " ") + for _, v := range resSlice { + if strings.Contains(v, "sin_port") { + port = strings.Split(v, "=")[1] + } + } + //locKnoxLog.DstIP = "0.0.0.0" + locKnoxLog.DstPort, _ = strconv.Atoi(port) + locKnoxLog.Direction = "INGRESS" + } else if strings.Contains(kalog.Data, "SYS_SOCKET") && strings.Contains(kalog.Resource, "SOCK_DGRAM") { locKnoxLog.Protocol = libs.IPProtocolUDP + //locKnoxLog.DstIP = "0.0.0.0" + locKnoxLog.Direction = "EGRESS" } if kalog.Result != "Passed" { From 521988fe5cd0a369d4d0dead151435ff105e0e7a Mon Sep 17 00:00:00 2001 From: Eswar Rajan Subramanian Date: Wed, 2 Nov 2022 19:01:22 +0530 Subject: [PATCH 2/8] k8s_net_policy -- CIDR/PodSelector based rules Signed-off-by: Eswar Rajan Subramanian --- src/networkpolicy/networkPolicy.go | 1 + src/plugin/k8sNetwork.go | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/networkpolicy/networkPolicy.go b/src/networkpolicy/networkPolicy.go index 9d7afa6a..3c0f3dea 100644 --- a/src/networkpolicy/networkPolicy.go +++ b/src/networkpolicy/networkPolicy.go @@ -2222,6 +2222,7 @@ func writeNetworkPoliciesYamlToDB(policies []types.KnoxNetworkPolicy) { k8sNetPolicies := plugin.ConvertKnoxNetPolicyToK8sNetworkPolicy("", "", policies) for i, np := range k8sNetPolicies { + np.ClusterName = "" jsonBytes, err := json.Marshal(np) if err != nil { log.Error().Msg(err.Error()) diff --git a/src/plugin/k8sNetwork.go b/src/plugin/k8sNetwork.go index 0e0422a6..78580b6b 100644 --- a/src/plugin/k8sNetwork.go +++ b/src/plugin/k8sNetwork.go @@ -60,16 +60,18 @@ func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string, knoxN } } - if len(eg.ToCIDRs) == 0 { + if len(eg.ToCIDRs) > 0 { to = nv1.NetworkPolicyPeer{ - PodSelector: &metav1.LabelSelector{ - MatchLabels: eg.MatchLabels, + IPBlock: &nv1.IPBlock{ + CIDR: eg.ToCIDRs[0].CIDRs[0], }, } - } else { + } + + if len(eg.MatchLabels) > 0 { to = nv1.NetworkPolicyPeer{ - IPBlock: &nv1.IPBlock{ - CIDR: eg.ToCIDRs[0].CIDRs[0], + PodSelector: &metav1.LabelSelector{ + MatchLabels: eg.MatchLabels, }, } } @@ -112,16 +114,18 @@ func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string, knoxN } } - if len(ing.FromCIDRs) == 0 { + if len(ing.FromCIDRs) > 0 { from = nv1.NetworkPolicyPeer{ - PodSelector: &metav1.LabelSelector{ - MatchLabels: ing.MatchLabels, + IPBlock: &nv1.IPBlock{ + CIDR: ing.FromCIDRs[0].CIDRs[0], }, } - } else { + } + + if len(ing.MatchLabels) > 0 { from = nv1.NetworkPolicyPeer{ - IPBlock: &nv1.IPBlock{ - CIDR: ing.FromCIDRs[0].CIDRs[0], + PodSelector: &metav1.LabelSelector{ + MatchLabels: ing.MatchLabels, }, } } From a9a3882d40bfe740b14c1b1eda33822a633e0e45 Mon Sep 17 00:00:00 2001 From: Eswar Rajan Subramanian Date: Thu, 3 Nov 2022 11:30:33 +0530 Subject: [PATCH 3/8] Changing nw policy src to hubble Signed-off-by: Eswar Rajan Subramanian --- src/conf/local-file.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/conf/local-file.yaml b/src/conf/local-file.yaml index 103e102f..04d7bf95 100644 --- a/src/conf/local-file.yaml +++ b/src/conf/local-file.yaml @@ -2,10 +2,10 @@ application: name: knoxautopolicy network: operation-mode: 1 # 1: cronjob | 2: one-time-job - operation-trigger: 5 + operation-trigger: 100 cron-job-time-interval: "0h0m10s" # format: XhYmZs network-log-limit: 10000 - network-log-from: "kubearmor" # db|hubble|feed-consumer|kubearmor + network-log-from: "hubble" # db|hubble|feed-consumer|kubearmor #network-log-file: "/home/rahul/feeds.json" # file path network-policy-to: "db" # db, file network-policy-dir: "./" From d25bafdaff190cca22ae70176b5f51bb27dd9948 Mon Sep 17 00:00:00 2001 From: Eswar Rajan Subramanian Date: Tue, 8 Nov 2022 23:40:49 +0530 Subject: [PATCH 4/8] Not required to add CIDR IP/PATH. Add only port/protocol Signed-off-by: Eswar Rajan Subramanian --- src/plugin/k8sNetwork.go | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/src/plugin/k8sNetwork.go b/src/plugin/k8sNetwork.go index 78580b6b..c7cd00d7 100644 --- a/src/plugin/k8sNetwork.go +++ b/src/plugin/k8sNetwork.go @@ -31,7 +31,6 @@ func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string, knoxN k8NetPol.Labels = knp.Spec.Selector.MatchLabels if len(knp.Spec.Egress) > 0 { - for _, eg := range knp.Spec.Egress { var egressRule nv1.NetworkPolicyEgressRule port := nv1.NetworkPolicyPort{} @@ -60,24 +59,18 @@ func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string, knoxN } } - if len(eg.ToCIDRs) > 0 { - to = nv1.NetworkPolicyPeer{ - IPBlock: &nv1.IPBlock{ - CIDR: eg.ToCIDRs[0].CIDRs[0], - }, - } - } - if len(eg.MatchLabels) > 0 { to = nv1.NetworkPolicyPeer{ PodSelector: &metav1.LabelSelector{ MatchLabels: eg.MatchLabels, }, } + egressRule.To = append(egressRule.To, to) + } else { + egressRule.To = nil } egressRule.Ports = append(egressRule.Ports, port) - egressRule.To = append(egressRule.To, to) k8NetPol.Spec.Egress = append(k8NetPol.Spec.Egress, egressRule) } @@ -114,30 +107,25 @@ func ConvertKnoxNetPolicyToK8sNetworkPolicy(clustername, namespace string, knoxN } } - if len(ing.FromCIDRs) > 0 { - from = nv1.NetworkPolicyPeer{ - IPBlock: &nv1.IPBlock{ - CIDR: ing.FromCIDRs[0].CIDRs[0], - }, - } - } - if len(ing.MatchLabels) > 0 { from = nv1.NetworkPolicyPeer{ PodSelector: &metav1.LabelSelector{ MatchLabels: ing.MatchLabels, }, } + ingressRule.From = append(ingressRule.From, from) + } else { + ingressRule.From = nil } ingressRule.Ports = append(ingressRule.Ports, port) - ingressRule.From = append(ingressRule.From, from) k8NetPol.Spec.Ingress = append(k8NetPol.Spec.Ingress, ingressRule) } k8NetPol.Spec.PolicyTypes = append(k8NetPol.Spec.PolicyTypes, nv1.PolicyType(nv1.PolicyTypeIngress)) } + k8NetPol.Spec.PodSelector.MatchLabels = k8NetPol.Labels res = append(res, k8NetPol) } From aeeb54bf9fee8a17bf92fde27714f2b87006bc58 Mon Sep 17 00:00:00 2001 From: Eswar Rajan Subramanian Date: Wed, 9 Nov 2022 14:36:16 +0530 Subject: [PATCH 5/8] Handling review comments Signed-off-by: Eswar Rajan Subramanian --- src/networkpolicy/networkPolicy.go | 98 +++++++++++++++++------------- 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/src/networkpolicy/networkPolicy.go b/src/networkpolicy/networkPolicy.go index 3c0f3dea..d986a566 100644 --- a/src/networkpolicy/networkPolicy.go +++ b/src/networkpolicy/networkPolicy.go @@ -1761,6 +1761,54 @@ func mergeHttpRules(existRule types.L47Rule, newRule types.L47Rule) (bool, bool, return false, false, nil } +func popultaeIngressEgressPolicyFromKnoxNetLog(log *types.KnoxNetworkLog, pods []types.Pod) types.KnoxNetworkPolicy { + iePolicy := types.KnoxNetworkPolicy{} + + if log.Direction == "EGRESS" { + iePolicy = buildNewKnoxEgressPolicy() + egress := types.Egress{} + + iePolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) + + var cidrs []string + cidrs = append(cidrs, "0.0.0.0/32") + + egress.ToCIDRs = append(egress.ToCIDRs, types.SpecCIDR{ + CIDRs: cidrs, + }) + + egress.ToPorts = append(egress.ToPorts, types.SpecPort{ + Port: strconv.Itoa(log.DstPort), + Protocol: libs.GetProtocol(log.Protocol), + }) + + iePolicy.Spec.Egress = append(iePolicy.Spec.Egress, egress) + iePolicy.Metadata["namespace"] = log.SrcNamespace + } else if log.Direction == "INGRESS" { + iePolicy = buildNewKnoxIngressPolicy() + ingress := types.Ingress{} + + iePolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) + + var cidrs []string + cidrs = append(cidrs, "0.0.0.0/32") + + ingress.FromCIDRs = append(ingress.FromCIDRs, types.SpecCIDR{ + CIDRs: cidrs, + }) + + ingress.ToPorts = append(ingress.ToPorts, types.SpecPort{ + Port: strconv.Itoa(log.DstPort), + Protocol: libs.GetProtocol(log.Protocol), + }) + + iePolicy.Spec.Ingress = append(iePolicy.Spec.Ingress, ingress) + iePolicy.Metadata["namespace"] = log.SrcNamespace + } + + return iePolicy +} + func convertKnoxNetworkLogToKnoxNetworkPolicy(log *types.KnoxNetworkLog, pods []types.Pod) (_, _ *types.KnoxNetworkPolicy) { var ingressPolicy, egressPolicy *types.KnoxNetworkPolicy = nil, nil @@ -1893,49 +1941,13 @@ func convertKnoxNetworkLogToKnoxNetworkPolicy(log *types.KnoxNetworkLog, pods [] ePolicy.Metadata["namespace"] = log.SrcNamespace egressPolicy = &ePolicy } - } else if log.DstPodName == "" && len(log.DstReservedLabels) == 0 && log.Direction == "EGRESS" { - // Egress Policy - ePolicy := buildNewKnoxEgressPolicy() - egress := types.Egress{} - - ePolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) - - var cidrs []string - cidrs = append(cidrs, "0.0.0.0/32") - - egress.ToCIDRs = append(egress.ToCIDRs, types.SpecCIDR{ - CIDRs: cidrs, - }) - - egress.ToPorts = append(egress.ToPorts, types.SpecPort{ - Port: strconv.Itoa(log.DstPort), - Protocol: libs.GetProtocol(log.Protocol), - }) - - ePolicy.Spec.Egress = append(ePolicy.Spec.Egress, egress) - ePolicy.Metadata["namespace"] = log.SrcNamespace - egressPolicy = &ePolicy - } else if log.DstPodName == "" && len(log.DstReservedLabels) == 0 && log.Direction == "INGRESS" { - iPolicy := buildNewKnoxIngressPolicy() - ingress := types.Ingress{} - - iPolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) - - var cidrs []string - cidrs = append(cidrs, "0.0.0.0/32") - - ingress.FromCIDRs = append(ingress.FromCIDRs, types.SpecCIDR{ - CIDRs: cidrs, - }) - - ingress.ToPorts = append(ingress.ToPorts, types.SpecPort{ - Port: strconv.Itoa(log.DstPort), - Protocol: libs.GetProtocol(log.Protocol), - }) - - iPolicy.Spec.Ingress = append(iPolicy.Spec.Ingress, ingress) - iPolicy.Metadata["namespace"] = log.SrcNamespace - ingressPolicy = &iPolicy + } else if log.DstPodName == "" && len(log.DstReservedLabels) == 0 { + iePolicy := popultaeIngressEgressPolicyFromKnoxNetLog(log, pods) + if log.Direction == "EGRESS" { + egressPolicy = &iePolicy + } else if log.Direction == "INGRESS" { + ingressPolicy = &iePolicy + } } if !isValidPolicy(ingressPolicy) { From ab7865cda37f8ade55b88f307bda8448237cf37b Mon Sep 17 00:00:00 2001 From: Eswar Rajan Subramanian Date: Thu, 10 Nov 2022 09:43:52 +0530 Subject: [PATCH 6/8] Removing reduntant code Signed-off-by: Eswar Rajan Subramanian --- src/networkpolicy/networkPolicy.go | 113 ++++++++++++++--------------- 1 file changed, 55 insertions(+), 58 deletions(-) diff --git a/src/networkpolicy/networkPolicy.go b/src/networkpolicy/networkPolicy.go index d986a566..ae7d84b0 100644 --- a/src/networkpolicy/networkPolicy.go +++ b/src/networkpolicy/networkPolicy.go @@ -1554,6 +1554,38 @@ func mergeNetworkPolicies(existPolicy types.KnoxNetworkPolicy, policies []types. return mergeEgressPolicies(existPolicy, policies) } +func checkIfIngressEgressPortExist(polType string, newToPort types.SpecPort, mergedPolicy types.KnoxNetworkPolicy) bool { + isExist := false + + if polType == "EGRESS" { + for _, existEgress := range mergedPolicy.Spec.Egress { + if len(existEgress.ToPorts) == 0 { + continue + } + existToPort := existEgress.ToPorts[0] + + if existToPort == newToPort { + isExist = true + break + } + } + } else if polType == "INGRESS" { + for _, existIngress := range mergedPolicy.Spec.Ingress { + if len(existIngress.ToPorts) == 0 { + continue + } + existToPort := existIngress.ToPorts[0] + + if existToPort == newToPort { + isExist = true + break + } + } + } + + return isExist +} + func mergeIngressPolicies(existPolicy types.KnoxNetworkPolicy, policies []types.KnoxNetworkPolicy) (types.KnoxNetworkPolicy, bool) { mergedPolicy := existPolicy updated := false @@ -1599,21 +1631,8 @@ func mergeIngressPolicies(existPolicy types.KnoxNetworkPolicy, policies []types. } } } else if len(newIngress.FromCIDRs) > 0 && len(newIngress.ToPorts) > 0 { - newCIDR := newIngress.FromCIDRs[0].CIDRs[0] newToPort := newIngress.ToPorts[0] - - for _, existIngress := range mergedPolicy.Spec.Ingress { - if len(existIngress.FromCIDRs) == 0 || len(existIngress.ToPorts) == 0 { - continue - } - existCIDR := existIngress.FromCIDRs[0].CIDRs[0] - existToPort := existIngress.ToPorts[0] - - if existCIDR == newCIDR && existToPort == newToPort { - ingressMatched = true - break - } - } + ingressMatched = checkIfIngressEgressPortExist("INGRESS", newToPort, mergedPolicy) } if !ingressMatched { @@ -1687,21 +1706,8 @@ func mergeEgressPolicies(existPolicy types.KnoxNetworkPolicy, policies []types.K } } } else if len(newEgress.ToCIDRs) > 0 && len(newEgress.ToPorts) > 0 { - newCIDR := newEgress.ToCIDRs[0].CIDRs[0] newToPort := newEgress.ToPorts[0] - - for _, existEgress := range mergedPolicy.Spec.Egress { - if len(existEgress.ToCIDRs) == 0 || len(existEgress.ToPorts) == 0 { - continue - } - existCIDR := existEgress.ToCIDRs[0].CIDRs[0] - existToPort := existEgress.ToPorts[0] - - if existCIDR == newCIDR && existToPort == newToPort { - egressMatched = true - break - } - } + egressMatched = checkIfIngressEgressPortExist("EGRESS", newToPort, mergedPolicy) } if !egressMatched { @@ -1761,51 +1767,42 @@ func mergeHttpRules(existRule types.L47Rule, newRule types.L47Rule) (bool, bool, return false, false, nil } -func popultaeIngressEgressPolicyFromKnoxNetLog(log *types.KnoxNetworkLog, pods []types.Pod) types.KnoxNetworkPolicy { +func populateIngressEgressPolicyFromKnoxNetLog(log *types.KnoxNetworkLog, pods []types.Pod) types.KnoxNetworkPolicy { iePolicy := types.KnoxNetworkPolicy{} + var cidrs []string + cidrs = append(cidrs, "0.0.0.0/32") + + specVal := types.SpecCIDR{ + CIDRs: cidrs, + } + + portVal := types.SpecPort{ + Port: strconv.Itoa(log.DstPort), + Protocol: libs.GetProtocol(log.Protocol), + } if log.Direction == "EGRESS" { iePolicy = buildNewKnoxEgressPolicy() egress := types.Egress{} - iePolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) - - var cidrs []string - cidrs = append(cidrs, "0.0.0.0/32") - - egress.ToCIDRs = append(egress.ToCIDRs, types.SpecCIDR{ - CIDRs: cidrs, - }) - - egress.ToPorts = append(egress.ToPorts, types.SpecPort{ - Port: strconv.Itoa(log.DstPort), - Protocol: libs.GetProtocol(log.Protocol), - }) + egress.ToPorts = append(egress.ToPorts, portVal) + egress.ToCIDRs = append(egress.ToCIDRs, specVal) iePolicy.Spec.Egress = append(iePolicy.Spec.Egress, egress) - iePolicy.Metadata["namespace"] = log.SrcNamespace + } else if log.Direction == "INGRESS" { iePolicy = buildNewKnoxIngressPolicy() ingress := types.Ingress{} - iePolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) - - var cidrs []string - cidrs = append(cidrs, "0.0.0.0/32") - - ingress.FromCIDRs = append(ingress.FromCIDRs, types.SpecCIDR{ - CIDRs: cidrs, - }) - - ingress.ToPorts = append(ingress.ToPorts, types.SpecPort{ - Port: strconv.Itoa(log.DstPort), - Protocol: libs.GetProtocol(log.Protocol), - }) + ingress.ToPorts = append(ingress.ToPorts, portVal) + ingress.FromCIDRs = append(ingress.FromCIDRs, specVal) iePolicy.Spec.Ingress = append(iePolicy.Spec.Ingress, ingress) - iePolicy.Metadata["namespace"] = log.SrcNamespace } + iePolicy.Metadata["namespace"] = log.SrcNamespace + iePolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) + return iePolicy } @@ -1942,7 +1939,7 @@ func convertKnoxNetworkLogToKnoxNetworkPolicy(log *types.KnoxNetworkLog, pods [] egressPolicy = &ePolicy } } else if log.DstPodName == "" && len(log.DstReservedLabels) == 0 { - iePolicy := popultaeIngressEgressPolicyFromKnoxNetLog(log, pods) + iePolicy := populateIngressEgressPolicyFromKnoxNetLog(log, pods) if log.Direction == "EGRESS" { egressPolicy = &iePolicy } else if log.Direction == "INGRESS" { From 3569bd8bb3e2bd614dd9a12005d0484f9f74b1f1 Mon Sep 17 00:00:00 2001 From: Eswar Rajan Subramanian Date: Thu, 10 Nov 2022 09:55:55 +0530 Subject: [PATCH 7/8] Fixed compilation errors Signed-off-by: Eswar Rajan Subramanian --- src/networkpolicy/networkPolicy.go | 1 - src/plugin/kubearmor.go | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/networkpolicy/networkPolicy.go b/src/networkpolicy/networkPolicy.go index ae7d84b0..8997033f 100644 --- a/src/networkpolicy/networkPolicy.go +++ b/src/networkpolicy/networkPolicy.go @@ -1800,7 +1800,6 @@ func populateIngressEgressPolicyFromKnoxNetLog(log *types.KnoxNetworkLog, pods [ iePolicy.Spec.Ingress = append(iePolicy.Spec.Ingress, ingress) } - iePolicy.Metadata["namespace"] = log.SrcNamespace iePolicy.Spec.Selector.MatchLabels = getEndpointMatchLabels(log.SrcPodName, pods) return iePolicy diff --git a/src/plugin/kubearmor.go b/src/plugin/kubearmor.go index 713b22bb..a4c32fa6 100644 --- a/src/plugin/kubearmor.go +++ b/src/plugin/kubearmor.go @@ -504,9 +504,9 @@ func StartKubeArmorRelay(StopChan chan struct{}, cfg types.ConfigKubeArmorRelay) } if config.CurrentCfg.ConfigNetPolicy.NetworkLogFrom == "kubearmor" { - - if log.Operation == "Network" { - KubeArmorNetworkLogs = append(KubeArmorNetworkLogs, &log) + + if kubearmorLog.Operation == "Network" { + KubeArmorNetworkLogs = append(KubeArmorNetworkLogs, &kubearmorLog) } } } From 265b37ee7e979de66f086f4250433c897279406b Mon Sep 17 00:00:00 2001 From: Eswar Rajan Subramanian Date: Fri, 11 Nov 2022 21:38:24 +0530 Subject: [PATCH 8/8] Fix for nw rules/policies being ignored in logs. Signed-off-by: Eswar Rajan Subramanian --- src/plugin/kubearmor.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugin/kubearmor.go b/src/plugin/kubearmor.go index a4c32fa6..4273e26a 100644 --- a/src/plugin/kubearmor.go +++ b/src/plugin/kubearmor.go @@ -422,7 +422,7 @@ func StartKubeArmorRelay(StopChan chan struct{}, cfg types.ConfigKubeArmorRelay) continue } - if !strings.HasPrefix(res.Resource, "/") { + if res.Operation != "Network" && !strings.HasPrefix(res.Resource, "/") { log.Warn().Msgf("Relative path found: %v", res) continue } @@ -490,7 +490,7 @@ func StartKubeArmorRelay(StopChan chan struct{}, cfg types.ConfigKubeArmorRelay) continue } - if !strings.HasPrefix(res.Resource, "/") { + if res.Operation != "Network" && !strings.HasPrefix(res.Resource, "/") { log.Warn().Msgf("Relative path found: %v", res) continue }