github.com/cilium/cilium@v1.16.2/Documentation/security/dns.rst (about) 1 .. only:: not (epub or latex or html) 2 3 WARNING: You are looking at unreleased Cilium documentation. 4 Please use the official rendered version released here: 5 https://docs.cilium.io 6 7 .. _gs_dns: 8 9 **************************************************** 10 Locking Down External Access with DNS-Based Policies 11 **************************************************** 12 13 This document serves as an introduction for using Cilium to enforce DNS-based 14 security policies for Kubernetes pods. 15 16 .. include:: gsg_requirements.rst 17 18 Deploy the Demo Application 19 =========================== 20 21 DNS-based policies are very useful for controlling access to services running outside the Kubernetes cluster. DNS acts as a persistent service identifier for both external services provided by AWS, Google, Twilio, Stripe, etc., and internal services such as database clusters running in private subnets outside Kubernetes. CIDR or IP-based policies are cumbersome and hard to maintain as the IPs associated with external services can change frequently. The Cilium DNS-based policies provide an easy mechanism to specify access control while Cilium manages the harder aspects of tracking DNS to IP mapping. 22 23 In this guide we will learn about: 24 25 - Controlling egress access to services outside the cluster using DNS-based policies 26 - Using patterns (or wildcards) to whitelist a subset of DNS domains 27 - Combining DNS, port and L7 rules for restricting access to external service 28 29 In line with our Star Wars theme examples, we will use a simple scenario where 30 the Empire's ``mediabot`` pods need access to GitHub for managing the Empire's 31 git repositories. The pods shouldn't have access to any other external service. 32 33 .. parsed-literal:: 34 35 $ kubectl create -f \ |SCM_WEB|\/examples/kubernetes-dns/dns-sw-app.yaml 36 $ kubectl wait pod/mediabot --for=condition=Ready 37 $ kubectl get pods 38 NAME READY STATUS RESTARTS AGE 39 pod/mediabot 1/1 Running 0 14s 40 41 42 Apply DNS Egress Policy 43 ======================= 44 45 The following Cilium network policy allows ``mediabot`` pods to only access ``api.github.com``. 46 47 .. tabs:: 48 49 .. group-tab:: Generic 50 51 .. literalinclude:: ../../examples/kubernetes-dns/dns-matchname.yaml 52 53 .. group-tab:: OpenShift 54 55 .. literalinclude:: ../../examples/kubernetes-dns/dns-matchname-openshift.yaml 56 57 .. note:: 58 59 OpenShift users will need to modify the policies to match the namespace 60 ``openshift-dns`` (instead of ``kube-system``), remove the match on the 61 ``k8s:k8s-app=kube-dns`` label, and change the port to 5353. 62 63 Let's take a closer look at the policy: 64 65 * The first egress section uses ``toFQDNs: matchName`` specification to allow 66 egress to ``api.github.com``. The destination DNS should match exactly the 67 name specified in the rule. The ``endpointSelector`` allows only pods with 68 labels ``class: mediabot, org:empire`` to have the egress access. 69 * The second egress section (``toEndpoints``) allows ``mediabot`` pods to access 70 ``kube-dns`` service. Note that ``rules: dns`` instructs Cilium to inspect and 71 allow DNS lookups matching specified patterns. In this case, inspect and allow 72 all DNS queries. 73 74 Note that with this policy the ``mediabot`` doesn't have access to any internal 75 cluster service other than ``kube-dns``. Refer to :ref:`Network Policy` to learn 76 more about policies for controlling access to internal cluster services. 77 78 Let's apply the policy: 79 80 .. parsed-literal:: 81 82 kubectl apply -f \ |SCM_WEB|\/examples/kubernetes-dns/dns-matchname.yaml 83 84 Testing the policy, we see that ``mediabot`` has access to ``api.github.com`` 85 but doesn't have access to any other external service, e.g., 86 ``support.github.com``. 87 88 .. code-block:: shell-session 89 90 $ kubectl exec mediabot -- curl -I -s https://api.github.com | head -1 91 HTTP/2 200 92 93 $ kubectl exec mediabot -- curl -I -s --max-time 5 https://support.github.com | head -1 94 curl: (28) Connection timed out after 5000 milliseconds 95 command terminated with exit code 28 96 97 DNS Policies Using Patterns 98 =========================== 99 100 The above policy controlled DNS access based on exact match of the DNS domain 101 name. Often, it is required to allow access to a subset of domains. Let's say, 102 in the above example, ``mediabot`` pods need access to any GitHub sub-domain, 103 e.g., the pattern ``*.github.com``. We can achieve this easily by changing the 104 ``toFQDN`` rule to use ``matchPattern`` instead of ``matchName``. 105 106 .. literalinclude:: ../../examples/kubernetes-dns/dns-pattern.yaml 107 108 .. parsed-literal:: 109 110 kubectl apply -f \ |SCM_WEB|\/examples/kubernetes-dns/dns-pattern.yaml 111 112 Test that ``mediabot`` has access to multiple GitHub services for which the DNS 113 matches the pattern ``*.github.com``. It is important to note and test that this 114 doesn't allow access to ``github.com`` because the ``*.`` in the pattern 115 requires one subdomain to be present in the DNS name. You can simply add more 116 ``matchName`` and ``matchPattern`` clauses to extend the access. (See :ref:`DNS based` 117 policies to learn more about specifying DNS rules using patterns and names.) 118 119 .. code-block:: shell-session 120 121 $ kubectl exec mediabot -- curl -I -s https://support.github.com | head -1 122 HTTP/1.1 200 OK 123 124 $ kubectl exec mediabot -- curl -I -s https://gist.github.com | head -1 125 HTTP/1.1 302 Found 126 127 $ kubectl exec mediabot -- curl -I -s --max-time 5 https://github.com | head -1 128 curl: (28) Connection timed out after 5000 milliseconds 129 command terminated with exit code 28 130 131 Combining DNS, Port and L7 Rules 132 ================================ 133 134 The DNS-based policies can be combined with port (L4) and API (L7) rules to 135 further restrict the access. In our example, we will restrict ``mediabot`` pods 136 to access GitHub services only on ports ``443``. The ``toPorts`` section in the 137 policy below achieves the port-based restrictions along with the DNS-based 138 policies. 139 140 .. literalinclude:: ../../examples/kubernetes-dns/dns-port.yaml 141 142 .. parsed-literal:: 143 144 kubectl apply -f \ |SCM_WEB|\/examples/kubernetes-dns/dns-port.yaml 145 146 Testing, the access to ``https://support.github.com`` on port ``443`` will 147 succeed but the access to ``http://support.github.com`` on port ``80`` will be 148 denied. 149 150 .. code-block:: shell-session 151 152 $ kubectl exec mediabot -- curl -I -s https://support.github.com | head -1 153 HTTP/1.1 200 OK 154 155 $ kubectl exec mediabot -- curl -I -s --max-time 5 http://support.github.com | head -1 156 curl: (28) Connection timed out after 5001 milliseconds 157 command terminated with exit code 28 158 159 Refer to :ref:`l4_policy` and :ref:`l7_policy` to learn more about Cilium L4 and 160 L7 network policies. 161 162 Clean-up 163 ======== 164 165 .. parsed-literal:: 166 167 kubectl delete -f \ |SCM_WEB|\/examples/kubernetes-dns/dns-sw-app.yaml 168 kubectl delete cnp fqdn