Edge Security with Cloud Armor
Cloud Armor is managed service from Google Cloud used to secure web applications behind external HTTP(S) load balancers.
Policies can be applied on external HTTP(S) load balancer to allow or deny traffic based on IP address, CIDR ranges, country code and request attributes.
cross-site scripting (XSS) and SQL injection (SQLi) attacks can be mitigated by using pre-configured rules.
In this blog we will deploy a simple app on Google Kubernetes Engine and configure Cloud Armor.
Create deployment in GKE
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
selector:
matchLabels:
run: web
template:
metadata:
labels:
run: web
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: IfNotPresent
name: web
ports:
- containerPort: 8080
protocol: TCPkubectl apply -f deployment.yaml
Create Security Policy
SECURITY_POLICY_NAME=security-policy-name
gcloud compute security-policies create ${SECURITY_POLICY_NAME} \
--description "policy for users"
Update Default Rule in Security Policy to deny all traffic
gcloud compute security-policies rules update 2147483647 \
--security-policy ${SECURITY_POLICY_NAME} \
--action "deny-404"
Define Security Policy Rules
gcloud compute security-policies rules create 1000 \
--security-policy ${SECURITY_POLICY_NAME} \
--expression "evaluatePreconfiguredExpr('sqli-stable')" \
--action "deny-403" \
--description "mitigate SQLi attack"
gcloud compute security-policies rules create 2000 \
--security-policy ${SECURITY_POLICY_NAME} \
--expression "evaluatePreconfiguredExpr('xss-stable')" \
--action "deny-403" \
--description "mitigate XSS attack"
gcloud compute security-policies rules create 3000 \
--security-policy ${SECURITY_POLICY_NAME} \
--expression "origin.region_code == 'IN' && inIpRange(origin.ip, '171.76.120.0/24')" \
--action "allow" \
--description "allow traffic from IN region with specific CIDR"
Creating a BackendConfig
A BackendConfig resource holds configuration information that’s specific to Cloud Load Balancing.
backend-config.yaml
apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
name: backend-config
namespace: default
spec:
securityPolicy:
name: SECURITY_POLICY_NAMEsed -i -e "s/SECURITY_POLICY_NAME/${SECURITY_POLICY_NAME}/g" backend-config.yaml
kubectl apply -f backend-config.yaml
Create Service
service.yaml
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
annotations:
beta.cloud.google.com/backend-config: '{"ports": {"8080":"backend-config"}}'
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
run: web
type: NodePortkubectl apply -f service.yaml
Reserve global static ip address
gcloud compute addresses create address-name --global --ip-version IPV4
STATIC_IP=`gcloud compute addresses describe address-name --global | awk 'NR == 1 {print $2}'`
Create ingress resource
ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: address-name
spec:
backend:
serviceName: web
servicePort: 8080
Test access
Wait for ingress resource to created.
curl ${STATIC_IP}
Hello, world!
Version: 1.0.0
Try SQL injection
curl http://${STATIC_IP}/?id=1%20or%201=1
403 Forbidden
Summary
When hosting any Web Applications or API’s, protecting against threats and unwanted traffic is important. Cloud Armor gives a simple interface to integrate security policies with external HTTP(S) Load Balancers.