<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Manuel Portillo</title>
    <description>The latest articles on DEV Community by Manuel Portillo (@manuel220x).</description>
    <link>https://dev.to/manuel220x</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F126868%2F3d49e9b8-a307-43e4-9575-9bd65411f862.jpeg</url>
      <title>DEV Community: Manuel Portillo</title>
      <link>https://dev.to/manuel220x</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/manuel220x"/>
    <language>en</language>
    <item>
      <title>Watching Vault's Audit Logs Using FluentD</title>
      <dc:creator>Manuel Portillo</dc:creator>
      <pubDate>Sun, 27 Jan 2019 23:03:02 +0000</pubDate>
      <link>https://dev.to/manuel220x/watching-vaults-audit-logs-using-fluentd-1e0p</link>
      <guid>https://dev.to/manuel220x/watching-vaults-audit-logs-using-fluentd-1e0p</guid>
      <description>&lt;p&gt;In this post I'm going to explain how you can capture audit logs from a HashiCorp Vault instance into a Fluentd setup running on Docker, this is a scenario where someone needs to troubleshoot specific transactions happening on a vault server with heavy live traffic, which makes a little bit difficult to spot specific known values since all the sensitive information sent to the audit devices in vault is hashed. &lt;/p&gt;

&lt;p&gt;Vault allows you to set up multiple audit devices, these "devices" are basically destination (currently: &lt;em&gt;file&lt;/em&gt;, &lt;em&gt;syslog&lt;/em&gt; and &lt;em&gt;socket&lt;/em&gt; are supported) for detailed logging of operations processed by vault, since audit is a key component on a security product if you enable audit devices on a running vault setup, all the operations processed by the server will wait until &lt;strong&gt;at least one&lt;/strong&gt; of the audit devices finished the processing of the entry, so you have to be careful when enabling audit devices that can be unavailable for long periods of time or that might take much time to process the logs, since this will slow down your operations in vault, in the case you only have that device enabled. &lt;/p&gt;

&lt;p&gt;For security reasons all sensitive information which is part of these log entries is hashed with a salt using HMAC-SHA256. The fields which values are hashed on a typical log are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;client_token&lt;/td&gt;
&lt;td&gt;This is the token that the client uses to authenticate with Vault&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;accessor&lt;/td&gt;
&lt;td&gt;An identifier or alias for the token&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;value&lt;/td&gt;
&lt;td&gt;This field can contain the actual secret being sent as a response&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An example of a couple of audit log entries look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"time":"2019-01-08T06:43:50.1574193Z","type":"request","auth":{"client_token":"hmac-sha256:ccef9257d8853c204ec5bb8a79af25863ad7a8e029093bca5a872d5f7bdee54e","accessor":"hmac-sha256:4340a68ddfefce45d8fb31e3be6f779ca8202cb6d7def6b6f302e8a563ea05fc","display_name":"root","policies":["root"],"token_policies":["root"],"metadata":null,"entity_id":""},"request":{"id":"d999de96-943f-b547-faf7-842c52c1150f","operation":"read","client_token":"hmac-sha256:ccef9257d8853c204ec5bb8a79af25863ad7a8e029093bca5a872d5f7bdee54e","client_token_accessor":"hmac-sha256:4340a68ddfefce45d8fb31e3be6f779ca8202cb6d7def6b6f302e8a563ea05fc","namespace":{"id":"root","path":""},"path":"secret/password","data":null,"policy_override":false,"remote_address":"172.17.0.1","wrap_ttl":0,"headers":{}},"error":""}
{"time":"2019-01-08T06:43:50.1616533Z","type":"response","auth":{"client_token":"hmac-sha256:ccef9257d8853c204ec5bb8a79af25863ad7a8e029093bca5a872d5f7bdee54e","accessor":"hmac-sha256:4340a68ddfefce45d8fb31e3be6f779ca8202cb6d7def6b6f302e8a563ea05fc","display_name":"root","policies":["root"],"token_policies":["root"],"metadata":null,"entity_id":""},"request":{"id":"d999de96-943f-b547-faf7-842c52c1150f","operation":"read","client_token":"hmac-sha256:ccef9257d8853c204ec5bb8a79af25863ad7a8e029093bca5a872d5f7bdee54e","client_token_accessor":"hmac-sha256:4340a68ddfefce45d8fb31e3be6f779ca8202cb6d7def6b6f302e8a563ea05fc","namespace":{"id":"root","path":""},"path":"secret/password","data":null,"policy_override":false,"remote_address":"172.17.0.1","wrap_ttl":0,"headers":{}},"response":{"secret":{"lease_id":""},"data":{"value":"hmac-sha256:420ba9936bd947e90f357f174abbb59bb7d4c2747648afc6498491f1a12dc773"}},"error":""}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the way to secure sensitive data here is by &lt;strong&gt;hashing&lt;/strong&gt; it, there is no way to reverse the process and show the plaintext values of all these hashed fields, however, lets say you know the actual value of the client token and the value of the secret being retrieved on this transaction, the objective would be to obtain something like the following during a live log tracing session, where you might see hundreds of transactions flowing that are not relevant to the client or the value that you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"type":"request","auth":{"client_token":"4VpEnQtil0Sd3GHkNNL25EGK","accessor":"hmac-sha256:e78fdc26ebab94c50101f2805ccb4526b9591a17d4c8e4949c0cc98f456d2288","display_name":"root","policies":["root"],"token_policies":["root"],"metadata":null,"entity_id":""},"request":{"id":"d999de96-943f-b547-faf7-842c52c1150f","operation":"read","client_token":"4VpEnQtil0Sd3GHkNNL25EGK","client_token_accessor":"hmac-sha256:e78fdc26ebab94c50101f2805ccb4526b9591a17d4c8e4949c0cc98f456d2288","namespace":{"id":"root","path":""},"path":"secret/password","data":null,"policy_override":false,"remote_address":"172.17.0.1","wrap_ttl":0,"headers":{}},"error":""}
{"type":"response","auth":{"client_token":"4VpEnQtil0Sd3GHkNNL25EGK","accessor":"hmac-sha256:e78fdc26ebab94c50101f2805ccb4526b9591a17d4c8e4949c0cc98f456d2288","display_name":"root","policies":["root"],"token_policies":["root"],"metadata":null,"entity_id":""},"request":{"id":"d999de96-943f-b547-faf7-842c52c1150f","operation":"read","client_token":"4VpEnQtil0Sd3GHkNNL25EGK","client_token_accessor":"hmac-sha256:e78fdc26ebab94c50101f2805ccb4526b9591a17d4c8e4949c0cc98f456d2288","namespace":{"id":"root","path":""},"path":"secret/password","data":null,"policy_override":false,"remote_address":"172.17.0.1","wrap_ttl":0,"headers":{}},"response":{"secret":{"lease_id":""},"data":{"value":"Ayuda2"}},"error":""}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  The Setup
&lt;/h4&gt;

&lt;p&gt;First, you should have a running instance of Vault, for demonstration purposes I will use a docker image that I have for local testing, the most relevant specifications about this image would be that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It runs Vault 0.11.5&lt;/li&gt;
&lt;li&gt;It uses file storage backend&lt;/li&gt;
&lt;li&gt;Uses TLS with a self-signed certificate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But technically you could do this on any kind of vault setup, as long as you have access to set up audit devices. &lt;/p&gt;

&lt;p&gt;Then we are going to create a Docker image with FluentD and a plugin that I created, basically the plugin, at startup, will connect to the given vault server and request the hash for each of the provided strings, then using this information, for every transaction that arrives at FluentD (vault audit logs), it will parse all the fields with hashed data and for the ones where the hash matches with any of the ones calculated at startup, it will replace the hash with the plaintext value. Then all the transactions will be just sent to stdout, this way, anyone tailing the logs of the docker container will see the plaintext strings. In general, the key elements of the Docker image are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's based on Fluend's 1.3-onbuild image&lt;/li&gt;
&lt;li&gt;Uses the TCP input plugin and its reachable by the vault instance&lt;/li&gt;
&lt;li&gt;It will have the configuration for the filter plugin required to communicate with vault along with the plaintext strings that you want to see in the stdout&lt;/li&gt;
&lt;li&gt;Uses stdout output plugin, so we can watch live entries&lt;/li&gt;
&lt;li&gt;Since FluentD has multiple plugins (input, filtering, forwarding, output), should be easy to extend and add any extra functionality &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To create the image we only need a folder with 3 things on it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The self-signed certificate to be used as a CA certificate file.&lt;/li&gt;
&lt;li&gt;An empty plugins directory (required by the on-build image, but we are not using this method to install the plugin)&lt;/li&gt;
&lt;li&gt;A file named: &lt;code&gt;fluent.conf&lt;/code&gt; which will have the configuration to set up the listener, the filter and the output plugins with the following content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;source&amp;gt;
  @type  tcp
  &amp;lt;parse&amp;gt;
    @type json
  &amp;lt;/parse&amp;gt;
  tag tcp.events
  port  24224
&amp;lt;/source&amp;gt;

&amp;lt;filter tcp.events&amp;gt;
  @type vault_decode
  keywords Ayuda2, 4VpEnQtil0Sd3GHkNNL25EGK #The first string is one of the secret values and the second one is an app token that I'm looking to find in the logs.
  vaultaddr https://172.17.0.4:8200 #This is the vault server that I'm playing with
  vaulttoken 1OIEBC7cLA87ddIJNePEA1U3 # This is a token that has access to call /sys/audit-hash/socket endpoint
&amp;lt;/filter&amp;gt;

&amp;lt;filter tcp.events&amp;gt;
  @type stdout
&amp;lt;/filter&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once these 3 things are in a folder, then we just need the Dockerfile that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; fluent/fluentd:v1.3-onbuild-1&lt;/span&gt;
&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; maintainer="manuel220@yahoo.com"&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; /fluentd/etc/certs

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--virtual&lt;/span&gt; .build-deps &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;sudo &lt;/span&gt;build-base ruby-dev git

&lt;span class="k"&gt;RUN &lt;/span&gt;git clone https://github.com/manuel220x/fluent-plugin-filter-vaultaudit.git &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;fluent-plugin-filter-vaultaudit &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; gem build fluent-plugin-filter-vault-decode.gemspec &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; gem &lt;span class="nb"&gt;install &lt;/span&gt;fluent-plugin-filter-vaultaudit-&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gem sources &lt;span class="nt"&gt;--clear-all&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apk del .build-deps

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; cert.crt /fluentd/etc/certs/&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; fluent.conf /fluentd/etc/&lt;/span&gt;


&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 24224 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And build the image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; fluentd:catchingvault &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the image ready, now you can just start your container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; catchingVaultLogs &lt;span class="nt"&gt;-p&lt;/span&gt; 24224:24224 fluentd:catchingvault
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And start tailing your logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs &lt;span class="nt"&gt;-f&lt;/span&gt; catchingVaultLogs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point your FluentD instance is ready to capture and parse logs, now lets just add an audit device into your vault server under the &lt;code&gt;/socket&lt;/code&gt; path (this is the default on the FluentD plugin and also in vault for socket audit devices, but you can change that), using vault's cli, something like the following should work, being &lt;code&gt;172.17.0.3&lt;/code&gt; the IP address where the vault server can reach the FluentD's container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vault audit &lt;span class="nb"&gt;enable &lt;/span&gt;socket &lt;span class="nv"&gt;address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;172.17.0.3:24224 &lt;span class="nv"&gt;socket_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My Vault instance has 2 audit devices, from which one of those is the one running our FluentD setup, in the following screenshot I'm running a read operation and tailing both audit devices, so you can see the different outputs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F64jh0xp6dd5roc9i4k96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F64jh0xp6dd5roc9i4k96.png" title="Vault CLI command" alt="alt text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8csei7kh8bqga9cpohrb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8csei7kh8bqga9cpohrb.png" title="File Audit Device" alt="alt text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjpyb3tlspqf5kv2yiwz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjpyb3tlspqf5kv2yiwz5.png" title="Socket Audit Device" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see the latest one, it shows the plaintext values that were found at the moment they were happening, as I mentioned before, from here you can extend this to add some grep expressions or even include other plugins to do cool stuff with your logs.&lt;/p&gt;

&lt;p&gt;You can take a look at the code of the plugin here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/manuel220x/fluent-plugin-filter-vaultaudit" rel="noopener noreferrer"&gt;https://github.com/manuel220x/fluent-plugin-filter-vaultaudit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any feedback either here on in Github is welcome. &lt;/p&gt;

</description>
      <category>vault</category>
      <category>fluentd</category>
    </item>
  </channel>
</rss>
