diff --git a/ingress/single-cluster/ingress-cloudarmor/README.md b/ingress/single-cluster/ingress-cloudarmor/README.md index 37fdf21d..9b05072b 100644 --- a/ingress/single-cluster/ingress-cloudarmor/README.md +++ b/ingress/single-cluster/ingress-cloudarmor/README.md @@ -1,6 +1,6 @@ # Google Cloud Armor enabled ingress -Following recipe provides a walk-through for setting up [GKE Ingress](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress) +The following recipe provides a walk-through for setting up [GKE Ingress](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress) with [Google Cloud Armor](https://cloud.google.com/armor) protection. Google Cloud Armor protects your applications and websites against denial of service and web attacks. @@ -47,17 +47,14 @@ by default**, so you need to configure CloudArmor policy for it explicitly. associated with an existing Ingress, makes no changes on underlying backend service. Refer to [following issue for details](https://github.com/kubernetes/ingress-gce/issues/1503). -## Walk-through - -Prerequisites: - +## Prerequisites: * GKE cluster up and running *(check [Prerequisite: GKE setup](#prerequisite-gke-setup) below)* -* Google Cloud Armor policy configured *(check [Configuring Google Cloud Armor security policies](https://cloud.google.com/armor/docs/configure-security-policies) - guide)* -Steps: +## Walk-through +1. Create a Google Cloud Armor policy *(check [Configuring Google Cloud Armor security policies](https://cloud.google.com/armor/docs/configure-security-policies) + guide)*. In this example, we create a Cloud Armor policy `allow-my-ip` that only allow one specific IP(34.83.21.159), and block all other traffics with 403 responses. -1. (Optional) Enable Google CloudArmor policy on a `default-http-backend` service +2. (Optional) Enable Google CloudArmor policy on a `default-http-backend` service * Create `BackendConfig` in a `kube-system` namespace. Substitute example policy name with your CloudArmor policy name @@ -70,7 +67,7 @@ Steps: name: cloudarmor-test spec: securityPolicy: - name: cloudarmor-test + name: allow-my-ip EOF ``` @@ -81,14 +78,14 @@ Steps: beta.cloud.google.com/backend-config='{"default": "cloudarmor-test"}' -n kube-system ``` -2. Replace `$POLICY_NAME` variable in `cloudarmor-ingress.yaml` file with your Google CloudArmor -policy name. +3. Replace `$POLICY_NAME` variable in `cloudarmor-ingress.yaml` file with your Google CloudArmor +policy name. ```bash - sed -i '.bak' 's/$POLICY_NAME/cloudarmor-test/g' cloudarmor-ingress.yaml + sed -i 's/$POLICY_NAME//g' cloudarmor-ingress.yaml ``` -3. Apply `cloudarmor-ingress.yaml` file +4. Apply `cloudarmor-ingress.yaml` file ```bash $ kubectl apply -f cloudarmor-ingress.yaml @@ -96,33 +93,63 @@ policy name. backendconfig.cloud.google.com/cloudarmor-test created service/whereami created deployment.apps/whereami created - $ ``` -4. Wait until all created objects reach desired state - -5. Verify and enjoy - -### Prerequisite: GKE setup - -1. Enable GKE API - - ```bash - gcloud services enable container.googleapis.com - ``` - -2. Create simple zonal GKE cluster for tests - - ```bash - gcloud container clusters create cluster-test \ - --zone europe-central2-a \ - --release-channel regular \ - --enable-ip-alias - ``` - -3. Configure client credentials for a new cluster - - ```bash - gcloud container clusters get-credentials cluster-test \ - --zone europe-central2-a - ```` +5. Wait until all created objects reach desired state +```bash +kubectl describe ingress +Name: cloudarmor-test +Labels: +Namespace: default +Address: 34.160.135.174 +Ingress Class: +Default backend: +Rules: + Host Path Backends + ---- ---- -------- + * + /whereami whereami:80 (10.24.0.31:8080,10.24.1.47:8080,10.24.2.39:8080) +Annotations: ingress.kubernetes.io/backends: + {"k8s1-02fed221-default-whereami-80-cda8fb8c":"HEALTHY","k8s1-02fed221-kube-system-default-http-backend-80-37075a2d":"HEALTHY"} + ingress.kubernetes.io/forwarding-rule: k8s2-fr-20aeohkx-default-cloudarmor-test-0aa8l6ah + ingress.kubernetes.io/target-proxy: k8s2-tp-20aeohkx-default-cloudarmor-test-0aa8l6ah + ingress.kubernetes.io/url-map: k8s2-um-20aeohkx-default-cloudarmor-test-0aa8l6ah + kubernetes.io/ingress.class: gce +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Sync 19m loadbalancer-controller UrlMap "k8s2-um-20aeohkx-default-cloudarmor-test-0aa8l6ah" created + Normal Sync 19m loadbalancer-controller TargetProxy "k8s2-tp-20aeohkx-default-cloudarmor-test-0aa8l6ah" created + Normal Sync 19m loadbalancer-controller ForwardingRule "k8s2-fr-20aeohkx-default-cloudarmor-test-0aa8l6ah" created + Normal IPChanged 19m loadbalancer-controller IP is now 34.160.135.174 + Normal Sync 9m37s (x7 over 20m) loadbalancer-controller Scheduled for sync +``` + +6. Verify the policy is acting as expected by sending traffic to our Ingress VIP. +We should expect connection from the IP specified in the policy with path `/whereami` to receive a `whereami` response, whereas connections from different IPs with the same path generating 403s(based on the configured Cloud Armor policy). +If step 2 is skipped, requests with non-matching paths should generate 404 responses from the default backend, no matter we are using allowed or blocked IPs. Otherwise, requests using blocked IPs would act depends on the Cloud Armor policy specification(in this example, we should receive 403s), and default 404 response is only received from IPs that allows traffics. + +Using allowed IP 34.83.21.159: +``` +curl 34.160.135.174/whereami +{"cluster_name":"gke-1","host_header":"34.160.135.174","pod_name":"whereami-59588795bb-7dx2c","pod_name_emoji":"\ud83c\udf24","zone":"us-west1-a"} +``` + +Using blocked IP +``` +curl 34.160.135.174/whereami +403403 Forbidden +``` + +## Cleanup + +```bash +kubectl delete -f internal-ingress-basic.yaml +``` + +If step2 is performed, also delete the `BackendConfig` and remove annotation for default-http-backend in the `kube-system` namespace, +``` +kubectl delete backendconfig cloudarmor-test -n kube-system + +kubectl annotate services default-http-backend beta.cloud.google.com/backend-config- -n kube-system +``` \ No newline at end of file diff --git a/ingress/single-cluster/ingress-cloudarmor/cloudarmor-ingress.yaml b/ingress/single-cluster/ingress-cloudarmor/cloudarmor-ingress.yaml index 8642930b..d8e18165 100644 --- a/ingress/single-cluster/ingress-cloudarmor/cloudarmor-ingress.yaml +++ b/ingress/single-cluster/ingress-cloudarmor/cloudarmor-ingress.yaml @@ -13,18 +13,23 @@ # See the License for the specific language governing permissions and # limitations under the License. -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cloudarmor-test + annotations: + kubernetes.io/ingress.class: "gce" spec: rules: - http: paths: - path: /whereami + pathType: Prefix backend: - serviceName: whereami - servicePort: 80 + service: + name: whereami + port: + number: 80 --- apiVersion: cloud.google.com/v1 kind: BackendConfig