<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Posts tagged with “Security” on Mark van Lent’s weblog</title>
  <updated>2026-01-31T00:00:00+00:00</updated>
  <link rel="self" type="application/atom+xml" href="https://markvanlent.dev/tags/security/index.xml" hreflang="en"/>
  <id>tag:markvanlent.dev,2010-04-02:/tags/security/index.xml</id>
  <link rel="alternate" type="text/html" href="https://markvanlent.dev/tags/security/" hreflang="en"/>
  <author>
      <name>Mark van Lent</name>
      <uri>https://markvanlent.dev/about/</uri>
    </author>
  <rights>Copyright (c) Mark van Lent, Creative Commons Attribution 4.0 International License.</rights>
  <icon>https://markvanlent.dev/favicon.ico</icon>
  <entry>
    <title type="html"><![CDATA[FOSDEM 2026]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2026/01/31/fosdem-2026/" type="text/html" />
    <id>https://markvanlent.dev/2026/01/31/fosdem-2026/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="ansible" />
    <category term="conference" />
    <category term="docker" />
    <category term="infrastructure as code" />
    <category term="git" />
    <category term="python" />
    <category term="security" />
    
    <updated>2026-02-01T14:54:22Z</updated>
    <published>2026-01-31T00:00:00Z</published>
    <content type="html"><![CDATA[<p>January is already almost over, so time for <a href="https://fosdem.org/2026/">FOSDEM</a>,
the yearly <q>free event for software developers to meet, share ideas and
collaborate</q> in Brussels. <a href="/2025/02/01/fosdem-2025/">Last year</a> I
focussed on the Go track, this year I selected a mix of security and Python
related talks to attend.</p>
<h2 id="streamlining-signed-artifacts-in-container-ecosystems--tonis-tiigi">Streamlining Signed Artifacts in Container Ecosystems &mdash; Tonis Tiigi</h2>
<p>It&rsquo;s possible to sign Docker images, but at the moment most are actually not
signed. Also, users should understand what the signature is protecting and what
it&rsquo;s <em>not</em> protecting. We should not want signing just to tick a box on the
security checlist, but because of the security it adds. And we need something
simple: integrated with existing tools, should not slow down tools.</p>
<p>Buildkit powers &ldquo;<code>docker build</code>&rdquo; but is not limited to Dockerfiles. It&rsquo;s high
performance, can build complex builds and has caching.</p>
<p>A modern build is a graph of images, Git repositories, local files, etc. The
results are images, binaries, archives.</p>
<figure><img src="/images/fosdem2026_tonis_tiigi.jpg"
    alt="Photo of Tonis Tiigi explaining the graph that is modern software building"><figcaption>
      <p>Tonis Tiigi explaining that builds of modern software are a complex graph</p>
    </figcaption>
</figure>

<p>We need Supply-chain Levels for Software Artifacts (SLSA) provenance: what has
actually happened in the build? What was the build config? Et cetera. It&rsquo;s useful to
figure out how an artifact was built.</p>
<p>Buildkit does not sign images by default. GitHub has <a href="https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#publishing-a-package-using-an-action">an example in the
documentation</a>
to run a build with Buildkit and generate an artifact. It claims to generate an
<q>unforgeable statement</q>. But if your GitHub credentials are
leaked and the attacker can get your hands on the temporary signing key, they can
use it to sign their own artifacts.</p>
<p>Docker created the <a href="https://github.com/docker/github-builder">github-builder</a>
repository. It contains reusable GitHub Actions to securely build images. If you
use this, your images are signed to prove that they were built from a certain
repository, using the configured build steps. Where Buildkit (among other
things) provides isolation, <code>github-builder</code> provides signing context. It also
protects against build dependency leaks.</p>
<p>So that takes care of the signatures, but how do you verify them?</p>
<ul>
<li>The command &ldquo;<code>docker inspect</code>&rdquo; now shows verified signatures</li>
<li>You can manually verify it with <a href="https://github.com/sigstore/cosign">cosign</a></li>
<li>You can also use sigstore/policy-controller for Kubernetes</li>
</ul>
<p>Buildx also includes experimental Rego (Open Policy Agent) policy support. This
means you can write a matching policy for <code>Dockerfile</code>, e.g. <code>Dockerfile.rego</code>,
which is then automatically loaded. All build sources now need to pass policy
for the build to continue (images, Git repositories, URLs, etc).</p>
<p>You can do very complex stuff in the policies. As simple example Tonis showed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rego" data-lang="rego"><span class="line"><span class="cl"><span class="kd">package</span><span class="w"> </span><span class="nx">docker</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">allow</span><span class="w"> </span><span class="kd">if</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">input</span><span class="o">.</span><span class="nx">image</span><span class="o">.</span><span class="nx">repo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&#34;org/app&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nf">docker_github_builder_tag</span><span class="p">(</span><span class="nx">input</span><span class="o">.</span><span class="nx">image</span><span class="o">,</span><span class="w"> </span><span class="s2">&#34;org/app&#34;</span><span class="o">,</span><span class="w"> </span><span class="nx">input</span><span class="o">.</span><span class="nx">image</span><span class="o">.</span><span class="nx">tag</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>This policy should make sure that the image can only be built from this
repository and that the image tag should match the Git tag.</p>
<p>Summary:</p>
<ul>
<li>No reason not to sign</li>
<li>Not all signatures are equal</li>
<li>Software pulling packages should verify pulled content</li>
</ul>
<p><a href="https://fosdem.org/2026/schedule/event/HJAJTU-streamlining_signed_artifacts_in_container_ecosystems/">Link to the conference page</a></p>
<h2 id="sequoia-git-making-signed-commits-matter--neal-h-walfield">Sequoia git: Making Signed Commits Matter &mdash; Neal H. Walfield</h2>
<p>Version control systems (also known as VCSs) track the following:</p>
<ul>
<li>Changes to the code</li>
<li>Authorship</li>
<li>Other metadata</li>
<li>Commit message</li>
</ul>
<p>But the author can be faked: the metadata is set by the author, including the
author&rsquo;s name. After a quick &ldquo;<code>git config</code>&rdquo; command you can commit as anyone you
want, for example <a href="https://en.wikipedia.org/wiki/Linus_Torvalds">Linus Torvalds</a>.
Sure, GitHub could see that the committer (the one pushing the commit) and
author are different. However, this is not necessarily bad because we might
simply want to give proper attribution to the author of the commit.</p>
<p>And in theory the forge might also be compromised, or someone may have gotten
permission to push to the project.</p>
<p>To prevent impersonations, we can cryptographically prove who the author is by
signing the commits. But now the problem shifts to the certificates. Because
anyone can create a key with any name (again, for example Linus) attached to it.
So what does a signed commit mean now?</p>
<p>How can we be sure that the author is who they say they are? There are ways:</p>
<ul>
<li>You could talk to developer the verify</li>
<li>You could go to <a href="https://en.wikipedia.org/wiki/Key_signing_party">key signing parties</a></li>
<li>You can use a central authority that you trust (e.g.
<a href="https://keys.openpgp.org/">keys.openpgp.org</a>, the Linux developer keyring,
the <code>distributions-gpg-keys</code> package, or, if you trust Github, use
<code>github.com/&lt;username&gt;.gpg</code>)</li>
</ul>
<p>You can use the following command to show the Git log and the signatures on them:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">git log --show-signature
</span></span></code></pre></div><p>But now you need to actually check that the signatures are indeed made by the
certificates you trust.</p>
<p>It&rsquo;s up to the maintainers of the software to curate a list of contributors and
track when contributors join and leave (yes, there is a temporal element as
well). This is hard. Maintainer needs tooling. And you would want to detect
unauthorized commits (impersonation, a malicious forge, a machine in the middle
or for instance when project is given to a new maintainer by a forge/registry).</p>
<p>What does the solution look like?</p>
<ul>
<li>Clear semantics</li>
<li>The project itself maintains signing policy</li>
<li>Third party uses maintainers&rsquo; policy to authenticate project</li>
<li>Verification, not attestation: do not rely on any external authority</li>
</ul>
<p>(Note that the maintainers can still be socially engineered to include the key
of an attacker in their policy. So they still have to be careful about who is
added to the policy.)</p>
<p>Sequoia git provides:</p>
<ul>
<li>Specification</li>
<li>Config</li>
<li>Tooling</li>
</ul>
<p>With <a href="https://gitlab.com/sequoia-pgp/sequoia-git">Sequoia git</a> (which part of
the <a href="https://sequoia-pgp.org/">Sequoia PGP project</a>) you can have a signing
policy in an <code>openpgp-policy.toml</code> file in the project&rsquo;s Git repository. It
specifies users, their keys and their capabilities. You can use <code>sg-git</code> to help
maintain this file.</p>
<p>For instance to add user Alice and then describe the current policy, you can use
the following commands:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sq-git policy authorize alice --committer &lt;cert&gt;
</span></span><span class="line"><span class="cl">sq-git policy describe
</span></span></code></pre></div><p>A commit is &ldquo;authenticated&rdquo; if at least one parent commit says the commit is
acceptable (via the policy). To verify that there is an authenticated path from
the current state back to a certain commit we trust, use this command:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sq-git log --trust-root &lt;sha of trusted commit&gt;
</span></span></code></pre></div><p>Projects may have contributions from others that are not included in the policy.
To maintain an authenticated path when accepting the contribution, a trusted
author needs to merge the contribution via a merge commit that <em>is</em>
authenticated. (You may need to use the &ldquo;<code>--no-ff</code>&rdquo; on the merge to make sure
there is a merge commit though.)</p>
<p><a href="https://fosdem.org/2026/schedule/event/KFSUCW-sequoia-git/">Link to the conference page</a></p>
<h2 id="an-endpoint-telemetry-blueprint-for-security-teams--victor-lyuboslavsky">An Endpoint Telemetry Blueprint for Security Teams &mdash; Victor Lyuboslavsky</h2>
<p>With open source we can inspect something that is broken, we can change the
defaults. With security we are used to the opposite; it&rsquo;s a black box. We are
not used to owning the data. The data exists on the endpoints, but ownership is
transferred to a different team. How can we add more security in a way engineers
understand and can use?</p>
<p>Victor presents a blueprint with the following layers:</p>
<ul>
<li>Endpoint agents</li>
<li>Control layer</li>
<li>Ingestion, streaming &amp; storage</li>
<li>Detection</li>
<li>Correlation, intelligence and response</li>
</ul>
<p>The value is not in the layers themselves, but the boundaries. For example, the
ingestion should move the data reliably but should not care which tool collected
it. This makes them loosely coupled.</p>
<p>For endpoint agents Victor suggests
<a href="https://github.com/osquery/osquery">osquery</a> which allows basic questions about
endpoints. Data is structured and consistent. It aligns with open source values.
(Alternatives: scripts &amp; cron, log shippers like filebeat or tools like auditd
or Event Tracing for Windows.)</p>
<p>Controlling the data (the next layer) means that you want to have:</p>
<ul>
<li>Central config</li>
<li>Live queries</li>
<li>Consistent schemas</li>
</ul>
<p><a href="https://github.com/fleetdm/fleet">Fleet</a> (disclaimer: Victor works here) is
built to manage <code>osquery</code> at scale and a good candidate for this layer.</p>
<p>The control layer needs to work hand-in-hand with ingestion layer. The ingestion
layer moves data to downstream system. E.g. <a href="https://github.com/vectordotdev/vector">Vector</a> or
<a href="https://www.elastic.co/logstash">Logstash</a> can be used here.</p>
<blockquote>
<p>Ingestion isn&rsquo;t where you get clever. It&rsquo;s where you get reliable.</p></blockquote>
<p>Streaming decouples users from consumers and e.g. allows replay. Note that this
is an optional step and it would come <em>after</em> ingestion, not <em>in place of</em> it.
For instance <a href="https://kafka.apache.org/">Apache Kafka</a> can be used in this
layer. Ingestion absorbs the mess. Streaming preserves flexibility.</p>
<p>The storage layer is where telemetry becomes durable. It&rsquo;s about being able to
ask hard questions later. Examples of useful tools:
<a href="https://github.com/ClickHouse/ClickHouse">ClickHouse</a>,
<a href="https://www.elastic.co/elasticsearch">Elasticsearch</a> (which is better at text
search) and <a href="https://github.com/apache/iceberg">Iceberg</a> (which is slower for
active investigation).</p>
<p>For the detection layer you might want to use
<a href="https://github.com/SigmaHQ/Sigma">Sigma</a>. It provided portability. Rules are
translated to native SQL running on ClickHouse. Intent (Sigma signatures)
becomes execution (SQL query to get the data).</p>
<p>Finally the correlation layer: <a href="https://github.com/grafana/grafana">Grafana</a>
can be used for correlation and visualisation. Grafana can query ClickHouse.
Grafana also has alerting.</p>
<p>Note that response isn&rsquo;t just about automation. It&rsquo;s also to pause and ask
better questions. The correlation layer should focus on enabling humans to act.</p>
<p>Open endpoint telemetry is <strong>not</strong> an &ldquo;EDR killer&rdquo;. It does not replace it. It adds
diversity and complements other tools. It provides a second set of eyes.</p>
<p><a href="https://fosdem.org/2026/schedule/event/HYXTPH-endpoint-telemetry-blueprint/">Link to the conference page</a></p>
<h2 id="the-bakery-how-pep810-sped-up-my-bread-operations-business--jacob-coffee">The Bakery: How PEP810 sped up my bread operations business &mdash; Jacob Coffee</h2>
<p>Python loads imports eagerly by default. This leads to memory bloat and cold
start issues. Explicit lazy imports (see
<a href="https://peps.python.org/pep-0810/">PEP 810</a>) only import a module when it&rsquo;s
first accessed not when the import statement is executed.</p>
<p>Lazy import is scheduled to be included in Python 3.15 and looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">lazy</span> <span class="kn">import</span> <span class="nn">foo</span> <span class="kn">from</span> <span class="nn">bar</span>
</span></span></code></pre></div><p>The design principles applied are that lazy imports are:</p>
<ul>
<li>Explicit</li>
<li>Local</li>
<li>Granular</li>
</ul>
<p>When parsing the Python code a proxy module is created. Only when the module is
actually used, the proxy is transparently replaced by the real package. You will
not always see improvements, so do not blindly replace all imports with lazy
imports.</p>
<p>PEP 810 also eliminates the need for <code>TYPE_CHECKING</code> guards. (See the <a href="https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING">typing
docs</a>, in
short: importing a module that is expensive and only contains types used for
type checking in an &ldquo;<code>if TYPE_CHECKING:</code>&rdquo; block.) It also helps for faster test
discovery and collection, less memory usage, decrease cold start slowness in
e.g. AWS Lambda functions, CLI applications, etc.</p>
<p>Meta (with Cinder) saw a 70% startup time reduction and 40% memory savings.
PySide has a 35% startup improvement.</p>
<p>About CLI tools: when using lazy imports you might notice the difference when
using <code>--help</code>. There&rsquo;s no need to load all dependencies to just output the help
text of a tool.</p>
<p>Some notes:</p>
<ul>
<li>Import time side effects (e.g. logging configuration, DB connections) are also
delayed!</li>
<li>Type checkers need to be updated</li>
<li>Import errors move to first use (so in runtime, not at launch). Keep that in
mind when debugging</li>
<li>It&rsquo;s not always faster, so profile your application before migrating and see
where you can potentially benefit</li>
<li>Document your lazy imports!</li>
<li>You cannot do lazy imports in functions</li>
</ul>
<p>Circular imports are probably still a problem, but they just show up later.</p>
<p><a href="https://github.com/JacobCoffee/breadctl">Link to the repo for this talk</a></p>
<p><a href="https://fosdem.org/2026/schedule/event/HAAABD-the_bakery_how_pep810_sped_up_my_bread_operations_business/">Link to the conference page</a></p>
<h2 id="modern-python-monorepo-with-uv-workspaces-prek-and-shared-libraries--jarek-potiuk">Modern Python monorepo with <code>uv</code>, <code>workspaces</code>, <code>prek</code> and shared libraries &mdash; Jarek Potiuk</h2>
<p>Jarek is, besides his other roles, the number 1 Apache Airflow contributor. The
<a href="https://github.com/apache/airflow">Apache Airflow repo</a> is the monorepo he
talks about today. There is also a series of blog posts about this topic: see
<a href="https://medium.com/apache-airflow/modern-python-monorepo-for-apache-airflow-part-1-1fe84863e1e1">part 1</a>,
which links to the other parts.</p>
<p>Airflow drove early requirements for
<a href="https://docs.astral.sh/uv/concepts/projects/workspaces/">uv workspaces</a>. They now
manage 120+ distributions seamlessly with it. It allows them to combine
distributions to work together in a workspace. Also used to import from one
distribution in another one.</p>
<p>The project shares a single virtual environment used by <code>uv</code> in root of project.
If you run &ldquo;<code>uv sync</code>&rdquo; from the top level you get everything. If you run it in a
subdirectory (e.g. <code>airflow-core</code>) you only get what is needed for that
distribution.</p>
<p>Benefits of the <code>uv</code> workspaces:</p>
<ul>
<li>Isolated</li>
<li>Explicit</li>
<li>Flexible</li>
</ul>
<p><a href="https://hatch.pypa.io/1.12/">Hatch</a> has (or will have, at the time of writing)
largely compatible workspaces.</p>
<p>However <a href="https://pre-commit.com/">pre-commit</a> became a bottleneck. They needed
to run 170+ pre commit hooks <strong>on every commit</strong>.
<a href="https://github.com/j178/prek">Prek</a> is drop-in replacement for pre-commit and
works fantastic. It is optimized for speed and monorepos.</p>
<p>Airflow uses symlinked shares libraries (where a shared lib is also a
distribution). The Hatchling build backend needs to replace links with physical
copies during packaging. They use Prek to maintain consistency.</p>
<p><code>uv sync</code> detects conflicts between merged requirements files and Prek hooks
enforce relative imports in shared code to prevent cross coupling issues (IIRC)</p>
<p><a href="https://fosdem.org/2026/schedule/event/WE7NHM-modern-python-monorepo-apache-airflow/">Link to the conference page</a></p>
<h2 id="pyinfra-because-your-infrastructure-deserves-real-code-in-python-not-yaml-soup--loïc-wowi42-tosser">PyInfra: Because Your Infrastructure Deserves Real Code in Python, Not YAML Soup &mdash; Loïc &ldquo;wowi42&rdquo; Tosser</h2>
<p>Loïc is a Frenchmen (which, as he himself states, means he <strong>must</strong> have
opinions) and not a YAML fan to put it mildly. That is: YAML as a programming
language, e.g. how it is used in <a href="https://github.com/ansible/ansible">Ansible</a>.</p>
<figure><img src="/images/fosdem2026_loic_tosser.jpg"
    alt="Photo of Loïc Tosser showing a complex Ansible task in YAML"><figcaption>
      <p>Loïc Tosser demonstrating what happens when you ask a config file to be a programming language</p>
    </figcaption>
</figure>

<p><a href="https://pyinfra.com/">PyInfra</a> is an infrastructure as code library to write
Python code which is then translated to shell scripts to run on the target
hosts. So, in contrast to Ansible, you do not need Python on the target. The
target machine only needs SSH and a POSIX shell. You can also configure Docker
containers with PyInfra.</p>
<blockquote>
<p>If it has SSH, PyInfra can talk to it.</p></blockquote>
<p>PyInfra has idempotent operations and built-in diff checking. Declarative
infrastructure with actual code and not YAML. You can use inventory from
Terraform, Coolify or any API.</p>
<p>You can leverage the entire Python packaging ecosystem. Slack integration? Just
use the right Python package.</p>
<p>PyInfra is not only a CLI tool, you can also use it as a library.</p>
<p>PyInfra is 10 times faster than Ansible, uses 70% less code, has proper code
reuse via <code>import</code> and proper loops instead of <code>with_items</code>. It can have actual
unit tests and can scale to thousands of servers. Also you no longer have error
messages stating that <q>the error appears to be in &hellip; <strong>but may be
elsewhere in the file</strong> &hellip;</q> (looking at you Ansible). PyInfra has
clear error messages without having to specify <code>-vvvv</code> and wading through
hundreds of lines of output.</p>
<p>The suggested migration path:</p>
<ul>
<li>Start small, one playbook at a time</li>
<li>Use your IDE for autocomplete and refactoring</li>
<li>Leverage Python&rsquo;s standard library and the ecosystem with all its packages</li>
<li>Sleep better because you don&rsquo;t have to debug at 3 AM.</li>
</ul>
<p>Is PyInfra production ready? Yes! It has a stable API, is already in use in
production, it&rsquo;s actively maintained and is MIT licensed (so no commercial
entity behind it to steer its direction).</p>
<p>You can get started today with a simple &ldquo;<code>pip install pyinfra</code>&rdquo;.</p>
<p><a href="https://fosdem.org/2026/schedule/event/VEQTLH-infrastructure-as-python/">Link to the conference page</a></p>
<p>(Note from me, Mark, I found Loïc a great speaker: he has lots of energy, is
funny and can transfer his enthusiasm to the room. If the topic interests you
and the video becomes available, I would recommend watching this talk as a great
sales pitch to get started with PyInfra.)</p>
<h2 id="ducks-to-the-rescue---etl-using-python-and-duckdb--marc-andré-lemburg">Ducks to the rescue - ETL using Python and DuckDB &mdash; Marc-André Lemburg</h2>
<p>ETL stands for Extract, Transform, Load. Nowadays we usually do Extract, Load,
Transform because databases are efficient in processing.</p>
<p>DuckDB is open source, in-process analytics data storage (OLAP). It is similar
to SQLite, but for OLAP workloads. It has great Python support and uses SQL as
standard query language. It&rsquo;s pip installable, column based
(<a href="https://arrow.apache.org/">Apache Arrow</a>). It&rsquo;s single writer but allows for
multiple readers, so it&rsquo;s not a distributed database.</p>
<p><a href="https://github.com/pola-rs/polars">Polars</a>&rsquo; streaming can help with processing
your data as a line-by-line stream so you don&rsquo;t have to load the whole file in
memory at once.</p>
<p>Example to load a CSV file into DuckDB extremely fast:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">read_csv</span><span class="p">(...)</span><span class="w">
</span></span></span></code></pre></div><p>You can load the data into staging tables first to prepare everything and not
mess up e.g. existing data. You can then transform data in DuckDB, e.g. filter
out unneeded and duplicate data, validate data, fill in missing data, convert
data types, etc. You can do the transforms in SQL. You can even use native
integrations to write to PostgreSQL, MySQL, etc. Or worst case stream to Python.</p>
<p>Guidelines:</p>
<ul>
<li>Know your queries, that is: know how your data is going to be used</li>
<li>Use the Pareto principle (80/20 rule): optimize for queries that are used
often</li>
<li>Keep a healthy balance between performance and space requirements (which are
often trade-offs)</li>
</ul>
<p>Huge datasets: use the <a href="https://github.com/duckdb/ducklake">DuckLake</a> extension.</p>
<p>To get started: &ldquo;<code>uv add duckdb</code>&rdquo;. Do some experiments and see how it works for
you.</p>
<p><a href="https://fosdem.org/2026/schedule/event/S7RELZ-ducks_to_the_rescue_-_etl_using_python_and_duckdb/">Link to the conference page</a></p>
<h2 id="my-takeaways">My takeaways</h2>
<ul>
<li>Yes, FOSDEM is crowded and you may not be able to get into every talk you want
to see in person, but it&rsquo;s still nice to be there. It&rsquo;s well organised and
there&rsquo;s a friendly atmosphere. Lots of interesting projects to see and people
to talk to. And it&rsquo;s convenient if you want to sponsor your favorite projects
by buying some merchandise.</li>
<li>It&rsquo;s worth investigating signing Docker images (in the right way) further.</li>
<li>Lazy imports look useful! Once Python 3.15 lands it&rsquo;s worth doing profiling on
the projects I work on to see if we can use those to speed things up on
startup and save some memory.</li>
<li>At work we recently decided to go for a monorepo for a project. I want to see
if/how <code>uv</code> workspaces and <code>prek</code> can help us.</li>
<li>I&rsquo;ve written a bunch of Ansible roles to configure my humble homelab and
laptop. Perhaps it&rsquo;s time to switch to PyInfra? It sounds promising and might
be worth the investment of migrating to.</li>
</ul>
<h2 id="about-the-trip">About the trip</h2>
<p><figure class="float-right"><img src="/images/fosdem2026_atomium.jpg"
    alt="Picture of the Atomium at night" width="200px"><figcaption>
      <p>The <a href="https://en.wikipedia.org/wiki/Atomium">Atomium</a> at night</p>
    </figcaption>
</figure>

Last year I drove to Brussels on Friday and stayed at the city center in the
<a href="https://cityboxhotels.com/hotels/brussels/citybox-brussels">Citybox Brussels
hotel</a> for one
night, since I had to be home on Sunday. The upside: it was just a short (15
minute?) tram ride to the FOSDEM location. Unfortunately it did mean I had to
drive home that evening.</p>
<p>This year I had more time, so I booked a room at
<a href="https://www.falkohotel.be/">Falko Hotel</a> for two nights. It&rsquo;s about a 20&ndash;30
minute drive (depending on traffic) to the <a href="https://www.interparking.be/en/parkings/brussels/toison-d-or/">parking
garage</a> I used.
And from there about 20 minutes with pubic transport to the Université libre de
Bruxelles.</p>
<p>Staying another night meant I had more time for sightseeing, had the time to
write this post from my notes and could drive home well rested the next day.</p>
<p>As for tech: besides a phone and laptop, I also brought along two items that
made the trip more comfortable:</p>
<ul>
<li>A <a href="https://mojogear.eu/en/products/mojogear-mini-evo-10-000-mah-power-bank-22-5w">MOJOGEAR Mini
Evo</a>
powerbank to give my phone extra juice to make it through the day. With 10.000
mAh and up to 22.5W of power it&rsquo;s more than sufficient for a day at a
conference. With its small size and less than 175 grams in weight, it&rsquo;s also
easy to carry around.</li>
<li>A <a href="https://www.gl-inet.com/products/gl-sft1200/">GL.iNet Opal (GL-SFT1200)</a>
travel router. I plug it in, hook it up to the hotel internet, start a VPN
connection and all my other devices automatically connect to it and can use
the internet without the hotel snooping on my traffic. (Not that I have an
indication that my hotel would do that, but theoretically they could if I
would not use a VPN.)</li>
</ul>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Open tabs — December 2022]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2022/12/30/open-tabs-december-2022/" type="text/html" />
    <id>https://markvanlent.dev/2022/12/30/open-tabs-december-2022/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="book" />
    <category term="docker" />
    <category term="homelab" />
    <category term="restic" />
    <category term="security" />
    <category term="tabs" />
    
    <updated>2025-09-13T21:07:32Z</updated>
    <published>2022-12-30T00:00:00Z</published>
    <content type="html"><![CDATA[<p>The end of the year is a nice time to review my open tabs on my phone and
computer to see what&rsquo;s worth saving and what is not. So here is
<a href="/tags/tabs/">another round</a>.</p>
<p>Note that I do not necessarily endorse the articles or applications I link to.
Most of the links to tools are here specifically because they seem interesting
to me, but I have no actual experience with them&mdash;hence the need for a reminder
on this list.</p>
<p>I have tried to group the links somewhat, but other than that they are listed in
more or less random order.</p>
<h2 id="development">Development</h2>
<dl>
<dt><a href="https://daniel.feldroy.com/posts/autodocumenting-makefiles">Autodocumenting Makefiles</a></dt>
<dd>A nice trick to document your <code>Makefile</code>.
This article was also discussed on <a href="https://news.ycombinator.com/item?id=30137254">Hacker News</a>.</dd>
<dt><a href="https://github.com/TomNomNom/gron">gron</a></dt>
<dd>From the <code>README</code>: <q>gron transforms JSON into discrete assignments to make it
easier to grep for what you want and see the absolute &lsquo;path&rsquo; to it. It eases the
exploration of APIs that return large blobs of JSON but have terrible
documentation.</q></dd>
<dt><a href="https://asdf-vm.com/">asdf</a></dt>
<dd>A version manager for e.g. Ruby, Node.js, Python.</dd>
<dt><a href="https://sharats.me/posts/shell-script-best-practices/">Shell Script Best Practices</a></dt>
<dd>Some rules of thumb for writing shell scripts which were also
<a href="https://news.ycombinator.com/item?id=33354286">discussed on Hacker News</a>.</dd>
<dt><a href="https://levelup.gitconnected.com/how-to-change-git-default-branch-from-master-3933afab08f9">How to change git default branch from master</a></dt>
<dd>I had to (or wanted to) switch from using the name &ldquo;master&rdquo; for my main branch
to something else (&ldquo;main&rdquo; in most cases) for a couple of Git repositories. It is
not hard, but if you do not do it often, it is convenient to have a guide like this
to make sure you do not forget anything.</dd>
</dl>
<h2 id="blogs">Blogs</h2>
<dl>
<dt><a href="https://bitfieldconsulting.com/">Bitfield Consulting</a></dt>
<dd>I&rsquo;m linking the whole website here since it has a bunch of nice <a href="https://bitfieldconsulting.com/golang">Go related
articles</a> but also interesting articles
in the <a href="https://bitfieldconsulting.com/blog">blog</a>.</dd>
<dt><a href="https://blog.kronis.dev/articles">Kristiāns Kronis&rsquo; blog</a></dt>
<dd>I have a couple of articles on this blog still open to (finish) reading, like
<a href="https://blog.kronis.dev/articles/using-ubuntu-as-the-base-for-all-of-my-containers">Using Ubuntu as the base for all of my containers</a>,
<a href="https://blog.kronis.dev/tutorials/moving-from-gitlab-ci-to-drone-ci">Moving from GitLab CI to Drone CI</a> and
<a href="https://blog.kronis.dev/articles/on-burnout">On burnout</a>.</dd>
<dt><a href="https://www.vharmers.com/">Valentine&rsquo;s blog</a></dt>
<dd>Informative blog of which I still want to read the last two articles in the
<a href="https://www.vharmers.com/tags/opsec/">OpSec blog series</a>.</dd>
<dt><a href="https://www.linuxserver.io/blog">linuxserver.io blog</a></dt>
<dd>A blog by the community that maintains &ldquo;the largest collection of Docker
images on the web&rdquo; (their words).</dd>
</dl>
<h2 id="security">Security</h2>
<dl>
<dt><a href="https://www.goldfiglabs.com/guide/personal-infosec-security-checklist/">The Personal Infosec &amp; Security Checklist</a></dt>
<dd>Actionable best practices to harden your security posture.</dd>
<dt><a href="https://security-list.js.org/#/">Personal security checkist</a></dt>
<dd>Tips for protecting your digital security and privacy.</dd>
<dt><a href="https://defensivecomputingchecklist.com/">A Defensive Computing Checklist</a></dt>
<dd>Another list of tips on how to make your digital life more safe.</dd>
<dt><a href="https://routersecurity.org/">Router Security</a></dt>
<dd>A site with the focus on the security of routers. From the same author as the
previous link.</dd>
<dt><a href="https://aegis-icons.github.io/">Aegis-icons</a></dt>
<dd>Unofficial set of icons for the <a href="https://getaegis.app/">Aegis Authenticator</a>
application.</dd>
<dt><a href="https://ppn.snovvcrash.rocks/">Pentester&rsquo;s Promiscuous Notebook</a></dt>
<dd>Notes by and for a pentester.</dd>
</dl>
<h2 id="homelab">Homelab</h2>
<dl>
<dt><a href="https://github.com/BaptisteBdn/docker-selfhosted-apps">BaptisteBdn/docker-selfhosted-apps</a></dt>
<dd>A GitHub repository with guides on how to run a bunch of applications via
Docker.</dd>
<dt><a href="https://petersem.github.io/dockerholics/">Dockerholics Application List</a></dt>
<dd>Another list of applications you can host yourself using Docker containers.</dd>
<dt><a href="https://github.com/awesome-selfhosted/awesome-selfhosted">Awesome-Selfhosted</a></dt>
<dd>Yet another (<em>the</em>?) list of applications you can run yourself.</dd>
<dt><a href="https://github.com/awesome-foss/awesome-sysadmin">Awesome Sysadmin</a></dt>
<dd>A list of Free and Open-Source sysadmin resources.</dd>
<dt><a href="https://containrrr.dev/watchtower/">Watchtower</a></dt>
<dd>Automatically update your Docker containers if newer images are available.</dd>
<dt><a href="https://crazymax.dev/diun/">Diun</a></dt>
<dd>If you do not like the idea of automatically updating your containers with
Watchtower, you might want to look at this <strong>D</strong>ocker <strong>I</strong>mage <strong>U</strong>pdate
<strong>N</strong>otifier application.</dd>
<dt><a href="https://www.drone.io/">Drone</a></dt>
<dd>I&rsquo;m already running a <a href="https://gitea.io/en-us/">Gitea</a> instance and a
<a href="https://hub.docker.com/_/registry">Docker Registry</a>. Drone might be a nice
third component to automatically build projects and e.g. create Docker images
and push them to my internal registry.</dd>
<dt><a href="https://homelab.khuedoan.com/">Khue&rsquo;s Homelab</a></dt>
<dd>Khue Doan has a project to provision, operate and update his homelab. As such
it is a nice inspiration.</dd>
<dt><a href="https://grafana.com/oss/loki/">Grafana Loki</a></dt>
<dd>A log aggregation system that looks like a useful addition to my setup, since
I&rsquo;m already running <a href="https://grafana.com/grafana/">Grafana</a> to visualise some
metrics.</dd>
<dt><a href="https://vector.dev/">Vector</a></dt>
<dd>This also looks like a interesting tool to collect logs.</dd>
<dt><a href="https://github.com/smallstep/certificates">Step Certificates</a></dt>
<dd>I am already using a private certificate authority to create certificates for
the services in my homelab, but it would be nice to have a self hosted
<a href="https://www.rfc-editor.org/rfc/rfc8555">ACME server</a> to do the tedious work.
This tool might be what I need.</dd>
</dl>
<h2 id="entertainment">Entertainment</h2>
<dl>
<dt><a href="https://play.elevatorsaga.com/">Elevator Saga</a></dt>
<dd>Fun game where you program an elevator/set of elevators to meet certain criteria.</dd>
<dt><a href="https://www.movieofthenight.com/">Movie of the Night</a></dt>
<dd>While officially a <q>movie/series recommendation engine</q> I use
this site regularly to check if I can stream a movie or series in my country and
if so, on which service it is available.</dd>
<dt><a href="https://osmc.tv/">OSMC</a></dt>
<dd>An interesting looking open source media center, which you can run on a
Raspberry Pi or on their devices, like the <a href="https://osmc.tv/vero/">Vero 4K+</a></dd>
<dt><a href="https://www.amazon.com/Lazarus-Heist-Hollywood-Finance-Inside/dp/024155425X">The Lazarus Heist: From Hollywood to High Finance: Inside North Korea&rsquo;s Global Cyber War</a></dt>
<dd>A book about the
<a href="https://en.wikipedia.org/wiki/Lazarus_Group">Lazarus Group</a>, tipped in
<a href="https://darknetdiaries.com/transcript/119/">Darknet Diaries episode 119</a>.</dd>
<dt><a href="https://scottjucha.com/silverships.html">The Silver Ships Series</a></dt>
<dd>A book series by Scott Jucha, tipped in the
<a href="https://twit.tv/shows/security-now">Security Now podcast</a>. (The series is
mentioned in <a href="https://www.grc.com/sn/sn-887.htm">episode 887</a> for the first
time.) I&rsquo;ve finished the first book and loved reading it!</dd>
<dt><a href="https://nostarch.com/open-circuits">Open Circuits</a></dt>
<dd>A lovely book about electronic components with beautiful pictures.</dd>
</dl>
<h2 id="miscellaneous">Miscellaneous</h2>
<dl>
<dt><a href="https://pfauth.com/intentioneel-leven/persoonlijk-manifest/">Schrijf een persoonlijk manifest voor richting in je werk en leven</a> (Dutch)</dt>
<dd>I&rsquo;m not sure I&rsquo;ll ever write such a personal manifest, but just reading this
article gave me enough food for thought to make some decisions.</dd>
<dt><a href="https://www.lifewire.com/use-file-history-in-windows-10-3891070">How to Use File History in Windows 10</a></dt>
<dd>Useful article for people that want to backup and restore files on
Windows machines.</dd>
<dt><a href="https://restic.net/">Restic</a></dt>
<dd>I&rsquo;m in the process of testing this backup tool to see if I want to switch over
to restic from my current <code>rsync</code> based script to backup my Linux machines to an
external disk. If I go that route, I&rsquo;ll also have to have a look at
<a href="https://github.com/binarybucks/restic-tools">restic-tools</a>.</dd>
<dt><a href="https://shen.hong.io/reproducible-pdfa-compliant-latex/">Creating Fully Reproducible, PDF/A Compliant Documents in LaTeX</a></dt>
<dd>When I was perparing my CV and a cover letter, I wanted the resulting PDF to
be more accessible. This article gave me useful instructions on how to achieve
that.</dd>
<dt><a href="https://thepihut.com/blogs/raspberry-pi-tutorials/using-neopixels-with-the-raspberry-pi">Using Neopixels with the Raspberry Pi</a></dt>
<dd>I&rsquo;m toying with the idea of upgrading my home office with some LED
strips. Perhaps I&rsquo;ll use Neopixels and a Raspberry Pi (or similar board) to do
this.</dd>
<dt><a href="https://jvns.ca/blog/things-your-manager-might-not-know/">Things your manager might not know</a></dt>
<dd>An article about how you can help your manager (help you).</dd>
</dl>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Podcasts I listen to — 2019 edition]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2019/10/13/podcasts-i-listen-to-2019-edition/" type="text/html" />
    <id>https://markvanlent.dev/2019/10/13/podcasts-i-listen-to-2019-edition/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="aws" />
    <category term="devops" />
    <category term="observability" />
    <category term="podcast" />
    <category term="python" />
    <category term="security" />
    
    <updated>2021-11-09T20:09:33Z</updated>
    <published>2019-10-13T17:08:00Z</published>
    <content type="html"><![CDATA[<p>Most of the time I use my commute to listen to podcasts. Because they reflect my
interests at this point in time, I thought it would be nice to share my current
list.</p>
<p>The last time I posted my selection of podcasts was back in
<a href="/2012/11/12/podcasts-i-listen-to/">2012</a>. Since then, a lot has changed:</p>
<ul>
<li>Only two out of the six podcasts on the 2012 list are still in my feed. But
there are quite a few new podcasts to compensate.</li>
<li>My commute has reduced from six hours/week to about four.</li>
<li>Out of necessity I no longer listen to all episodes of all podcasts&mdash;I just
do not have enough time to listen to them. But all podcasts in the list below
have interesting episodes, so unsubscribing from them is also not an option.
(I know, first world problems&hellip;)</li>
</ul>
<p>My podcast feed with the reason why I listen to each show:</p>
<ul>
<li><a href="https://www.lastweekinaws.com/">AWS Morning brief</a>: I use this podcast to
quickly get up to speed on AWS related developments. Oh, and I like the snarky
way Corey Quinn summarises the news.</li>
<li><a href="https://www.redhat.com/en/command-line-heroes">Command line heroes</a>: a fun
and educational podcast about topics that interest me as a developer. For
example season 2 was focussed open source development and season 3 was all
about (the history of) programming languages.</li>
<li><a href="https://darknetdiaries.com/">Darknet Diaries</a>: interesting stories about
<q>the dark side of the internet.</q> I love the stories and the way
Jack Rhysider tells them.</li>
<li><a href="https://freakonomics.com/">Freakonomics Radio</a>: a completely different show
because it is not technology focussed. Stephen Dubner discusses topic I often
don&rsquo;t know much about or have not thought about much. I think the episodes are
not only educational but also fun to listen to.</li>
<li><a href="https://www.heavybit.com/library/podcasts/o11ycast/">O11ycast</a>: this one I
recently discovered. Since I&rsquo;m interested in the subject of observability,
this podcast gives me new ideas to think about.</li>
<li><a href="https://www.realworlddevops.com/">Real World DevOps</a>: I really like Mike
Julian&rsquo;s interviews with people from the tech industry about DevOps related
topics. Unfortunately there has not been a new episode for a few months; I
hope Mike will start podcasting again in the future.</li>
<li><a href="https://gimletmedia.com/shows/reply-all">Reply All</a>: a brilliant show. I had
lost track of the hosts, PJ Vogt and Alex Goldman, after they stopped with the
TLDR podcast. Unfortunately I did not search for them, otherwise I would have
found Reply All a lot sooner! I listen to this podcast primarily to get
amused; learning something from it is a nice side effect though.</li>
<li><a href="https://www.lastweekinaws.com/podcast/screaming-in-the-cloud/">Screaming in the cloud</a>: another podcast
from Corey Quinn which I listen to, to learn more about cloud related topics
from the interviews on this show.</li>
<li><a href="https://twit.tv/shows/security-now">Security Now</a>:  I listen to this podcast
for the security related  news and an occasional deep dive into a technical
topic.</li>
<li><a href="https://shoptalkshow.com/">Shop Talk Show</a>: although these days I&rsquo;m more into
infrastructure and automation, I like listening to this show allow to keep in
touch with web development.</li>
<li><a href="https://talkpython.fm/">Talk Python to me</a>: more or less the same as with
Shop Talk Show: I like this podcast for its (Python) development related topics.</li>
<li><a href="https://www.tech45.eu/">Tech45</a>: a podcast I&rsquo;ve listened to for quite some years
now and one of the few shows I want to listen to every single episode of. I
enjoy the way the panel discusses the (tech related) news each week.
Informative and &ldquo;gezellig.&rdquo;</li>
<li><a href="https://soundcloud.com/user-98066669">The privacy, security &amp; OSINT show</a>:
the most recent addition to my list. I have only listened to a few shows yet,
but the topics seem interesting. We&rsquo;ll see if this one sticks or not.</li>
</ul>
<p>And there you have it: my list of podcasts of October 2019. (Also available in
<a href="/files/podcasts-2019.opml">OPML format</a>.)</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Using MFA with AWS CLI]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2019/02/24/using-mfa-with-aws-cli/" type="text/html" />
    <id>https://markvanlent.dev/2019/02/24/using-mfa-with-aws-cli/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="aws" />
    <category term="cli" />
    <category term="mfa" />
    <category term="security" />
    
    <updated>2021-11-09T20:09:33Z</updated>
    <published>2019-02-24T12:10:00Z</published>
    <content type="html"><![CDATA[<p>This post will explain what my workflow looks like when using the command
line interface (CLI) for Amazon Web Services (AWS) when multi-factor
authentication (MFA) is required.</p>
<p>Since it took me a little while to figure out how to get it working in the first
place, and get a comfortable workflow in the second place, I decided to write it
down here for future reference.</p>
<h2 id="context">Context</h2>
<p>First a bit of context.</p>
<p>One of the AWS best practices is to
<a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#enable-mfa-for-privileged-users">enable multi-factor authentication (MFA)</a>
for privileged users. You can even
<a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage.html">create a policy to require MFA</a>.
This means that users affected by the policy will have to enter their MFA code
to log in via the web console, but also if they want to access the AWS APIs from
the command line (e.g. in a Python script or using the
<a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html">AWS CLI</a>).</p>
<p><strong>Without</strong> MFA, you can configure your credentials in <code>~/.aws/credentials</code> and that
file might look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[default]</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_access_key_id</span> <span class="o">=</span> <span class="s">AKIAIFFJM737PF5LH4VA</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_secret_access_key</span> <span class="o">=</span> <span class="s">+gGgW9ElnjG73//uJxziR8dvgQzs++SFbR4at1Q9</span>
</span></span></code></pre></div><p><em>(Don&rsquo;t worry, the credentials have already been revoked.)</em></p>
<p>Assuming you have
<a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html">installed the AWS CLI</a>,
you can now interact with the AWS API like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ aws s3 ls example.user.bucket
</span></span><span class="line"><span class="cl">2019-02-19 20:23:44 <span class="m">3023</span> Vagrantfile
</span></span><span class="line"><span class="cl">2019-02-19 20:23:42 <span class="m">372</span> config.yml
</span></span><span class="line"><span class="cl">2019-02-19 20:23:44 <span class="m">206115</span> screenshot-1.png
</span></span></code></pre></div><p>But when the use of MFA is enforced, you&rsquo;ll see this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ aws s3 ls example.user.bucket
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">An error occurred <span class="o">(</span>AccessDenied<span class="o">)</span> when calling the ListObjects operation: Access Denied
</span></span></code></pre></div><h2 id="assign-an-mfa-device">Assign an MFA device</h2>
<p>Before we can continue, you&rsquo;ll have to configure an MFA device. See the official
documentation on
<a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html">enabling a Virtual Multi-factor Authentication (MFA) Device</a>
for instructions.</p>
<p>Make note of the assigned device, we&rsquo;ll need it in a moment.</p>
<p><img src="/images/mfa-device.png" alt="The AWS console showing the configured MFA devices"></p>
<h2 id="manual-authentication">Manual authentication</h2>
<p>To be able to use the CLI, you&rsquo;ll have to request a so called &ldquo;session token&rdquo;:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ aws sts get-session-token <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    --serial-number arn:aws:iam::xxxxxxxxxxxx:mfa/example.user <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    --token-code <span class="m">287632</span>
</span></span><span class="line"><span class="cl"><span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Credentials&#34;</span>: <span class="o">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;AccessKeyId&#34;</span>: <span class="s2">&#34;ASIARYSXPEDHOE73FL3V&#34;</span>,
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;SecretAccessKey&#34;</span>: <span class="s2">&#34;S1rS...F8KL&#34;</span>,
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;SessionToken&#34;</span>: <span class="s2">&#34;FQoG...seMF&#34;</span>,
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Expiration&#34;</span>: <span class="s2">&#34;2019-02-20T07:36:27Z&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>Note the 6 digit code at the end of the command, this is the code generate by
your MFA device (probably Google Authenticator or a similar app).</p>
<p>You can use these credentials in several ways:</p>
<ul>
<li>
<p>Expose them via environment variables:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ <span class="nb">export</span> <span class="nv">AWS_ACCESS_KEY_ID</span><span class="o">=</span>ASIARYSXPEDHOE73FL3V
</span></span><span class="line"><span class="cl">$ <span class="nb">export</span> <span class="nv">AWS_SECRET_ACCESS_KEY</span><span class="o">=</span>S1rS...F8KL
</span></span><span class="line"><span class="cl">$ <span class="nb">export</span> <span class="nv">AWS_SESSION_TOKEN</span><span class="o">=</span>FQoG...1seMF
</span></span></code></pre></div></li>
<li>
<p>Put them in the credentials file (<code>~/.aws/credentials</code>) as a new profile:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[default]</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_access_key_id</span> <span class="o">=</span> <span class="s">AKIAIFFJM737PF5LH4VA</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_secret_access_key</span> <span class="o">=</span> <span class="s">+gGgW9ElnjG73//uJxziR8dvgQzs++SFbR4at1Q9</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[session]</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_access_key_id</span><span class="o">=</span><span class="s">ASIARYSXPEDHOE73FL3V</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_secret_access_key</span><span class="o">=</span><span class="s">S1rS...F8KL</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_session_token</span><span class="o">=</span><span class="s">FQoG...1seMF</span>
</span></span></code></pre></div><p>Note that with this solution, you&rsquo;ll have to specify the new profile when
using the CLI, e.g. &ldquo;<code>aws s3 ls example.user.bucket --profile session</code>&rdquo;</p>
</li>
</ul>
<p>Since the token is only valid for 12 hours in my case, the manual workflow means
you would have to do the copy/paste routine at least once per (work)day. Since I
don&rsquo;t like repetitive tasks and this is an excellent task to (at least
partially) automate, let&rsquo;s make the computer do the repetitive work for us.</p>
<h2 id="assisted-management-of-session-tokens">Assisted management of session tokens</h2>
<p>Obviously, I&rsquo;m not the first one to want this, so I use a tool that already
exists: <code>aws-mfa</code> (<a href="https://pypi.org/project/aws-mfa/">PyPI</a>,
<a href="https://github.com/broamski/aws-mfa">GitHub</a>).</p>
<p>There are alternatives that do, more or less, the same thing. What I liked about
this tool:</p>
<ul>
<li>MIT license</li>
<li>They use the <a href="https://pypi.org/project/boto3/">boto3</a> library instead of
starting a subprocess, running AWS CLI and parsing the JSON output.</li>
</ul>
<p>As described in the documentation of the tool, you&rsquo;ll have to modify your
credentials file (again: <code>~/.aws/credentials</code>) a little bit:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[default-long-term]</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_access_key_id</span> <span class="o">=</span> <span class="s">AKIAIFFJM737PF5LH4VA</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_secret_access_key</span> <span class="o">=</span> <span class="s">+gGgW9ElnjG73//uJxziR8dvgQzs++SFbR4at1Q9</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_mfa_device</span> <span class="o">=</span> <span class="s">arn:aws:iam::xxxxxxxxxxxx:mfa/example.user</span>
</span></span></code></pre></div><p>Note that the profile name has changed and that the &ldquo;<code>aws_mfs_device</code>&rdquo; line has
been added.</p>
<p>With this configuration in place, you can request an session token:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ aws-mfa
</span></span><span class="line"><span class="cl">INFO - Validating credentials <span class="k">for</span> profile: default
</span></span><span class="line"><span class="cl">INFO - Short term credentials section default is missing, obtaining new credentials.
</span></span><span class="line"><span class="cl">Enter AWS MFA code <span class="k">for</span> device <span class="o">[</span>arn:aws:iam::xxxxxxxxxxxx:mfa/example.user<span class="o">]</span> <span class="o">(</span>renewing <span class="k">for</span> <span class="m">43200</span> seconds<span class="o">)</span>: <span class="m">466139</span>
</span></span><span class="line"><span class="cl">INFO - Fetching Credentials - Profile: default, Duration: <span class="m">43200</span>
</span></span><span class="line"><span class="cl">INFO - Success! Your credentials will expire in <span class="m">43200</span> seconds at: 2019-02-20 08:03:25+00:00
</span></span></code></pre></div><p>If you check your credentials file again, you&rsquo;ll see that a &ldquo;<code>default</code>&rdquo; profile
has been added.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[default]</span>
</span></span><span class="line"><span class="cl"><span class="na">assumed_role</span> <span class="o">=</span> <span class="s">False</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_access_key_id</span> <span class="o">=</span> <span class="s">ASIARYSXPEDHNH5EOH3I</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_secret_access_key</span> <span class="o">=</span> <span class="s">fcD3...+FL3A</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_session_token</span> <span class="o">=</span> <span class="s">FQoG...seMF</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_security_token</span> <span class="o">=</span> <span class="s">FQo...seMF</span>
</span></span><span class="line"><span class="cl"><span class="na">expiration</span> <span class="o">=</span> <span class="s">2019-02-20 08:03:25</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[default-long-term]</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_access_key_id</span> <span class="o">=</span> <span class="s">AKIAIFFJM737PF5LH4VA</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_secret_access_key</span> <span class="o">=</span> <span class="s">+gGgW9ElnjG73//uJxziR8dvgQzs++SFbR4at1Q9</span>
</span></span><span class="line"><span class="cl"><span class="na">aws_mfa_device</span> <span class="o">=</span> <span class="s">arn:aws:iam::xxxxxxxxxxxx:mfa/example.user</span>
</span></span></code></pre></div><p>Your original credentials in the &ldquo;<code>default-long-term</code>&rdquo; section are unchanged,
but the new &ldquo;<code>default</code>&rdquo; profile has all the short lived credentials.</p>
<p>As you can see, the new profile has an &ldquo;<code>aws_session_token</code>&rdquo; and an
&ldquo;<code>aws_security_token</code>&rdquo; entry with the same token. Apparently this is to
<a href="https://github.com/broamski/aws-mfa/blob/0.0.12/awsmfa/__init__.py#L345-L346">support both boto and boto3</a></p>
<p>Once again the AWS CLI is working again:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ aws s3 ls example.user.bucket
</span></span><span class="line"><span class="cl">2019-02-19 20:23:44 <span class="m">3023</span> Vagrantfile
</span></span><span class="line"><span class="cl">2019-02-19 20:23:42 <span class="m">372</span> config.yml
</span></span><span class="line"><span class="cl">2019-02-19 20:23:44 <span class="m">206115</span> screenshot-1.png
</span></span></code></pre></div><p>The biggest difference with the manual workflow is that this takes a whole lot
less typing and is much less error prone.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Open Source Summit Europe 2018: day two]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2018/10/23/open-source-summit-europe-2018-day-two/" type="text/html" />
    <id>https://markvanlent.dev/2018/10/23/open-source-summit-europe-2018-day-two/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="cloud" />
    <category term="conference" />
    <category term="devops" />
    <category term="security" />
    
    <updated>2021-10-26T18:57:58Z</updated>
    <published>2018-10-23T00:00:00Z</published>
    <content type="html"><![CDATA[<p>Another set of notes taken at the Open Source Summit Europe 2018.</p>
<p><em>These are just notes. They are not proper summaries of the talks.</em></p>
<p><img src="/images/osse18_day2.jpg" alt="Day two of the Open Source Summit Europe 2018"></p>
<h2 id="three-years-of-lessons-from-running-potentially-malicious-code-inside-containers--ben-hall-katacoda">Three years of Lessons from Running Potentially Malicious Code Inside Containers &mdash; Ben Hall (Katacoda)</h2>
<p>Katacoda is an interactive learning environment where people can get shell
access on machines provided by Katacoda via their browser. People are prone to
experiment. Katacoda needs to make sure that one person cannot have an impact on
other customers.</p>
<p>Docker has a number of security related features, like:</p>
<ul>
<li>Running as a non root user in the container.</li>
<li>File isolation via copy on write.</li>
<li>Limits on what resources users can use (memory, CPU), via cgroups.</li>
<li>Constrict a container via namespaces.</li>
<li>Restrict privileges so you cannot use e.g. setuid/setgid.</li>
<li>Seccomp to limit system calls.</li>
<li>Running profiles via AppArmor.</li>
</ul>
<p><img src="/images/osse18_ben_hall.jpg" alt="Ben Hall: is the CPU spike malicious or not?"></p>
<p>You need visibility into your containers. If the CPU spikes, is there
cryptocurrency mining going on, or is it a legitimate machine learning job?</p>
<p>How do we solve a problem like mining? Cgroups are not enough. You would like
to have traffic shaping to e.g. limit the amount of data a container can send.
You can also:</p>
<ul>
<li>Kill long running processes (easier to do when using orchestrators like Docker
Swarm or Kubernetes)</li>
<li>Block or restrict outbound network traffic (block by default and only allow
legit usage)</li>
</ul>
<p>You could use iptables for the latter. However, this does not work with Docker
since it uses a separate Docker chain. When running in Kubernetes it would be
easier via a service mesh (like Consul or Istio).</p>
<p>But if you cannot block everything, it fundamentally is a cat and mouse game.</p>
<p>When the host is attacked via a container, having privileged containers is the
worst since you can easily break out of them (inserting SSH keys, finding
Docker credentials, etc, etc).</p>
<p>You can limit the number of processes to prevent e.g. fork bombs
(<code>--pids-limit=2048</code>).</p>
<p>Visibility into your system is key.</p>
<p>Tips:</p>
<ul>
<li>Log iptables drops</li>
<li>Sysdig Falco</li>
<li>Have a security pipeline (e.g. using Aqua)</li>
</ul>
<p>Are containers secure? Fundamentally yes. But you also have to think about the
security measures that are in place.</p>
<p>Quick wins:</p>
<ul>
<li>Don&rsquo;t allow root</li>
<li>Read only file systems</li>
<li>Block egress (why do you need run <code>apt-get</code> in production?)</li>
<li>Network policies / service mesh / Istio!</li>
<li>Create visibility</li>
</ul>
<h2 id="cloud-object-storage-the-right-way--orit-wasserman-lightbits-labs">Cloud Object Storage: The Right Way &mdash; Orit Wasserman (Lightbits Labs)</h2>
<p>Objects are organized in a bucket (like a folder, but they cannot be nested) and
are immutable. Cloud object storage means you use a restful API to access the
objects. Common clouds: AWS S3, Swift (OpenStack), Google cloud storage and Ceph
(which can be used as private cloud object storage solution).</p>
<p>You&rsquo;ll want to use cloud object storage:</p>
<ul>
<li>if you need to scale</li>
<li>have lots of large objects that are rarely updated</li>
<li>have small objects that are infrequently updated and are not performance sensitive</li>
<li>slow hard drives</li>
</ul>
<p>When <strong>not</strong> to use cloud object storage:</p>
<ul>
<li>When the application does a lot of in place writes in big files.</li>
<li>Legacy applications that cannot use the object storage API.</li>
</ul>
<p>Special features:</p>
<ul>
<li>Multipart upload
<ul>
<li>Upload one object as a set of parts (initiate object, upload the bits and
complete the object).</li>
<li>Benefits are improved throughput, quick recovery from network issues,
pause/resume upload.</li>
<li>Pitfalls: not recommended for small objects, limit for regular uploads is
5GB, unless you are careful you can leave orphans after incomplete uploads.</li>
</ul>
</li>
<li>Versioning
<ul>
<li>Not enables by default because it takes up space (and you pay for what you
use).</li>
</ul>
</li>
<li>Lifecycle
<ul>
<li>Expire old objects.</li>
<li>Move objects to colder storage.</li>
</ul>
</li>
<li>Virtual hierarchy
<ul>
<li>By adding a prefix you can &lsquo;fake&rsquo; hierarchy.</li>
</ul>
</li>
<li>Static website
<ul>
<li>Cloud storage already has a webserver. You can serve your website directly
from cloud object storage.</li>
</ul>
</li>
</ul>
<p><img src="/images/osse18_orit_wasserman.jpg" alt="Orit Wasserman about cloud object storage security"></p>
<p>To increase security of your cloud object storage usage, you should use
signatures if your provider and SDK support it.</p>
<p>You should also encrypt the traffic (there is a performance penalty though).
Server side encryption is not enough because this means you will have to trust
your cloud provider. You should also encrypt client side (SSE-C or SSE-KMS).</p>
<p>Pay attention to access control. It might not be simple or convenient, but
please use it. Give as little permission as needed. Be very careful with public
buckets!</p>
<p>Even though your storage is now safe, you can still have a disaster you need to
recover from. You need to have a disaster recovery plan and test that plan
regularly. Ceph provides geo replication.</p>
<p>Replication in Ceph makes a distinction between metadata and data operations.
Metadata is usually small and updated infrequently. It is replicated
synchronous.</p>
<p>Data on the other hand is usually about large amounts of data and there are
frequent operations. These operations are asynchronous.</p>
<p>(<a href="https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Cloud-Object-Storage-The-Right-Way-Orit-Wasserman-Lightbits-Labs.pdf">Slides</a>)</p>
<h2 id="cloud-init-the-cross-cloud-magic-sauce--scott-moser--chad-smith-canonical">Cloud-init: The cross-cloud Magic Sauce &mdash; Scott Moser &amp; Chad Smith (Canonical)</h2>
<p>Cloud-init helps with initial initialization, which is convenient for you. It
also allows cloud platform providers to have a few generic images and only on
instantiation make them specific (instead of having thousands of specific images
to begin with). Cloud-init supports a bunch of distributions, not just Ubuntu.
It also supports many cloud providers.</p>
<p><img src="/images/osse18_scott_moser_and_chad_smith.jpg" alt="Scott Moser talking about the supported cloud providers and Chad Smith listening"></p>
<p>The goals of cloud-init:</p>
<ul>
<li>Remove the need to make a custom image or reboot. There are a couple of moment
where you can execute code: ASAP, once the network is up or at the end.</li>
<li>Option to create an image from a snapshot. You can choose to execute code on
boot once, per instance or per boot.</li>
<li>Make it easier to migrate to different clouds.</li>
<li>OSes should only have to ship one single image.</li>
</ul>
<p>Instance input:</p>
<ul>
<li>Disk image</li>
<li>Meta data (hostname, authorization info like SSH keys, etc)</li>
<li>Network configuration (multiple NICs and IPs, bridges, vlans, etc)</li>
<li>User data (e.g. commands to execute)</li>
<li>Vendor data (like vendor data but for the platform)</li>
</ul>
<p>Cloud-init wanted to provide a common interface since every cloud provider does
things (slightly) different.</p>
<p>Cloud-init provides specific configuration to (amongst others):</p>
<ul>
<li>Grow the root partition</li>
<li>Add/upgrade packages</li>
<li>Set the timezone/locale</li>
<li>Run arbitrary code</li>
<li>Start Puppet or Chef</li>
</ul>
<p>Notable changes in cloud-init versions 18.4 and 18.5:</p>
<ul>
<li>Standardized instance metadata in <code>/run/cloud-init/instance-data.json</code></li>
<li>Extended command line tooling (<code>query</code>, <code>analyze</code> and <code>status</code>).</li>
<li>Automatic network configuration based on metadata/udev events (to come in 18.5)</li>
</ul>
<p>You can use Jinja templates for your cloud-init config. The example from the slides:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-plaintext" data-lang="plaintext"><span class="line"><span class="cl">## template: jinja
</span></span><span class="line"><span class="cl">#cloud-config
</span></span><span class="line"><span class="cl">{% set HN=&#39;oss-&#39; ~ v1.platform ~ &#39;-&#39; ~ v1.region ~ &#39;-&#39; ~ range(9) | random %}
</span></span><span class="line"><span class="cl">puppet:
</span></span><span class="line"><span class="cl">  conf:
</span></span><span class="line"><span class="cl">    agent:
</span></span><span class="line"><span class="cl">    server: puppetserver.blackboxsw.com
</span></span><span class="line"><span class="cl">    certname: {{ HN }}
</span></span><span class="line"><span class="cl">hostname: {{ HN }}
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">{% if v1.region == &#39;us-east-2&#39; and v1.cloud_name == &#39;aws&#39; -%}
</span></span><span class="line"><span class="cl">echo &#39;Installing custom proxies ...’
</span></span><span class="line"><span class="cl">{%- endif %}
</span></span></code></pre></div><p>(<a href="https://events19.linuxfoundation.org/wp-content/uploads/2017/12/cloud-init-The-cross-cloud-Magic-Sauce-Scott-Moser-Chad-Smith-Canonical.pdf">Slides</a>)</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[All Day DevOps conference]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2018/10/17/all-day-devops-conference/" type="text/html" />
    <id>https://markvanlent.dev/2018/10/17/all-day-devops-conference/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="conference" />
    <category term="devops" />
    <category term="monitoring" />
    <category term="security" />
    
    <updated>2021-10-26T18:57:58Z</updated>
    <published>2018-10-17T00:00:00Z</published>
    <content type="html"><![CDATA[<p><a href="https://www.alldaydevops.com/">All Day DevOps</a> is a 24 hours long, online
conference about DevOps with 125 sessions in five tracks.</p>
<p><em>Note: these are my notes. They are not necessarily representative or complete summaries of the talks.</em></p>
<h2 id="container-security-monitoring-using-open-source--madhu-akula-appsecco">Container security monitoring using open source &mdash; Madhu Akula (AppSecCo)</h2>
<p>Why is container security monitoring  (CSM) important? An attacker could gain
access to one of your containers. Or you may be using an image from the Docker
Hub with malicious code. CSM can help you to take actions based on the
monitoring alerts.</p>
<p>For CSM it is important to collect your logs on a central location. Then we can
analyse them to find suspicious patterns. Based on the patterns we identified,
we can set thresholds and create pattern to trigger alerts.</p>
<p>How to look at logs? E.g. using commands like &ldquo;<code>docker events</code>&rdquo; or &ldquo;<code>docker logs</code>&rdquo;.
Using &ldquo;<code>docker diff &lt;container&gt;</code>&rdquo; you can check which files have changed in your
container. Although not security specific, for system level monitoring you can
use <a href="https://github.com/google/cadvisor">cAdvisor</a>.</p>
<p>For security specific monitoring you can have a look at AppArmor, Auditd,
Elastic Beats (e.g. the
<a href="https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-module-auditd.html">auditd module</a>)
and <a href="https://sysdig.com/opensource/falco/">Sysdig Falco</a>.</p>
<p>Sysdig Falco is not an enforcement tool, but an auditing and monitoring tool.
With Falco you can load rules that trigger on events, e.g. when a shell was
spawned or a sensitive file has been opened. Falco comes with rules, but you can
also customize rules yourself.</p>
<p>You can even create an automated defence to e.g. deploy new versions when an
alert triggers (as was shown in a demo).</p>
<h2 id="7-container-design-patterns-you-need-to-know--christian-melendez-equinix">7 Container design patterns you need to know &mdash; Christian Melendez (Equinix)</h2>
<p>Most of your problems are not unique, both in software development and container
usage. Having patterns makes it easier to communicate: they provide a shared
language to known problems. Having patterns also allows you to reuse shared
components (solutions).</p>
<h3 id="patterns-for-a-single-container">Patterns for a single container</h3>
<h4 id="single-container-pattern">Single-container pattern</h4>
<p>A base for other patterns.</p>
<ul>
<li>Establish resource boundaries</li>
<li>Isolate resources from others</li>
<li>Separate concerns &mdash; the container only has one responsibility</li>
</ul>
<h4 id="sidecar-pattern">Sidecar pattern</h4>
<p>Extend an application container with extra tools.</p>
<ul>
<li>Co-schedule the sidecar in the same node (same pod in the case of Kubernetes)</li>
<li>Shared resources (volumes)</li>
</ul>
<h4 id="ambassador-pattern">Ambassador pattern</h4>
<p>The ambassador is a broker or proxy between an application and consumers.</p>
<ul>
<li>Modular</li>
<li>Reusable in other applications</li>
</ul>
<h4 id="adapter-pattern">Adapter pattern</h4>
<p>An application container to modify the interface of the application to e.g.
provide a consistent interface.</p>
<ul>
<li>Helps to set a communication standard</li>
<li>Can translate between protocols</li>
<li>Reusable modules, perhaps environment variables to configure behaviour</li>
<li>Examples: collect metrics, parse and store logs, custom health checks</li>
</ul>
<h3 id="multi-node-patterns">Multi-node patterns</h3>
<p>Used to scale at the node level for loosely coupled applications. Communication
is via network calls. They are the base for microservices.</p>
<h4 id="scattergather-pattern">Scatter/Gather pattern</h4>
<p>Split a big task to into smaller tasks that can run simultaneous and combine the
results afterwards.</p>
<ul>
<li>Partial processing</li>
<li>Multiple threads for requests and process</li>
<li>Response time is the sum of all requests</li>
</ul>
<h4 id="leader-election-pattern">Leader election pattern</h4>
<p>How to select a new leader when the old leader fails.</p>
<ul>
<li>Reuse, don&rsquo;t invent your own wheel</li>
<li>Container implementations like etcd, Zookeeper and Consul</li>
</ul>
<h4 id="work-queue">Work Queue</h4>
<p>One manager container with multiple worker containers. The manger concurrently
distributes the tasks to the workers.</p>
<h2 id="how-to-build-an-effective-container-based-local-development-environment--martino-fornasa-kiratech">How To Build An Effective Container-Based Local Development Environment &mdash; Martino Fornasa (Kiratech)</h2>
<p>Having a local development workflow is important:</p>
<ul>
<li>Easier onboarding</li>
<li>Consistent software dependency management</li>
<li>Environment similar to production</li>
<li>Local testing (faster than waiting for CI tool)</li>
<li>You build knowledge</li>
</ul>
<p>Creating a local environment is <em>hard</em>. Lots of variables to take into account
like languages, preferences of developers, you need to keep allow a certain
flexibility.</p>
<p>A first attempt led to issues:</p>
<ul>
<li>Speed</li>
<li>Sync issues</li>
<li>Cleanup</li>
<li>Resources (CPU/memory)</li>
</ul>
<p>And people hated it.</p>
<p>Goals for a proper solution:</p>
<ul>
<li>Tune for performance and reusability</li>
<li>Allow people to use their preferred tools</li>
<li>Make it easy to do the right thing.</li>
</ul>
<p>When your target is Kubernetes, your development workflow should also take this
into account. Benefits of a Kubernetes workflow:</p>
<ul>
<li>Easier to setup complex environments</li>
<li>Same/similar tools for development and deployment</li>
<li>Each developer is able to run the full system (perhaps using external systems)</li>
</ul>
<p>Three approaches:</p>
<ul>
<li>Auto rebuild the image on each code change, push to registry and deploy in the
cluster. Related tools: <a href="https://github.com/Azure/draft/">draft</a> and
<a href="https://github.com/GoogleContainerTools/skaffold">skaffold</a>. Skaffold is
probably more convenient for interpreted languages.</li>
<li>Run on cluster + sync the filesystem between the local system and the cluster.
Higher risk of drift between local image and image built by your CI system.
Tools: <a href="https://github.com/GoogleContainerTools/skaffold">skaffold</a> and
<a href="https://github.com/ksync/ksync">ksync</a>.</li>
<li>Run locally + develop against remote resources. Tool: <a href="https://www.telepresence.io/">telepresence</a>.</li>
</ul>
<h2 id="devsecops-toolchain-blocking-dangerous-containers--siamak-sadeghianfar-red-hat--georgios-kryparos-tink">DevSecOps Toolchain: Blocking Dangerous Containers &mdash; Siamak Sadeghianfar (Red Hat) &amp; Georgios Kryparos (Tink)</h2>
<p>DevSecOps is a shift in both mindset (everyone is responsible for security) and
security work (security as code).</p>
<p>We&rsquo;ve gone from running applications on hardware to running them in a VM using
a hypervisor. Then we started running applications in containers (which may or may not run in
a VM). Now the world is even more complex with container orchestrators. In
summary: many layers to take into account. And then we haven&rsquo;t even touched on
the registry for images&hellip;</p>
<p>Containers have brought good things (consistency from dev to production, faster
deployments), but they have also brought security concerns:</p>
<ul>
<li>isolation breakouts</li>
<li>outdated apps and dependencies</li>
<li>secret management is an additional headache</li>
<li>auditing and monitoring are still issues we need to deal with</li>
</ul>
<p>You need vulnerability scanners, configuration auditors, secret scanners and
traffic monitors on all levels: host, container engines, orchestrator and
registry.</p>
<p>Tools you can use to help you:</p>
<ul>
<li><a href="https://www.sonarqube.org/">SonarQube</a>: code analysis</li>
<li><a href="https://cloud.redhat.com/products/quay">Quay Security Scanner</a> (using <a href="https://github.com/quay/clair">Clair</a>)</li>
<li><a href="https://www.aquasec.com/aqua-cloud-native-security-platform/">Aqua Container Security Platform</a></li>
</ul>
<p>Takeaways:</p>
<ul>
<li>Automation! Shift security to the left.</li>
<li>Shared visibility</li>
<li>Train first, enforce later</li>
<li>Collaboration between dev, sec and ops teams, but also e.g. quality assurance</li>
</ul>
<h2 id="zero-gain-vs-zero-loss-practical-tales-of-enterprise-decision-making--amélie-koran-hhs">Zero Gain vs. Zero Loss: Practical Tales of Enterprise Decision-Making &mdash; Amélie Koran (HHS)</h2>
<p>Leadership would like to see as little loss as possible. Selling the value of
what you do on a day-to-day basis to others in the organization is important.</p>
<p>A &ldquo;play&rdquo; is an action you can take to affect a certain outcome.
Examples: skills development and applicability of what you do to the mission of
the business.</p>
<h3 id="play-one-metaphors">Play one: metaphors</h3>
<p>Metaphors allow you to connect on a common touchstone. E.g. use physical
security measures as a metaphor for &ldquo;cyber&rdquo; security measures; executives can
conceptualize the former, but perhaps not the latter.</p>
<p>Don&rsquo;t talk tech, talk about something they are familiar with. Examples: risk,
saving money, spend a little to prevent a greater loss.</p>
<h3 id="play-two-participation">Play two: participation</h3>
<p>Having a seat at the table is valuable. Think about design sprints, strategy
sessions, budget planning sessions. This leads to deeper connections, reduces
communication barriers, creates more empathy and enables awareness.</p>
<h3 id="play-three-conceptualization">Play three: conceptualization</h3>
<p>Defining stuff is important. Having a shared lexicon helps communication. The
terms and definitions enable knowledge sharing.</p>
<p>Clear communication has all kinds of benefits like reducing questions, stress
and anxiety.</p>
<h3 id="story-time">Story time</h3>
<p>Why do people want dashboards? They would love to have a single number to give
them insight in how things are going. But what is the question that is to be
answered? What decision should the dashboard support? Is what is being presented
actionable?</p>
<p>Tips:</p>
<ul>
<li>Aim to reduce user errors (via good UX/UI)</li>
<li>Automate tests</li>
<li>Don&rsquo;t deploy to production, invest in development and test environments</li>
<li>Perform root cause analysis for major issues</li>
<li>Include the proper team members (for instance: include security people)</li>
</ul>
<h2 id="monitoring-the-easy-way--daniel-barker-national-association-of-insurance-commissioners">Monitoring the easy way &mdash; Daniel Barker (National Association of Insurance Commissioners)</h2>
<p>Some definitions:</p>
<dl>
<dt>Observability</dt>
<dd>Based on the output the system state should be deterministic.</dd>
<dt>Controllability</dt>
<dd>Based on the input the system state should be deterministic.</dd>
</dl>
<p>Observability tools (in implementation order):</p>
<ul>
<li>Metrics aggregation</li>
<li>Log aggregation</li>
<li>Alerting and visualizations</li>
<li>Distributed tracing (harder than the others to implement, not all systems need it)</li>
</ul>
<p>Let&rsquo;s have a look at each of those tools.</p>
<h3 id="metrics">Metrics</h3>
<p>Metrics aggregation tools:</p>
<ul>
<li>Prometheus, used a lot with Kubernetes</li>
<li>Graphite</li>
<li>InfluxDB</li>
<li>OpenTSDB</li>
</ul>
<p>The two last ones are great for long term storage for Prometheus.</p>
<p>OpenMetrics is a metrics exposition format. Implement your metrics once and
different products can understand them. Datadog is currently the only commercial
product that support this standard; it is still early days though.</p>
<h3 id="logs">Logs</h3>
<p>Log aggregation tools:</p>
<ul>
<li>Splunk (commercial)</li>
<li>ELK stack</li>
<li>Graylog</li>
<li>FluentD (not log aggregation, but you can use it to replace Logstash in your
ELK stack because it is a bit more efficient)</li>
</ul>
<p>Tips:</p>
<ul>
<li>Assume your logs arrive in a random order in your log aggregation service so
include a timestamp</li>
<li>Use UTC for your timestamps</li>
<li>Format logs in JSON</li>
<li>Log <em>all</em> application errors, don&rsquo;t eat them without logging them, otherwise
you don&rsquo;t find out about them until your users start complaining</li>
<li>Turn logging on</li>
<li>Make the log messages human readable because they are meant to be read by humans</li>
<li>Do not log informational/debug data in production</li>
<li>Do not log anything a human cannot read or react on</li>
<li>Only log significant events</li>
<li>Do not print personally identifiable information (PII)</li>
</ul>
<h3 id="alerting-and-visualization">Alerting and visualization</h3>
<p>Only send alerts when action can be taken. Information is never an alert.</p>
<blockquote>
<p>You would not go running around the town square yelling the weather.</p></blockquote>
<p>Visualization: you should be able to look at it and understand the system better.</p>
<p>Tools:</p>
<ul>
<li>Prometheus AlertManager</li>
<li>Bosun</li>
<li>Cabot</li>
<li>StatsAgg (does a lot more than just alerting)</li>
<li>Grafana</li>
<li>Vizceral</li>
<li>Flame graphs</li>
</ul>
<h3 id="distributed-tracing">Distributed tracing</h3>
<p>Track requests throughout the system</p>
<p>Tools:</p>
<ul>
<li>Zipkin</li>
<li>Jaeger</li>
<li>AppDash</li>
</ul>
<p>More information in the article <a href="https://opensource.com/article/18/8/now-available-open-source-guide-devops-monitoring-tools">The open source guide to DevOps monitoring tools</a>.</p>
<h2 id="getting-started-with-chaos-engineering--ana-medina-gremlin">Getting started with chaos engineering &mdash; Ana Medina (Gremlin)</h2>
<p>Definition of chaos engineering: thoughtful, planned experiments designed to
reveal the weakness in our systems.</p>
<p>Chaos engineering is <strong>not</strong> about unexpected or unmonitored experiments. It is
also <strong>not</strong> about creating outages.</p>
<blockquote>
<p>Like a vaccine, we inject harm to build immunity.</p></blockquote>
<p>Use cases: outage reproduction, on-call training, strengthen products and battle
test infrastructure.</p>
<p>Prerequisites for chaos engineering:</p>
<ul>
<li>Monitoring and observability in place</li>
<li>On-call and incident management (a good SRE practice in general)</li>
<li>Know the cost of downtime per hour</li>
</ul>
<p>You can inject chaos on all layers. Nice places to do it are e.g. Elasticsearch,
Cassandra, etc.</p>
<p>To get started with chaos engineering, pick one of the top 5 most critical
systems. Whiteboard the system and determine what experiment you want to run
(e.g. maximize CPU, kill processes, packet loss) and determine the blast radius
(for example only impact 1% of your traffic).</p>
<p>Chaos day is a dedicated day where the whole company focuses on resilience.
There&rsquo;s a <a href="https://www.gremlin.com/community/tutorials/planning-your-own-chaos-day/">tutorial on the Gremlin site</a>
if you want help to plan your own chaos day.</p>
<p>Examples of experiments:</p>
<ul>
<li>Reproduce actual outage</li>
<li>Data center failure</li>
<li>Large traffic spikes</li>
<li>Maxing out CPU and disk</li>
</ul>
<p>Tools:</p>
<ul>
<li><a href="https://github.com/Netflix/chaosmonkey">Chaos Monkey</a></li>
<li><a href="https://github.com/Netflix/SimianArmy">Simian Army</a></li>
<li><a href="https://github.com/asobti/kube-monkey">Kube Monkey</a></li>
<li><a href="https://github.com/openebs/e2e-tests">Litmus</a></li>
<li><a href="https://github.com/powerfulseal/powerfulseal">Powerfulseal</a></li>
<li><a href="https://www.gremlin.com/">Gremlin</a>: failure as a service</li>
</ul>
<h2 id="what-is-sre-and-why-every-devops-professional-should-care--dave-rensin-google">What is SRE and why every DevOps professional should care &mdash; Dave Rensin (Google)</h2>
<p>How do we choose between DevOps and SRE?</p>
<p>DevOps principles:</p>
<ul>
<li>Reduce organizational silos</li>
<li>Accept failure as normal</li>
<li>Implement gradual changes</li>
<li>Leverage tooling and automation</li>
<li>Measure everything (otherwise you run your business by luck)</li>
</ul>
<p>SRE principles:</p>
<ul>
<li>Reliability is the most important feature of a system (<em>every</em> system, not just software).</li>
<li>The only measure that actually matters is the reliability experienced by your users.</li>
<li>100% is always the wrong goal all the time. (Your users also don&rsquo;t need 100%
reliability, they won&rsquo;t even notice it.)</li>
</ul>
<p>The space between 100% and your availability target (e.g. 99.99%) is called the
&ldquo;error budget.&rdquo; If you achieve higher reliability than you targeted for, you
are wasting budget.</p>
<p>Terms:</p>
<dl>
<dt>SLI</dt>
<dd>A service level indicator tells us how our user is experiencing our system.</dd>
<dt>SLO</dt>
<dd>A service level objective is an SLI plus a goal.</dd>
<dt>SLA</dt>
<dd>A service level agreement, in contrast to SLI and SLO, points outward.
SLA = SLO + margin + consequences. Purely a business discussion; there is no
engineering involved.</dd>
</dl>
<p>SRE practices:</p>
<ul>
<li>Metrics &amp; monitoring (are we measuring and alerting on the right thing?)</li>
<li>Capacity planning</li>
<li>Change management (consistency is important because you want to automate this)</li>
<li>Emergency response</li>
<li>Culture (toil management, engineering alignment, blamelessness)</li>
</ul>
<p>Why choose between SRE and Devops? It is not one <em>or</em> the other. SRE is a
concrete, highly opinionated implementation of DevOps! (Also see the video
<a href="https://www.youtube.com/watch?v=uTEL8Ff1Zvk&amp;list=PLIivdWyY5sqJrKl7D2u-gmis8h9K66qoj">class SRE implements DevOps</a>.)
It provides a consistent and optimized way of implementing DevOps principles.</p>
<p>Some nice quotes:</p>
<blockquote>
<p>The closer to zero you can drive the blast radius of a mistake, the closer to
infinity you can drive your risk.</p></blockquote>
<p>(And SRE manages risk.)</p>
<blockquote>
<p>SRE is what happens when you ask a software engineer to design operations.</p></blockquote>
<p>Take the SLO and calculate your error budget. Then apply risk analysis and
calculate how many bad minutes/year something cost (or could cost). Then you
start working on the items that are &gt; 25% of your error budget. Tool to play
with this: <a href="https://docs.google.com/spreadsheets/d/1XTsPG79XCCiaOEMj8K4mgPg39ZWB1l5fzDc1aDjLW2Y/view">CRE Risk Analysis Template</a></p>
<p>How to start with SRE? The most important thing is willingness to do SRE. You
cannot adopt SRE unless you have executive buy-in. (Note that you &lsquo;only&rsquo; need
buy-in, it does not work if executives enforce implementation.)</p>
<p>The next important thing is to pick <strong>one</strong> application (defined as a &ldquo;discrete
failure domain&rdquo;) first. This will reduce the number of people you need buy-in
from. But it has to be a <strong>meaningful</strong> application, otherwise the lessons you
learn won&rsquo;t be internalized. Once the reliability and velocity are increasing
and the frustration between dev and ops is decreasing, others will want to do it
too!</p>
<p>When you have the willingness and know which application to work on, you start
with defining your SLIs, SLOs and error budgets. Answer the question &ldquo;what do my
customers care about?&rdquo; Pick the smallest number of things that answer that
question. So not &ldquo;CPU utilization&rdquo; but e.g. &ldquo;latency of the application.&rdquo; Then
determine the first set of objectives. Also determine a policy, for instance: feature
freezes until you go below the error budget.</p>
<p>Note that the SLOs don&rsquo;t have to be perfect. You can re-evaluate them
periodically (monthly or quarterly for instance).</p>
<p>Now, before you do any engineering, get your alerting and monitoring in order.
Make sure you monitor the things that are relevant for your SLOs. Usually you
can turn off half of your alerts without impacting the experience of your user.
More alerting is almost never better. More logging and measurements <em>are</em>
(probably) better. Simple test: only alert on something <em>your customer</em> would
want to be alerted on.</p>
<p>An important prerequisite for doing SRE is having a blameless culture! The
highest return on investment of a mistake is if you learn as much as possible
from it. You can only do that in a blameless culture.</p>
<p>Take one step at a time:</p>
<ol>
<li>Define SLIs, SLOs and error budgets</li>
<li>Audit and adjust monitoring and alerting</li>
<li>Model and reward blameless postmortems</li>
</ol>
<p>If you do this, you will improve things!</p>
<p>More information: <a href="https://sre.google/">sre.google</a></p>
<h2 id="devsecops---securing-a-great-developer-experience--stefan-streichsbier-guardrails">DevSecOps - securing a great developer experience &mdash; Stefan Streichsbier (GuardRails)</h2>
<p>Some stats: 51% of the world&rsquo;s population has internet access (June 2017) and
there are 31 million developers on GitHub (October 2018).</p>

  <figure>

<blockquote >
In the future every company will become a software company
</blockquote>

  <figcaption>
    &mdash;Marc Andreessen
  </figcaption>
  </figure>


<p>Having a website used to be simple: you uploaded the needed files to your
hosting provider via FTP. There was no to little collaboration (just one &ldquo;web
master&rdquo;), no build steps (PHP, ASP, etc) and you tested by checking if there
were parse errors.</p>
<p>Now there is a whole bunch of additional (and different) steps required. There
are code repositories, build pipelines, several environments (test,
production). Deployment on e.g. a Kubernetes cluster is much more complex
than putting some files somewhere. And then there&rsquo;s the complexity of all the
development tools and all the products that the cloud providers offer.</p>
<p>So how does security fit in?</p>
<p>Michael Wittig wrote an <a href="https://cloudonaut.io/aws-security-primer/">AWS security
primer</a> in which he has a mind map
of all security related tasks and activities there are in AWS. On <a href="https://news.ycombinator.com/item?id=14628108">Hacker
News</a> someone posted a comment on
it:</p>
<blockquote>
<p>I&rsquo;ve worked extensively with AWS over the last 4 years, and I can barely wrap
my head around the scope of managing security in AWS. We have an entire
department dedicated to security in our company, and none of them are remotely
close to being experts in AWS security either.</p>
<p>I&rsquo;m starting to get curious if there even is an expert who could set up and
maintain a bulletproof AWS Account.</p></blockquote>
<p>Steps in the evolution of security:</p>
<ul>
<li>Penetration testing</li>
<li>Secure software development life cycle</li>
<li>DevSecOps</li>
</ul>
<p>Going to DevSecOps is not easy for typical security teams. They have to get into
the mindset of software development. Security tools are typically also not made
with developers in mind.</p>
<p>Tools are not everything. We need to have a proper workflow around it. We should
not &ldquo;automate the nagging&rdquo; by building in security tools in the development
pipeline.</p>
<p>Only a fraction of the 31 million developers on GitHub have access to
(enterprise grade) security tools and penetration testing.</p>
<p>Quality had to face some of the challenges security is currently facing. Quality
is now more and more a first class citizen.</p>
<p>Some definitions:</p>
<ul>
<li>Usability: can the user accomplish his/her goal very effectively when they
interface with a product?</li>
<li>User experience: everything around using a certain product</li>
<li>Developer experience: user experience where your audience is exclusively developers.</li>
</ul>
<p>To increase the developer experience with regards to security we have to keep
some things in mind:</p>
<ul>
<li>Signal vs noise
<ul>
<li>Security tools should not add more noise.</li>
<li>Instead they should focus on high impact issues.</li>
<li>Make sure that issues are reported with a high level of accuracy.</li>
</ul>
</li>
<li>Lost in translation
<ul>
<li>Security has to speak the same language as developers. Otherwise
developers have to become security experts as well to understand what the
security team is talking about.</li>
<li>Use the right communication channel. So not a PDF report or Excel sheet
per email, but notifications in the workflow (e.g. in a pull request,
issue, chat application).</li>
<li>Describe the issues clear so that developer know how to solve them.</li>
</ul>
</li>
<li>Make it easy
<ul>
<li>Make it simple to get started and try out (not: &ldquo;schedule an appointment
with our sales rep&rdquo;)</li>
<li>Tight integration with the workflow</li>
<li>Provide all functionality in one tool.</li>
</ul>
</li>
</ul>
<p>How to make security a part of DevOps?</p>
<ul>
<li>Acknowledge that developers are key. Tools should bring them joy using it and
provide value.</li>
<li>Respect that security is a complex topic but provide clear focus and make it easy
to consume for developers.</li>
<li>Security has to become a commodity, not just for big enterprises.</li>
</ul>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Devopsdays Amsterdam 2018: day one]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2018/06/28/devopsdays-amsterdam-2018-day-one/" type="text/html" />
    <id>https://markvanlent.dev/2018/06/28/devopsdays-amsterdam-2018-day-one/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="cloud" />
    <category term="cloud native" />
    <category term="conference" />
    <category term="consul" />
    <category term="devops" />
    <category term="security" />
    
    <updated>2021-10-26T18:57:58Z</updated>
    <published>2018-06-28T00:00:00Z</published>
    <content type="html"><![CDATA[<p>After the workshops from
<a href="/2018/06/27/devopsdays-amsterdam-2018-workshops/">yesterday</a>,
this was the first day filled with talks.</p>
<p><em>Note: these are my notes. They are not necessarily representative summaries of the talks.</em></p>
<h2 id="welcome-to-devopsdays-amsterdam-6--peter-nijenhuis">Welcome to devopsdays Amsterdam 6 &mdash; Peter Nijenhuis</h2>
<p>Continuous improvement is part of DevOps. We improve things we want to be
better, like our build pipeline. Don&rsquo;t forget to also improving yourself!</p>
<h2 id="cloud-containers-kubernetes--bridget-kromhout-microsoft">Cloud, containers, Kubernetes &mdash; Bridget Kromhout (Microsoft)</h2>
<p>The title was a way to get all the buzzwords on one slide. And they are
hand-wavy enough to be able to talk about anything. ;-)</p>
<p><img src="/images/devopsdays2018_bridget_kromhout_talk.jpg" alt="Bridget Kromhout with the buzzword laden slide"></p>
<blockquote>
<p>Rollbacks are a damn, dirty lie.</p></blockquote>
<p>We can only move forward to a future state which we hope is similar to the old
state.</p>
<p>Containers solve problems in our deployments. They make it a lot easier to ship
for example. They do not magically solve all the problems you have.
You get new problems, like having to update your base images.</p>
<p>We have had container like things in the past: chroot, FreeBSD jails, Solaris
Zones and LXC. Containers have become mainstream now and are easier to use. It
is exciting to talk about orchestration, service meshes and storage today.
However, orchestration and such are a means to an end, they are not the goal
itself.</p>
<p>It is hard and a lot of work to take care of your application and the layers
beneath it, all the way down to the hardware. Especially given that disruption
is part if daily life&mdash;you know that stuff is going to happen.</p>
<p>Our systems could be less complex, but there is also a lot of &ldquo;résumé-driven
development.&rdquo; We should not add things &ldquo;because.&rdquo; It is very tempting to build
whatever is exciting. For instance: microservices makes some things more
complex, so you have to know what problems they are solving in <em>your</em> case and
then decide if it is worth the added complexity.</p>
<p>If you want to use Kubernetes, be aware it also adds complexity. To learn about
it, check out:</p>
<ul>
<li><a href="https://github.com/kelseyhightower/kubernetes-the-hard-way">https://github.com/kelseyhightower/kubernetes-the-hard-way</a></li>
<li><a href="https://github.com/ivanfioravanti/kubernetes-the-hard-way-on-azure">https://github.com/ivanfioravanti/kubernetes-the-hard-way-on-azure</a></li>
<li><a href="https://github.com/jpetazzo/container.training">https://github.com/jpetazzo/container.training</a></li>
</ul>
<p>Picking the &ldquo;right&rdquo; things to use is a hard problem. Check out the Cloud Native
Computing Foundation website and see how <a href="https://www.cncf.io/projects/">many projects</a>
there are! Kubernetes is the only &ldquo;graduated&rdquo; project, all the other projects
move even faster than Kubernetes.</p>
<p>&ldquo;Legacy&rdquo; is where the customers and money live. We are not operating in a
vacuum. We are working in a wider ecosystem which still matters and should be
taken into consideration.</p>
<p>Projects to watch:</p>
<ul>
<li><a href="https://helm.sh/">Helm</a> (package manager for Kubernetes)</li>
<li><a href="https://brigade.sh/">Brigade</a> (when you get sick of the YAML or find it not flexible enough)</li>
<li><a href="https://github.com/virtual-kubelet/virtual-kubelet">Virtual Kubelet</a> (add
legacy systems to your clusters)</li>
</ul>
<p>Bridget reiterates that Kubernetes is a tool, not the end game.</p>

  <figure>

<blockquote cite="https://twitter.com/lady_nerd">
In a world that celebrates pioneers&mdash;be the settlers instead.
</blockquote>

  <figcaption>
    &mdash;<cite><a href="https://twitter.com/lady_nerd">Laura Bell</a></cite>
  </figcaption>
  </figure>


<p>We can end up feeling negative. DevOps should not be <q>sadness as a
service.</q> We should stay positive.</p>
<p>We, the nerds have won and we probably should not screw this up. We have the
opportunity to shape reality. Which is a profound responsibility. We should make
the world we are living in a world we <em>want</em> to live in.</p>
<p>Ask yourself the question &ldquo;how can I enable someone in another team to spend
their time better?&rdquo;</p>
<h2 id="the-rocky-path-to-migrating-production-applications-to-serverless-architecture--serhat-can-opsgenie">The rocky path to migrating production applications to serverless architecture &mdash; Serhat Can (OpsGenie)</h2>
<p>Examples of when serverless is not great.</p>
<p>They do not hate serverless/AWS Lambda at OpsGenie, but they have had their
problems.</p>
<p>The serverless journey of OpsGenie began in 2015 with small scale custom
integration. In 2017 they started to use AWS Lambda for a production service. In
2018 they started a spin-off, <a href="https://www.thundra.io/">Thundra</a>, to offer
observability for AWS Lambda.</p>
<p>OpsGenie stack:</p>
<ul>
<li>Java 8</li>
<li>AWS services, including &ldquo;serverless&rdquo; DynamoDB, SQS</li>
</ul>
<p>Some of the problems they had (and their solutions):</p>
<ul>
<li>Cold start
<ul>
<li>Increase memory (and pay more).</li>
<li>Lightweight application framework (instead of using e.g. Sprint).</li>
<li>Do some &lsquo;smart&rsquo; warmup.</li>
</ul>
</li>
<li>Scaling
<ul>
<li>Don&rsquo;t put your functions in a VPC unless you have to.</li>
<li>Use you 6th sense to debug a scaling issue.</li>
</ul>
</li>
<li>Observability
<ul>
<li><a href="https://aws.amazon.com/xray/">AWS X-Ray</a> can help, but is often not enough.</li>
<li>Custom tooling, Thundra spin-off.</li>
</ul>
</li>
<li>Event driven (unexpected bills from AWS)
<ul>
<li>Avoid infinite retries.</li>
<li>Monitor and alert for pricing (unfortunately no specific pricing metric for AWS Lambda).</li>
<li>Think of Cloudwatch costs and sample logs &amp; metrics.</li>
</ul>
</li>
<li>Idempotency
<ul>
<li>Design the function idempotent, taking the type into consideration.</li>
</ul>
</li>
</ul>
<p><img src="/images/devopsdays2018_serhat_can.jpg" alt="Serhat Can has some suggestions for the AWS Lambda suggestions page"></p>
<h2 id="devops-and-cloud-native--michael-ducy-sysdig">DevOps and Cloud Native &mdash; Michael Ducy (Sysdig)</h2>
<p>Mapping existing principles into a DevOps world.</p>
<p>Definition of DevOps: CALMS</p>
<ul>
<li>Culture
<ul>
<li>People over process.</li>
<li>Failure is normal and is something you can learn from.</li>
<li>Treat everyone as a valuable member of the team we can learn from.</li>
</ul>
</li>
<li>Automation
<ul>
<li>You need a level of automation to get to <em>x</em> deploys per day.</li>
<li>Use Infrastructure as Code, Continuous Integration, Continuous Deployment.</li>
</ul>
</li>
<li>Lean
<ul>
<li>Learning from other industries about their manufacturing and production
processes.</li>
<li>Removing waste from processes.</li>
</ul>
</li>
<li>Measurement
<ul>
<li>Performance, process and people metrics.</li>
<li>DORA: DevOps Research Assessment (authors of <a href="https://puppet.com/resources/report/2018-state-devops-report">The State of DevOps Report</a>)</li>
</ul>
</li>
<li>Sharing
<ul>
<li>Intra- and inter organization.</li>
<li>Best practices and learnings to improve overall industry.</li>
<li>Share work and code.</li>
</ul>
</li>
</ul>
<p>What is Cloud Native? Basically an architectural pattern.
<a href="https://blog.heptio.com/cloud-native-part-1-definition-716ed30e9193">Joe Beda&rsquo;s definition</a>
includes &ldquo;teams&rdquo; and &ldquo;culture&rdquo;:</p>
<blockquote>
<p>Cloud Native is structuring teams, culture and technology to utilize
automation and architectures to manage complexity and unlock velocity.</p></blockquote>
<p>Pivotal has a nice image to explain Cloud Native:</p>
<p><img src="/images/devopsdays2018_michael_ducy.jpg" alt="Pivotal sees Cloud Nation as a combination of DevOps, continuous delivery, microservices and containers"></p>
<p>Cloud Native in CALMS terms:</p>
<ul>
<li>Culture: blameless, inclusion &amp; diversity, self-care and fail fast.</li>
<li>Automation, Lean, Measurement: Cloud Native, we&rsquo;ll get to this in
a moment.</li>
<li>Sharing: open source, public postmortems, public presentations.</li>
</ul>
<p>When we zoom in on the automation, measurement and lean components:</p>
<ul>
<li>Automation
<ul>
<li>Automation is a first principle of Cloud Native, built into the platform.
The platform has scaling built in. You don&rsquo;t have to worry about the
platform, only your own application.</li>
<li>Makes Infrastructure as Code easier
(<a href="https://www.weave.works/blog/gitops-operations-by-pull-request">GitOps</a>
for example).</li>
<li>Orchestration is incorporated from the start via Kubernetes which provides
abstractions and robustness.</li>
<li>Service Mesh as proxy for service requests, discovery, etc and to detect
abnormal conditions.</li>
</ul>
</li>
<li>Measurement
<ul>
<li>Common instrumentation, like Prometheus. Instrumentation means visibility.</li>
<li>Distributed tracing is a new, but interesting development to correlate
events through the distributed stack. Examples: Jaeger, Zipkin, etc.</li>
<li>Service Mesh</li>
</ul>
</li>
<li>Lean:
<ul>
<li>This is a side effect of Cloud Native because processes are improved,
points of friction are removed and best practices are automated into the
platform.</li>
</ul>
</li>
</ul>
<p>&ldquo;DevOps team&rdquo; is often a misnomer. What does this team do for the culture, lean,
measurement and sharing aspects? Perhaps you mean the &ldquo;automation team&rdquo; instead?
The DevOps team is often a developer services team, providing infrastructure,
tooling and services.</p>
<p>What about Site Reliability Engineering? The
<a href="https://en.wikipedia.org/wiki/Site_reliability_engineering">Wikipedia article on SRE</a>
maps SRE on DevOps principles.</p>
<p>Summary:</p>
<ul>
<li>DevOps is the entire organization&rsquo;s job, not one team.</li>
<li>Cloud Native is a culmination of technological advancements.</li>
<li>Cloud Native provides real benefits of agility and velocity.</li>
</ul>
<p>Advice: watch the video
<a href="https://www.youtube.com/watch?v=LdOe18KhtT4">10+ Deploys Per Day: Dev and Ops Cooperation at Flickr</a>
again if you haven&rsquo;t in a while.</p>
<h2 id="service-mesh-for-microservices--armon-dadgar-hashicorp">Service mesh for microservices &mdash; Armon Dadgar (HashiCorp)</h2>
<p>We used to have monoliths where multiple pieces of functionality were combined.
Interaction between these components was quite easy; just a function call. We
did use external components though, e.g. a load balancer and a database.</p>
<p>We stopped developing monoliths and started with microservices. The advantage is
that we can release components independent from each other. We gained
development agility. We lost on the operational side though. With microservices
there are operational challenges, like discovery. Adding to this pain is a
movement towards containers and a cloud environment, which means a much more dynamic
environment.</p>
<p>Having multiple instances of a certain component means that you would probably
place a load balancer in front of that component to distribute the requests.
But now your load balancer has become the single point of failure. A
central registry keeping track of what is running where (like Consul, ZooKeeper,
etc) can help you out.</p>
<p>To mitigate attacks we need service segmentation. With the monolith we had
three segments: the load balancer in front of the application, the monolith and
the database. We used to have firewalls, virtual LANs, etc. Conceptually we are
limiting the blast radius of an incident. But when you are using microservices,
the story is not that simple anymore. There are still many components in a
single segment. Segmentation with microservices is much harder since all
components need to communicate. How do we segment these?</p>
<p><img src="/images/devopsdays2018_armon_dadgar.jpg" alt="Armon Dadgar showing many microservices communicating with each other"></p>
<p>Infrastructure is a means to an end. Microservice architecture comes with a
common set of challenges. Consul wants to provide common wheels for these challenges:</p>
<ul>
<li>Service discovery
<ul>
<li>Via DNS (e.g &ldquo;<code>dig redis.service.consul</code>&rdquo;) or HTTP API.</li>
<li>You can hard code a name, not an IP.</li>
</ul>
</li>
<li>Service configuration
<ul>
<li>Hierarchical key/value store with an HTTP API.</li>
<li>Use Consul as distributed lock service.</li>
</ul>
</li>
<li>Service segmentation
<ul>
<li>We&rsquo;ll talk about this shortly.</li>
</ul>
</li>
</ul>
<p>Consul launched in 2014 and is the oldest application from HashiCorp and the
application with the biggest footprint. Consul Connect was announced earlier
this week and is meant to handle the service segmentation aspect:</p>
<ul>
<li>Service access graph: who can do what, based on service name not IP address
(and thus scales better).</li>
<li>Certificate authority, based on standard TLS. (The format is an X.509
certificate which is <a href="https://spiffe.io/">SPIFFE</a> compatible.)</li>
<li>Application integration:
<ul>
<li>Sidecar proxy integration where the application connects to other
components via the proxy (over an encrypted channel). No code changes
needed. The proxy is pluggable: you can use other proxies like Envoy.</li>
<li>Native integration. You do need to change your application, but lose the
performance overhead of talking to the application. So if latency is an
issue, have a look at native integration; otherwise use the proxy to keep
flexibility.</li>
</ul>
</li>
</ul>
<p>Consul as a control plane, pluggable proxies as data plane.</p>
<p>Already using Consul and want to start with Consul Connect? Upgrade to the
latest version of Consul (1.2.0 at the moment) and change three lines of code on
the server and the client and you are good to go.</p>
<h2 id="dont-be-a-bystander-be-an-incident-commander--rachael-byrne-pagerduty">Don&rsquo;t be a bystander, be an incident commander! &mdash; Rachael Byrne (PagerDuty)</h2>
<p>Incident commanders are the key decision makers in the response to a major
incident (and can even outrank the CEO during incidents, assuming you have
leadership buy-in). Technical leaders seem to be the most likely incident
commanders, but this does not scale very well since there are only that many of
them.</p>
<p>Having non-technical incident commanders scales better. An incident commander
does not have to know the tech stack. It does help to have a basic, high level
understanding of system architecture.</p>
<p>Incident commander skills:</p>
<ul>
<li>Mind for process</li>
<li>Communication (directive communication specifically, avoid too long
discussions)</li>
<li>Time boxing (time management, give people time boxes and check up on them,
keep information flowing)</li>
<li>Active listening</li>
</ul>
<p><img src="/images/devopsdays2018_rachael_byrne.jpg" alt="Rachael Byrne talking about the listening skill"></p>
<p>Once you have identified incident commanders, you need inclusive incident
response training. Being outside of engineering is quite a hurdle to overcome
for the incident commander, especially during a business critical time.</p>
<p>Advice for training:</p>
<ul>
<li>Define the role: responsible for communication and coordination. Incident
commanders do not solve the problem themselves, they delegate to subject
matter experts. (So that these experts can focus on solving the issue and not
communication.)</li>
<li>Make sure that the entire business understands the process of what happens
during an outage.</li>
<li>The trainee should shadow the experienced incident commander and silently
observe (don&rsquo;t interfere with the process, ask questions later).</li>
<li>Scribe: the trainee keeps track of what happens. This helps with getting
familiar with the process, plus it gives the feeling that you <em>can</em>
contribute.</li>
<li>Let the trainee handle a failure exercise.</li>
<li>Reverse the shadow: the trainee becomes the commander. Note that the mentor
should only provide help in the background to not undermine the trainee&mdash;the
trainee is in command.</li>
</ul>
<p>Celebrate that the trainee is now an incident commander!</p>
<p>DevOps is about creating empathy. Why stop at Dev and Ops and not include the
whole business?</p>
<p>More information at <a href="https://response.pagerduty.com/">https://response.pagerduty.com</a>.</p>
<h2 id="ignites">Ignites</h2>
<p>Ignites are short talks. Each speaker provides twenty slides which automatically
advance every fifteen seconds.</p>
<h3 id="going-dutch-observaties-over-nederlandse-cultuur--devops--jason-yee-datadog">Going Dutch: observaties over Nederlandse cultuur &amp; DevOps &mdash; Jason Yee (Datadog)</h3>
<p>If you&rsquo;ve walked around in Amsterdam you may have noticed that there are no
curtains. Dutch people like their privacy, we just don&rsquo;t want to block the view.</p>
<p>Since you write the software, you can remove the curtains from your application
so you can look inside. The reason we are not doing this is because of silos:
Dev does not talk to Ops and neither talks to the business people.</p>
<p><a href="https://en.wikipedia.org/wiki/FEBO">FEBO</a> (known for its automat vending
machines) reminds him of PaaS: fast and convenient. Dev can deploy and Ops need
not be involved; everything will be fine, right?</p>
<p>Don&rsquo;t be the FEBOps!</p>
<p>Better service leads to better food. Ops should be a service.</p>
<p>Go Dutch: share responsibility.</p>
<p>In summary: get visibility, focus on services and share responsibility.</p>
<h3 id="extreme-feedback-in-devops--joep-weijers-topdesk">Extreme feedback in DevOps &mdash; Joep Weijers (TOPdesk)</h3>
<p>Email alerts from Jenkins have been abolished at TOPdesk. They needed
something more &ldquo;in your face.&rdquo;</p>
<p>They use a build monitor for Jenkins and added a blue light which starts flashing
when the build is broken. Not as easy to ignore as an email.</p>
<p>Using the <a href="https://twitter.com/internetofshit">@internetofshit twitter account</a>
as inspiration he came up with the following ideas:</p>
<ul>
<li>Automatically shooting developers that broke the build with a Nerf gun.</li>
<li>A drone hoovering next to the developer that broke the build.</li>
<li>Using the &ldquo;The Car Hacker&rsquo;s Handbook&rdquo;: if you break the build, your car
flashes its emergency lights. Or lock the car until the build is working
again.</li>
<li>Use the salary payment API to withhold the salary payment if the build breaks.</li>
</ul>
<h3 id="talk-selection-as-mockumentary-film-editing--matty-stratton-pagerduty">Talk selection as mockumentary film editing &mdash; Matty Stratton (PagerDuty)</h3>
<p>Matty was responsible for a devopsdays talk selection. There were 176 talk
submissions for only 18 slots last year.</p>
<p>A mockumentary is a fake documentary, heavily improvised (3&ndash;4 page script).</p>
<p>You don&rsquo;t know what story you are going to tell when you start with a
documentary. The same goes for organizing a conference. You are dependent on the
submissions. You have to read all of them and a theme and story will come out.
Start with an idea but be flexible.</p>
<h2 id="security-as-code--geert-van-der-cruijsen-xpirit-and-rene-van-osnabrugge-xpirit">Security as code &mdash; Geert van der Cruijsen (Xpirit) and Rene van Osnabrugge (Xpirit)</h2>
<p>Rene and Geert both had an assignment: &ldquo;implement a secure pipeline.&rdquo;</p>
<p>The security officers they had to work with had a huge lists of compliancy
rules. These rules are impossible to understand, implement, validate and
maintain.</p>
<p>What usually happens is that once companies are compliant, the security level
decreases over time until a next audit is near.</p>
<p><img src="/images/devopsdays2018_geert_van_der_cruijsen_and_rene_van_osnabrugge.jpg" alt="Geert van der Cruijsen talking about the security compliancy level with Rene van Osnabrugge listening"></p>
<p>They needed a different solution. They got back to the &ldquo;why&rdquo; of the rules:</p>
<ul>
<li>Confidentiality</li>
<li>Integrity</li>
<li>Availability</li>
</ul>
<p>Compliancy is not about security. If you are secure however, you are probably
also compliant.</p>
<p>The way we do security checking now is not sustainable if we release more than a
couple of times per year. Security is the next silo that should fall.</p>
<p>What needs to be secure?</p>
<ul>
<li>Infrastructure (servers &amp; containers, firewalls &amp; networks, identity &amp; access)</li>
<li>Applications (libraries, safe coding, passwords)</li>
<li>Build and delivery pipeline</li>
</ul>
<p>We need to move from a manual approach to an automated approach.</p>
<p>Phases:</p>
<ul>
<li>Identify the risks
<ul>
<li>Work together with security (e.g. as part of the scrum team, even if only part-time).</li>
<li>These days most applications consist for 80&ndash;90 percent out of third party
code (libraries, containers, etc).</li>
</ul>
</li>
<li>Prevent bad things from happening
<ul>
<li>Have a look at Gauntlet to check existing code and infrastructure.</li>
<li>Scan for credentials.</li>
</ul>
</li>
<li>React if bad things happen
<ul>
<li>Detect
<ul>
<li>Monitor</li>
<li>Have baselines</li>
<li>Alerts</li>
</ul>
</li>
<li>Respond
<ul>
<li>Mean time to recovery</li>
<li>Pipelines</li>
<li>Continuous delivery</li>
<li>You build it, you run it</li>
</ul>
</li>
<li>Recover
<ul>
<li>Post mortems</li>
<li>Share experience</li>
<li>Rebuild</li>
<li>Everything as code</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Azure has the <a href="https://azsk.azurewebsites.net/">Secure DevOps Kit</a>. You can use
these tools to perform checks and generate reports about the status.</p>
<p>Even when developers are just experimenting with something, you can tell them
that the tools they are looking into for future use have issues that need to be
addressed before going into production. This may help them with their
evaluation.</p>
<p>Bake security into your processes. Embed it in your teams.</p>
<h2 id="rabobanks-journey-to-agile-and-devops-security--alex-duivelshof-rabobank">Rabobanks&rsquo; journey to agile and DevOps security &mdash; Alex Duivelshof (Rabobank)</h2>
<p>Security needs to be part of the continuous delivery process as early as
possible.</p>
<p>They identified a number of risks:</p>
<ul>
<li>Fraud</li>
<li>Rapid delivery of features can also mean rapid delivery of mistakes</li>
<li>Data exposure</li>
<li>Unauthorized access</li>
<li>Security debt in time (many small changes combined can become a big change)</li>
</ul>
<p><img src="/images/devopsdays2018_alex_duivelshof.jpg" alt="Alex Duivelshof about the identified risks"></p>
<p>One of the key principles in DevOps is shifting responsibility back to the teams.
We can do the same for security related issues.</p>
<p>Security principles they identified:</p>
<ul>
<li>Maintain (code) integrity including audit trail of code changes.</li>
<li>Enforce four eyes for every change to production.</li>
<li>Automate security testing where possible.</li>
<li>Reduce impact by release methodology.</li>
<li>Prevent unauthorized access.</li>
<li>All processes are auditable.</li>
</ul>
<p>(These principles are not new by the way&mdash;they already existed.)</p>
<p>The security officers asked the teams how they would apply the principles.</p>
<p>Security principles were geared towards implementation. The teams noticed that
there were no principles for the security of the product. The security officers
are now translating their requirements to business features. This makes it
easier for product owners to understand what is needed and why.</p>
<p>Working with the teams and being available and involved from the beginning
requires a different state of mind for the security officers.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Open tabs]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2018/05/12/open-tabs/" type="text/html" />
    <id>https://markvanlent.dev/2018/05/12/open-tabs/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="backups" />
    <category term="devops" />
    <category term="git" />
    <category term="python" />
    <category term="security" />
    <category term="tabs" />
    <category term="terraform" />
    
    <updated>2025-09-13T21:07:32Z</updated>
    <published>2018-05-12T00:00:00Z</published>
    <content type="html"><![CDATA[<p>Currently I have about 30 tabs open in the browser on my phone. Quite
a bunch of them I have open because I want to read the article in the
future, already have read the article and want to reread or act on it,
or a combination of the above. In this article I list the open tabs
(and some notes) so I can close them on my phone, but still have a
reference to them.</p>
<h2 id="development">Development</h2>
<dl>
<dt><a href="https://blog.scottnonnenberg.com/better-git-configuration/">Better Git configuration</a></dt>
<dd>Some tips from Scott Nonnenberg to improve your Git configuration.</dd>
<dt><a href="https://jacobian.org/2018/feb/21/python-environment-2018/">My Python Development Environment, 2018 Edition</a></dt>
<dd>A good description by Jacob Kaplan-Moss of how he uses
<a href="https://github.com/pyenv/pyenv">pyenv</a>,
<a href="https://pipenv.pypa.io/en/latest/">pipenv</a> and
<a href="https://github.com/mitsuhiko/pipsi">pipsi</a> for Python development.</dd>
</dl>
<h2 id="operations">Operations</h2>
<dl>
<dt><a href="https://borgbackup.readthedocs.io/en/stable/">BorgBackup documentation</a></dt>
<dd>Something I want to play around with&mdash;and perhaps use&mdash;to make
backups.</dd>
<dt><a href="https://www.opsschool.org/">Ops School Curriculum</a></dt>
<dd>A very comprehensive resource to learn to be an operations engineer.</dd>
<dt><a href="https://www.serverlessops.io/blog/serverless-ops-what-do-we-do-when-the-server-goes-away">Serverless Ops: What do we do when the server goes away?</a></dt>
<dd>Tom McLaughlin writes about the changing role of DevOps/Operations
engineers in a &lsquo;serverless&rsquo; world.</dd>
<dt><a href="https://news.ycombinator.com/item?id=12672797">Ask HN: How do you back up your site hosted on a VPS such as Digital Ocean?</a></dt>
<dd>A bunch of comments with suggestions on how to arrange backups for a
VPS. (I need some inspiration for my own VPS.)</dd>
<dt><a href="https://steemit.com/technology/@taoteh1221/securely-using-amazon-s3-buckets-for-server-backups">Securely Using Amazon S3 Buckets For Server Backups</a></dt>
<dd>See above; this is one of the candidates.</dd>
<dt><a href="https://github.com/kahun/awesome-sysadmin/blob/master/README.md">Awesome Sysadmin</a></dt>
<dd><q>A curated list of amazingly awesome open source sysadmin resources.</q></dd>
</dl>
<h2 id="security">Security</h2>
<dl>
<dt><a href="https://dev-sec.io/">Automatic Server Hardening</a></dt>
<dd>Server hardening tips plus Chef, Puppet and Ansible modules. (Source:
<a href="https://ma.ttias.be/cronweekly/issue-94/">Cron weekly, issue 94</a>)</dd>
<dt><a href="https://decentsecurity.com/">Decent Security</a></dt>
<dd>Information on how to secure your devices (Windows, routers).</dd>
</dl>
<h2 id="devops">DevOps</h2>
<dl>
<dt><a href="https://github.com/chris-short/DevOps-README.md">DevOps README.md</a></dt>
<dd><q>A curated list of things to read to level up your DevOps skills and
knowledge</q> by Chris Short. (Source: <a href="https://devopsish.com/043/">DevOps&rsquo;ish, issue 043</a>)</dd>
<dt><a href="https://copyconstruct.medium.com/monitoring-and-observability-8417d1952e1c">Monitoring and Observability</a></dt>
<dd>A great post by Cindy Sridharan explaining the difference between
monitoring and observability.</dd>
<dt><a href="https://www.contino.io/insights/a-model-for-scaling-terraform-workflows-in-a-large-complex-organization">A Model for Scaling Terraform Workflows in a Large, Complex Organization</a></dt>
<dd>An article by Ryan Lockard and Hibri Marzook about scaling your Terraform working practices.</dd>
<dt><a href="https://mybinder-sre.readthedocs.io/en/latest/">Site Reliability Guide for mybinder.org</a></dt>
<dd>This might contain useful information about how mybinder.org sets
things up and how to write this kind of documentation.</dd>
<dt><a href="https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/">Terraform, VPC, and why you want a tfstate file per env</a></dt>
<dd>Another Terraform article, this time by Charity Majors.</dd>
<dt><a href="https://copyconstruct.medium.com/testing-in-production-the-safe-way-18ca102d0ef1">Testing in Production, the safe way</a></dt>
<dd>Lots of information in this article by Cindy Sridharan.</dd>
<dt><a href="https://medium.com/statics-and-dynamics/working-with-terraform-10-months-in-c15ade10c9b9">Working with Terraform: 10 Months In</a></dt>
<dd>Perhaps this article by J.D. Hollis might save me some headache (if I get around to read it in time :) ).</dd>
</dl>
<h2 id="miscellaneous">Miscellaneous</h2>
<dl>
<dt><a href="https://www.goodreads.com/book/show/27833670-dark-matter">Dark Matter</a></dt>
<dd>A book recommendation that I still need to check out. This was the
first link that popped up when I Googled the title.</dd>
<dt><a href="https://engineer.john-whittington.co.uk/2016/11/raspberry-pi-data-logger-influxdb-grafana/">Raspberry Pi Data Logger with InfluxDB and Grafana</a></dt>
<dd>An article by John Whittington as input for my (almost dead) side
project to collect and graph data from my smart meter.</dd>
</dl>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[DockerCon EU 2017: day one]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2017/10/17/dockercon-eu-2017-day-one/" type="text/html" />
    <id>https://markvanlent.dev/2017/10/17/dockercon-eu-2017-day-one/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="conference" />
    <category term="devops" />
    <category term="docker" />
    <category term="security" />
    <category term="tools" />
    
    <updated>2021-10-08T19:02:07Z</updated>
    <published>2017-10-17T00:00:00Z</published>
    <content type="html"><![CDATA[<p>These are my notes of my first day at DockerCon.</p>
<p>Where I usually try to make summaries of conference talks I attend,
I&rsquo;ve only made notes for this conference. Most, if not all, talks have
been recorded as far as I know, so you should be able to watch them to
place the notes into context.</p>
<h2 id="general-session">General session</h2>
<p>In the context of &ldquo;MTA&rdquo; (modernize traditional applications) we saw a
demo of how easy it is to convert legacy applications with the Docker
application converter (dac). In the demo they showed how the tool can
generate a <code>Dockerfile</code> from a tarball of a Java application.</p>
<p>Not everyone is using Swarm. Unfortunately, using a different
orchestration tool means that you do not have the seamless integration
that Swarm has. However, the next version of Docker will have native
integration for both Swarm and Kubernetes.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<p><img src="/images/dockerconeu17_native_kubernetes.jpg" alt="Kubernetes will have native support in Docker"></p>
<p>This way you can still use the same tools and workflow while being
able to choose between Swarm and Kubernetes. It also means you can
still use your <code>docker-compose.yml</code> files.</p>
<p><img src="/images/dockerconeu17_kubernetes_win_mac.jpg" alt="Kubernetes supported in Docker CE for Windows and Mac"></p>
<h2 id="hacked-run-time-security-for-containers--gianluca-borello-sysdig">Hacked! Run time security for containers &mdash; Gianluca Borello (Sysdig)</h2>
<p>A container is ephemeral and you don&rsquo;t need to protect it. You want
to protect the application/service instead.</p>
<p>SELinux is very powerful, but difficult to master. And thus people
often turn it off. To avoid users turning off or circumventing
security measures, one should reduce friction.</p>
<p>Forensics on containers is difficult, for instance because containers
may only live for a few minutes.</p>
<p>To build a security framework, you need to:</p>
<ul>
<li>observe, e.g. using Sysdig</li>
<li>understand the services, e.g. using Sysdig ServiceVision</li>
<li>detect bad behaviour, e.g. using <a href="https://sysdig.com/opensource/falco/">Sysdig Falco</a></li>
</ul>
<p><img src="/images/dockerconeu17_gianluca_borello.jpg" alt="Gianluca explaining what you need to build a security framework"></p>
<p>Gianluca demonstrated that Falco can detect e.g. network activity
performed by known binaries that are not supposed to send or receive
data over the network.</p>
<p>Sysdig maintains a ruleset for Falco. They update it weekly.  They are
also experimenting with automatic ruleset creation based on normal
behaviour of a container.</p>
<p><a href="https://sysdig.com/products/secure/">Sysdig Secure</a>: A new product to
provide run-time security for containers. You can define policies when
to trigger an event. You can also store Sysdig captures so that you
can see what happened <em>before</em> the event triggered.</p>
<p><a href="https://sysdig.com/blog/sysdig-inspect/">Sysdig Inspect</a> is a UI
around open source Sysdig tool to analyse Sysdig captures.</p>
<p>Sysdig has a low overhead (different from strace). It is meant to run
24/7 on production systems.</p>
<h2 id="docker-but-im-a-sysadmin--mike-coleman-docker">Docker?!?! But I&rsquo;m a SysAdmin &mdash; Mike Coleman (Docker)</h2>
<p>There was a contest to create the smallest Docker container that
printed out &ldquo;Hello world&rdquo;. The result was an image of only 64
kilobyte.</p>
<p>Security is about more than just isolation. For instance: where did
the images come from, are they up to date, how do you deal with
sensitive data and/or passwords?</p>
<p>Docker for AWS and Docker for Azure have integration for those platforms. They
offer more than installing standard Docker on an EC2 instance.</p>
<p><img src="/images/dockerconeu17_mike_coleman.jpg" alt="Mike Coleman about some of the considerations you have to make"></p>
<p>When you start integrating Docker into your environment, don&rsquo;t forget
to change your processes. Think about your backup and recovery
strategies, et cetera.</p>
<p>Mike encourages us to share our knowledge, and our missteps.</p>
<h2 id="creating-effective-images--abby-fuller-aws">Creating effective images &mdash; Abby Fuller (AWS)</h2>
<p>This is a talk about disk space.</p>
<p>Smaller images mean faster builds and deploys, but also a smaller
attack surface.</p>
<p>Some tips:</p>
<ul>
<li>Use shared base image where possible.</li>
<li>Limit the data written to the container layer.</li>
<li>Chain <code>RUN</code> statements.</li>
<li>Prevent cache misses at build for as long a possible.</li>
</ul>
<p>To prevent cache misses, put all static stuff first (labels, etc). You
really want to make sure that you use the cache as much as possible.</p>
<p>Read the documentation about the <a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache">build cache</a>.</p>
<p>Pick your base images wisely. You can go for a minimal OS, but there
are also reasons for wanting a full base OS:</p>
<ul>
<li>Security (with a minimal image, you have to roll your own)</li>
<li>Compliance</li>
<li>Ease of deployment (a minimal image can mean extra work)</li>
</ul>
<p>(Note to self: have a look at the
<a href="https://docs.docker.com/engine/reference/builder/#onbuild">ONBUILD</a>
command.)</p>
<p>Some random notes:</p>
<ul>
<li>MSI installations (for Windows images) are not space efficient.</li>
<li>Coming up soon: run Linux containers &ldquo;as-is&rdquo; on Windows.</li>
<li>Switching users also adds another layer.</li>
<li>Where possible use two images: one to build an artefact, one to build an image.</li>
<li><code>scratch</code> is a special, empty Docker image. Use this to build your own base images.</li>
<li>Use a <a href="https://docs.docker.com/engine/reference/builder/#dockerignore-file">.dockerignore</a> file.</li>
</ul>
<p><img src="/images/dockerconeu17_abby_fuller.jpg" alt="Abby Fuller with tips for creating Docker images"></p>
<p>Cleaning up:</p>
<ul>
<li><code>docker image prune -a</code>: Remove dangling images</li>
<li><code>docker system prune -a</code>: Also remove untagged volumes, etc.</li>
<li>Make sure your orchestration platform is garbage collecting.</li>
</ul>
<p>Recap:</p>
<ul>
<li>Less layers is more</li>
<li>Choose or build your base wisely</li>
<li>Not all languages should build the same</li>
<li>Keep it simple, avoid extras (e.g. use <code>apt install --no-install-recommends</code>)</li>
<li>Tools are here to help</li>
</ul>
<h2 id="docker-500-going-fast-while-protecting-data--diogo-mónica-docker">Docker 500: Going fast while protecting data &ndash; Diogo Mónica (Docker)</h2>
<p>Security means <q>a state of being free from danger or threat.</q> But as
soon as we connect something to a network, we are exposing it to
threats. So it would be better to talk about &ldquo;safety&rdquo; since that is
about <q>being protected from or unlikely to cause danger, risk or
injury.</q></p>
<p><img src="/images/dockerconeu17_diogo_monica.jpg" alt="Diogo Mónica about going as fast as possible, safely"></p>
<p>The &ldquo;Docker 500&rdquo; from the title is a play on the <a href="https://en.wikipedia.org/wiki/Indianapolis_500">Indy 500</a></p>
<p>While there can be horrible accidents in the Indy 500, the drivers
often can just walk away from their car. We must architect our systems
to protect our data, just like the drivers are protected in the Indy
500.</p>
<p>In racing, two categories of measures are taken: before the crash and
after/during the crash.</p>
<p>If we translate the pre-crash measures to our world, we&rsquo;d get
something like this:</p>
<ul>
<li>Test: create a trusted, repeatable and <strong>adversarial</strong> CI/CD
pipeline. Unless you have adversarial tests, you are effectively
testing in production.</li>
<li>Design applications to segment portions of their infrastructure
(microsegmentation).</li>
<li>Practice worst case scenarios. For example: if a secret (key) is
leaked, can you revoke trust of that secret in under X time?</li>
<li>Reverse uptime! Have a maximum uptime for a server. Note that this
is also good for operations because the machines don&rsquo;t get a
chance to drift.</li>
</ul>
<p>Measures after/during a crash:</p>
<ul>
<li>Freeze the container (disk and memory state), solve the problem
and inspect the frozen container later.</li>
<li>Automatic scaling.</li>
<li>Sandbox by default (by putting it in Docker).  Make sure that data
cannot be operated outside your data center by so called
&ldquo;crypto-anchors&rdquo; (a term coined by Diogo) via e.g. a hardware
security module.</li>
<li>Role based access control + visibility</li>
<li>Have data about the crash. This is where the Docker security
ecosystem shines.</li>
</ul>
<p>Access to the data should not just be secure, but also safe. With careful
engineering you can be fast and safe at the same time.</p>
<p>Note that containerd can freeze memory and push to a registry. For
freezing the disk you can use <code>commit</code> and then push to a registry.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Update 2017-10-19: I now understand that Docker CE will only
include Kubernetes in Docker for Windows and Docker for Mac because
those platforms use LinuxKit. Docker (the company) is not clear on
how/when Kubernetes will be supported on Linux.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[How does the Django Cross-site request forgery protection work?]]></title>
    <link rel="alternate" href="https://markvanlent.dev/2016/11/16/how-does-the-django-cross-site-request-forgery-protection-work/" type="text/html" />
    <id>https://markvanlent.dev/2016/11/16/how-does-the-django-cross-site-request-forgery-protection-work/</id>
    <author>
      <name>map[name:Mark van Lent uri:https://markvanlent.dev/about/]</name>
    </author>
    <category term="django" />
    <category term="security" />
    
    <updated>2021-09-29T16:22:03Z</updated>
    <published>2016-11-16T00:00:00Z</published>
    <content type="html"><![CDATA[<p>Dan Poirier wrote an article on the Caktus Group blog about common web
site security vulnerabilities. In it he talked about the CSRF
protection in Django. Although he is right about a CSRF token having
to be part of the POST request, this is not the entire story.</p>
<p><strong>It is <em>not</em> my intention to claim that mister Poirier does not
know how the CSRF protection in Django works. I only want to present a
more complete version.</strong></p>
<p>First things first, for those of you that have not read the
<a href="https://www.caktusgroup.com/blog/2016/11/10/common-web-site-vulnerabilities-Django-security/">Dan Poirier&rsquo;s article</a>,
here&rsquo;s a short summary of the CSRF related parts.</p>
<p>Cross-site request forgery (CSRF or XSRF) is a type of attack where a
malicious site is trying to make your browser send requests to another
site in an attempt to leverage the permissions of the user&mdash;you. (For
more information and examples, check the original article or the
<a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)">OWASP page on CSRF</a>.)</p>
<p>Besides making sure that GET requests do not change data the article
talks about the
<a href="https://docs.djangoproject.com/en/dev/ref/csrf/">CSRF protection provided by Django</a>. Specifically
it states the following (emphasis mine):</p>

<blockquote >
Django&rsquo;s protection is to always include a user-specific, unguessable
string as part of such requests, and reject any such request that
doesn&rsquo;t include it. This string is called the CSRF token. Any form on
a Django site that does a POST etc has to include it as one of the
submitted parameters. <strong>Since the malicious site doesn&rsquo;t know the token,
it cannot generate a malicious POST request that the Django site will
pay any attention to.</strong>
</blockquote>


<p>This is where the author is not incorrect (the POST request indeed has
to include the CSRF token), but <strong>this is only one half of the
mechanism</strong>. The other half is a cookie that is set by the original
site where the user is logged in. Only when the server receives
<strong>both</strong> values from the browser (and they match) will the POST
request be valid. This is described as the &ldquo;Double Submit Cookie&rdquo;
defence in the
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#Double_Submit_Cookie">Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet</a>
by OWASP.</p>
<h2 id="example">Example</h2>
<p>Here&rsquo;s an example with a very simple form
(<a href="https://gitlab.com/markvl/csrf_example">source code on GitLab</a>). Let&rsquo;s
first request the form:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ curl -i http://localhost:8000/post_to_me/
</span></span></code></pre></div><p>The response will look something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="err">    </span><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.0</span> <span class="m">200</span> <span class="ne">OK</span>
</span></span><span class="line"><span class="cl">    <span class="l">Date: Tue, 15 Nov 2016 20:25:58 GMT</span>
</span></span><span class="line"><span class="cl">    <span class="l">Server: WSGIServer/0.2 CPython/3.4.3</span>
</span></span><span class="line"><span class="cl">    <span class="l">Content-Type: text/html; charset=utf-8</span>
</span></span><span class="line"><span class="cl">    <span class="l">Vary: Cookie</span>
</span></span><span class="line"><span class="cl">    <span class="l">X-Frame-Options: SAMEORIGIN</span>
</span></span><span class="line hl"><span class="cl">    <span class="l">Set-Cookie:  csrftoken=wVFdNQ1Hz487w7yk2mVjre2qlsclXi99w2jEcGyvXorojDLd7jH09NGhmbavG3tx; expires=Tue, 14-Nov-2017 20:55:58 GMT; Max-Age=31449600; Path=/</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="g">    &lt;!doctype html&gt;
</span></span></span><span class="line"><span class="cl"><span class="g">    &lt;html&gt;
</span></span></span><span class="line"><span class="cl"><span class="g">      &lt;body&gt;
</span></span></span><span class="line"><span class="cl"><span class="g">        &lt;form action=&#34;/post_to_me/&#34; method=&#34;post&#34;&gt;
</span></span></span><span class="line hl"><span class="cl"><span class="g">          &lt;input type=&#39;hidden&#39; name=&#39;csrfmiddlewaretoken&#39; value=&#39;JBWuPGvKU54xW9YIwEIknst1azSkBmg3JIAVew2yipnOJFbBBBu1517SbiQuk7Ar&#39; /&gt;
</span></span></span><span class="line"><span class="cl"><span class="g">          &lt;tr&gt;&lt;th&gt;&lt;label for=&#34;id_name&#34;&gt;Name:&lt;/label&gt;&lt;/th&gt;&lt;td&gt;&lt;input id=&#34;id_name&#34; name=&#34;name&#34; type=&#34;text&#34; required /&gt;&lt;/td&gt;&lt;/tr&gt;
</span></span></span><span class="line"><span class="cl"><span class="g">          &lt;input type=&#34;submit&#34; value=&#34;Post&#34; /&gt;
</span></span></span><span class="line"><span class="cl"><span class="g">        &lt;/form&gt;
</span></span></span><span class="line"><span class="cl"><span class="g">      &lt;/body&gt;
</span></span></span><span class="line"><span class="cl"><span class="g">    &lt;/html&gt;</span></span></span></code></pre></div>
<p>Note the <code>csrftoken</code> value in the <code>Set-Cookie</code> header. Also note the
<code>csrfmiddlewaretoken</code> value in the form in the body of the
response. We&rsquo;ll use these values in our examples where we send POST
requests.</p>
<p>First a demonstration that we can successfully post a value using both
the cookie and the value in the form (in the <code>--data</code> parameter):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ curl -s -D - -o /dev/null <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>-H <span class="s1">&#39;Cookie: csrftoken=wVFdNQ1Hz487w7yk2mVjre2qlsclXi99w2jEcGyvXorojDLd7jH09NGhmbavG3tx&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>--data <span class="s1">&#39;csrfmiddlewaretoken=JBWuPGvKU54xW9YIwEIknst1azSkBmg3JIAVew2yipnOJFbBBBu1517SbiQuk7Ar&amp;name=mark&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>http://localhost:8000/post_to_me/
</span></span></code></pre></div><p>The response is a nice <code>200 OK</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.0</span> <span class="m">200</span> <span class="ne">OK</span>
</span></span><span class="line"><span class="cl"><span class="n">Date</span><span class="o">:</span> <span class="l">Tue, 15 Nov 2016 20:30:35 GMT</span>
</span></span><span class="line"><span class="cl"><span class="n">Server</span><span class="o">:</span> <span class="l">WSGIServer/0.2 CPython/3.4.3</span>
</span></span><span class="line"><span class="cl"><span class="n">X-Frame-Options</span><span class="o">:</span> <span class="l">SAMEORIGIN</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Type</span><span class="o">:</span> <span class="l">text/html; charset=utf-8</span>
</span></span></code></pre></div><p>If we do not send the cookie along, we expect that the POST request
will fail:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ curl -s -D - -o /dev/null <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>--data <span class="s1">&#39;csrfmiddlewaretoken=JBWuPGvKU54xW9YIwEIknst1azSkBmg3JIAVew2yipnOJFbBBBu1517SbiQuk7Ar&amp;name=mark&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>http://localhost:8000/post_to_me/
</span></span></code></pre></div><p>And indeed the server responds with a <code>403 Forbidden</code> status:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.0</span> <span class="m">403</span> <span class="ne">Forbidden</span>
</span></span><span class="line"><span class="cl"><span class="n">Date</span><span class="o">:</span> <span class="l">Tue, 15 Nov 2016 20:32:47 GMT</span>
</span></span><span class="line"><span class="cl"><span class="n">Server</span><span class="o">:</span> <span class="l">WSGIServer/0.2 CPython/3.4.3</span>
</span></span><span class="line"><span class="cl"><span class="n">X-Frame-Options</span><span class="o">:</span> <span class="l">SAMEORIGIN</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Type</span><span class="o">:</span> <span class="l">text/html</span>
</span></span></code></pre></div><p>We could try to include the cookie but leave out the value in the form
to check if the cookie alone is enough:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -s -D - -o /dev/null <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>-H <span class="s1">&#39;Cookie: csrftoken=wVFdNQ1Hz487w7yk2mVjre2qlsclXi99w2jEcGyvXorojDLd7jH09NGhmbavG3tx&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>--data <span class="s1">&#39;name=mark&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>http://localhost:8000/post_to_me/
</span></span></code></pre></div><p>However, this has the same result:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.0</span> <span class="m">403</span> <span class="ne">Forbidden</span>
</span></span><span class="line"><span class="cl"><span class="n">Date</span><span class="o">:</span> <span class="l">Tue, 15 Nov 2016 20:33:35 GMT</span>
</span></span><span class="line"><span class="cl"><span class="n">Server</span><span class="o">:</span> <span class="l">WSGIServer/0.2 CPython/3.4.3</span>
</span></span><span class="line"><span class="cl"><span class="n">X-Frame-Options</span><span class="o">:</span> <span class="l">SAMEORIGIN</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Type</span><span class="o">:</span> <span class="l">text/html</span>
</span></span></code></pre></div><p>As you can see Django requires both components to be present. The
actual value of the token is less relevant. Sure, it is &ldquo;unguessable&rdquo;,
but that is (in my humble opinion) not the most relevant part. The
CSRF token is also not stored. Django could not care that much about
the actual value&mdash;as long as the value in the cookie matches the one
in the POST data, the token is considered valid.</p>
<p>To demonstrate that I can make up my own values if I want to (as
long as they are 32 or 64 characters in length):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ curl -s -D - -o /dev/null <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>-H <span class="s1">&#39;Cookie: csrftoken= markmarkmarkmarkmarkmarkmarkmark&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>--data <span class="s1">&#39;csrfmiddlewaretoken=markmarkmarkmarkmarkmarkmarkmark&amp;name=mark&#39;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>http://localhost:8000/post_to_me/
</span></span></code></pre></div><p>This succeeds:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.0</span> <span class="m">200</span> <span class="ne">OK</span>
</span></span><span class="line"><span class="cl"><span class="n">Date</span><span class="o">:</span> <span class="l">Tue, 15 Nov 2016 20:35:55 GMT</span>
</span></span><span class="line"><span class="cl"><span class="n">Server</span><span class="o">:</span> <span class="l">WSGIServer/0.2 CPython/3.4.3</span>
</span></span><span class="line"><span class="cl"><span class="n">X-Frame-Options</span><span class="o">:</span> <span class="l">SAMEORIGIN</span>
</span></span><span class="line"><span class="cl"><span class="n">Content-Type</span><span class="o">:</span> <span class="l">text/html; charset=utf-8</span>
</span></span></code></pre></div><p>This example uses an older version of the CSRF token. As of Django
1.10 the CSRF form token value is salted and changed every
request. (For details, see
<a href="https://github.com/django/django/commit/5112e65ef2df1dbb95ff83026b6a962fb2688661">this commit</a>
and the <a href="https://code.djangoproject.com/ticket/20869">related issue</a>.)
This does not change the mechanism behind the defence though.</p>
<h3 id="why-does-this-defence-work">Why does this defence work?</h3>
<p>Back to the attack. Why does it matter that the POST request has to
have matching tokens both via the cookie and the POST data?</p>
<p>Cookies are set for a specific domain. Your browser protects this in
two ways:</p>
<ul>
<li>You cannot set a cookie for a different domain.</li>
<li>Cookies for one domain are not sent to another domain.</li>
</ul>
<p>This defence against CSRF works because although the evil site <em>can</em>
force the browser to make a request to the site it wants to abuse, the
attacker can only manipulate the request and its data. The attacker
<em>cannot</em> set, modify or even read a cookie for a different domain than
its own. As a result the attacker cannot determine or even guess which
CSRF token should be in the request and thus the request will fail.</p>
<p>Note that this is the protection chosen by Django. Other forms of
defence are possible. See the aforementioned
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html">Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet</a>
for more information.</p>
<p><em>As already stated at the top of the article, I do not want to imply
that mister Poirier does not know how the CSRF protection in Django
works; perhaps he decided to leave out some of these details to make
his article more succinct. Either way, in my opinion his article only
told half of the story with regards to CSRF protection. So I decided
to talk about the other half.</em></p>]]></content>
  </entry>
</feed>
