Chapter 15. Securing a service network using Skupper policies
Chapter 15. Securing a service network using Skupper policies By default, Skupper includes many security features, including using mutual TLS for all service network communication between sites. You can add extra security features by installing the Skupper policy CRD. By default, applying a Skupper policy CRD to a cluster prevents all service network communication to and from that cluster. You specify granular Skupper policies CRs to permit only the service network communication you require. Note A Skupper policy is distinct from the Kubernetes network policy, that is the network-policy option, which restricts access to Skupper services to the current namespace as described in Using the Skupper CLI . Each site in a service network runs a Skupper router and has a private, dedicated certificate authority (CA). Communication between sites is secured with mutual TLS, so the service network is isolated from external access, preventing security risks such as lateral attacks, malware infestations, and data exfiltration. A set of Skupper policies adds another layer at a cluster level to help a cluster administrator control access to a service network. This guide assumes that you understand the following Skupper concepts: site A namespace in which Skupper is installed. token A token is required to establish a link between two sites. service network After exposing services using Skupper, you have created a service network. 15.1. About Skupper policies After a cluster administrator installs a Skupper policy Custom Resource Definition (CRD), the cluster administrator needs to configure one or more policies to allow developers create and use services on the service network. Note In this guide, developers refers to users of a cluster who have access to a namespace, but do not have administrator privileges. A cluster administrator configures one or more of following items using custom resources (CRs) to enable communication: Allow incoming links Use allowIncomingLinks to enable developers create tokens and configure incoming links. Allow outgoing links to specific hosts Use allowedOutgoingLinksHostnames to specify hosts that developers can create links to. Allow services Use allowedServices to specify which services developers can create or use on the service network. Allow resources to be exposed Use allowedExposedResources to specify which resources a developer can expose on the service network. Note A cluster administrator can apply each policy CR setting to one or more namespaces. For example, the following policy CR fully allows all Skupper capabilities on all namespaces, except for: only allows outgoing links to any domain ending in .example.com . only allows 'deployment/nginx' resources to be exposed on the service network. apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: cluster-policy-sample-01 spec: namespaces: - "*" allowIncomingLinks: true allowedExposedResources: - "deployment/nginx" allowedOutgoingLinksHostnames: [".*\.example.comUSD"] allowedServices: - "*" Note You can apply many policy CRs, and if there are conflicts in the items allowed, the most permissive policy is applied. For example, if you apply an additional policy CR with the line allowedOutgoingLinksHostnames: [] , which does not list any hostnames, outgoing links to *.example.com are still permitted because that is permitted in the original CR. namespaces One or more patterns to specify the namespaces that this policy applies to. Note that you can use Label selectors to match the namespaces. allowIncomingLinks Specify true to allow other sites create links to the specified namespaces. allowedOutgoingLinksHostnames Specify one or more patterns to determine which hosts you can create links to from the specified namespaces. allowedServices Specify one or more patterns to determine the permitted names of services allowed on the service network from the specified namespaces. allowedExposedResources Specify one or more permitted names of resources allowed on the service network from the specified namespaces. Note that patterns are not supported. Tip Use regular expressions to create pattern matches, for example: .*\.comUSD matches any string ending in .com . A double backslash is required to avoid issues in YAML. ^abcUSD matches the string abc . If you create another Skupper policy CR that allows outgoing links for a specific namespace, a user can create a link from that namespace to join a service network. That is, the logic for multiple policy CRs is OR . An operation is permitted if any single policy CR permits the operation. 15.2. Installing the Skupper policy CRD Installing the Skupper policy CRD enables a cluster administrator to enforce policies for service networks. Note If there are existing sites on the cluster, see Section 15.3, "Installing a Skupper policy CRD on a cluster with existing sites" to avoid service network disruption. Prerequisites Access to a cluster using a cluster-admin account The Skupper operator is installed Procedure Log in to the cluster using a cluster-admin account. Download the CRD: USD wget https://raw.githubusercontent.com/skupperproject/skupper/1.8/api/types/crds/skupper_cluster_policy_crd.yaml Apply the CRD: USD kubectl apply -f skupper_cluster_policy_crd.yaml customresourcedefinition.apiextensions.k8s.io/skupperclusterpolicies.skupper.io created clusterrole.rbac.authorization.k8s.io/skupper-service-controller created To verify that a Skupper policy is active, use the skupper status command and check that the output includes the following line: Skupper is enabled for namespace "<namespace>" in interior mode (with policies). 15.3. Installing a Skupper policy CRD on a cluster with existing sites If the cluster already hosts Skupper sites, note the following before installing the CRD: All existing connections are closed. You must apply a policy CR to reopen connections. All existing service network services and exposed resources are removed. You must create those resources again. Procedure To avoid disruption: Plan the CRD deployment for an appropriate time. Search your cluster for sites: USD kubectl get pods --all-namespaces --selector=app=skupper Document each service and resource exposed on the service network. Install the CRD as described in Section 15.2, "Installing the Skupper policy CRD" . This step closes connections and removes all service network services and exposed resources. If Skupper sites that were not created by cluster-admin exist in the cluster, you must grant permissions to read Skupper policies to avoid that site being blocked from the service network. For each site namespace: USD kubectl create clusterrolebinding skupper-service-controller-<namespace> --clusterrole=skupper-service-controller --serviceaccount=<namespace>:skupper-service-controller where <namespace> is the site namespace. Create Skupper policy CRs as described in Section 15.4, "Creating Skupper policy CRs" Recreate any services and exposed resources as required. 15.4. Creating Skupper policy CRs Skupper Policy CRs allow a cluster administrator to control communication across the service network from a cluster. Prerequisites Access to a cluster using a cluster-admin account. The Skupper policy CRD is installed on the cluster. Procedure Typically, you create a Skupper policy CR that combines many elements from the steps below. See Section 15.1, "About Skupper policies" for an example CR. Section 15.4.1, "Implement a policy to allow incoming links" Section 15.4.2, "Implement a policy to allow outgoing links to specific hosts" Section 15.4.3, "Implement a policy to allow specific services" Section 15.4.4, "Implement a policy to allow specific resources" 15.4.1. Implement a policy to allow incoming links Use allowIncomingLinks to enable developers create tokens and configure incoming links. Procedure Determine which namespaces you want to apply this policy to. Create a CR with allowIncomingLinks set to true or false . Create and apply the CR. For example, the following CR allows incoming links for all namespaces: apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: allowincominglinks spec: namespaces: - "*" allowIncomingLinks: true 15.4.2. Implement a policy to allow outgoing links to specific hosts Use allowedOutgoingLinksHostnames to specify hosts that developers can create links to. You cannot create a allowedOutgoingLinksHostnames policy to disallow a specific host that was previously allowed. Determine which namespaces you want to apply this policy to. Create a CR with allowedOutgoingLinksHostnames set to a pattern of allowed hosts. Create and apply the CR. For example, the following CR allows links to all subdomains of example.com for all namespaces: apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: allowedoutgoinglinkshostnames spec: namespaces: - "*" allowedOutgoingLinksHostnames: ['.*\.example\.com'] 15.4.3. Implement a policy to allow specific services Use allowedServices to specify which services a developer can create or use on the service network. You cannot create a allowedServices policy to disallow a specific service that was previously allowed. Procedure Determine which namespaces you want to apply this policy to. Create a CR with allowedServices set to specify the services allowed on the service network. Create and apply the CR. For example, the following CR allows users to expose and consume services with the prefix backend- for all namespaces: apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: allowedservices spec: namespaces: - "*" allowedServices: ['^backend-'] Note When exposing services, you can use the --address <name> parameter of the skupper CLI to name services to match your policy. 15.4.4. Implement a policy to allow specific resources Use allowedExposedResources to specify which resources a developer can expose on the service network. You cannot create a allowedExposedResources policy to disallow a specific resource that was previously allowed. Procedure Determine which namespaces you want to apply this policy to. Create a CR with allowedExposedResources set to specify resources that a developer can expose on the service network. Create and apply the CR. For example, the following CR allows you to expose an nginx deployment for all namespaces: apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: allowedexposedresources spec: namespaces: - "*" allowedExposedResources: ['deployment/nginx'] Note For allowedExposedResources , each entry must conform to the type/name syntax.
apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: cluster-policy-sample-01 spec: namespaces: - "*" allowIncomingLinks: true allowedExposedResources: - "deployment/nginx" allowedOutgoingLinksHostnames: [".*\.example.comUSD"] allowedServices: - "*" wget https://raw.githubusercontent.com/skupperproject/skupper/1.8/api/types/crds/skupper_cluster_policy_crd.yaml kubectl apply -f skupper_cluster_policy_crd.yaml customresourcedefinition.apiextensions.k8s.io/skupperclusterpolicies.skupper.io created clusterrole.rbac.authorization.k8s.io/skupper-service-controller created Skupper is enabled for namespace "<namespace>" in interior mode (with policies). kubectl get pods --all-namespaces --selector=app=skupper kubectl create clusterrolebinding skupper-service-controller-<namespace> --clusterrole=skupper-service-controller --serviceaccount=<namespace>:skupper-service-controller apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: allowincominglinks spec: namespaces: - "*" allowIncomingLinks: true apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: allowedoutgoinglinkshostnames spec: namespaces: - "*" allowedOutgoingLinksHostnames: ['.*\.example\.com'] apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: allowedservices spec: namespaces: - "*" allowedServices: ['^backend-'] apiVersion: skupper.io/v1alpha1 kind: SkupperClusterPolicy metadata: name: allowedexposedresources spec: namespaces: - "*" allowedExposedResources: ['deployment/nginx']