diff --git a/cni/network/network_windows.go b/cni/network/network_windows.go index f7d2e5defb..f6941335b3 100644 --- a/cni/network/network_windows.go +++ b/cni/network/network_windows.go @@ -59,6 +59,7 @@ func setEndpointOptions(cnsNwConfig *cns.GetNetworkContainerResponse, epInfo *ne epInfo.AllowInboundFromHostToNC = cnsNwConfig.AllowHostToNCCommunication epInfo.AllowInboundFromNCToHost = cnsNwConfig.AllowNCToHostCommunication epInfo.NetworkContainerID = cnsNwConfig.NetworkContainerID + epInfo.DefaultDenyACL = cnsNwConfig.DefaultDenyACL } } diff --git a/cns/NetworkContainerContract.go b/cns/NetworkContainerContract.go index 394f871f09..4b0c4b3b38 100644 --- a/cns/NetworkContainerContract.go +++ b/cns/NetworkContainerContract.go @@ -127,6 +127,7 @@ type CreateNetworkContainerRequest struct { EndpointPolicies []NetworkContainerRequestPolicies NCStatus v1alpha.NCStatus NetworkInterfaceInfo NetworkInterfaceInfo //nolint // introducing new field for backendnic, to be used later by cni code + DefaultDenyACL bool // specifies whether a "deny all" policy is applied to l1vh multi-tenant pods } func (req *CreateNetworkContainerRequest) Validate() error { @@ -487,6 +488,7 @@ type GetNetworkContainerResponse struct { AllowHostToNCCommunication bool AllowNCToHostCommunication bool NetworkInterfaceInfo NetworkInterfaceInfo + DefaultDenyACL bool // specifies whether a "deny all" policy is applied to l1vh multi-tenant pods } type PodIpInfo struct { diff --git a/cns/networkcontainers/networkcontainers.go b/cns/networkcontainers/networkcontainers.go index 19dc99f34c..b184b4c0c7 100644 --- a/cns/networkcontainers/networkcontainers.go +++ b/cns/networkcontainers/networkcontainers.go @@ -106,7 +106,7 @@ func DeleteLoopbackAdapter(adapterName string) error { } // This function gets the flattened network configuration (compliant with azure cni) in byte array format -func getNetworkConfig(configFilePath string) ([]byte, error) { +func getNetworkConfig(configFilePath string, defaultDenyACL bool) ([]byte, error) { content, err := os.ReadFile(configFilePath) if err != nil { return nil, err @@ -134,6 +134,36 @@ func getNetworkConfig(configFilePath string) ([]byte, error) { flatNetConfigMap[versionStr] = configMap[versionStr].(string) flatNetConfigMap[nameStr] = configMap[nameStr].(string) + if defaultDenyACL { + // insert default deny policies here + defaultDenyOutACL := map[string]interface{}{ + "Name": "EndpointPolicy", + "Value": map[string]interface{}{ + "Type": "ACL", + "Action": "Block", + "Direction": "Out", + "Priority": 300, + }, + } + + defaultDenyInACL := map[string]interface{}{ + "Name": "EndpointPolicy", + "Value": map[string]interface{}{ + "Type": "ACL", + "Action": "Block", + "Direction": "In", + "Priority": 300, + }, + } + additionalArgsKey := "AdditionalArgs" + if _, exists := flatNetConfigMap[additionalArgsKey]; !exists { + flatNetConfigMap[additionalArgsKey] = []interface{}{} + } + + flatNetConfigMap[additionalArgsKey] = append(flatNetConfigMap[additionalArgsKey].([]interface{}), defaultDenyOutACL) + flatNetConfigMap[additionalArgsKey] = append(flatNetConfigMap[additionalArgsKey].([]interface{}), defaultDenyInACL) + } + // convert into bytes format netConfig, err := json.Marshal(flatNetConfigMap) if err != nil { @@ -198,17 +228,17 @@ func execPlugin(rt *libcni.RuntimeConf, netconf []byte, operation, path string) } // Attach - attaches network container to network. -func (cn *NetworkContainers) Attach(podInfo cns.PodInfo, dockerContainerid string, netPluginConfig *NetPluginConfiguration) error { +func (cn *NetworkContainers) Attach(podInfo cns.PodInfo, dockerContainerid string, netPluginConfig *NetPluginConfiguration, defaultDenyACL bool) error { logger.Printf("[Azure CNS] NetworkContainers.Attach called") - err := configureNetworkContainerNetworking(cniAdd, podInfo.Name(), podInfo.Namespace(), dockerContainerid, netPluginConfig) + err := configureNetworkContainerNetworking(cniAdd, podInfo.Name(), podInfo.Namespace(), dockerContainerid, netPluginConfig, defaultDenyACL) logger.Printf("[Azure CNS] NetworkContainers.Attach finished") return err } // Detach - detaches network container from network. -func (cn *NetworkContainers) Detach(podInfo cns.PodInfo, dockerContainerid string, netPluginConfig *NetPluginConfiguration) error { +func (cn *NetworkContainers) Detach(podInfo cns.PodInfo, dockerContainerid string, netPluginConfig *NetPluginConfiguration, defaultDenyACL bool) error { logger.Printf("[Azure CNS] NetworkContainers.Detach called") - err := configureNetworkContainerNetworking(cniDelete, podInfo.Name(), podInfo.Namespace(), dockerContainerid, netPluginConfig) + err := configureNetworkContainerNetworking(cniDelete, podInfo.Name(), podInfo.Namespace(), dockerContainerid, netPluginConfig, defaultDenyACL) logger.Printf("[Azure CNS] NetworkContainers.Detach finished") return err } diff --git a/cns/networkcontainers/networkcontainers_linux.go b/cns/networkcontainers/networkcontainers_linux.go index 1d1a28e2a4..772da17506 100644 --- a/cns/networkcontainers/networkcontainers_linux.go +++ b/cns/networkcontainers/networkcontainers_linux.go @@ -64,7 +64,7 @@ func updateInterface(createNetworkContainerRequest cns.CreateNetworkContainerReq logger.Printf("[Azure CNS] run time configuration for CNI plugin info %+v", rt) - netConfig, err := getNetworkConfig(netpluginConfig.networkConfigPath) + netConfig, err := getNetworkConfig(netpluginConfig.networkConfigPath, false) if err != nil { logger.Printf("[Azure CNS] Failed to build network configuration with error %v", err) return err @@ -85,7 +85,7 @@ func deleteInterface(networkContainerID string) error { return nil } -func configureNetworkContainerNetworking(operation, podName, podNamespace, dockerContainerid string, netPluginConfig *NetPluginConfiguration) (err error) { +func configureNetworkContainerNetworking(operation, podName, podNamespace, dockerContainerid string, netPluginConfig *NetPluginConfiguration, defaultDenyACL bool) (err error) { return fmt.Errorf("[Azure CNS] Operation is not supported in linux.") } diff --git a/cns/networkcontainers/networkcontainers_windows.go b/cns/networkcontainers/networkcontainers_windows.go index bbb3d3a9ee..36e883b3c2 100644 --- a/cns/networkcontainers/networkcontainers_windows.go +++ b/cns/networkcontainers/networkcontainers_windows.go @@ -219,7 +219,7 @@ func deleteInterface(interfaceName string) error { return err } -func configureNetworkContainerNetworking(operation, podName, podNamespace, dockerContainerid string, netPluginConfig *NetPluginConfiguration) (err error) { +func configureNetworkContainerNetworking(operation, podName, podNamespace, dockerContainerid string, netPluginConfig *NetPluginConfiguration, defaultDenyACL bool) (err error) { cniRtConf := &libcni.RuntimeConf{ ContainerID: dockerContainerid, NetNS: "none", @@ -231,7 +231,7 @@ func configureNetworkContainerNetworking(operation, podName, podNamespace, docke } logger.Printf("[Azure CNS] run time conf info %+v", cniRtConf) - netConfig, err := getNetworkConfig(netPluginConfig.networkConfigPath) + netConfig, err := getNetworkConfig(netPluginConfig.networkConfigPath, defaultDenyACL) if err != nil { logger.Printf("[Azure CNS] Failed to build network configuration with error %v", err) return err diff --git a/cns/restserver/util.go b/cns/restserver/util.go index 43d1e1aef9..58ec0d8608 100644 --- a/cns/restserver/util.go +++ b/cns/restserver/util.go @@ -531,6 +531,7 @@ func (service *HTTPRestService) getAllNetworkContainerResponses( AllowHostToNCCommunication: savedReq.AllowHostToNCCommunication, AllowNCToHostCommunication: savedReq.AllowNCToHostCommunication, NetworkInterfaceInfo: savedReq.NetworkInterfaceInfo, + DefaultDenyACL: savedReq.DefaultDenyACL, } // If the NC version check wasn't skipped, take into account the VFP programming status when returning the response @@ -675,6 +676,9 @@ func (service *HTTPRestService) attachOrDetachHelper(req cns.ConfigureContainerN var returnCode types.ResponseCode var returnMessage string + nc := service.state.ContainerStatus[req.NetworkContainerid] + defaultDenyACL := nc.CreateNetworkContainerRequest.DefaultDenyACL + switch service.state.OrchestratorType { case cns.Batch: podInfo, err := cns.UnmarshalPodInfo(existing.CreateNetworkContainerRequest.OrchestratorContext) @@ -686,9 +690,9 @@ func (service *HTTPRestService) attachOrDetachHelper(req cns.ConfigureContainerN netPluginConfig := service.getNetPluginDetails() switch operation { case attach: - err = nc.Attach(podInfo, req.Containerid, netPluginConfig) + err = nc.Attach(podInfo, req.Containerid, netPluginConfig, defaultDenyACL) case detach: - err = nc.Detach(podInfo, req.Containerid, netPluginConfig) + err = nc.Detach(podInfo, req.Containerid, netPluginConfig, defaultDenyACL) } if err != nil { returnCode = types.UnexpectedError @@ -933,6 +937,7 @@ func (service *HTTPRestService) handleGetNetworkContainers(w http.ResponseWriter LocalIPConfiguration: ncDetails.CreateNetworkContainerRequest.LocalIPConfiguration, AllowHostToNCCommunication: ncDetails.CreateNetworkContainerRequest.AllowHostToNCCommunication, AllowNCToHostCommunication: ncDetails.CreateNetworkContainerRequest.AllowNCToHostCommunication, + DefaultDenyACL: ncDetails.CreateNetworkContainerRequest.DefaultDenyACL, } networkContainers[i] = getNcResp i++ diff --git a/crd/multitenancy/api/v1alpha1/podnetworkinstance.go b/crd/multitenancy/api/v1alpha1/podnetworkinstance.go index 4a775363ae..77d4e73654 100644 --- a/crd/multitenancy/api/v1alpha1/podnetworkinstance.go +++ b/crd/multitenancy/api/v1alpha1/podnetworkinstance.go @@ -56,6 +56,8 @@ type PodNetworkInstanceSpec struct { // optional for now in case orchestrator uses the deprecated fields // +kubebuilder:validation:Optional PodNetworkConfigs []PodNetworkConfig `json:"podNetworkConfigs"` + // DefaultDenyACL is a bool that specifies whether a "deny all" policy is applied to l1vh multi-tenant pods + DefaultDenyACL bool `json:"defaultDenyACL"` } // PodNetworkInstanceStatus defines the observed state of PodNetworkInstance diff --git a/crd/multitenancy/manifests/multitenancy.acn.azure.com_podnetworkinstances.yaml b/crd/multitenancy/manifests/multitenancy.acn.azure.com_podnetworkinstances.yaml index ff539c6834..001301b13d 100644 --- a/crd/multitenancy/manifests/multitenancy.acn.azure.com_podnetworkinstances.yaml +++ b/crd/multitenancy/manifests/multitenancy.acn.azure.com_podnetworkinstances.yaml @@ -57,6 +57,10 @@ spec: default: 0 description: Deprecated - use PodNetworks type: integer + DefaultDenyACL: + default: false + description: indicates whether default deny policy will be present on the pods upon pod creation + type: bool podNetworkConfigs: description: |- PodNetworkConfigs describes each PodNetwork to attach to a single Pod diff --git a/network/endpoint.go b/network/endpoint.go index 0dc122ce9c..18c1413a01 100644 --- a/network/endpoint.go +++ b/network/endpoint.go @@ -112,6 +112,7 @@ type EndpointInfo struct { IsIPv6Enabled bool HostSubnetPrefix string // can be used later to add an external interface PnPID string + DefaultDenyACL bool } // RouteInfo contains information about an IP route. diff --git a/test/integration/manifests/swiftv2/pni.yaml b/test/integration/manifests/swiftv2/pni.yaml index 04cd0847b5..78c8123e8b 100644 --- a/test/integration/manifests/swiftv2/pni.yaml +++ b/test/integration/manifests/swiftv2/pni.yaml @@ -5,3 +5,4 @@ metadata: spec: podnetwork: aksswiftvnetv20425 podIPReservationSize: 2 + defaultDenyACL: false