github.com/imran-kn/cilium-fork@v1.6.9/Documentation/gettingstarted/memcached.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      http://docs.cilium.io
     6  
     7  **********************************
     8  Getting Started Securing Memcached
     9  **********************************
    10  
    11  This document serves as an introduction to using Cilium to enforce memcached-aware
    12  security policies. It walks through a single-node
    13  Cilium environment running on your machine. It is designed to take 15-30
    14  minutes.
    15  
    16  **NOTE:** memcached-aware policy support is still in beta.  It is not yet ready for
    17  production use. Additionally, the memcached-specific policy language is highly likely to
    18  change in a future Cilium version.
    19  
    20  `Memcached <https://memcached.org/>`_ is a high performance, distributed memory object caching system. It's simple yet powerful, and used by dynamic web applications to alleviate database load. Memcached is designed to work efficiently for a very large number of open connections. Thus, clients are encouraged to cache their connections rather
    21  than the overhead of reopening TCP connections every time they need to store or retrieve data. Multiple clients can benefit from this distributed cache's performance benefits.
    22  
    23  There are two kinds of data sent in the memcache protocol: text lines
    24  and unstructured (binary) data.  We will demonstrate clients using both types of protocols to communicate with a memcached server.
    25  
    26  .. include:: gsg_requirements.rst
    27  
    28  Step 2: Deploy the Demo Application
    29  ===================================
    30  
    31  Now that we have Cilium deployed and ``kube-dns`` operating correctly we can
    32  deploy our demo memcached application.  Since our first
    33  `HTTP-aware Cilium demo <https://www.cilium.io/blog/2017/5/4/demo-may-the-force-be-with-you>`_ was based on Star Wars, we continue with the theme for the memcached demo as well.
    34  
    35  Ever wonder how the Alliance Fleet manages the changing positions of their ships? The Alliance Fleet uses memcached to store the coordinates of their ships. The Alliance Fleet leverages the memcached-svc service implemented as a memcached server. Each ship in the fleet constantly updates its coordinates and has the ability to get the coordinates of other ships in the Alliance Fleet.
    36  
    37  In this simple example, the Alliance Fleet uses a memcached server for their starfighters to store their own supergalatic coordinates and get those of other starfighters.
    38  
    39  In order to avoid collisions and protect against compromised starfighters, memcached commands are limited to gets for any starfighter coordinates and sets only to a key specific to the starfighter. Thus the following operations are allowed:
    40  
    41  - **A-wing**: can set coordinates to key "awing-coord" and get the key coordinates.
    42  - **X-wing**: can set coordinates to key "xwing-coord" and get the key coordinates.
    43  - **Alliance-Tracker**: can get any coordinates but not set any.
    44  
    45  To keep the setup small, we will launch a small number of pods to represent a larger environment:
    46  
    47  - **memcached-server** : A Kubernetes service represented by a single pod running a memcached server (label app=memcd-server).
    48  - **a-wing** memcached binary client : A pod representing an A-wing starfighter, which can update its coordinates and read it via the binary memcached protocol (label app=a-wing).
    49  - **x-wing** memcached text-based client : A pod representing an X-wing starfighter, which can update its coordinates and read it via the text-based memcached protocol (label app=x-wing).
    50  - **alliance-tracker** memcached binary client : A pod representing the Alliance Fleet Tracker, able to read the coordinates of all starfighters (label name=fleet-tracker).
    51  
    52  
    53  Memcached clients access the *memcached-server* on TCP port 11211 and send memcached protocol messages to it.
    54  
    55  .. image:: images/cilium_memcd_gsg_topology.png
    56  
    57  
    58  The file ``memcd-sw-app.yaml`` contains a Kubernetes Deployment for each of the pods described
    59  above, as well as a Kubernetes Service *memcached-server* for the Memcached server.
    60  
    61  .. parsed-literal::
    62  
    63      $ kubectl create -f \ |SCM_WEB|\/examples/kubernetes-memcached/memcd-sw-app.yaml
    64      deployment.extensions/memcached-server created
    65      service/memcached-server created
    66      deployment.extensions/a-wing created
    67      deployment.extensions/x-wing created
    68      deployment.extensions/alliance-tracker created
    69  
    70  Kubernetes will deploy the pods and service in the background.
    71  Running ``kubectl get svc,pods`` will inform you about the progress of the operation.
    72  Each pod will go through several states until it reaches ``Running`` at which
    73  point the setup is ready.
    74  
    75  .. parsed-literal::
    76  
    77      $ kubectl get svc,pods
    78      NAME                       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
    79      service/kubernetes         ClusterIP   10.96.0.1    <none>        443/TCP     31m
    80      service/memcached-server   ClusterIP   None         <none>        11211/TCP   14m
    81  
    82      NAME                                    READY   STATUS    RESTARTS   AGE
    83      pod/a-wing-67db8d5fcc-dpwl4             1/1     Running   0          14m
    84      pod/alliance-tracker-6b6447bd69-sz5hz   1/1     Running   0          14m
    85      pod/memcached-server-bdbfb87cd-8tdh7    1/1     Running   0          14m
    86      pod/x-wing-fd5dfb9d9-wrtwn              1/1     Running   0          14m
    87  
    88  We suggest having a main terminal window to execute *kubectl* commands and two additional terminal windows dedicated to accessing the **A-Wing** and **Alliance-Tracker**, which use a python library to communicate to the memcached server using the binary protocol.
    89  
    90  In **all three** terminal windows, set some handy environment variables for the demo with the following script:
    91  
    92  .. parsed-literal::x
    93  
    94     $  curl -s \ |SCM_WEB|\/examples/kubernetes-memcached/memcd-env.sh > memcd-env.sh
    95     $  source memcd-env.sh
    96  
    97  
    98  In the terminal window dedicated for the A-wing pod, exec in, use python to import the binary memcached library and set the client connection to the memcached server:
    99  
   100  .. parsed-literal::
   101  
   102      $ kubectl exec -ti $AWING_POD sh
   103      # python
   104      Python 3.7.0 (default, Sep  5 2018, 03:25:31)
   105      [GCC 6.3.0 20170516] on linux
   106      Type "help", "copyright", "credits" or "license" for more information.
   107      >>> import bmemcached
   108      >>> client = bmemcached.Client(("memcached-server:11211", ))
   109  
   110  In the terminal window dedicated for the Alliance-Tracker, exec in, use python to import the binary memcached library and set the client connection to the memcached server:
   111  
   112  .. parsed-literal::
   113  
   114      $ kubectl exec -ti $TRACKER_POD sh
   115      # python
   116      Python 3.7.0 (default, Sep  5 2018, 03:25:31)
   117      [GCC 6.3.0 20170516] on linux
   118      Type "help", "copyright", "credits" or "license" for more information.
   119      >>> import bmemcached
   120      >>> client = bmemcached.Client(("memcached-server:11211", ))
   121  
   122  
   123  
   124  Step 3: Test Basic Memcached Access
   125  ===================================
   126  
   127  Let's show that each client is able to access the memcached server. Execute the following to have the A-wing and X-wing starfighters update the Alliance Fleet memcached-server with their respective supergalatic coordinates:
   128  
   129  A-wing will access the memcached-server using the *binary protocol*. In your terminal window for A-Wing, set A-wing's coordinates:
   130  
   131  .. parsed-literal::
   132  
   133      >>> client.set("awing-coord","4309.432,918.980",time=2400)
   134      True
   135      >>> client.get("awing-coord")
   136      '4309.432,918.980'
   137  
   138  
   139  In your main terminal window, have X-wing starfighter set their coordinates using the text-based protocol to the memcached server.
   140  
   141  .. parsed-literal::
   142  
   143      $ kubectl exec $XWING_POD sh -- -c "echo -en \\"$SETXC\\" | nc memcached-server 11211"
   144      STORED
   145      $ kubectl exec $XWING_POD sh -- -c "echo -en \\"$GETXC\\" | nc memcached-server 11211"
   146      VALUE xwing-coord 0 16
   147      8893.34,234.3290
   148      END
   149  
   150  Check that the Alliance Fleet Tracker is able to get all starfighters' coordinates in your terminal window for the Alliance-Tracker:
   151  
   152  .. parsed-literal::
   153  
   154      >>> client.get("awing-coord")
   155      '4309.432,918.980'
   156      >>> client.get("xwing-coord")
   157      '8893.34,234.3290'
   158  
   159  
   160  Step 4:  The Danger of a Compromised Memcached Client
   161  =====================================================
   162  
   163  Imagine if a starfighter ship is captured. Should the starfighter be able to set the coordinates of other ships, or get the coordinates of all other ships? Or if the Alliance-Tracker is compromised, can it modify the coordinates of any starfighter ship?
   164  If every client has access to the Memcached API on port 11211, all have over-privileged access until further locked down.
   165  
   166  With L4 port access to the memcached server, all starfighters could write to any key/ship and read all ship coordinates. In your main terminal, execute:
   167  
   168  .. parsed-literal::
   169  
   170      $ kubectl exec $XWING_POD sh -- -c "echo -en \\"$GETAC\\" | nc memcached-server 11211"
   171      VALUE awing-coord 0 16
   172      4309.432,918.980
   173      END
   174  
   175  In your A-Wing terminal window, confirm the over-privileged access:
   176  
   177  .. parsed-literal::
   178  
   179      >>> client.get("xwing-coord")
   180      '8893.34,234.3290'
   181      >>> client.set("xwing-coord","0.0,0.0",time=2400)
   182      True
   183      >>> client.get("xwing-coord")
   184      '0.0,0.0'
   185  
   186  From A-Wing, set the X-Wing coordinates back to their proper position:
   187  
   188  .. parsed-literal::
   189  
   190      >>> client.set("xwing-coord","8893.34,234.3290",time=2400)
   191      True
   192  
   193  Thus, the Alliance Fleet Tracking System could be made weak if a single starfighter ship is compromised.
   194  
   195  Step 5: Securing Access to Memcached with Cilium
   196  ================================================
   197  
   198  Cilium helps lock down Memcached servers to ensure clients have secure access to it. Beyond just providing access to port 11211,
   199  Cilium can enforce specific key value access by understanding both the text-based and the unstructured (binary) memcached protocol.
   200  
   201  We'll create a policy that limits the scope of what a starfighter can access and write. Thus, only the intended memcached protocol calls to the memcached-server can be made.
   202  
   203  In this example, we'll only allow A-Wing to get and set the key "awing-coord", only allow X-Wing to get and set key "xwing-coord", and allow Alliance-Tracker to only get coordinates.
   204  
   205  
   206  .. image:: images/cilium_memcd_gsg_attack.png
   207  
   208  Here is the *CiliumNetworkPolicy* rule that limits the access of starfighters to their own key and allows Alliance Tracker to get any coordinate:
   209  
   210  .. literalinclude:: ../../examples/kubernetes-memcached/memcd-sw-security-policy.yaml
   211  
   212  A *CiliumNetworkPolicy* contains a list of rules that define allowed memcached commands, and requests
   213  that do not match any rules are denied. The rules explicitly match connections destined to the Memcached Service on TCP 11211.
   214  
   215  The rules apply to inbound (i.e., "ingress") connections bound for memcached-server pods (as indicated by ``app:memcached-server``
   216  in the "endpointSelector" section).  The rules apply differently depending on the
   217  client pod: ``app:a-wing``, ``app:x-wing``, or ``name:fleet-tracker`` as indicated by the "fromEndpoints" section.
   218  
   219  With the policy in place, A-wings can only get and set the key "awing-coord"; similarly the X-Wing can only get and set "xwing-coord". The Alliance Tracker can only get coordinates - not set.
   220  
   221  Apply this Memcached-aware network security policy using ``kubectl`` in your main terminal window:
   222  
   223  .. parsed-literal::
   224  
   225      $ kubectl create -f \ |SCM_WEB|\/examples/kubernetes-memcached/memcd-sw-security-policy.yaml
   226  
   227  If we then try to perform the attacks from the *X-wing* pod from the main terminal window, we'll see that they are denied:
   228  
   229  .. parsed-literal::
   230  
   231      $ kubectl exec $XWING_POD sh -- -c "echo -en \\"$GETAC\\" | nc memcached-server 11211"
   232      CLIENT_ERROR access denied
   233  
   234  From the A-Wing terminal window, we can confirm that if *A-wing* goes outside of the bounds of its allowed calls. You may need to run the ``client.get`` command twice for the python call:
   235  
   236  .. parsed-literal::
   237  
   238      >>> client.get("awing-coord")
   239      '4309.432,918.980'
   240      >>> client.get("xwing-coord")
   241      Traceback (most recent call last):
   242        File "<stdin>", line 1, in <module>
   243        File "/usr/local/lib/python3.7/site-packages/bmemcached/client/replicating.py", line 42, in get
   244          value, cas = server.get(key)
   245        File "/usr/local/lib/python3.7/site-packages/bmemcached/protocol.py", line 440, in get
   246          raise MemcachedException('Code: %d Message: %s' % (status, extra_content), status)
   247      bmemcached.exceptions.MemcachedException: ("Code: 8 Message: b'access denied'", 8)
   248  
   249  Similarly, the Alliance-Tracker cannot set any coordinates, which you can attempt from the Alliance-Tracker terminal window:
   250  
   251  .. parsed-literal::
   252  
   253      >>> client.get("xwing-coord")
   254      '8893.34,234.3290'
   255      >>> client.set("awing-coord","0.0,0.0",time=1200)
   256      Traceback (most recent call last):
   257        File "<stdin>", line 1, in <module>
   258        File "/usr/local/lib/python3.7/site-packages/bmemcached/client/replicating.py", line 112, in set
   259          returns.append(server.set(key, value, time, compress_level=compress_level))
   260        File "/usr/local/lib/python3.7/site-packages/bmemcached/protocol.py", line 604, in set
   261          return self._set_add_replace('set', key, value, time, compress_level=compress_level)
   262        File "/usr/local/lib/python3.7/site-packages/bmemcached/protocol.py", line 583, in _set_add_replace
   263          raise MemcachedException('Code: %d Message: %s' % (status, extra_content), status)
   264      bmemcached.exceptions.MemcachedException: ("Code: 8 Message: b'access denied'", 8)
   265  
   266  The policy is working as expected.
   267  
   268  With the CiliumNetworkPolicy in place, the allowed Memcached calls are still allowed from the respective pods.
   269  
   270  In the main terminal window, execute:
   271  
   272  .. parsed-literal::
   273  
   274    $ kubectl exec $XWING_POD sh -- -c "echo -en \\"$GETXC\\" | nc memcached-server 11211"
   275    VALUE xwing-coord 0 16
   276    8893.34,234.3290
   277    END
   278    $ SETXC="set xwing-coord 0 1200 16\\r\\n9854.34,926.9187\\r\\nquit\\r\\n"
   279    $ kubectl exec $XWING_POD sh -- -c "echo -en \\"$SETXC\\" | nc memcached-server 11211"
   280    STORED
   281    $ kubectl exec $XWING_POD sh -- -c "echo -en \\"$GETXC\\" | nc memcached-server 11211"
   282    VALUE xwing-coord 0 16
   283    9854.34,926.9187
   284    END
   285  
   286  In the A-Wing terminal window, execute:
   287  
   288  .. parsed-literal::
   289  
   290    >>> client.set("awing-coord","9852.542,892.1318",time=1200)
   291    True
   292    >>> client.get("awing-coord")
   293    '9852.542,892.1318'
   294    >>> exit()
   295    # exit
   296  
   297  In the Alliance-Tracker terminal window, execute:
   298  
   299  .. parsed-literal::
   300  
   301    >>> client.get("awing-coord")
   302    >>> client.get("xwing-coord")
   303    >>> exit()
   304    # exit
   305  
   306  
   307  Step 7: Clean Up
   308  ================
   309  
   310  You have now installed Cilium, deployed a demo app, and tested
   311  L7 memcached-aware network security policies.  To clean up, in your main terminal window, run:
   312  
   313  .. parsed-literal::
   314  
   315      $ minikube delete
   316  
   317  For some handy memcached references, see below:
   318  
   319  * https://memcached.org/
   320  * https://github.com/memcached/memcached/blob/master/doc/protocol.txt
   321  * https://python-binary-memcached.readthedocs.io/en/latest/intro/