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/