<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Projects on Edbro.net - A Cybersecurity Blog</title>
    <link>https://edbro.net/categories/projects/</link>
    <description>Recent content in Projects on Edbro.net - A Cybersecurity Blog</description>
    <image>
      <title>Edbro.net - A Cybersecurity Blog</title>
      <url>https://edbro.net/images/edbro</url>
      <link>https://edbro.net/images/edbro</link>
    </image>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Tue, 03 Jan 2023 14:32:37 +0100</lastBuildDate>
    <atom:link href="https://edbro.net/categories/projects/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Thoughts on Mastodon</title>
      <link>https://edbro.net/posts/thoughts-on-mastodon/</link>
      <pubDate>Tue, 03 Jan 2023 14:32:37 +0100</pubDate>
      <guid>https://edbro.net/posts/thoughts-on-mastodon/</guid>
      <description>&lt;p&gt;Over the holidays I finally took my time to dig into &lt;a href=&#34;https://joinmastodon.org/sv&#34;&gt;Masodon&lt;/a&gt;. It has been a bit of a journey, both to understand how it works, and how to use it. From the start it feels like twitter, but as you use it you see the differences and realise how different they are. Regardless I do now feel at home on Mastodon, and the lack of an algorithm feeding posts it thinks I will like is most refreshing.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Over the holidays I finally took my time to dig into <a href="https://joinmastodon.org/sv">Masodon</a>. It has been a bit of a journey, both to understand how it works, and how to use it. From the start it feels like twitter, but as you use it you see the differences and realise how different they are. Regardless I do now feel at home on Mastodon, and the lack of an algorithm feeding posts it thinks I will like is most refreshing.</p>
<h2 id="what-is-mastodon">What is Mastodon?</h2>
<p>The main selling point of Mastodon is that it is a decentralised social network. Think of it as combination of Twitter and Email. Just as Twitter, Mastodon gives you a timeline of posts by people you follow. However, it is not a centralised system, instead you chose your Mastodon instance. That way your username looks as an email address. Mine for example is <a href="https://swecyb.com/@edbro">@edbro@swecyber.com</a>, and my posts can be seen by any other instance.</p>
<p>This is called a federated solution. You work towards your instance, that shares its data with other instances. In practice this minimises the dependency on a single centralised entity. If you wish to change instance due to a lack of trust, it not being maintained or closed down you can just export your data and import it on a new instance. That could be on a personal instance or one of the larger ones that is already existing.</p>
<p>For now it seems to be mostly tech people whom have migrated from Twitter, but there are others as well. However, since each instance usually have a focus, this might be somewhat due to the my choice of instance to join, and the people I follow.</p>
<p>This design of Mastodon puts a big responsibility on its users to follow accounts with diverse opinions to not end up in a bubble. There is a risk that if you only follow people with opinions like your own, they will be further deepened, regardless if they are right or wrong. It is up to the user to ensure that views are challenged in a good way and that everyone uses their critical thinking to not be fooled by malicious actors.</p>
<h2 id="main-differences-from-twitter">Main Differences from Twitter</h2>
<p>The main things that confused me was the likeness of twitter, while Mastodon is different. Some things that seem similar works quite different.</p>
<ul>
<li>There is no algorithm. You see the posts authored (or boosted) by the pepole you follow. If you want to find new people to follow you can also see the timeline of your instance and instances configured by its admin. However this timeline is sorted chronologically, and all posts of those instances are shown.</li>
<li>The difference between <em>Boosts</em>, <em>Favourites</em>, and <em>Bookmarks</em>.
<ul>
<li><em>Boosts</em> are retweets. On Mastodon they are used to further spread a post. This allows your followers (regardless of instance) to see the original post. Note also that it is not possible to quote boost. If you want to add something to the discussion, you need to do so as a reply.</li>
<li><em>Favourites</em> shares some features with likes. They can be seen on an original post, but does not push the post to your followers. Also note that there are no algorithm pushing posts with many likes. Therefore the effect of favouriteing is limited.</li>
<li><em>Bookmarks</em> are a way to save a post so that you can find it again later. These are seen by neither the author of the post nor your followers.</li>
</ul>
</li>
<li>The search does not search the full text. Instead only displaynames, tags, and usernames are searched. In addition, searches can only find things the instance is aware of. For example that could be posts that are federated to the users of the instance or the authors of those posts. To find a user of another instance you need their full username, including the address to the instance.</li>
<li>Each post is tagged with a language. This makes it possible to use 1 account to communicate in different languages. Your followers can easily filter your posts to the languages they speak, and does not see the posts in other languages.</li>
</ul>
<h2 id="thoughts-on-mastodon">Thoughts on Mastodon</h2>
<p>After getting used to the behaviour of Mastodon I really like what it does. It is a nice social network, and allows for discussions and networking in a way that twitter today doesn&rsquo;t. It is easier to perform personal moderation of what I wish to see.</p>
<p>I have found a small instance with individuals interested in cybersecurity. This however does not limit me, I still partake in the broader community, replying to posts or sharing my thoughts from the beginning.</p>
<p>Hope to see you on Mastodon!</p>
]]></content:encoded>
    </item>
    <item>
      <title>Connecting a MikroTik AccessPoint to RouterOS via CapsMAN</title>
      <link>https://edbro.net/posts/connecting-a-mikrotik-accesspoint-to-routeros-via-capsman/</link>
      <pubDate>Sun, 13 Nov 2022 13:01:14 +0100</pubDate>
      <guid>https://edbro.net/posts/connecting-a-mikrotik-accesspoint-to-routeros-via-capsman/</guid>
      <description>&lt;p&gt;After getting tiered of the shortcomings of commercial network equipment I decided to invest in some professional devices. However, investigating the different brands are even more difficult than for commercial products. In the end I decided to go for &lt;a href=&#34;https://mikrotik.com&#34;&gt;MikroTik&lt;/a&gt;, due to their small office offerings. The devices are great and when first connecting to them you realise their potential through the sheer volume of configuration. As expected you need to design and configure you network to get it to work at all. This made me realise that I have not touched professional network equipment since university, and that was Cisco equipment. To my dread I could not find a good guide on how to configure a simple network with my equipment, so after finishing this is my guide.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>After getting tiered of the shortcomings of commercial network equipment I decided to invest in some professional devices. However, investigating the different brands are even more difficult than for commercial products. In the end I decided to go for <a href="https://mikrotik.com">MikroTik</a>, due to their small office offerings. The devices are great and when first connecting to them you realise their potential through the sheer volume of configuration. As expected you need to design and configure you network to get it to work at all. This made me realise that I have not touched professional network equipment since university, and that was Cisco equipment. To my dread I could not find a good guide on how to configure a simple network with my equipment, so after finishing this is my guide.</p>
<h2 id="goals">Goals</h2>
<p>When setting up our network we have a couple of goals. Namely we want a stable network where we can plug in wired devices, as well as connect via Wi-Fi. For now we are happy with creating a single wireless network that all devices connect to, and that is not separated from the wired network. However, it would be possible to create a secondary guest network, separated from our trusted devices.</p>
<p>In addition to the main goal the network should be as easy to maintain as possible. The less configuration that can break the better, and the more resilient it is to changes the better.</p>
<h2 id="equipment-and-terminology">Equipment and Terminology</h2>
<p>Due to the configurability of the RouterOS firmware (the firmware used by MikroTik devices) this guide will likely be applicable for other devices as well. However, it is only tested with my setup of a <a href="https://mikrotik.com/product/RBwAP2nD">wireless access point</a>, and a <a href="https://mikrotik.com/product/RB750UPr2">router/switch combo</a>.</p>
<p>To make it easier to follow along while using other devices this guide will use the name (or Identity in RouterOS terms) cap for the access-point and capMan for the router/switch. The table below gives an overview of the name and role of each device.</p>
<table>
  <thead>
      <tr>
          <th>Device</th>
          <th>Model</th>
          <th>Identity</th>
          <th style="text-align: left">Role</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Wireless Access Point</td>
          <td><a href="https://mikrotik.com/product/RBwAP2nD">wAP</a></td>
          <td>CAP</td>
          <td style="text-align: left">The access-point used to provide Wi-Fi access</td>
      </tr>
      <tr>
          <td>Router/Switch</td>
          <td><a href="https://mikrotik.com/product/RB750UPr2">hEX PoE</a></td>
          <td>CAPMAN</td>
          <td style="text-align: left">The router switch combo used as the center of the network. It will be the manager configuring the access-point.</td>
      </tr>
  </tbody>
</table>
<p>To achieve our goal of maintainability we will use a function called <a href="https://wiki.mikrotik.com/wiki/Manual:CAPsMAN">CAPsMAN (Controlled Access Point system Manager)</a>. This will allow us to centrally manage the access point (and new access-points in the future) from a centralised point. The router will then send updates to all access-points, removing the need to manage them one by one.</p>
<h2 id="steps">Steps</h2>
<p>So how to configure a wireless network with MikroTik devices? I&rsquo;ve broken it down into two steps, first the preparations, and then configuring the Wi-Fi network.</p>
<h3 id="preparation">Preparation</h3>
<p>The first step to any network configuration is to ensure that each device is reachable and has a recognisable identity (name). I found that it was easiest to factory reset the access-point from the GUI, and choosing the cap preset. This puts the device into a bridge mode, disabling all router functionality and NAT. This gave a good starting point for the rest of the configuration.</p>
<p>With a reset access-point it is time to ensure that each device have a recognisable identity. As described in <a href="#equipment-and-terminology">Equipment and Terminology</a> I will use CAP for the access-point and CAPMAN for the router. It is also important to ensure that the devices has good passwords and are up to date, so I recommend doing so now.</p>
<p>To make it easier to troubleshoot the network I also recommend setting a static DHCP lease for the CAP device. In my case the following IP configuration is used:</p>
<table>
  <thead>
      <tr>
          <th>Device</th>
          <th>Name</th>
          <th>IP</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Router</td>
          <td>CAPMAN</td>
          <td>192.168.88.1</td>
      </tr>
      <tr>
          <td>Access-Point</td>
          <td>CAP</td>
          <td>192.168.88.2</td>
      </tr>
  </tbody>
</table>
<h3 id="configuring-a-wireless-network-with-mikrotik-devices">Configuring a Wireless Network with MikroTik Devices</h3>
<p>With our network in a state were we have a connection between CAPMAN and CAP we can begin to configure the network. The first step is to configure CAP to ask CAPMAN for configurations. This is done by using <code>[admin@CAP] &gt; /interface wireless cap set caps-man-addresses 192.168.88.1</code>. This command sets the address of the manager and ensures that it is the one responsible for the configuration.</p>
<p>Next up we need to configure the wireless network. This is done in multiple steps, as shown below.</p>
<pre tabindex="0"><code>[admin@CAPMAN] &gt; /caps-man security add name=&#34;wpa2psk&#34; authentication-types=wpa2-psk encryption=aes-ccm
[admin@CAPMAN] &gt; /caps-man security set 0 passphrase=[REDACTED]
[admin@CAPMAN] &gt; /caps-man configuration add name=master-cfg ssid=[My-Wifi-Network] security=wpa2psk country=sweden
[admin@CAPMAN] &gt; /caps-man provisioning add action=create-dynamic-enabled master-configuration=master-cfg
[admin@CAPMAN] &gt; /caps-man configuration set 0 datapath.bridge=bridge
[admin@CAPMAN] &gt; /caps-man manager set enabled yes
</code></pre><p>The first command will create a new security configuration, specifying that the Wi-Fi shall use wpa2-psk for authentication and AES encryption.
After that we set the password. This is the password used to connect to the wireless network when it gets activated.
The third step is to set the name of the Wi-Fi (the SSID). Note that we do not want to configure a band here. This will allow the CAP to create a network on 2.4ghz as well as on 5ghz. Otherwise, it would only create the network on the configured band. If we wish to configure the a second Wi-Fi, we would create a second configuration here and add it as a slave configuration in the next step.
On line 5 we provision the network to be created. This tells CAPMAN what configuration to push to what device.
This means that if you have multiple devices you can set what devices to push it to. For more information use the built-in help or the online documentation for provisioning.
The last row is the thing that got me confused. It tells the CAPMAN what bridge (interfaces) the network should be attached to. In my case this is the default bridge, and this allows devices to connected to the Wi-Fi to access the network.
The last step is to enable the CAPsMAN configuration on CAPMAN. This turns the configuration on and you should now be able to see your wireless network and connect to it.</p>
<p><strong>Note</strong> that if you wish to change something in an existing configuration you need to remove the configured interfaces and then trigger a re provision. This is done by:</p>
<pre tabindex="0"><code>[admin@CAPMAN] &gt; /caps-man interface print
# This shows all interfaces, remove all interfaces
[admin@CAPMAN] &gt; /caps-man interface remove 0
[admin@CAPMAN] &gt; /caps-man remote-cap print
[admin@CAPMAN] &gt; /caps-man remote-cap provision 0
# Reprovision all CAPs
</code></pre><p>There are lots more that can be done with CAPsMAN, but this should be a good starting point. However, I recommend the <a href="https://wiki.mikrotik.com/wiki/Manual:CAPsMAN">MikroTik wiki</a> to read up more on the options. There might be other things relevant for your needs.</p>
<h2 id="summary">Summary</h2>
<p>Setting up a wireless network with MikroTik infrastructure is quite easy, when you know what steps to take. The steps to take are on the managing device (CAPMAN):</p>
<ol>
<li>Set CAP to use CAPMAN for configuration.</li>
<li>Configure the security to use for the Wi-Fi.</li>
<li>Configure the password for the network.</li>
<li>Create a network configuration to use.</li>
<li>Provision the configuration to be pushed to access-points.</li>
<li>Configure datapath for the wireless network.</li>
<li>Enable the network</li>
</ol>
<p>And on the CAP:</p>
<ol>
<li>Configure the CAPsMAN manager to use.</li>
</ol>
<p>This should allow your CAPMAN to dynamically configure any access-points connected to provide network access.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Migrating to Hugo</title>
      <link>https://edbro.net/posts/migrating-to-hugo/</link>
      <pubDate>Sun, 16 Oct 2022 00:00:00 +0000</pubDate>
      <guid>https://edbro.net/posts/migrating-to-hugo/</guid>
      <description>&lt;p&gt;It has now come to an end of an era. The time has come to move on from from my previous way of building this blog (with Jekyll) to something new. For a while now I&amp;rsquo;ve been looking for a reason to dig some more into &lt;a href=&#34;https://go.dev/&#34;&gt;golang&lt;/a&gt;, so when i began looking for a new theme for my blog the choice to migrate to &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; came quite easy. At first glance it does exactly the same thing as &lt;a href=&#34;https://jekyllrb.com/&#34;&gt;Jekyll&lt;/a&gt;, but for someone who from time to time make changes to the theme it makes more sense (my personal opinion).&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>It has now come to an end of an era. The time has come to move on from from my previous way of building this blog (with Jekyll) to something new. For a while now I&rsquo;ve been looking for a reason to dig some more into <a href="https://go.dev/">golang</a>, so when i began looking for a new theme for my blog the choice to migrate to <a href="https://gohugo.io/">Hugo</a> came quite easy. At first glance it does exactly the same thing as <a href="https://jekyllrb.com/">Jekyll</a>, but for someone who from time to time make changes to the theme it makes more sense (my personal opinion).</p>
<p><img alt="The old website, built in Jekyll" loading="lazy" src="/images/2022/Migrating-to-Hugo/jekyll.png" title="The old website"></p>
<h2 id="buidling-the-site">Buidling the Site</h2>
<p>The first thing to do when migrating is to find a new theme and adapt/move things into it. I ended up choosing <a href="https://github.com/adityatelange/hugo-PaperMod/">PaperMod</a>, due to its simplicity in combination with a modern look and feel. With that out of the way it was time to move my logotype and descriptive texts. In both cases this kind of information is stored in the configuration files.</p>
<p>The next step is to move the actual contents of the blog. In Jekyll this is stored in two folders (at least in my case):</p>
<ol>
<li>The posts: <code>/_posts</code> -&gt; <code>/content/posts</code></li>
<li>The images <code>/assets</code> -&gt; <code>/static/images</code></li>
</ol>
<p>With this out of the way it is time to go through every single post to update the syntax. The first thing is the metadata of the posts, the top of my markdown files. In my case there was no difference. The following is the configuration is what was used in Jekyll.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">layout</span><span class="p">:</span><span class="w"> </span><span class="l">post</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">title</span><span class="p">:</span><span class="w">  </span><span class="s2">&#34;Building a Webpage&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">date</span><span class="p">:</span><span class="w">   </span><span class="ld">2020-08-19</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">categories</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Projects&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">tags</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;Jekyll&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;Projects&#34;</span><span class="p">]</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">author</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Oskar Edbro&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nn">---</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>The <code>layout</code> is just discarded, and the rest have the same functionality in both Jekyll and Hugo. With this knowledge it is time to look at how each post looks. And sadly there is a difference between how images are included. The good thing is that Hugo better handles the default image syntax from markdown. This means that images can be included as shown below:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-md" data-lang="md"><span class="line"><span class="cl">![<span class="nt">A phone with apps seen as privacy violations</span>](<span class="na">/images/2022/The-Modern-Con/The-Modern-Con-Privacy-Violation.jpg &#39;Photo by Jeremy Bezanger on Unsplash&#39;</span>)
</span></span></code></pre></div><p>With that all the modifications required for the application is finished. The next step is to polish the site with information and ensure that all information is available.</p>
<h2 id="hosting">Hosting</h2>
<p>Setting up the hosting i Decided to use GitHub Actions instead of just using the Cloudflare auto build (as I did previously in <a href="https://edbro.net/posts/migrating-to-cloudflare/">Migrating to Cloudflare</a>). This means that I am required to learn some thing about how to create a CICD Pipeline.</p>
<p>Getting everything to play nicely was a bit of a hazel, especially since I to insisted on separating the build and deploy actions into different jobs. In the end, the issue was in regards to saving and then retrieving the artefacts. When that issue was solved all went smooth. So how was it done? To build the page I used the following job:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">  </span><span class="nt">build</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Checkout</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">submodules</span><span class="p">:</span><span class="w"> </span><span class="l">recursive</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Setup Hugo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">peaceiris/actions-hugo@v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">hugo-version</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;latest&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="c"># extended: true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build with Hugo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">env</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="c"># For maximum backward compatibility with Hugo modules</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">HUGO_ENVIRONMENT</span><span class="p">:</span><span class="w"> </span><span class="l">production</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">HUGO_ENV</span><span class="p">:</span><span class="w"> </span><span class="l">production</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          hugo \
</span></span></span><span class="line"><span class="cl"><span class="sd">            --minify </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Upload artifact</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/upload-artifact@v3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">${{ github.workspace }}/public</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">retention-days</span><span class="p">:</span><span class="w"> </span><span class="m">7</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>Noteworthy things are the use of an existing Hugo build action, and saving the artefacts to my GitHub workspace. We also make sure to minify the generated HTML, just to save a bit of data. It does not make much difference, but every little bit counts. For the deployment, there are just two steps. Downloading the artefacts we saved, and then uploading them to Cloudflare. The project name has however been masked.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">  </span><span class="nt">deploy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Deploy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="l">build</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Download a single artifact</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/download-artifact@v3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">${{ github.workspace }}/public</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Publish</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">cloudflare/pages-action@1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">apiToken</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.CF_API_TOKEN }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">accountId</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.CF_API_ID }}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">projectName</span><span class="p">:</span><span class="w"> </span><span class="l">XXXXXX</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">directory</span><span class="p">:</span><span class="w"> </span><span class="l">./public</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">gitHubToken</span><span class="p">:</span><span class="w"> </span><span class="l">${{ secrets.GH_PAT }}</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="summary">Summary</h2>
<p>So in the end, it took more time than expected to migrate to Hugo. However, most of the time spent was in learning things. How to use GitHub Actions, how Hugo works, etc. With that out of the way, it was quite easy. Now, the next step is to start modifying the small things to get the theme even better.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Cloudflare, a Couple Months Later</title>
      <link>https://edbro.net/posts/cloudflare-a-couple-months-later/</link>
      <pubDate>Sun, 11 Jul 2021 00:00:00 +0000</pubDate>
      <guid>https://edbro.net/posts/cloudflare-a-couple-months-later/</guid>
      <description>&lt;p&gt;In a previous &lt;a href=&#34;https://edbro.net/posts/migrating-to-cloudflare/&#34;&gt;post&lt;/a&gt; I shared my experience with moving my page from Github pages to Cloudflare. It is now time to follow up that post and comment on my experiences after approximately a quarter.&lt;/p&gt;
&lt;p&gt;The experience of publishing new posts is about the same as when hosting on Github, you just push an update to the specified branch and then a build is triggered that will be published upon completion. The main difference is that the build process is somewhat slower in Cloudflare than on Github. This means that a build can take about 5 minutes, instead of the previous 1. This is most likely due to the fact that Cloudflare pulls everything and builds locally, instead of using Jekyll remote themes.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In a previous <a href="https://edbro.net/posts/migrating-to-cloudflare/">post</a> I shared my experience with moving my page from Github pages to Cloudflare. It is now time to follow up that post and comment on my experiences after approximately a quarter.</p>
<p>The experience of publishing new posts is about the same as when hosting on Github, you just push an update to the specified branch and then a build is triggered that will be published upon completion. The main difference is that the build process is somewhat slower in Cloudflare than on Github. This means that a build can take about 5 minutes, instead of the previous 1. This is most likely due to the fact that Cloudflare pulls everything and builds locally, instead of using Jekyll remote themes.</p>
<p>When the post is published, there are no major difference for the user, however the statistics for the creator is much deeper. The pure web analytics (provided by JavaScript) could be implemented wherever the site was hosted, but there is more. The web analytics is the most detailed analytics, since it provides what posts were visited, referrers, user agents and more. The Cloudflare proxy analytics on the other hand does not require JavaScript, and can therefore not be blocked. The amount of information provided is not as detailed, but it gives a broader picture of the visitors. This data contains unique visitors and their origin country, but not much more. This could be seen in the web statistics as well, but that tracking is easily blocked.</p>
<p>Even though I have a quite negative stance on tracking, I think that information that is collected in the server anyway can be shown to the content creator without infringing the readers privacy. By being able to track number of readers it&rsquo;s possible to gain insight in the trends depending on the type of content published. For this blog for example I can from the statistics note that the most interesting content is in the divide between technical security and policies. For example <a href="https://edbro.net/posts/an-analysis-of-the-spotify-gdpr-data-export/">Spotify GDPR Analysis</a> is one of the most read articles on the blog, and it was written before I added analysis, and posts are often read the most directly at launch.</p>
<p>Getting back to the topic at hand, the experience of using Cloudflare, it gives the possibility to handle everything at a single location. This includes managing the domain as an registrar, hosting the application, managing TLS certificates and much more. The only thing I&rsquo;ve found that is a bit tricky is that I&rsquo;ve not found a way to register a new domain, only to transfer an existing one. With that said, I&rsquo;ve been very happy with my switch to Cloudflare, it gives me the tools I need for my blog, and just works.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Migrating to Cloudflare</title>
      <link>https://edbro.net/posts/migrating-to-cloudflare/</link>
      <pubDate>Sat, 17 Apr 2021 00:00:00 +0000</pubDate>
      <guid>https://edbro.net/posts/migrating-to-cloudflare/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been looking around on how to get some statistics from my blog, especially regarding the number of visitors. Sadly the current solution (GitHub pages) does not seem to natively support this kind of statistics without adding third party tracking. After looking around for different solutions Cloudflare caught my attention. I know that among others, &lt;a href=&#34;https://www.troyhunt.com/&#34;&gt;Troy Hunt&lt;/a&gt; writes about and uses Cloudflare, so I decided to give it a try.&lt;/p&gt;
&lt;p&gt;Migrating from GitHub pages to Cloudflare pages was as easy as configuring what GitHub repo to use in Cloudflare, picking Jekyll and then it just worked. Right after the page was built you see some basic statistics, such as the amount of request grouped by country. Below the first hours of traffic is shown in a map, as presented by Cloudflare.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve been looking around on how to get some statistics from my blog, especially regarding the number of visitors. Sadly the current solution (GitHub pages) does not seem to natively support this kind of statistics without adding third party tracking. After looking around for different solutions Cloudflare caught my attention. I know that among others, <a href="https://www.troyhunt.com/">Troy Hunt</a> writes about and uses Cloudflare, so I decided to give it a try.</p>
<p>Migrating from GitHub pages to Cloudflare pages was as easy as configuring what GitHub repo to use in Cloudflare, picking Jekyll and then it just worked. Right after the page was built you see some basic statistics, such as the amount of request grouped by country. Below the first hours of traffic is shown in a map, as presented by Cloudflare.</p>
<p><img alt="Cloudflare map" loading="lazy" src="/images/2021/migrating-to-cloudflare/Cloudflare-map.png"></p>
<p>In addition to providing basic statistics, using Cloudflare gives a lot of additional benefits. This includes the use of their Content Delivery Network, protection from Denial of Service, and easy HTTPS. I have not dug deep into which is best in these regards, but i find it difficult to believe that I have made a significant downgrade.</p>
<p>So in conclusion to gain some basic statistics of the usage of my blog, I&rsquo;ve migrated it to Cloudflare. The solution will not track any personal data, only basic statistics to gain some insight in how many readers are  using/enjoying my blog.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Building a Webpage</title>
      <link>https://edbro.net/posts/building-a-webpage/</link>
      <pubDate>Wed, 19 Aug 2020 00:00:00 +0100</pubDate>
      <guid>https://edbro.net/posts/building-a-webpage/</guid>
      <description>&lt;p&gt;So here we go, I finally got around to building a blog, and after looking around at different options i ended up using Jekyll and github pages. In addition to getting me this webpage, it allowed me to get some basic insight into ruby, making this a case of two birds one stone.&lt;/p&gt;
&lt;p&gt;Getting things to work have been quite a fiddle, so lets walk through how I got things up and running.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>So here we go, I finally got around to building a blog, and after looking around at different options i ended up using Jekyll and github pages. In addition to getting me this webpage, it allowed me to get some basic insight into ruby, making this a case of two birds one stone.</p>
<p>Getting things to work have been quite a fiddle, so lets walk through how I got things up and running.</p>
<p>The first step was to get ruby and jekyll installed on my local machine for testing. After trying with wsl I lost my patience and to my surprise it was easier to install directly in windows. Jekyll has a great guide on how to install ruby, jekyll and all dependencies at <a href="https://jekyllrb.com/docs/installation/windows/">https://jekyllrb.com/docs/installation/windows/</a>.</p>
<p>The next step was to create my github repository. To be able to host github pages you have to name the repository <code>&lt;username&gt;.github.io</code> where you replace <code>&lt;username&gt;</code> with your github username. After that I cloned my repository to my local machine and initiated jekyll by running <code>jekyll new .</code> in my repository.</p>
<p>At this point I got a basic blog. By using <code>bundle exec jekyll serve</code> the webpage is built and hosted locally for testing. It works, but now it&rsquo;s time to pretty the page up a bit. After looking around on different themes for a while I ended up choosing <a href="https://github.com/ngzhio/jekyll-theme-hamilton">Hamilton</a>, it fits my needs nicely, and i really enjoy the look. Installing it was as easy as following the guide in the documentation, you just have to remember to change the theme in <code>_config.yml</code>, to ensure that you use the new theme. That took far to long to realise, but finally I made it.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
