Goal: Leverage network policies to segment connections within the AKS cluster and prevent known bad actors from accessing the workloads.
-
Test connectivity between application components and across application stacks, since we don't have network policy in place, the pods are reachable from any endpoints.
a. Test connectivity between workloads within each namespace.
# test connectivity within dev namespace kubectl -n dev exec -t centos -- sh -c 'curl -m2 -sI http://nginx-svc 2>/dev/null | grep -i http' # test connectivity within default namespace kubectl exec -it $(kubectl get po -l app=loadgenerator -ojsonpath='{.items[0].metadata.name}') -c main -- sh -c 'curl -m2 -sI frontend 2>/dev/null | grep -i http' kubectl exec -it $(kubectl get po -l app=frontend -ojsonpath='{.items[0].metadata.name}') -c server -- sh -c 'nc -zv productcatalogservice 3550'
b. Test connectivity across namespaces.
# test connectivity from dev namespace to default namespace kubectl -n dev exec -t centos -- sh -c 'curl -m2 -sI http://frontend.default 2>/dev/null | grep -i http' # test connectivity from default namespace to dev namespace kubectl exec -it $(kubectl get po -l app=loadgenerator -ojsonpath='{.items[0].metadata.name}') -c main -- sh -c 'curl -m2 -sI http://nginx-svc.dev 2>/dev/null | grep -i http'
c. Test connectivity from each namespace to the Internet.
# test connectivity from dev namespace to the Internet kubectl -n dev exec -t centos -- sh -c 'curl -m2 -sI http://www.bing.com 2>/dev/null | grep -i http' # test connectivity from default namespace to the Internet kubectl exec -it $(kubectl get po -l app=loadgenerator -ojsonpath='{.items[0].metadata.name}') -c main -- sh -c 'curl -m2 -sI www.bing.com 2>/dev/null | grep -i http'
All of these tests should succeed if there are no policies in place to govern the traffic for
dev
anddefault
namespaces. -
Apply staged
default-deny
policy.Staged
default-deny
policy is a good way of catching any traffic that is not explicitly allowed by a policy without explicitly blocking it.kubectl apply -f demo/10-security-controls/staged.default-deny.yaml
Review the network policy created by clicking
Policies
on the left menu. A staged default deny policy has been created in thedefault
tier. You can view or edit the policy by double clicking the policy.You can view the potential affect of the staged
default-deny
policy if you navigate to theDashboard
view in your Calico Cloud Manager UI and look at thePackets by Policy
histogram.To view more traffic in the
Packets by Policy
histogram we can generate traffic from thecentos
pod to thefrontend
service.# make a request across namespaces and view Packets by Policy histogram for i in {1..5}; do kubectl -n dev exec -t centos -- sh -c 'curl -m2 -sI http://frontend.default 2>/dev/null | grep -i http'; sleep 2; done
The staged policy does not affect the traffic directly but allows you to view the policy impact if it were to be enforced.
-
Apply network policies to control East-West traffic.
# deploy dev policies kubectl apply -f demo/dev/policies.yaml # deploy boutiqueshop policies kubectl apply -f demo/boutiqueshop/policies.yaml # deploy policies for pods to access metadata API kubectl apply -f demo/20-egress-access-controls/netset.metadata-api.yaml kubectl apply -f demo/20-egress-access-controls/metadata-policy.yaml
Now as we have proper policies in place, we can enforce
default-deny
policy moving closer to zero-trust security approach. You can either enforced the already deployed stageddefault-deny
policy using thePolicies Board
view in your Calico Cloud Manager UI, or you can apply an enforcingdefault-deny
policy manifest.# apply enforcing default-deny policy manifest kubectl apply -f demo/10-security-controls/default-deny.yaml
If the above yaml definition is deployed the policy
Staged default-deny
can be deleted through the Web UI. Within the policy board click the edit icon from theStaged default deny
policy in thedefault
tier. Then clickDelete
-
Test connectivity with policies in place.
a. The only connections between the components within each namespaces should be allowed as configured by the policies.
# test connectivity within dev namespace kubectl -n dev exec -t centos -- sh -c 'curl -m2 -sI http://nginx-svc 2>/dev/null | grep -i http' # test connectivity within default namespace kubectl exec -it $(kubectl get po -l app=loadgenerator -ojsonpath='{.items[0].metadata.name}') -c main -- sh -c 'curl -m2 -sI frontend 2>/dev/null | grep -i http'
b. The connections across
dev
anddefault
namespaces should be blocked by the globaldefault-deny
policy.# test connectivity from dev namespace to default namespace kubectl -n dev exec -t centos -- sh -c 'curl -m2 -sI http://frontend.default 2>/dev/null | grep -i http' # test connectivity from default namespace to dev namespace kubectl exec -it $(kubectl get po -l app=loadgenerator -ojsonpath='{.items[0].metadata.name}') -c main -- sh -c 'curl -m2 -sI http://nginx-svc.dev 2>/dev/null | grep -i http'
c. The connections to the Internet should be blocked by the configured
default-deny
policies.# test connectivity from dev namespace to the Internet kubectl -n dev exec -t centos -- sh -c 'curl -m2 -sI http://www.bing.com 2>/dev/null | grep -i http' # test connectivity from default namespace to the Internet kubectl exec -it $(kubectl get po -l app=loadgenerator -ojsonpath='{.items[0].metadata.name}') -c main -- sh -c 'curl -m2 -sI www.bing.com 2>/dev/null | grep -i http'
-
Implement egress policy to allow egress access from a workload in one namespace, e.g.
dev/centos
, to a service in another namespace, e.g.default/frontend
. After the deployment, you can view the policy details underplatform
tier inPolicies Board
a. Deploy egress policy.
kubectl apply -f demo/20-egress-access-controls/centos-to-frontend.yaml
b. Test connectivity between
dev/centos
pod anddefault/frontend
service.kubectl -n dev exec -t centos -- sh -c 'curl -m2 -sI http://frontend.default 2>/dev/null | grep -i http'
The access should be allowed once the egress policy is in place.