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