mirror of
https://github.com/nicolabs/nicolabs.net.git
synced 2025-09-21 00:32:01 +02:00
1694 lines
213 KiB
XML
1694 lines
213 KiB
XML
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://www.nicolabs.net/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.nicolabs.net/" rel="alternate" type="text/html" /><updated>2024-12-20T23:59:34+01:00</updated><id>https://www.nicolabs.net/feed.xml</id><title type="html">nicolabs</title><subtitle>Work in progress...</subtitle><author><name>nicobo</name></author><entry><title type="html">Install LineageOS with Google Services and root</title><link href="https://www.nicolabs.net/2024/LineageOS4microG-Upgrade" rel="alternate" type="text/html" title="Install LineageOS with Google Services and root" /><published>2024-12-21T00:00:00+01:00</published><updated>2024-12-21T00:00:00+01:00</updated><id>https://www.nicolabs.net/2024/LineageOS4microG-Upgrade</id><content type="html" xml:base="https://www.nicolabs.net/2024/LineageOS4microG-Upgrade"><, they DO NOT support it.</p>
|
||
|
||
<p><a href="https://lineage.microg.org/">LineageOS of microG</a> provides LineageOS images for your phone, <em>directly shipping with microG</em>, which is an implementation of gapps.
|
||
shipping</p>
|
||
|
||
<p>This short tutorial gives some details about the <strong>upgrade</strong> procedure, which were not clear to me.
|
||
There is no per-device specific documentation for <em>LineageOS for microG</em>, so it is based on <a href="https://wiki.lineageos.org/devices/">the official LineageOS one</a>.</p>
|
||
|
||
<h2 id="the-easy-way">The easy way</h2>
|
||
|
||
<ol>
|
||
<li>
|
||
<p>Download the new image from : https://lineage.microg.org/
|
||
The image to install is named something like <a href="https://download.lineage.microg.org/FP3/lineage-20.0-20230604-microG-FP3.zip">lineage-20.0-20230604-microG-FP3.zip</a>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Copy the image onto your smartphone.
|
||
You can just plug your phone as an USB disk.</p>
|
||
</li>
|
||
<li>
|
||
<p>Use the “Local update” menu from the LineageOS installer app (Android admin menu > System > System updates > expand menu button).
|
||
<strong>Do not use the images proposed by the LineageOS updater app</strong> as it would install the official LineageOS image, not the microG one.
|
||
You can just ignore the items proposed for download, they will disappear at the next reboot after the upgrade.</p>
|
||
</li>
|
||
<li>
|
||
<p>Reboot the phone.</p>
|
||
</li>
|
||
</ol>
|
||
|
||
<h2 id="the-not-so-easy-way">The not-so-easy way</h2>
|
||
|
||
<ol>
|
||
<li>
|
||
<p>Download the new image as above.</p>
|
||
</li>
|
||
<li>
|
||
<p>Make sure you have a custom <em>recovery</em> on your smartphone.
|
||
This is a whole procedure to do if you don’t have it already, but afterwards you will keep it for future upgrades. There are indications on how to do it <em>somewhere…</em></p>
|
||
</li>
|
||
<li>
|
||
<p>Reboot into recovery and “just” flash the .zip image
|
||
Read detailed instructions for your device ; it’s something like : <code class="language-plaintext highlighter-rouge">fastboot [...]</code>, then <code class="language-plaintext highlighter-rouge">adb sideload [...]</code> (e.g. <a href="https://wiki.lineageos.org/devices/FP3/install/variant1">for Fairphone3</a>)</p>
|
||
</li>
|
||
<li>
|
||
<p>To (re)get <em>root</em>, <a href="https://topjohnwu.github.io/Magisk/install.html">install Magisk</a> :</p>
|
||
<ul>
|
||
<li>Even if installing from the app, you have to download the zip (and select it from the app or install it from recovery)</li>
|
||
<li>Magisk installs itself into the ROM of your phone, for this :
|
||
<ol>
|
||
<li>it needs the current image of the boot/recovery partition (either <code class="language-plaintext highlighter-rouge">boot.img</code>, <code class="language-plaintext highlighter-rouge">init_boot.img</code> or <code class="language-plaintext highlighter-rouge">recovery.img</code> depending on your device). So you must give it the exact image that you’ve just installed so it can patch it : e.g. for LineageOS for microG the boot.img of FP3 is in the same folder as other images to download : <a href="https://download.lineage.microg.org/FP3/lineage-20.0-20230601-microG-FP3-boot.img">lineage-20.0-20230601-microG-FP3-boot.img</a></li>
|
||
<li>Then you patch it (from the app)</li>
|
||
<li>Once done, download the patched image (it’s in the Downloads directory on your phone ; e.g. <code class="language-plaintext highlighter-rouge">/sdcard/Download/magisk_patched-26100_c1Cdy.img</code>) to your PC</li>
|
||
<li>Finally flash back this image on your phone (<code class="language-plaintext highlighter-rouge">fastboot [...]</code>)</li>
|
||
</ol>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ol>]]></content><author><name>nicobo</name></author><category term="Android" /><category term="Fairphone" /><category term="Google" /><category term="gapps" /><category term="LineageOS" /><category term="Magisk" /><category term="microG" /><category term="root" /><summary type="html"><, they DO NOT support it. LineageOS of microG provides LineageOS images for your phone, directly shipping with microG, which is an implementation of gapps. shipping This short tutorial gives some details about the upgrade procedure, which were not clear to me. There is no per-device specific documentation for LineageOS for microG, so it is based on the official LineageOS one. The easy way Download the new image from : https://lineage.microg.org/ The image to install is named something like lineage-20.0-20230604-microG-FP3.zip. Copy the image onto your smartphone. You can just plug your phone as an USB disk. Use the “Local update” menu from the LineageOS installer app (Android admin menu > System > System updates > expand menu button). Do not use the images proposed by the LineageOS updater app as it would install the official LineageOS image, not the microG one. You can just ignore the items proposed for download, they will disappear at the next reboot after the upgrade. Reboot the phone. The not-so-easy way Download the new image as above. Make sure you have a custom recovery on your smartphone. This is a whole procedure to do if you don’t have it already, but afterwards you will keep it for future upgrades. There are indications on how to do it somewhere… Reboot into recovery and “just” flash the .zip image Read detailed instructions for your device ; it’s something like : fastboot [...], then adb sideload [...] (e.g. for Fairphone3) To (re)get root, install Magisk : Even if installing from the app, you have to download the zip (and select it from the app or install it from recovery) Magisk installs itself into the ROM of your phone, for this : it needs the current image of the boot/recovery partition (either boot.img, init_boot.img or recovery.img depending on your device). So you must give it the exact image that you’ve just installed so it can patch it : e.g. for LineageOS for microG the boot.img of FP3 is in the same folder as other images to download : lineage-20.0-20230601-microG-FP3-boot.img Then you patch it (from the app) Once done, download the patched image (it’s in the Downloads directory on your phone ; e.g. /sdcard/Download/magisk_patched-26100_c1Cdy.img) to your PC Finally flash back this image on your phone (fastboot [...])]]></summary></entry><entry><title type="html">Introduction to Home Automation</title><link href="https://www.nicolabs.net/2024/Intro-home-automation" rel="alternate" type="text/html" title="Introduction to Home Automation" /><published>2024-06-05T00:00:00+02:00</published><updated>2024-06-05T00:00:00+02:00</updated><id>https://www.nicolabs.net/2024/Intro-home-automation</id><content type="html" xml:base="https://www.nicolabs.net/2024/Intro-home-automation"><![CDATA[<p>Recently, I have been looking for a way to measure the typical energy consumption of the electric equipments I have at home.
|
||
I only wanted to buy a simple plug-in energy monitor but I ended up spending several days to understand what were the possible options (and about 6 more hours to write this article…) !</p>
|
||
|
||
<p>Here is what I’ve learned.</p>
|
||
|
||
<h2 id="the-watt-meter-buying-guide">The watt-meter buying guide</h2>
|
||
|
||
<p>What you need to measure electric power consumption is called a <em>watt-meter</em>.
|
||
Depending on what kind of equipment you want to monitor, there are different form factors.</p>
|
||
|
||
<h3 id="clamp">Clamp</h3>
|
||
|
||
<p>A <em>clamp meter</em><sup id="fnref:clamp-meter"><a href="#fn:clamp-meter" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> is simply closed around the <em>phase wire</em> you want to measure.
|
||
Therefore it can only be used when you have the phase wire apart, not for molded cables.
|
||
Still, it seems to be a very versatile tool and you may build a custom extension cord with a separate phase wire to make it work with any plugable electric device.</p>
|
||
|
||
<h3 id="electric-plug">Electric plug</h3>
|
||
|
||
<p>A power meter in the form of a <em>plug</em><sup id="fnref:power-plug"><a href="#fn:power-plug" class="footnote" rel="footnote" role="doc-noteref">2</a></sup> is probably the most convenient device to measure the consumption of individual electrical devices.
|
||
You just put it between the mains and the device’s plug.</p>
|
||
|
||
<p>Make sure to check what is the maximum power supported ; a lot of devices are not able to measure high power equipments like ovens for instance.</p>
|
||
|
||
<h3 id="home-power-supply">Home power supply</h3>
|
||
|
||
<p>There are also monitors made as modules to plug into the home power supply panel<sup id="fnref:shelly"><a href="#fn:shelly" class="footnote" rel="footnote" role="doc-noteref">3</a></sup>, or interfacing with a dedicated connection<sup id="fnref:zlinky"><a href="#fn:zlinky" class="footnote" rel="footnote" role="doc-noteref">4</a></sup> or even by hacking the visual signals of the home energy counter.</p>
|
||
|
||
<p>Many power companies nowadays have them installed by default, so you may just need to request access to your dashboard.</p>
|
||
|
||
<p>This kind of monitor allows to follow the power consumption of the whole house or a given circuit.</p>
|
||
|
||
<h3 id="smart-meters">Smart meters</h3>
|
||
|
||
<p>Although you will find those devices with embedded screens and keypad to monitor the power consumption, most of the stores just don’t describe if they keep an history of the measures, during how long and at what pace.
|
||
It is also almost impossible to know, before buying, if / how to download the data to a computer, and in which format.</p>
|
||
|
||
<p>Electric plugs and power supply monitors also exist as so-called “smart”<sup id="fnref:nous-plug"><a href="#fn:nous-plug" class="footnote" rel="footnote" role="doc-noteref">5</a></sup>, reporting to a central “smart home gateway”.
|
||
As far as I’ve seen, there are no “smart” clamps.</p>
|
||
|
||
<h3 id="conclusion">Conclusion</h3>
|
||
|
||
<p>If you want to get a detailed overview of your home consumption, you will probably need several kind of power meters.</p>
|
||
|
||
<p><strong>For my “simple” needs, I decided to monitor the global consumption of the house by the means of my power provider, and one or few plugs that I could move from one device to another, in order to drill down to the individual suspects<sup id="fnref:hass-energy-full-approach"><a href="#fn:hass-energy-full-approach" class="footnote" rel="footnote" role="doc-noteref">6</a></sup>.</strong></p>
|
||
|
||
<p>Since I was not confident <em>at all</em> that I could extract the data from any autonomous watt-meter to Linux out of the box, I chose to buy smart plugs instead.
|
||
Even though it requires an additional infrastructure (the gateway, a local network, a computer to exploit the measures), the ones I chose makes use of open protocols, which I consider more durable.</p>
|
||
|
||
<p>Reminder of the attention points, in short :</p>
|
||
<ul>
|
||
<li>form factor</li>
|
||
<li>maximum power supported</li>
|
||
<li>history keeping and extraction</li>
|
||
<li>protocol / standard (for smart meters)</li>
|
||
</ul>
|
||
|
||
<h2 id="standards-in-short">Standards, in short</h2>
|
||
|
||
<p><a href="https://xkcd.com/927"><img src="https://imgs.xkcd.com/comics/standards.png" alt="xkcd : How standards proliferate" /></a></p>
|
||
|
||
<h3 id="zigbee">Zigbee</h3>
|
||
|
||
<p><a href="https://csa-iot.org/all-solutions/zigbee/">Zigbee</a> is currently the most widespread <em>open</em> standard communication protocol.
|
||
It works on specific radio frequencies and therefore, <strong>as most home automation protocols, requires physical devices with the right radio hardware.</strong>
|
||
As most home automation network protocols, it’s made to be low-energy.</p>
|
||
|
||
<p>Devices are nodes in a <em>mesh network</em> : they act as repeaters (“routers” is the term) in order to extend the network (well, most mains-powered devices do).
|
||
Within all devices, there must be one with <em>coordinator</em> capabilities to orchestrate all others.
|
||
This coordinator may be an all-in-one appliance (often a ‘gateway’ implementing other protocols as well) or an extension to an existing machine (for instance an USB dongle with zigbee chipsets & radio antenna).</p>
|
||
|
||
<p>One thing to notice : zigbee devices may use the <a href="https://www.metageek.com/training/resources/zigbee-wifi-coexistence/">same radio bandwidth as Wi-Fi</a> and Bluetooth (2.4 GHz) and therefore you may need to <a href="https://community.home-assistant.io/t/zigbee-networks-how-to-guide-for-avoiding-interference-optimizing-using-zigbee-router-devices-repeaters-extenders-to-get-best-possible-range-and-coverage/515752">take care of interferences</a>.</p>
|
||
|
||
<p><strong>For the sake of clarity : I’ve chosen Zigbee for my own installation so other protocols are not detailed as much.</strong></p>
|
||
|
||
<h3 id="z-wave">Z-Wave</h3>
|
||
|
||
<p>In short, <a href="https://z-wavealliance.org/">Z-wave</a> is the ancestor of Zigbee.
|
||
Overall it is almost as much efficient, but has a few more limits like a maximum network depth and number of devices (<a href="https://www.spiceworks.com/tech/iot/articles/zigbee-vs-z-wave/">maximum 4 hops and 232 devices</a> - which is probably enough for a smart home but maybe not for industrial use cases).</p>
|
||
|
||
<p>The historic driver to invent Zigbee was apparently the fact that Z-Wave is a proprietary protocol (read : it has fees).</p>
|
||
|
||
<h3 id="matter">Matter</h3>
|
||
|
||
<p><a href="https://csa-iot.org/all-solutions/matter/">Matter</a> is new.
|
||
But does not really bring any novelty.</p>
|
||
|
||
<p>Matter simply aims to provide users with a single protocol for all their smart home devices, and is compatible with existing protocols.</p>
|
||
|
||
<p>It is announced as a marketing success because of the participation (takeover ?) of major mass market industry players like Google, Samsung, Amazon, Apple.
|
||
As I write this article there are still NOT a lot of compatible devices : think twice if you have existing devices or need to build something up quickly.</p>
|
||
|
||
<h3 id="io-and-rts">IO and RTS</h3>
|
||
|
||
<p><a href="https://www.somfy.co.uk/about-somfy/brand-partners-and-compatibilities/technologies-and-protocols">IO</a> is a proprietary protocol by Somfy.
|
||
You will get it with professional-grade shutters for instance.</p>
|
||
|
||
<p>It is considered higher-grade than <a href="https://www.somfy.co.uk/about-somfy/brand-partners-and-compatibilities/technologies-and-protocols">RTS</a>, another Somfy proprietary protocol.
|
||
One difference is that RTS devices do not provide feedback about their state while IO does (e.g. is the shutters closed, closing, etc.).</p>
|
||
|
||
<p>While <em>IO</em> is newer and requires an expensive proprietary gateway, <a href="https://somfy-rts.readthedocs.io/en/latest/"><em>RTS</em> has been reverse-engineered</a> and open source components now exist.</p>
|
||
|
||
<p>Unfortunately, Somfy pushes towards IO products by deprecating others, and all IO gateways require Internet access at least to configure them.
|
||
With this kind of product you will absolutely depend on the vendor’s will to support it (except if you are an electronics-ninja to build your own, using spare Somfy remotes).</p>
|
||
|
||
<p>Nowadays the only two available gateways for IO are the <em>connectivity kit</em> (costs ~70€), which is fully orchestrated through Somfy’s Internet services, or the full <em>Tahoma Switch</em> gateway (~200€), which absolutely needs Somfy’s web services at least each time you need to configure it.</p>
|
||
|
||
<h3 id="wi-fi-and-bluetooth">Wi-Fi and Bluetooth</h3>
|
||
|
||
<p><strong>Wi-Fi</strong> is also used for many smart devices in the mass market.
|
||
This works, from a business point of view, because most customers already have a Wi-Fi router, releasing them from having to buy a gateway.</p>
|
||
|
||
<p><strong>However</strong> this is a quite <a href="https://www.smarthomepoint.com/zigbee-zwave-wifi-bluetooth-comparison/">power-consuming</a> protocol, which does not really makes sense when you have many devices running all the time, and even less if you do this in order to fine tune your power usage !</p>
|
||
|
||
<p><strong>Bluetooth</strong> consumes a bit less energy and Bluetooth Low Energy (BLE) even more, so it might compete with home automation dedicated protocols, but I have only found few smart meters with bluetooth support…</p>
|
||
|
||
<h3 id="zigbee2mqtt">Zigbee2MQTT</h3>
|
||
|
||
<p><a href="https://www.zigbee2mqtt.io/">Zigbee2MQTT</a> is not a <em>real</em> home automation protocol, but is a complementary tool.</p>
|
||
|
||
<p>It simply exports metrics from Zigbee devices to a MQTT server<sup id="fnref:mosquitto"><a href="#fn:mosquitto" class="footnote" rel="footnote" role="doc-noteref">7</a></sup>.
|
||
<a href="https://mqtt.org/">MQTT</a> is a very efficient publish/subscribe protocol for IoT.
|
||
It is very well known in the IoT world so you will probably come across it.</p>
|
||
|
||
<p>Apart from the technical differences in the protocols, it is known that Zigbee2MQTT exports more metrics and is faster that native Zigbee plugins/vendors to support new devices.
|
||
So if you need to get all the potential of your devices and can afford installing an additional server, this may be a good choice to run this <em>Zigbee-to-MQTT bridge</em>.</p>
|
||
|
||
<p><br />
|
||
There are even more protocols (Thread, Tuya, …) that I don’t have time to investigate…</p>
|
||
|
||
<h2 id="vendor-lock-in">Vendor lock-in</h2>
|
||
|
||
<p>Referring to the Somfy example above, I want to demonstrate how much this lock-in trend is ridiculously…</p>
|
||
|
||
<p><a href="https://forum.somfy.fr/questions/3313144-tahoma-switch-deja-connectee-compte-remedier">This thread on Somfy’s french forum</a> shows many people having bought a gateway from Somfy being forced to ask for the helpdesk to unlock it remotely !</p>
|
||
|
||
<p><a href="https://forum.somfy.fr/questions/1510502-fonctionnement-tahoma-internet">In the following french thread</a> someone from Somfy customer support even justify the need for Internet (and their web services) saying that every vendor does the same and it is a marketing choice :</p>
|
||
|
||
<blockquote>
|
||
<p>Je vous informe qu’il s’agit du fonctionnement de notre domotique comme la grande majorité des systèmes de domotique, il s’agit d’un choix marketing dont il n’est pas prévu à l’heure actuel que ça change.</p>
|
||
</blockquote>
|
||
|
||
<p><strong>Think about it.</strong></p>
|
||
|
||
<p><strong>Internet. Is. Required. To. OPEN YOUR SHUTTERS !</strong></p>
|
||
|
||
<p><strong>Because. Of. A MARKETING CHOICE !</strong></p>
|
||
|
||
<p>Although some people in the same forum thread seem to think that ‘Somfy will always be there 🥰’, it is obvious that it is not true and that a company acting this way will eventually end up making choice against the user’s interest (you can easily find <a href="https://www.businessinsider.com/tech-companies-that-shut-down-went-bankrupt-in-last-decade-2019-11?op=1#2018-alta-motors-13">dozens of big companies</a> and products that failed or were discontinued : Palm, Compaq, Nokia, BlackBerry, AltaVista, Google+, Windows Mobile, gaming consoles, …).</p>
|
||
|
||
<p>So…</p>
|
||
|
||
<p>If you want to automate Somfy IO devices you have no other choice today than buying one of their <em>locked-in</em> gateways.
|
||
BUT you may still use an additional, open, gateway to control Somfy proprietary devices through the Somfy gateway, to reduce the risks implied by proprietary products. For instance by using the <a href="https://www.home-assistant.io/integrations/overkiz/">overkiz plugin</a> in <em>Home Assistant</em>.</p>
|
||
|
||
<p>According to what I’ve discovered, this applies to many other vendors as well…</p>
|
||
|
||
<h2 id="the-gateways">The gateways</h2>
|
||
|
||
<p>Let’s come back to the gateway you will need to buy or make.</p>
|
||
|
||
<p>There are many gateways : vendors propose their own<sup id="fnref:tahoma"><a href="#fn:tahoma" class="footnote" rel="footnote" role="doc-noteref">8</a></sup>, some third party actors also do<sup id="fnref:enki"><a href="#fn:enki" class="footnote" rel="footnote" role="doc-noteref">9</a></sup> <sup id="fnref:tradfri"><a href="#fn:tradfri" class="footnote" rel="footnote" role="doc-noteref">10</a></sup> <sup id="fnref:tuya"><a href="#fn:tuya" class="footnote" rel="footnote" role="doc-noteref">11</a></sup>, some only work with one or few protocols while others implement many.
|
||
Noticeably, some big actors have adopted standard protocols, like Ikea<sup id="fnref:ikea-zigbee"><a href="#fn:ikea-zigbee" class="footnote" rel="footnote" role="doc-noteref">12</a></sup> or Lidl<sup id="fnref:lidl-smart-home"><a href="#fn:lidl-smart-home" class="footnote" rel="footnote" role="doc-noteref">13</a></sup> with Zigbee.</p>
|
||
|
||
<p>I have been focusing on open source software gateways that can be installed on an existing appliance.</p>
|
||
|
||
<p><a href="https://www.home-assistant.io/"><strong>Home Assistant</strong></a> (aka “HA”) and <a href="https://www.jeedom.com/"><strong>Jeedom</strong></a> are two versatile and popular open source software gateways.
|
||
They both work on Raspberry Pi, and can be run as a Docker container (although the official images are not perfect).</p>
|
||
|
||
<p>There are others, but I haven’t investigated. They work the same by installing plugins dedicated to the protocols and smart devices you want to control. Some users with a lot of smart devices have instances of different gateways because they can’t find all the features in one.</p>
|
||
|
||
<p><strong>In my case <em>I have only installed Home Assistant</em>.</strong> It was really quick to setup : the Docker image<sup id="fnref:hass-docker"><a href="#fn:hass-docker" class="footnote" rel="footnote" role="doc-noteref">14</a></sup> immediately worked and no more than 2-3 hours were needed to fully tune it (permissions and alike). It has been working great for weeks.</p>
|
||
|
||
<h2 id="the-adapters">The adapters</h2>
|
||
|
||
<p>When you install a software gateway on an existing appliance (like a PC or a <a href="raspberrypi.com">Raspberry Pi</a>), you need to complement it with a radio transmitter that is compatible with the protocols you want.</p>
|
||
|
||
<p>In my case - I wanted a Zigbee adapter for Raspberry Pi - I have bought an USB adapter rather than a HAT<sup id="fnref:raspbee"><a href="#fn:raspbee" class="footnote" rel="footnote" role="doc-noteref">15</a></sup> to plug on the GPIO pins because it is more portable (it can be plugged on any computer with USB ports) and allows having a USB cable extend its range.</p>
|
||
|
||
<p>With open standards you may even make your own, from cheap radio transmitters and the appropriate software !
|
||
For instance, radio adapters for Z-Wave (908.42 MHz) or Zigbee (mainly on 2.4 GHz) can easily be bought but not for RTS, which uses 433,42 MHz, often missing in “433 MHz family” radio adapters.</p>
|
||
|
||
<h3 id="compatibility">Compatibility</h3>
|
||
|
||
<p>As we are talking about hardware stuff, make sure to buy one that implements the correct <strong>version</strong> of the chosen protocol.
|
||
For instance there are several “Zigbees” around that <em>may</em> have different compatibility levels : “v3.0”, “Tuya”, …</p>
|
||
|
||
<p>Check also that the firmware can be updated (think about security fixes). Some devices are already labeled “Thread / Matter-ready”, awaiting for firmware patches.</p>
|
||
|
||
<h3 id="antenna-or-not-">Antenna or not ?</h3>
|
||
|
||
<p>Often, the adapters are too small to get a correct radio reception.</p>
|
||
|
||
<p><strong>This is normal</strong>. It is not a defect, physics cannot do better.</p>
|
||
|
||
<p>Some adapters include an amplifier and/or an antenna but they tend to require more power and they may still be subject to local interferences (there are many discussions about USB 3 hard drives interfering with radio signals on Raspberry Pi).</p>
|
||
|
||
<p>There is an easy solution : just use a cable to plug your device and extend its range.</p>
|
||
|
||
<h3 id="vendors">Vendors</h3>
|
||
|
||
<p>I have not found a good benchmark of vendors, mostly trolls between users comparing different devices in different contexts…</p>
|
||
|
||
<p>As IoT standards are designed with low production costs in mind, electronic chipset are usually not complex to build, so most of the devices are probably just OK from a technical point of view.</p>
|
||
|
||
<p>Just be aware that most of them are built in a <em>not-so-human-friendly-and-not-so-privacy-friendly country…</em> See ?</p>
|
||
|
||
<h2 id="smart-marketing">Smart marketing</h2>
|
||
|
||
<p>As introduced before, there are a lot of standards.</p>
|
||
|
||
<p>But even within a single standard, <strong>full support</strong> is not always guaranteed.
|
||
For instance, different models of smart plug may not implement the same Zigbee metrics (<em>profiles</em>), and all gateways may not support them in the same way (the metrics AND the devices).</p>
|
||
|
||
<p>A good starting point is to check both the vendor’s compatibility list and the gateway’s one.</p>
|
||
|
||
<p>Unfortunately, product informations in stores are usually very poor (try to get the zigbee profiles for a device, or even just the protocol, on web marketplaces…).</p>
|
||
|
||
<p>Also, <strong>the vendors will let you think that you have to use their own mobile app, ecosystem and connect your device to “The Cloud”</strong>.
|
||
<strong>Fortunately, this is false, as I’ve experienced.</strong>
|
||
They just have to provide custom apps and gateways for newbies, and they tend to oversell those products in order to get a return on investment, but they just don’t care giving more advanced options.</p>
|
||
|
||
<p>In my (very small, ok) experience, I’ve had no problem and no need to install/register/connect to anything else that <strong>just the gateway and NO INTERNET</strong>, the plugs were all recognized through plain Zigbee.</p>
|
||
|
||
<p>Of course, if you want to use Internet services like Amazon Alexa (don’t) or the vendor’s ones you <em>will</em> need to install/register/connect through Internet. Choose your fate.</p>
|
||
|
||
<p><br />
|
||
<br />
|
||
End.</p>
|
||
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<ol>
|
||
<li id="fn:clamp-meter">
|
||
<p><a href="https://commons.wikimedia.org/w/index.php?curid=47203181">Pince ampèremétrique.jpg</a> <a href="#fnref:clamp-meter" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:power-plug">
|
||
<p><a href="https://commons.wikimedia.org/wiki/File:Power-Meter_33409-480x360_(5000495108).jpg">Power-Meter 33409-480x360 (5000495108).jpg</a> <a href="#fnref:power-plug" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:shelly">
|
||
<p><a href="https://www.shelly.com/en-gb/products/energy-metering">Shelly energy metering products</a> <a href="#fnref:shelly" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:zlinky">
|
||
<p><a href="https://github.com/fairecasoimeme/Zlinky_TIC">ZLinky_TIC</a> <a href="#fnref:zlinky" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:nous-plug">
|
||
<p><a href="https://nous.technology/product/a1z-1.html">Smart ZigBee Socket NOUS A1Z</a> <a href="#fnref:nous-plug" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:hass-energy-full-approach">
|
||
<p><a href="https://community.home-assistant.io/t/an-approach-to-both-detailed-and-group-level-energy-management/393261">You may find here another, full approach to energy monitoring with Home Assistant</a> <a href="#fnref:hass-energy-full-approach" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:mosquitto">
|
||
<p><a href="https://www.mosquitto.org">Mosquitto, an MQTT server</a> <a href="#fnref:mosquitto" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:tahoma">
|
||
<p><a href="https://www.somfy.co.uk/products/smart-home-with-tahoma">Tahoma</a> <a href="#fnref:tahoma" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:enki">
|
||
<p><a href="https://enki-home.com/">Enki</a> <a href="#fnref:enki" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:tradfri">
|
||
<p><a href="https://www.ikea.com/gb/en/customer-service/faq/tradfri-app-and-gateway-pub802ccaa1">TRÅDFRI app & Gateway</a> <a href="#fnref:tradfri" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:tuya">
|
||
<p><a href="https://www.tuya.com/developer-stories/lidl">tuya & lidl</a> <a href="#fnref:tuya" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:ikea-zigbee">
|
||
<p><a href="https://www.ikea.com/gb/en/customer-service/knowledge/articles/0f5877f2-10gg-46g8-bbg7-83f26d4112df.html">Ikea & zigbee</a> <a href="#fnref:ikea-zigbee" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:lidl-smart-home">
|
||
<p><a href="https://customer-service.lidl.co.uk/SelfServiceUK/s/article/How-does-smart-home-work">Lidl Smart Home</a> <a href="#fnref:lidl-smart-home" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:hass-docker">
|
||
<p>Running Home Assistant as a docker container is probably of no use to most people, and may be complex to understand as it requires access to the physical port with the Zigbee adapter, but for me it was still better than a local installation as it fitted my existing deployment routines. <a href="#fnref:hass-docker" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:raspbee">
|
||
<p><a href="https://phoscon.de/en/raspbee2/">RaspBee II</a> <a href="#fnref:raspbee" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>]]></content><author><name>nicobo</name></author><category term="smart home" /><category term="home-assistant" /><category term="zigbee" /><category term="mqtt" /><category term="IoT" /><summary type="html"><![CDATA[Recently, I have been looking for a way to measure the typical energy consumption of the electric equipments I have at home. I only wanted to buy a simple plug-in energy monitor but I ended up spending several days to understand what were the possible options (and about 6 more hours to write this article…) ! Here is what I’ve learned. The watt-meter buying guide What you need to measure electric power consumption is called a watt-meter. Depending on what kind of equipment you want to monitor, there are different form factors. Clamp A clamp meter1 is simply closed around the phase wire you want to measure. Therefore it can only be used when you have the phase wire apart, not for molded cables. Still, it seems to be a very versatile tool and you may build a custom extension cord with a separate phase wire to make it work with any plugable electric device. Electric plug A power meter in the form of a plug2 is probably the most convenient device to measure the consumption of individual electrical devices. You just put it between the mains and the device’s plug. Make sure to check what is the maximum power supported ; a lot of devices are not able to measure high power equipments like ovens for instance. Home power supply There are also monitors made as modules to plug into the home power supply panel3, or interfacing with a dedicated connection4 or even by hacking the visual signals of the home energy counter. Many power companies nowadays have them installed by default, so you may just need to request access to your dashboard. This kind of monitor allows to follow the power consumption of the whole house or a given circuit. Smart meters Although you will find those devices with embedded screens and keypad to monitor the power consumption, most of the stores just don’t describe if they keep an history of the measures, during how long and at what pace. It is also almost impossible to know, before buying, if / how to download the data to a computer, and in which format. Electric plugs and power supply monitors also exist as so-called “smart”5, reporting to a central “smart home gateway”. As far as I’ve seen, there are no “smart” clamps. Conclusion If you want to get a detailed overview of your home consumption, you will probably need several kind of power meters. For my “simple” needs, I decided to monitor the global consumption of the house by the means of my power provider, and one or few plugs that I could move from one device to another, in order to drill down to the individual suspects6. Since I was not confident at all that I could extract the data from any autonomous watt-meter to Linux out of the box, I chose to buy smart plugs instead. Even though it requires an additional infrastructure (the gateway, a local network, a computer to exploit the measures), the ones I chose makes use of open protocols, which I consider more durable. Reminder of the attention points, in short : form factor maximum power supported history keeping and extraction protocol / standard (for smart meters) Standards, in short Zigbee Zigbee is currently the most widespread open standard communication protocol. It works on specific radio frequencies and therefore, as most home automation protocols, requires physical devices with the right radio hardware. As most home automation network protocols, it’s made to be low-energy. Devices are nodes in a mesh network : they act as repeaters (“routers” is the term) in order to extend the network (well, most mains-powered devices do). Within all devices, there must be one with coordinator capabilities to orchestrate all others. This coordinator may be an all-in-one appliance (often a ‘gateway’ implementing other protocols as well) or an extension to an existing machine (for instance an USB dongle with zigbee chipsets & radio antenna). One thing to notice : zigbee devices may use the same radio bandwidth as Wi-Fi and Bluetooth (2.4 GHz) and therefore you may need to take care of interferences. For the sake of clarity : I’ve chosen Zigbee for my own installation so other protocols are not detailed as much. Z-Wave In short, Z-wave is the ancestor of Zigbee. Overall it is almost as much efficient, but has a few more limits like a maximum network depth and number of devices (maximum 4 hops and 232 devices - which is probably enough for a smart home but maybe not for industrial use cases). The historic driver to invent Zigbee was apparently the fact that Z-Wave is a proprietary protocol (read : it has fees). Matter Matter is new. But does not really bring any novelty. Matter simply aims to provide users with a single protocol for all their smart home devices, and is compatible with existing protocols. It is announced as a marketing success because of the participation (takeover ?) of major mass market industry players like Google, Samsung, Amazon, Apple. As I write this article there are still NOT a lot of compatible devices : think twice if you have existing devices or need to build something up quickly. IO and RTS IO is a proprietary protocol by Somfy. You will get it with professional-grade shutters for instance. It is considered higher-grade than RTS, another Somfy proprietary protocol. One difference is that RTS devices do not provide feedback about their state while IO does (e.g. is the shutters closed, closing, etc.). While IO is newer and requires an expensive proprietary gateway, RTS has been reverse-engineered and open source components now exist. Unfortunately, Somfy pushes towards IO products by deprecating others, and all IO gateways require Internet access at least to configure them. With this kind of product you will absolutely depend on the vendor’s will to support it (except if you are an electronics-ninja to build your own, using spare Somfy remotes). Nowadays the only two available gateways for IO are the connectivity kit (costs ~70€), which is fully orchestrated through Somfy’s Internet services, or the full Tahoma Switch gateway (~200€), which absolutely needs Somfy’s web services at least each time you need to configure it. Wi-Fi and Bluetooth Wi-Fi is also used for many smart devices in the mass market. This works, from a business point of view, because most customers already have a Wi-Fi router, releasing them from having to buy a gateway. However this is a quite power-consuming protocol, which does not really makes sense when you have many devices running all the time, and even less if you do this in order to fine tune your power usage ! Bluetooth consumes a bit less energy and Bluetooth Low Energy (BLE) even more, so it might compete with home automation dedicated protocols, but I have only found few smart meters with bluetooth support… Zigbee2MQTT Zigbee2MQTT is not a real home automation protocol, but is a complementary tool. It simply exports metrics from Zigbee devices to a MQTT server7. MQTT is a very efficient publish/subscribe protocol for IoT. It is very well known in the IoT world so you will probably come across it. Apart from the technical differences in the protocols, it is known that Zigbee2MQTT exports more metrics and is faster that native Zigbee plugins/vendors to support new devices. So if you need to get all the potential of your devices and can afford installing an additional server, this may be a good choice to run this Zigbee-to-MQTT bridge. There are even more protocols (Thread, Tuya, …) that I don’t have time to investigate… Vendor lock-in Referring to the Somfy example above, I want to demonstrate how much this lock-in trend is ridiculously… This thread on Somfy’s french forum shows many people having bought a gateway from Somfy being forced to ask for the helpdesk to unlock it remotely ! In the following french thread someone from Somfy customer support even justify the need for Internet (and their web services) saying that every vendor does the same and it is a marketing choice : Je vous informe qu’il s’agit du fonctionnement de notre domotique comme la grande majorité des systèmes de domotique, il s’agit d’un choix marketing dont il n’est pas prévu à l’heure actuel que ça change. Think about it. Internet. Is. Required. To. OPEN YOUR SHUTTERS ! Because. Of. A MARKETING CHOICE ! Although some people in the same forum thread seem to think that ‘Somfy will always be there 🥰’, it is obvious that it is not true and that a company acting this way will eventually end up making choice against the user’s interest (you can easily find dozens of big companies and products that failed or were discontinued : Palm, Compaq, Nokia, BlackBerry, AltaVista, Google+, Windows Mobile, gaming consoles, …). So… If you want to automate Somfy IO devices you have no other choice today than buying one of their locked-in gateways. BUT you may still use an additional, open, gateway to control Somfy proprietary devices through the Somfy gateway, to reduce the risks implied by proprietary products. For instance by using the overkiz plugin in Home Assistant. According to what I’ve discovered, this applies to many other vendors as well… The gateways Let’s come back to the gateway you will need to buy or make. There are many gateways : vendors propose their own8, some third party actors also do9 10 11, some only work with one or few protocols while others implement many. Noticeably, some big actors have adopted standard protocols, like Ikea12 or Lidl13 with Zigbee. I have been focusing on open source software gateways that can be installed on an existing appliance. Home Assistant (aka “HA”) and Jeedom are two versatile and popular open source software gateways. They both work on Raspberry Pi, and can be run as a Docker container (although the official images are not perfect). There are others, but I haven’t investigated. They work the same by installing plugins dedicated to the protocols and smart devices you want to control. Some users with a lot of smart devices have instances of different gateways because they can’t find all the features in one. In my case I have only installed Home Assistant. It was really quick to setup : the Docker image14 immediately worked and no more than 2-3 hours were needed to fully tune it (permissions and alike). It has been working great for weeks. The adapters When you install a software gateway on an existing appliance (like a PC or a Raspberry Pi), you need to complement it with a radio transmitter that is compatible with the protocols you want. In my case - I wanted a Zigbee adapter for Raspberry Pi - I have bought an USB adapter rather than a HAT15 to plug on the GPIO pins because it is more portable (it can be plugged on any computer with USB ports) and allows having a USB cable extend its range. With open standards you may even make your own, from cheap radio transmitters and the appropriate software ! For instance, radio adapters for Z-Wave (908.42 MHz) or Zigbee (mainly on 2.4 GHz) can easily be bought but not for RTS, which uses 433,42 MHz, often missing in “433 MHz family” radio adapters. Compatibility As we are talking about hardware stuff, make sure to buy one that implements the correct version of the chosen protocol. For instance there are several “Zigbees” around that may have different compatibility levels : “v3.0”, “Tuya”, … Check also that the firmware can be updated (think about security fixes). Some devices are already labeled “Thread / Matter-ready”, awaiting for firmware patches. Antenna or not ? Often, the adapters are too small to get a correct radio reception. This is normal. It is not a defect, physics cannot do better. Some adapters include an amplifier and/or an antenna but they tend to require more power and they may still be subject to local interferences (there are many discussions about USB 3 hard drives interfering with radio signals on Raspberry Pi). There is an easy solution : just use a cable to plug your device and extend its range. Vendors I have not found a good benchmark of vendors, mostly trolls between users comparing different devices in different contexts… As IoT standards are designed with low production costs in mind, electronic chipset are usually not complex to build, so most of the devices are probably just OK from a technical point of view. Just be aware that most of them are built in a not-so-human-friendly-and-not-so-privacy-friendly country… See ? Smart marketing As introduced before, there are a lot of standards. But even within a single standard, full support is not always guaranteed. For instance, different models of smart plug may not implement the same Zigbee metrics (profiles), and all gateways may not support them in the same way (the metrics AND the devices). A good starting point is to check both the vendor’s compatibility list and the gateway’s one. Unfortunately, product informations in stores are usually very poor (try to get the zigbee profiles for a device, or even just the protocol, on web marketplaces…). Also, the vendors will let you think that you have to use their own mobile app, ecosystem and connect your device to “The Cloud”. Fortunately, this is false, as I’ve experienced. They just have to provide custom apps and gateways for newbies, and they tend to oversell those products in order to get a return on investment, but they just don’t care giving more advanced options. In my (very small, ok) experience, I’ve had no problem and no need to install/register/connect to anything else that just the gateway and NO INTERNET, the plugs were all recognized through plain Zigbee. Of course, if you want to use Internet services like Amazon Alexa (don’t) or the vendor’s ones you will need to install/register/connect through Internet. Choose your fate. End. Pince ampèremétrique.jpg ↩ Power-Meter 33409-480x360 (5000495108).jpg ↩ Shelly energy metering products ↩ ZLinky_TIC ↩ Smart ZigBee Socket NOUS A1Z ↩ You may find here another, full approach to energy monitoring with Home Assistant ↩ Mosquitto, an MQTT server ↩ Tahoma ↩ Enki ↩ TRÅDFRI app & Gateway ↩ tuya & lidl ↩ Ikea & zigbee ↩ Lidl Smart Home ↩ Running Home Assistant as a docker container is probably of no use to most people, and may be complex to understand as it requires access to the physical port with the Zigbee adapter, but for me it was still better than a local installation as it fitted my existing deployment routines. ↩ RaspBee II ↩]]></summary></entry><entry><title type="html">An email domain for your family</title><link href="https://www.nicolabs.net/2023/An-email-domain-for-your-family" rel="alternate" type="text/html" title="An email domain for your family" /><published>2023-06-23T00:00:00+02:00</published><updated>2024-02-14T00:00:00+01:00</updated><id>https://www.nicolabs.net/2023/An-email-domain-for-your-family</id><content type="html" xml:base="https://www.nicolabs.net/2023/An-email-domain-for-your-family"><![CDATA[<p>Do you want your <em>tribe</em> to share the same <em>cool</em> email addresses suffix like <strong>@smith.org</strong>, <strong>@smith.family</strong>, <strong>@thesmithes.club</strong>… ?</p>
|
||
|
||
<p>You have several choices :
|
||
<!--more--></p>
|
||
|
||
<p><strong>1. Pay an email provider to host all email accounts.</strong> This forces everyone to use the same provider and may become expensive if your pals are many or require lots of storage…
|
||
You may get it “free of charge” but you will have to pay by giving up your personal data.</p>
|
||
<p><img class="plantuml" id="e577fc42d35c3ed221796c679264f932" alt="PlantUML diagram" src="/assets/uml/e577fc42d35c3ed221796c679264f932.svg" /></p>
|
||
|
||
<p><strong>2. Self-host an email server.</strong> This implies a lot of technical maintenance (because you want it to be highly available). Nowadays aggressive anti-spam features of the major email providers also make it very VERY complicated for self-hosting.</p>
|
||
<p><img class="plantuml" id="d378de7292c39d261459005b376c7a4b" alt="PlantUML diagram" src="/assets/uml/d378de7292c39d261459005b376c7a4b.svg" /></p>
|
||
|
||
<p><strong>3. Let everyone choose their own email provider and redirect to/from the tribe’s domain.</strong></p>
|
||
<p><img class="plantuml" id="ee5fba42c3117eb066c5457610319abb" alt="PlantUML diagram" src="/assets/uml/ee5fba42c3117eb066c5457610319abb.svg" /></p>
|
||
|
||
<p><strong>This article is a very draft description on how to do it the 3rd way.</strong></p>
|
||
|
||
<blockquote>
|
||
<p><em>Disclaimer :</em> The providers in this article are just examples. I am not saying that you should use them.</p>
|
||
</blockquote>
|
||
|
||
<h2 id="the-pattern">The pattern</h2>
|
||
|
||
<p>Let’s say you chose <em>Gandi</em> as a front domain and email provider for your family (or friends) to share the same email domain : <em>thelma@smith.org</em>, <em>tim@smith.org</em>, <em>tom@smith.org</em>, …</p>
|
||
|
||
<p>There are two things to consider :</p>
|
||
|
||
<p><strong>In order for them to receive emails</strong> at their custom <code class="language-plaintext highlighter-rouge">@smith.org</code> address, we need to :</p>
|
||
|
||
<ol>
|
||
<li>Make the <a href="https://www.cloudflare.com/learning/dns/dns-records/dns-mx-record/">MX records</a> of <code class="language-plaintext highlighter-rouge">smith.org</code> domain point at <em>Gandi’s</em><sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> email servers</li>
|
||
<li>Configure redirection rules at <em>Gandi’s</em> email servers for each tribe member ; e.g. <code class="language-plaintext highlighter-rouge">tim@smith.org --> tim@gmail.com</code></li>
|
||
</ol>
|
||
|
||
<p><strong>For them to be able to send emails</strong> from their custom <code class="language-plaintext highlighter-rouge">@smith.org</code> address, we also need to :</p>
|
||
|
||
<ol>
|
||
<li>Configure new ‘identities’ in each member’s account at their current email provider to use the custom email address</li>
|
||
<li>Configure anti-spam DNS records at <em>Gandi</em> so that each member can send emails from their own provider’s domain without being blocked</li>
|
||
</ol>
|
||
|
||
<p>Details for each step are explained in the following paragraphs.</p>
|
||
|
||
<h2 id="choose-an-email-provider-that-can-forward">Choose an email provider that can forward</h2>
|
||
|
||
<p>So you need an email server to forward emails received at <em>@smith.org</em> to each members’ personal mailbox.</p>
|
||
|
||
<p>In this tutorial we don’t want to host the email server ourselves, so you should choose any email provider offering a <em>forwarding</em> service to external email addresses (I guess they all provide it).
|
||
It may be the one of your personal mailbox or a totally different one.
|
||
Often the domain registrar itself will offer this already so you probably don’t need to look further.</p>
|
||
|
||
<p><strong>For each family member you will need to add a forward rule</strong> ; e.g. :</p>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>From</th>
|
||
<th>To</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code class="language-plaintext highlighter-rouge">tim@smith.org</code></td>
|
||
<td><code class="language-plaintext highlighter-rouge">tim@gmail.com</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code class="language-plaintext highlighter-rouge">thelma@smith.org</code></td>
|
||
<td><code class="language-plaintext highlighter-rouge">thelma455678@iamaboomer.com</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code class="language-plaintext highlighter-rouge">tom@smith.org</code></td>
|
||
<td><code class="language-plaintext highlighter-rouge">snoopy@snoopymail.waf</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>See the mail provider for the exact procedure (if you’re using the domain registrar’s to do this, <a href="https://docs.gandi.net/en/gandimail/forwarding_and_aliases/index.html">you probably just have to find the correct tab…</a>).</p>
|
||
|
||
<h2 id="register-and-configure-the-family-domain">Register and configure the family domain</h2>
|
||
|
||
<p>There are at least two things to configure on the domain side :</p>
|
||
|
||
<ul>
|
||
<li>Set <em>MX records</em> pointing at the <em>forwarding</em> email server you chose.</li>
|
||
<li>Set anti-spam records (<a href="https://www.cloudflare.com/learning/dns/dns-records/dns-spf-record/">a.k.a. “SPF”</a>) to allow other email providers to send upon the family addresses without being flagged as spammers</li>
|
||
</ul>
|
||
|
||
<h3 id="mx-records-">MX records :</h3>
|
||
|
||
<p><strong>See the mail provider’s documentation for the values to put in the MX records</strong>. Basically, it consists of putting the email server address.
|
||
If your third-party email provider is also the domain registrar, then maybe it is already configured or there is a one-click procedure.</p>
|
||
|
||
<p>E.g. (beware of then ending dot !) : <code class="language-plaintext highlighter-rouge">example.org. 3600 MX 10 mailserver1.example.org.</code></p>
|
||
|
||
<p>Once MX records and forward rules are configured, you will start receiving emails to the <code class="language-plaintext highlighter-rouge">@smith.org</code> address.</p>
|
||
|
||
<p><br />
|
||
<strong>That’s all about <em>receiving</em> emails.</strong></p>
|
||
|
||
<h3 id="spf-records-">SPF records :</h3>
|
||
|
||
<p><strong>To pass through spam filters sending emails from this domain, you will have to set anti-spam records on the DNS</strong> : this is called <a href="https://www.cloudflare.com/learning/dns/dns-records/dns-spf-record/">SPF (Sender Policy Framework)</a>.</p>
|
||
|
||
<p>The principle is straightforward : this is a <a href="https://www.cloudflare.com/learning/dns/dns-records/dns-txt-record/">TXT record</a> on the <code class="language-plaintext highlighter-rouge">smith.org</code> domain which contains the email providers allowed to send emails with this domain.
|
||
For instance if some members use Gmail and others Yahoo Mail, you need to include both <code class="language-plaintext highlighter-rouge">_spf.google.com</code> and <code class="language-plaintext highlighter-rouge">_spf.mail.yahoo.com</code> to this list (exact values are provided by each mail provider).</p>
|
||
|
||
<p>However if you include too many of them you will reach the <strong>limit of 10 total DNS queries allowed</strong> by the SPF specification !</p>
|
||
|
||
<p><strong>In addition <a href="https://toolbox.googleapps.com/apps/checkmx/">each initial domain may resolve to several ones</a></strong> : for instance <code class="language-plaintext highlighter-rouge">_spf.google.com</code> currently resolves to 3 other domains (3 additional DNS queries). Since your family members probably use different email providers, you may quickly reach the limit…</p>
|
||
|
||
<p>The only way to bypass this limitation is to directly include the IP addresses instead of domain names, as IP addresses don’t trigger a domain name resolution.
|
||
<strong>In this case you have to take care of updating them if they change</strong> (choice of the provider, not you..).
|
||
This is called <a href="https://smalltechstack.com/blog/flattening-your-spf-record"><strong>SPF flattening</strong></a>.</p>
|
||
|
||
<p>You <a href="https://dmarcly.com/blog/spf-permerror-too-many-dns-lookups-when-spf-record-exceeds-10-dns-lookup-limit">might find online tools</a> to do this, as well as other tools to update by hand or automatically…
|
||
As I haven’t found nice & working ones <a href="https://github.com/nicolabs/gandi-spf-flatten/tree/main">I have made one</a>.</p>
|
||
|
||
<p><br />
|
||
<strong>Alright. This was the touchy part, other steps are usually straightforward…</strong></p>
|
||
|
||
<h2 id="steps-for-each-family-member">Steps for each family member</h2>
|
||
|
||
<h3 id="allow-their-account-to-send-e-mails-with-their-family-address">Allow their account to send e-mails with their family address</h3>
|
||
|
||
<p>In order to <em>send</em> emails with their family address, members need to configure their account at their own email provider : the procedure differs for one to another but it often simply implies activating the feature and sending a verification email to the new address <a href="https://support.google.com/mail/answer/22370">e.g. for Gmail</a>.</p>
|
||
|
||
<h3 id="add-a-new-identity-in-their-e-mail-apps">Add a new identity in their e-mail apps</h3>
|
||
|
||
<p>As a final step, each member will probably want to add their family address as a new identity so that they don’t need to manually change the <code class="language-plaintext highlighter-rouge">from:</code> field for each message to send.</p>
|
||
|
||
<p>This is also app-specific configuration (e.g. for <a href="https://docs.k9mail.app/en/6.400/settings/account/#manage-identities">K9-Mail</a> ; for <a href="https://support.mozilla.org/en-US/kb/using-identities">Thunderbird</a>).</p>
|
||
|
||
<hr />
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>In this example Gandi has both roles : DNS & email provider <a href="#fnref:1" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>]]></content><author><name>nicobo</name></author><category term="mail" /><category term="self hosting" /><category term="domain" /><summary type="html"><![CDATA[Do you want your tribe to share the same cool email addresses suffix like @smith.org, @smith.family, @thesmithes.club… ? You have several choices :]]></summary></entry><entry><title type="html">I got bored of Google reading my emails</title><link href="https://www.nicolabs.net/2023/protonmail-vs-mailfence" rel="alternate" type="text/html" title="I got bored of Google reading my emails" /><published>2023-06-06T00:00:00+02:00</published><updated>2024-11-05T00:00:00+01:00</updated><id>https://www.nicolabs.net/2023/ProtonMail-vs-Mailfence</id><content type="html" xml:base="https://www.nicolabs.net/2023/protonmail-vs-mailfence"><![CDATA[<p><a href="https://proton.me/mail"><strong>Proton Mail</strong></a> and <a href="https://mailfence.com"><strong>Mailfence</strong></a> are two famous email service providers known for their privacy-friendly policies.</p>
|
||
|
||
<p>You will find <a href="https://www.lifewire.com/best-secure-email-services-4136763">many</a> <a href="https://restoreprivacy.com/email/secure/">articles</a> <a href="https://www.makeuseof.com/mailfence-vs-protonmail-which-is-more-secure/">comparing</a> them as well as <a href="https://restoreprivacy.com/email/secure/">other</a> <a href="https://itsfoss.com/secure-private-email-services/">similar</a> providers, but most of them are just theoretical, so I decided to give them a <em>real world</em> test run.</p>
|
||
|
||
<p>My use case was to exchange emails with <em>normal people</em> (i.e. without requiring them all to have state-of-the-art encrypted mailboxes).</p>
|
||
|
||
<p>After reading enough of both providers documentation, I’ve became confident that they were both offering adequate security to evade at least a bit from greedy GAFAs through <strong>end-to-end encryption</strong>, <strong>OpenPGP encryption & signature</strong>, a lot of <strong>security & privacy best practices</strong>, as well as recommendations from many trustworthy sources.</p>
|
||
|
||
<p>The below comparison will therefore go straight to the differences that I’ve found to be decisive for a practical day to day usage. Depending on how far your paranoia goes, you may read by yourself the thrilling crypto details elsewhere….</p>
|
||
|
||
<blockquote>
|
||
<p>Please note that both providers have their issues so you may not find the perfect one in this article. However it may still give advices on comparing email providers in general, and especially Proton Mail vs others.</p>
|
||
</blockquote>
|
||
|
||
<h2 id="where-proton-mail-wins">Where Proton Mail wins</h2>
|
||
|
||
<p><img src="/assets/blog/3rdparty/logos/Mail-logomark-logotype-colored-noborder.svg" alt="Proton Mail logo" class="inline" height="120px" /></p>
|
||
<figcaption>Proton Mail logo - https://proton.me</figcaption>
|
||
|
||
<h3 id="security">Security</h3>
|
||
|
||
<p>As introduced, I’ll be very quick on the pure security features : overall Proton Mail has a slightly superior security model.
|
||
It provides a <strong>zero-knowledge architecture</strong>, has never access to the private key which encrypts your data on their servers, and <a href="https://github.com/ProtonMail/proton-mail-android">publishes the sources of the client applications</a>.</p>
|
||
|
||
<p>On the contrary, Mailfence stores the private key on its servers as a trade-off in favor of user experience (e.g. seamless encryption/decryption from the web UI). Of course you should encrypt the key itself before sending it through the web UI, but it is still easy to send it in clear by mistake (I’ve tested it : it’s absolutely possible and they purposely display a warning when detected). This may also facilitate the exploitation of vulnerable keys by a malicious admin.</p>
|
||
|
||
<h3 id="multi-factor-authentication">Multi-factor authentication</h3>
|
||
|
||
<p>Proton Mail allows <a href="https://proton.me/support/two-factor-authentication-2fa">2FA with hardware U2F or FIDO2 tokens in addition to TOTP</a> while Mailfence only supports TOTP.</p>
|
||
|
||
<p>Additionally, when 2FA is activated on Mailfence, you need to define dedicated passwords for each service (IMAP, SMTP, POP, etc) <a href="https://twitter.com/Mailfence/status/1673985727485419525">but you can only define <em>a single</em> password for each of them</a>, which is displayed only once at set up time !
|
||
<strong>This is nonsense</strong> as such a password should be unique per device, not per service. This is just how it’s done everywhere else… This mailfence system forces you to configure all of your devices <em>at the same time</em> (and do it again for all of them <em>each time you add one</em>)…</p>
|
||
|
||
<h2 id="where-mailfence-wins">Where Mailfence wins</h2>
|
||
|
||
<p><img src="/assets/blog/3rdparty/logos/mailfence-logo-black-white-barbed.svg" alt="Mailfence logo" class="inline" height="120px" /></p>
|
||
<figcaption>Mailfence logo - https://mailfence.com</figcaption>
|
||
|
||
<h3 id="standards-and-usability">Standards and usability</h3>
|
||
|
||
<p>This is probably the major difference between Proton and others (not only Mailfence).</p>
|
||
|
||
<p>Because they wanted to go further than current email security standards, Proton had to build a non-standard ecosystem. This is justified because there is no widespread end-to-end encryption standard. However this leads to <strong>locking you into Proton-specific applications</strong> : custom Android / iOS applications and a local proxy for desktop. <strong>You will not be able to use your favorite email client with Proton Mail</strong> (no POP, no IMAP).</p>
|
||
|
||
<p>Despite delivering very high quality products, I’ve observed some annoying bugs in Proton Mail and Proton apps lack in features, a bit behind other open source products with larger communities, like Thunderbird and K9-Mail.</p>
|
||
|
||
<p>This is also the reason why I had to reach their customer support more than once, which was not the case with Mailfence, for which I could get around configuration problems myself.</p>
|
||
|
||
<p>Actual examples of bad experience with Proton include :</p>
|
||
|
||
<ul>
|
||
<li>attachments in the Android mail app are saved “somewhere” but the user is not notified, which is misleading and not the convention in such app</li>
|
||
<li><code class="language-plaintext highlighter-rouge">@protonmail.com</code> address is used when responding to an email even if it was sent to an alias, making it easy to reveal your private e-mail</li>
|
||
<li>Mobile (Android) app was very slow (it has improved <em>a lot</em> in a few months but it still freezes a few seconds when clicking the button and the CPU seems to be put under heavy load when searching in messages) - I assume this is because of client-side cryptography</li>
|
||
</ul>
|
||
|
||
<p>I also encounter from time to time quite <em>scary</em> bugs like :</p>
|
||
|
||
<ul>
|
||
<li>message loss (I still haven’t identified the cause)</li>
|
||
<li>impossibility to send messages (especially on bad mobile network), producing tons of copies of the draft message as as side effect</li>
|
||
<li>multiple messages mixed together 😱 (in Thunderbird it frequently happens that I click on a message but the content of another one is loaded, or the body of an email continues in another one)</li>
|
||
</ul>
|
||
|
||
<p>On the other side, <strong>Mailfence implements plain email standards</strong>.</p>
|
||
|
||
<p>This gives Mailfence a lot of advantages over Proton : you can use your favorite POP/IMAP-compatible email client, import/export using standard procedures (see below for more details), advertises support for *DAV protocols (not tested) for calendar, contacts, remote file access (get access to the attachments via WebDAV !) …</p>
|
||
|
||
<h3 id="sending-with-custom-domain-address">Sending with custom domain address</h3>
|
||
|
||
<p>This one is a small advantage for Mailfence, but still…</p>
|
||
|
||
<p>Custom domain hosting works fine, but the more specific case when you just want to use your custom-domain address to <strong>send</strong> emails from Proton Mail (i.e. without having Proton be the mail provider for all the domain’s addresses) is probably not intended by Proton <em>(there is a trick however : go first through the full procedure to define Proton as the mail host for the domain, so Proton lets you register your alias - by adding MX, TXT, etc. records to the DNS - then remove or update the MX priority to go back to the previous MX handler)</em>.</p>
|
||
|
||
<p>On the other side, with Mailfence you just have to add an email in <a href="https://mailfence.com/flatx/index.jsp#tool=prefs&page=perso">your personal data section</a>, then validate by following the link in a confirmation email ! This feature is a bit hidden / not well documented but actually works perfectly.</p>
|
||
|
||
<p>This will not prevent you from properly configuring your custom domain to redirect <strong>incoming</strong> emails and pass through spam filter (SPF-related entries), though.</p>
|
||
|
||
<h2 id="draw">Draw</h2>
|
||
|
||
<p>There are a few features worth describing even though they don’t give a clear advantage to one or the other.</p>
|
||
|
||
<h3 id="trust">Trust</h3>
|
||
|
||
<p>Proton Mail has a good reputation among the global community and <a href="https://support.mozilla.org/en-US/kb/new-email-address">Mailfence is recommended by Thunderbird</a>.</p>
|
||
|
||
<p>Even though they are both located in privacy-friendly countries (<a href="https://proton.me/about">Switzerland for Proton</a> and <a href="https://mailfence.com/en/company.jsp">Belgium for Mailfence</a>), they have to comply with the local laws and both publish reports about the legal inquiries they receive (<a href="https://proton.me/legal/transparency">Proton</a>, <a href="https://blog.mailfence.com/transparency-report-and-warrant-canary/">transparency report</a>).</p>
|
||
|
||
<p>They both promote security by transparency : Proton <a href="https://proton.me/blog/security-audit-all-proton-apps">audits its client apps</a>, which are also open source, and Mailfence lets you use your favorite client apps, while <a href="https://blog.mailfence.com/fr/chiffrement-de-bout-en-bout-mailfence/#h-comment-nous-procedons">using OpenPGP.js</a> in their web client.</p>
|
||
|
||
<p>None of them publish the server-side code though, but you will not get better today, and hopefully this should not be required thanks to end-to-end encryption.</p>
|
||
|
||
<h3 id="importing-emails">Importing emails</h3>
|
||
|
||
<p>Proton Mail has a helpful feature to import mail history from external providers. You may have to run the procedure several times to get all mail transferred with high volumes, but I found it OK to merge ~1GB of data from 2 GMail accounts (I’ve not tested on my whole 20+ GB of emails because it was a good opportunity to trim old mails).</p>
|
||
|
||
<p>As Mailfence supports IMAP, it’s even easier to import messages from another provider : <a href="https://mailfence.com/en/doc/#import">just download all messages in your local mail client from the old account and drag & drop them to Mailfence’s</a>. It’s long because messages are copied one by one. But it could not be simpler.</p>
|
||
|
||
<p>This may seems like a little advantage for Mailfence but I consider it a draw because Proton’s features just does the job.</p>
|
||
|
||
<h3 id="overall-offer-maturity-and-support">Overall offer, maturity and support</h3>
|
||
|
||
<p><a href="https://proton.me/mail/pricing">Proton Mail</a> and <a href="https://mailfence.com/#pricing">Mailfence</a> plans have each pros & cons but Proton always offer more storage for the same price, and shows a more ambitious portfolio of services (VPN, password manager).
|
||
Mailfence should probably do better here ; their free plan was so much limited that I could not test without paying.
|
||
This is still a limited advantage for Proton because as good as they are, their services are less usable due to non-standard protocols and not always mature apps (e.g. <em>Proton Drive</em> provides huge storage but at the time of writing it can only be accessed through the web interface - no API, no automatic upload / synchronization).</p>
|
||
|
||
<p>It’s also rare enough to mention that Proton’s support team answered quickly and, after a cold start, were quite efficient to answer my questions, even speaking a perfect French (although always pushing first the English response).
|
||
However as said before, I haven’t even had <em>the need</em> to contact Mailfence’s customer support.</p>
|
||
|
||
<p>Mailfence documentation, on its side, is quite a mess to search for : Google was better than their own website to find out <a href="https://kb.mailfence.com/kb/set-up-anti-spoofing-defense-custom-domain/">SPF/DKIM/DMARC values</a> for instance.</p>
|
||
|
||
<p>Mailfence has other bugs also, which can be quite annoying :</p>
|
||
|
||
<ul>
|
||
<li>Aggressive <a href="https://mailfence.com/en/doc/#antispam">anti-spam</a> filters : it happens every day that legit messages end up in the <em>spams</em> folder… In fact it never happened to me to miss legit messages so much ! Additionally, Mailfence does not learn from the actions I take to move them back to the <em>inbox</em> or the <em>spam</em> folders so I had to deactivate the anti-spam for all incoming mails !</li>
|
||
<li>Read messages are not marked as read ! Most of the time they just come back as ‘unread’, making it a never-ending story…</li>
|
||
<li>Mailfence advertises providing XMPP instant messaging, but they don’t support <a href="https://prosody.im/doc/dns#srv_records">SRV records</a> - which is a basic recommendation to implement, and seemingly other features are missing / not open so I just could not make it work correctly in Thunderbird and Conversations.im.</li>
|
||
<li>Searching emails on the server is also not working well from clients (currently it’s not working <em>at all</em> in my K9-Mail) ; this can really be show-stopper</li>
|
||
</ul>
|
||
|
||
<p>Although it may be a bit in favor of Proton, I could not clearly determine a winner on this one…</p>
|
||
|
||
<h3 id="anti-spam-addresses">Anti-spam addresses</h3>
|
||
|
||
<p>Both ProtonMail and Mailfence support <em><a href="https://blog.mailfence.com/plus-addressing-to-track-spammers/">Plus Addressing</a></em> to fight against spam : e.g. <code class="language-plaintext highlighter-rouge">uniqueprefix+myname@mf.me</code> or <code class="language-plaintext highlighter-rouge">uniqueprefix+myname@pm.me</code>.</p>
|
||
|
||
<h2 id="conclusion">Conclusion</h2>
|
||
|
||
<p><strong>Proton Mail is probably the closest to zero-knowledge security email provider</strong>, but it comes at a price : you will be locked within their ecosystem.
|
||
Proton is therefore probably well advised for a closed group of people who want to securely exchange messages, files, events, … Probably OK for small businesses.</p>
|
||
|
||
<p>On the other hand if, like most people, you want to exchange emails with non-Proton users, copies of your messages will be found <em>unencrypted</em> in others’ mailboxes anyway.
|
||
In this case Proton does not offer significant advantages and <strong>you will prefer providers implementing email standards like Mailfence or others, for a better integration</strong> with common software.</p>
|
||
|
||
<p>Note that what applies to Mailfence here might apply to other email providers with end-to-end encryption as well.</p>
|
||
|
||
<p>Ultimately, <strong>if you search for secure and practical <em>messaging</em>, then you might not want to use emails at all</strong> and switch over to other protocols like XMPP, Signal, … which have a larger user base than Proton and are built on security-focused standards, unlike emails.</p>]]></content><author><name>nicobo</name></author><category term="mail" /><category term="security" /><summary type="html"><![CDATA[Proton Mail and Mailfence are two famous email service providers known for their privacy-friendly policies. You will find many articles comparing them as well as other similar providers, but most of them are just theoretical, so I decided to give them a real world test run. My use case was to exchange emails with normal people (i.e. without requiring them all to have state-of-the-art encrypted mailboxes). After reading enough of both providers documentation, I’ve became confident that they were both offering adequate security to evade at least a bit from greedy GAFAs through end-to-end encryption, OpenPGP encryption & signature, a lot of security & privacy best practices, as well as recommendations from many trustworthy sources. The below comparison will therefore go straight to the differences that I’ve found to be decisive for a practical day to day usage. Depending on how far your paranoia goes, you may read by yourself the thrilling crypto details elsewhere…. Please note that both providers have their issues so you may not find the perfect one in this article. However it may still give advices on comparing email providers in general, and especially Proton Mail vs others. Where Proton Mail wins Proton Mail logo - https://proton.me Security As introduced, I’ll be very quick on the pure security features : overall Proton Mail has a slightly superior security model. It provides a zero-knowledge architecture, has never access to the private key which encrypts your data on their servers, and publishes the sources of the client applications. On the contrary, Mailfence stores the private key on its servers as a trade-off in favor of user experience (e.g. seamless encryption/decryption from the web UI). Of course you should encrypt the key itself before sending it through the web UI, but it is still easy to send it in clear by mistake (I’ve tested it : it’s absolutely possible and they purposely display a warning when detected). This may also facilitate the exploitation of vulnerable keys by a malicious admin. Multi-factor authentication Proton Mail allows 2FA with hardware U2F or FIDO2 tokens in addition to TOTP while Mailfence only supports TOTP. Additionally, when 2FA is activated on Mailfence, you need to define dedicated passwords for each service (IMAP, SMTP, POP, etc) but you can only define a single password for each of them, which is displayed only once at set up time ! This is nonsense as such a password should be unique per device, not per service. This is just how it’s done everywhere else… This mailfence system forces you to configure all of your devices at the same time (and do it again for all of them each time you add one)… Where Mailfence wins Mailfence logo - https://mailfence.com Standards and usability This is probably the major difference between Proton and others (not only Mailfence). Because they wanted to go further than current email security standards, Proton had to build a non-standard ecosystem. This is justified because there is no widespread end-to-end encryption standard. However this leads to locking you into Proton-specific applications : custom Android / iOS applications and a local proxy for desktop. You will not be able to use your favorite email client with Proton Mail (no POP, no IMAP). Despite delivering very high quality products, I’ve observed some annoying bugs in Proton Mail and Proton apps lack in features, a bit behind other open source products with larger communities, like Thunderbird and K9-Mail. This is also the reason why I had to reach their customer support more than once, which was not the case with Mailfence, for which I could get around configuration problems myself. Actual examples of bad experience with Proton include : attachments in the Android mail app are saved “somewhere” but the user is not notified, which is misleading and not the convention in such app @protonmail.com address is used when responding to an email even if it was sent to an alias, making it easy to reveal your private e-mail Mobile (Android) app was very slow (it has improved a lot in a few months but it still freezes a few seconds when clicking the button and the CPU seems to be put under heavy load when searching in messages) - I assume this is because of client-side cryptography I also encounter from time to time quite scary bugs like : message loss (I still haven’t identified the cause) impossibility to send messages (especially on bad mobile network), producing tons of copies of the draft message as as side effect multiple messages mixed together 😱 (in Thunderbird it frequently happens that I click on a message but the content of another one is loaded, or the body of an email continues in another one) On the other side, Mailfence implements plain email standards. This gives Mailfence a lot of advantages over Proton : you can use your favorite POP/IMAP-compatible email client, import/export using standard procedures (see below for more details), advertises support for *DAV protocols (not tested) for calendar, contacts, remote file access (get access to the attachments via WebDAV !) … Sending with custom domain address This one is a small advantage for Mailfence, but still… Custom domain hosting works fine, but the more specific case when you just want to use your custom-domain address to send emails from Proton Mail (i.e. without having Proton be the mail provider for all the domain’s addresses) is probably not intended by Proton (there is a trick however : go first through the full procedure to define Proton as the mail host for the domain, so Proton lets you register your alias - by adding MX, TXT, etc. records to the DNS - then remove or update the MX priority to go back to the previous MX handler). On the other side, with Mailfence you just have to add an email in your personal data section, then validate by following the link in a confirmation email ! This feature is a bit hidden / not well documented but actually works perfectly. This will not prevent you from properly configuring your custom domain to redirect incoming emails and pass through spam filter (SPF-related entries), though. Draw There are a few features worth describing even though they don’t give a clear advantage to one or the other. Trust Proton Mail has a good reputation among the global community and Mailfence is recommended by Thunderbird. Even though they are both located in privacy-friendly countries (Switzerland for Proton and Belgium for Mailfence), they have to comply with the local laws and both publish reports about the legal inquiries they receive (Proton, transparency report). They both promote security by transparency : Proton audits its client apps, which are also open source, and Mailfence lets you use your favorite client apps, while using OpenPGP.js in their web client. None of them publish the server-side code though, but you will not get better today, and hopefully this should not be required thanks to end-to-end encryption. Importing emails Proton Mail has a helpful feature to import mail history from external providers. You may have to run the procedure several times to get all mail transferred with high volumes, but I found it OK to merge ~1GB of data from 2 GMail accounts (I’ve not tested on my whole 20+ GB of emails because it was a good opportunity to trim old mails). As Mailfence supports IMAP, it’s even easier to import messages from another provider : just download all messages in your local mail client from the old account and drag & drop them to Mailfence’s. It’s long because messages are copied one by one. But it could not be simpler. This may seems like a little advantage for Mailfence but I consider it a draw because Proton’s features just does the job. Overall offer, maturity and support Proton Mail and Mailfence plans have each pros & cons but Proton always offer more storage for the same price, and shows a more ambitious portfolio of services (VPN, password manager). Mailfence should probably do better here ; their free plan was so much limited that I could not test without paying. This is still a limited advantage for Proton because as good as they are, their services are less usable due to non-standard protocols and not always mature apps (e.g. Proton Drive provides huge storage but at the time of writing it can only be accessed through the web interface - no API, no automatic upload / synchronization). It’s also rare enough to mention that Proton’s support team answered quickly and, after a cold start, were quite efficient to answer my questions, even speaking a perfect French (although always pushing first the English response). However as said before, I haven’t even had the need to contact Mailfence’s customer support. Mailfence documentation, on its side, is quite a mess to search for : Google was better than their own website to find out SPF/DKIM/DMARC values for instance. Mailfence has other bugs also, which can be quite annoying : Aggressive anti-spam filters : it happens every day that legit messages end up in the spams folder… In fact it never happened to me to miss legit messages so much ! Additionally, Mailfence does not learn from the actions I take to move them back to the inbox or the spam folders so I had to deactivate the anti-spam for all incoming mails ! Read messages are not marked as read ! Most of the time they just come back as ‘unread’, making it a never-ending story… Mailfence advertises providing XMPP instant messaging, but they don’t support SRV records - which is a basic recommendation to implement, and seemingly other features are missing / not open so I just could not make it work correctly in Thunderbird and Conversations.im. Searching emails on the server is also not working well from clients (currently it’s not working at all in my K9-Mail) ; this can really be show-stopper Although it may be a bit in favor of Proton, I could not clearly determine a winner on this one… Anti-spam addresses Both ProtonMail and Mailfence support Plus Addressing to fight against spam : e.g. uniqueprefix+myname@mf.me or uniqueprefix+myname@pm.me. Conclusion Proton Mail is probably the closest to zero-knowledge security email provider, but it comes at a price : you will be locked within their ecosystem. Proton is therefore probably well advised for a closed group of people who want to securely exchange messages, files, events, … Probably OK for small businesses. On the other hand if, like most people, you want to exchange emails with non-Proton users, copies of your messages will be found unencrypted in others’ mailboxes anyway. In this case Proton does not offer significant advantages and you will prefer providers implementing email standards like Mailfence or others, for a better integration with common software. Note that what applies to Mailfence here might apply to other email providers with end-to-end encryption as well. Ultimately, if you search for secure and practical messaging, then you might not want to use emails at all and switch over to other protocols like XMPP, Signal, … which have a larger user base than Proton and are built on security-focused standards, unlike emails.]]></summary></entry><entry><title type="html">A nice multi-factor setup for SSH</title><link href="https://www.nicolabs.net/2022/nice-MFA-setup-for-SSH" rel="alternate" type="text/html" title="A nice multi-factor setup for SSH" /><published>2022-12-22T00:00:00+01:00</published><updated>2022-12-22T00:00:00+01:00</updated><id>https://www.nicolabs.net/2022/nice-MFA-setup-for-SSH</id><content type="html" xml:base="https://www.nicolabs.net/2022/nice-MFA-setup-for-SSH"><![CDATA[<p><img src="/assets/blog/3rdparty/pictures/solokeys.png" alt="SoloKeys" /></p>
|
||
<figcaption>Illustration © 2022 SOLOKEYS - https://solokeys.com</figcaption>
|
||
|
||
<p>This article shows how to set up an SSH server so that users can authenticate :</p>
|
||
|
||
<ol>
|
||
<li>either with a hardware token (FIDO-compatible actually)</li>
|
||
<li>or with a two-factor authentication (2FA) process, using their password and a one-time password (OTP)</li>
|
||
<li>from the intranet, with a standard SSH key</li>
|
||
</ol>
|
||
|
||
<!--more-->
|
||
|
||
<p><img class="plantuml" id="a9c25247fe82234d611a9ce56a05b526" alt="PlantUML diagram" src="/assets/uml/a9c25247fe82234d611a9ce56a05b526.svg" /></p>
|
||
|
||
<p>In order to do that, we will see how to :</p>
|
||
<ul>
|
||
<li>set up SSH for TOTP (with a PAM module)</li>
|
||
<li>generate an OTP secret and “pair” with the user’s OTP application</li>
|
||
<li>set up SSH for FIDO authentication</li>
|
||
<li>set up the hardware token (I’m using a <a href="https://yubikey.me/">YubiKey</a> here)</li>
|
||
<li>generate a FIDO key on the hardware token and “pair” with the server</li>
|
||
</ul>
|
||
|
||
<blockquote>
|
||
<p><strong><em>Note</em></strong></p>
|
||
|
||
<p>This setup is only an example but should be a good starting point to build and tune your own authentication workflow.</p>
|
||
|
||
</blockquote>
|
||
|
||
<h2 id="lets-start-with-otp-setup-">Let’s start with OTP setup !</h2>
|
||
|
||
<p><img src="https://upload.wikimedia.org/wikipedia/commons/0/03/Security_token.jpg" alt="TOTP hardware token" class="inline" /></p>
|
||
|
||
<h3 id="server-host-setup">Server host setup</h3>
|
||
|
||
<p>In order for a “One-Time Password” (OTP) to be asked for after the usual password, we have to install a <a href="https://en.wikipedia.org/wiki/Linux_PAM">PAM module (Pluggable Authentication Module)</a> on the server side.
|
||
The module is <a href="https://github.com/google/google-authenticator-libpam">google-authenticator-libpam</a> : it’s from Google but it works with any TOTP-or-HOTP-compatible generator application.</p>
|
||
|
||
<p>Please note that this is not SSH-specific, the module will work for all authentications on this machine.</p>
|
||
|
||
<p>First install the module :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>libpam-google-authenticator
|
||
</code></pre></div></div>
|
||
|
||
<p>And enable it by editing PAM configuration ; here a sample <code class="language-plaintext highlighter-rouge">/etc/pam.d/common-auth</code> file :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 1. here are the per-package modules (the "Primary" block)</span>
|
||
<span class="c"># pam_unix is the standard password authentication</span>
|
||
<span class="c"># success=1 means to bypass one step (here pam_ldap.so) straight to the OTP module</span>
|
||
auth <span class="o">[</span><span class="nv">success</span><span class="o">=</span>1 <span class="nv">default</span><span class="o">=</span>ignore] pam_unix.so nullok_secure
|
||
<span class="c"># In this sample setup, we allow users to connect with their LDAP password</span>
|
||
<span class="c"># success=ok means to go to the next step (which is the OTP module)</span>
|
||
auth <span class="o">[</span><span class="nv">success</span><span class="o">=</span>ok <span class="nv">default</span><span class="o">=</span>ignore] pam_ldap.so <span class="nv">minimum_uid</span><span class="o">=</span>1000 use_first_pass
|
||
<span class="c"># Finally, the OTP password is asked</span>
|
||
<span class="c"># In case of success the 'deny' step is bypassed, leading to the 'permit' module</span>
|
||
auth <span class="o">[</span><span class="nv">success</span><span class="o">=</span>1 <span class="nv">default</span><span class="o">=</span>ignore] pam_google_authenticator.so
|
||
|
||
<span class="c"># 2. here's the fallback if no module succeeds</span>
|
||
auth requisite pam_deny.so
|
||
|
||
<span class="c"># 3. prime the stack with a positive return value if there isn't one already;</span>
|
||
<span class="c"># this avoids us returning an error just because nothing sets a success code</span>
|
||
<span class="c"># since the modules above will each just jump around</span>
|
||
auth required pam_permit.so
|
||
</code></pre></div></div>
|
||
|
||
<p><strong>From here, each user must generate a secret on the server in order to log in !</strong>
|
||
<strong>So, DO NOT LOG OUT now or generate an OTP secret for yourself (see below) and test the authentication before !</strong></p>
|
||
|
||
<p>There are other possible layouts for the PAM configuration, like <code class="language-plaintext highlighter-rouge">nullok</code> to allow users to log in without OTP until they have set it up : <a href="https://github.com/google/google-authenticator-libpam">github.com/…/google-authenticator-libpam</a>.</p>
|
||
|
||
<p>For this PAM configuration to work with SSH you will have to enable the corresponding authentication method in <code class="language-plaintext highlighter-rouge">/etc/ssh/sshd_config</code> :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Allows OTP authentication</span>
|
||
KbdInteractiveAuthentication <span class="nb">yes</span>
|
||
<span class="c">#ChallengeResponseAuthentication is a deprecated alias for KbdInteractiveAuthentication</span>
|
||
<span class="c">#ChallengeResponseAuthentication yes</span>
|
||
|
||
<span class="c"># Actually enables it</span>
|
||
AuthenticationMethods keyboard-interactive
|
||
</code></pre></div></div>
|
||
|
||
<p>And restart the SSH server :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>sshd <span class="nt">-t</span> <span class="o">&&</span> <span class="nb">sudo </span>service ssh restart
|
||
</code></pre></div></div>
|
||
|
||
<h3 id="per-user-setup">Per-user setup</h3>
|
||
|
||
<p>To connect using OTP, each user must have a <code class="language-plaintext highlighter-rouge">~/.google_authenticator</code> file on the server, with the OTP secret and configuration.
|
||
Running the following console-interactive process on the server will create this file and print informations to import the secret into an OTP application (e.g. via a QRCode) :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Runs a console-interactive process</span>
|
||
google-authenticator
|
||
</code></pre></div></div>
|
||
|
||
<p>You may need <a href="https://www.linode.com/docs/guides/secure-ssh-access-with-2fa/#generate-a-key">some help</a> to get the right answers.</p>
|
||
|
||
<p>Once generated, the secret file can be copied to other hosts in order to reuse the same OTP entry (of course you have to make sure users are not blocked by OTP until they can upload their secret) :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Once done, send the file to other hosts where you want to use</span>
|
||
<span class="c"># the same OTP secret (e.g. same network servers)</span>
|
||
scp ~/.google_authenticator me@anotherhost.intranet
|
||
<span class="c"># This should not be necessary, but might help if the file was manually crafted</span>
|
||
ssh me@anotherhost.intranet <span class="s1">'chmod 0600 ~/.google_authenticator'</span>
|
||
</code></pre></div></div>
|
||
|
||
<p>Some good open source OTP apps for Android and iOS :</p>
|
||
<ul>
|
||
<li><img src="https://getaegis.app/images/icon.png" alt="Aegis logo" class="inline" height="32px" /> <a href="https://getaegis.app/">Aegis</a></li>
|
||
<li><img src="https://freeotp.github.io/img/freeotp.svg" alt="FreeOTP logo" class="inline" height="32px" /> <a href="https://freeotp.github.io/">FreeOTP</a></li>
|
||
</ul>
|
||
|
||
<p>A successful connection with OTP will look like this :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ssh me@somehost.intranet
|
||
<span class="o">(</span>me@somehost.intranet<span class="o">)</span> Password:
|
||
<span class="o">(</span>me@somehost.intranet<span class="o">)</span> Verification code:
|
||
You have new mail.
|
||
me@somehost.intranet:~<span class="err">$</span>
|
||
</code></pre></div></div>
|
||
|
||
<h2 id="now-lets-add-authentication-with-a-hardware-token">Now let’s add authentication with a hardware token</h2>
|
||
|
||
<p><img src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.nitrokey.com%2Fsites%2Fall%2Fthemes%2Fnitrokey%2Fmedia%2Fnitrokey-u2f.jpg&f=1&nofb=1&ipt=4ceb7b4ae8bf482c619f9428b5ca9679676b065c92c82f765df867bb54975994&ipo=images" alt="Nitrokey" class="inline" height="120px" /><img src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fcdn.shopify.com%2Fs%2Ffiles%2F1%2F0196%2F3068%2F6272%2Fproducts%2Fsomu_580x.jpg%3Fv%3D1618577369&f=1&nofb=1&ipt=8876f1516c3911fe122bbf20ebf9f0b28e3671427634f29bb3c2a3756155459e&ipo=images" alt="SoloKeys somu" class="inline" height="120px" /><img src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fcdn.shopify.com%2Fs%2Ffiles%2F1%2F2670%2F1700%2Fproducts%2F1_Main_Image_530x%402x.jpg%3Fv%3D1550701254&f=1&nofb=1&ipt=17adad9edf2b1ee0fcf30b4889c643cf3858204b15972710d8dfd86106edeb4a&ipo=images" alt="OnlyKey" class="inline" height="120px" /></p>
|
||
|
||
<p>Since OpenSSH 8.2 it is possible to authenticate with a <a href="https://fidoalliance.org/fido2/">FIDO</a> device, which brings support for a whole lot of hardware tokens.</p>
|
||
|
||
<blockquote>
|
||
<p><strong><em>Note</em></strong></p>
|
||
|
||
<p>Before 8.2, there were procedures like using a specific <a href="https://www.linode.com/docs/guides/how-to-use-yubikey-for-two-factor-ssh-authentication/">yubico-pam module for YubiKeys</a> (not described here).</p>
|
||
</blockquote>
|
||
|
||
<p>The process is the same as with <em>public key</em> authentication but with a specific type of key, and you need your hardware token to be plugged in at authentication time.</p>
|
||
|
||
<h3 id="client-setup">Client setup</h3>
|
||
|
||
<h4 id="set-a-pin-on-the-fido2-token">Set a PIN on the FIDO2 token</h4>
|
||
|
||
<p>In order to use a <em>resident key</em> (see below) on a FIDO2 device, you will probably be required to set a PIN.</p>
|
||
|
||
<blockquote>
|
||
<p><strong><em>Note</em></strong></p>
|
||
|
||
<p>Instructions in this paragraph are specific for YubiKey because it’s the one I had for my tests but the rest of the article should work seamlessly with any other FIDO2 devices (<a href="https://solokeys.com/">SoloKeys</a>, <a href="https://www.nitrokey.com/fr">Nitrokey</a>, <a href="https://onlykey.io/">OnlyKey</a>, … ) which may additionally bring interesting features like full open source design, reversible USB-A, firmware upgrades, hardware password manager, …</p>
|
||
</blockquote>
|
||
|
||
<p>For a YubiKey, you will need to <a href="https://support.yubico.com/hc/en-us/articles/360016649039-Enabling-the-Yubico-PPA-on-Ubuntu">install the <em>YubiKey Manager (ykman)</em></a>.
|
||
You will <em>not</em> need the <em>YubiKey Personalization Tool</em> for this tutorial, if you wonder.</p>
|
||
|
||
<p>If you’ve never set up a PIN on your YubiKey, simply run :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Sample OS-independent installation command</span>
|
||
pip <span class="nb">install</span> <span class="nt">--user</span> yubikey-manager
|
||
<span class="c"># Set the PIN for the first time</span>
|
||
ykman fido access change-pin <span class="nt">--new-pin</span> tfbZxxGY3r
|
||
</code></pre></div></div>
|
||
|
||
<p>It’s important to note that the PIN is not limited to digits, FIDO2 allows up to <strong>63 alphanumeric characters</strong> !</p>
|
||
|
||
<h4 id="generate-an-ssh-key">Generate an SSH key</h4>
|
||
|
||
<p>Each user must then generate a compatible private key ; run this on a client workstation (choose between option a or b) :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># (option a) Generates a 'resident' key on the token so that it can be used on other computers</span>
|
||
<span class="c"># Replace 'NameYourKeyHere' with some string to identify this key</span>
|
||
<span class="c"># from others on the hardware token (e.g. 'intranet')</span>
|
||
ssh-keygen <span class="nt">-t</span> ed25519-sk <span class="nt">-O</span> resident <span class="nt">-O</span> <span class="nv">application</span><span class="o">=</span>ssh:NameYourKeyHere <span class="nt">-O</span> verify-required <span class="nt">-f</span> ~/.ssh/ed25519_sk_yubikey1
|
||
|
||
<span class="c"># OR (option b) Generates a key that will only be usable from this computer</span>
|
||
ssh-keygen <span class="nt">-t</span> ed25519-sk <span class="nt">-f</span> ~/.ssh/ed25519_sk_yubikey1
|
||
|
||
<span class="c"># Authorize it to the remote machines</span>
|
||
<span class="c"># I've observed that you may need to force with '-f' if you already have keys there</span>
|
||
ssh-copy-id <span class="nt">-i</span> ~/.ssh/ed25519_sk_yubikey1.pub me@somehost.intranet
|
||
ssh-copy-id <span class="nt">-i</span> ~/.ssh/ed25519_sk_yubikey1.pub me@anotherhost.intranet
|
||
</code></pre></div></div>
|
||
|
||
<p>You could use <code class="language-plaintext highlighter-rouge">-t ecdsa-sk</code> key type instead. From what I understand, <code class="language-plaintext highlighter-rouge">ecdsa-sk</code> is more compatible ; <code class="language-plaintext highlighter-rouge">ed25519-sk</code> is <a href="https://www.hyperelliptic.org/tanja/vortraege/20130531.pdf">not affiliated with NIST</a>.</p>
|
||
|
||
<p>The <code class="language-plaintext highlighter-rouge">-O resident</code> parameter (<em>option a</em>) puts all key material on the hardware token, meaning that you will be able to use it from another computer (<code class="language-plaintext highlighter-rouge">ssh-keygen -K</code> will extract some <em>key handle</em> from the token into <code class="language-plaintext highlighter-rouge">~/.ssh/</code> on the local machine). In this case, <code class="language-plaintext highlighter-rouge">-O verify-required</code> is also used so that a PIN is required.
|
||
<strong>This is only available for FIDO2 devices.</strong></p>
|
||
|
||
<p>On the contrary, the alternative (<em>option b</em>) command will require a private key to be present on the computer <em>in addition</em> to the hardware token, meaning that another person will not be able to log in from another computer even she finds/steals the hardware token.
|
||
<strong>This works with older FIDO devices.</strong></p>
|
||
|
||
<p>More explanations in the <a href="https://www.openssh.com/txt/release-8.2">release notes of OpenSSH</a>.</p>
|
||
|
||
<p>It is a good practice to repeat all those steps with another security token, so you are not locked-out in case you loose one, but you might also use the OTP process to recover.</p>
|
||
|
||
<h4 id="setting-up-the-ssh-client">Setting up the SSH client</h4>
|
||
|
||
<p>Finally, users should make sure that their SSH client configuration is ready to use their FIDO keys.
|
||
Here is a partial <code class="language-plaintext highlighter-rouge">~/.ssh/config</code> <em>(more infos in <a href="https://man.openbsd.org/ssh_config">the man page</a>)</em> :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Makes sure public key authentication is enabled</span>
|
||
PubkeyAuthentication <span class="nb">yes</span>
|
||
<span class="c"># In some weird configurations you might also want to check that</span>
|
||
<span class="c"># PreferredAuthentications includes publickey</span>
|
||
|
||
<span class="c"># Specify my keys for all hosts of the intranet (example)</span>
|
||
Host <span class="k">*</span>.intranet
|
||
IdentityFile ~/.ssh/id_rsa
|
||
IdentityFile ~/.ssh/ed25519_sk_yubikey1
|
||
IdentityFile ~/.ssh/ed25519_sk_yubikey2
|
||
</code></pre></div></div>
|
||
|
||
<p>Client is ready !</p>
|
||
|
||
<h3 id="ssh-server-setup">SSH server setup</h3>
|
||
|
||
<p>Now, the server part.</p>
|
||
|
||
<p>First make sure your server runs OpenSSH ≥ <a href="https://www.openssh.com/txt/release-8.2">8.2/8.2p1</a>.
|
||
With older Debian systems <a href="https://forums.raspberrypi.com/viewtopic.php?t=265211#p1817379">you can get it from backports</a>.</p>
|
||
|
||
<p>Then check <code class="language-plaintext highlighter-rouge">/etc/ssh/sshd_config</code> (some parts are common with OTP above) <em>(more infos in <a href="https://man.openbsd.org/sshd_config">the man page</a>)</em> :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Public key authentication is used for keys on FIDO devices</span>
|
||
PubkeyAuthentication <span class="nb">yes</span>
|
||
|
||
<span class="c"># Actually enables it (we also keep keyboard-interactive for OTP)</span>
|
||
AuthenticationMethods publickey keyboard-interactive
|
||
|
||
<span class="c"># Makes sure to allow enough tries for users who have many keys</span>
|
||
<span class="c"># otherwise, they may encounter a 'Too many authentication failures' error</span>
|
||
<span class="c"># even before their FIDO key is tried...</span>
|
||
MaxAuthTries 9
|
||
|
||
<span class="c"># We also enable classic publickey authentication from the local network,</span>
|
||
<span class="c"># so connecting from there does not require a password nor a security token.</span>
|
||
<span class="c">#</span>
|
||
<span class="c"># Because 'PubkeyAuthentication' enables or disables both classic and FIDO keys</span>
|
||
<span class="c"># at the same time, we use 'PubkeyAcceptedKeyTypes' to limit key types to FIDO</span>
|
||
<span class="c"># by default. Because of the negative matches ('!'), this is applied only if</span>
|
||
<span class="c"># it does NOT match a local network address.</span>
|
||
<span class="c">#</span>
|
||
<span class="c"># Beware that this may not work as expected if connections to the SSH server</span>
|
||
<span class="c"># go through a (reverse) proxy or router which does not correctly relay the original client IP !</span>
|
||
Match Address <span class="s2">"!10.0.0.0/8,!172.16.0.0/12,!192.168.0.0/16,!fe80::%eth0/10,*"</span>
|
||
PubkeyAcceptedKeyTypes sk-ssh-ed25519@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com
|
||
</code></pre></div></div>
|
||
|
||
<p>The <code class="language-plaintext highlighter-rouge">Match Address</code> block is to allow normal public key authentication <strong>from the local network only</strong> ; read the comments carefully.</p>
|
||
|
||
<p>Now restart the SSH server :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>sshd <span class="nt">-t</span> <span class="o">&&</span> <span class="nb">sudo </span>service ssh restart
|
||
</code></pre></div></div>
|
||
|
||
<p><strong>From another session</strong>, try to authenticate :</p>
|
||
|
||
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ssh somehost.intranet
|
||
<span class="c"># The following message may be different or even absent (your token might be flashing) !</span>
|
||
<span class="c"># See https://developers.yubico.com/SSH/Securing_SSH_with_FIDO2.html#_troubleshooting</span>
|
||
Confirm user presence <span class="k">for </span>key ssh:NameYourKeyHere
|
||
<span class="c"># Then, touch your FIDO2 token</span>
|
||
You have new mail.
|
||
me@somehost.intranet:~<span class="err">$</span>
|
||
</code></pre></div></div>
|
||
|
||
<p>You’re in !</p>
|
||
|
||
<h2 id="bugs-and-limitations">Bugs and limitations</h2>
|
||
|
||
<h3 id="agent-refused-operation">Agent refused operation</h3>
|
||
|
||
<p>When your hardware token is not plugged in, you might have the following message :</p>
|
||
|
||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sign_and_send_pubkey: signing failed for ED25519-SK "/home/me/.ssh/ed25519_sk_yubikey1" from agent: agent refused operation
|
||
</code></pre></div></div>
|
||
|
||
<p>This is not blocking and SSH will use another method to authenticate (another ssh key or OTP).</p>
|
||
|
||
<h3 id="non-interactive-logins">Non-interactive logins</h3>
|
||
|
||
<p>OTP and FIDO2 “touch” method are suited for interactive login, but you might need to keep SSH public key authentication open for background services (e.g. mounting remote filesystems via SFTP).</p>
|
||
|
||
<p>In this case finer tuning is possible by targeting specific users in the SSH configuration.</p>
|
||
|
||
<h2 id="references">References</h2>
|
||
|
||
<ul>
|
||
<li>Tutorials :
|
||
<ul>
|
||
<li><a href="https://www.youtube.com/watch?v=4lPvjON4-k8">Using YubiKey to Secure Remote Servers in 10 minutes or less | Nextcloud 2FA</a> (video)</li>
|
||
<li><a href="https://xosc.org/u2fandssh.html">Using a U2F/FIDO key with OpenSSH</a></li>
|
||
<li><a href="https://developers.yubico.com/SSH/Securing_SSH_with_FIDO2.html">Securing SSH with FIDO2 @ yubico.com</a></li>
|
||
</ul>
|
||
</li>
|
||
<li>Tutorials on OTP + SSH :
|
||
<ul>
|
||
<li><a href="https://www.linode.com/docs/guides/secure-ssh-access-with-2fa/">Use 2FA (Two-Factor Authentication) with SSH</a></li>
|
||
<li><a href="https://www.hallam.ch/blog/index.php/2020/04/19/ssh-sftp-with-two-factor-authentication/">SSH/SFTP with Two Factor Authentication @ hallam.ch</a></li>
|
||
</ul>
|
||
</li>
|
||
<li>YubiKey :
|
||
<ul>
|
||
<li><a href="https://support.yubico.com/hc/en-us/articles/4402836718866-Understanding-YubiKey-PINs">Understanding YubiKey PINs</a></li>
|
||
<li><a href="https://www.yubico.com/support/download/yubikey-manager/">YubiKey Manager downloads for all OS</a></li>
|
||
<li><a href="https://docs.yubico.com/software/yubikey/tools/ykman/FIDO_Commands.html">YubiKey Manager (ykman) CLI and GUI Guide > FIDO Commands</a></li>
|
||
<li>Legacy method with <em>pam_yubico</em> :
|
||
<ul>
|
||
<li><a href="https://developers.yubico.com/yubico-pam/Two_Factor_PAM_Configuration.html">Two Factor PAM Configuration</a></li>
|
||
<li><a href="https://www.linode.com/docs/guides/how-to-use-yubikey-for-two-factor-ssh-authentication/">Using a YubiKey for 2FA when Logging in over SSH</a> (legacy )</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li>Linux PAM :
|
||
<ul>
|
||
<li><a href="https://www.digitalocean.com/community/tutorials/how-to-use-pam-to-configure-authentication-on-an-ubuntu-12-04-vps">How To Use PAM to Configure Authentication on an Ubuntu 12.04 VPS @ digitalocean.com</a></li>
|
||
<li><a href="https://linux.die.net/man/5/pam.d">pam.d(5) - Linux man page</a></li>
|
||
</ul>
|
||
</li>
|
||
<li>More links :
|
||
<ul>
|
||
<li><a href="https://forums.raspberrypi.com/viewtopic.php?t=265211">forums.raspberrypi.com > openssh 8.2 enables u2f / fido2 tokens</a></li>
|
||
<li><a href="http://www.openssh.com/manual.html">OpenSSH manuals</a></li>
|
||
<li><a href="https://www.hyperelliptic.org/tanja/vortraege/20130531.pdf">Security dangers of the NIST curves</a></li>
|
||
<li><a href="https://unix.stackexchange.com/a/685221/389700">sshd_config - “Match Address <IPv6>” not matching @ stackexchange</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Gemalto_usb_shell_token_with_a_punched_OpenPGP_card_inside.jpg/640px-Gemalto_usb_shell_token_with_a_punched_OpenPGP_card_inside.jpg" alt="Gemalto usb shell token with a punched OpenPGP card inside.jpg" /></p>]]></content><author><name>nicobo</name></author><category term="security" /><category term="ssh" /><category term="mfa" /><category term="2fa" /><category term="fido" /><category term="yubikey" /><summary type="html"><![CDATA[Illustration © 2022 SOLOKEYS - https://solokeys.com This article shows how to set up an SSH server so that users can authenticate : either with a hardware token (FIDO-compatible actually) or with a two-factor authentication (2FA) process, using their password and a one-time password (OTP) from the intranet, with a standard SSH key]]></summary></entry><entry><title type="html">Tuxedo InfinityBook S 15 review</title><link href="https://www.nicolabs.net/2021/Tuxedo-InfinityBook-review" rel="alternate" type="text/html" title="Tuxedo InfinityBook S 15 review" /><published>2021-12-29T00:00:00+01:00</published><updated>2021-12-29T00:00:00+01:00</updated><id>https://www.nicolabs.net/2021/Tuxedo-InfinityBook-review</id><content type="html" xml:base="https://www.nicolabs.net/2021/Tuxedo-InfinityBook-review"><![CDATA[<p><img src="/assets/blog/screenshots/tuxedo-infinity/tuxinfinity_kblight.jpg" alt="Tuxedo InfinityBook with keyboard lights" /></p>
|
||
|
||
<p>After almost ten years of good and loyal services 🎖, I had to give up on my <a href="https://pcsupport.lenovo.com/us/en/products/laptops-and-netbooks/thinkpad-t-series-laptops/thinkpad-t520">Lenovo Thinkpad T520</a>, which was getting too slow for things like intensive Docker building…</p>
|
||
|
||
<p>Althought I still trust Lenovo for providing excellent Linux laptops, I wanted to try one of the newcomers in the Linux laptop market.</p>
|
||
|
||
<p>I made up my mind on <a href="https://www.tuxedocomputers.com/en/Linux-Hardware/Linux-Notebooks/15-16-inch/TUXEDO-InfinityBook-S-15-Gen6.tuxedo">InfinityBook S 15</a> from Tuxedo Computers (‘TC’).</p>
|
||
|
||
<h2 id="whats-in-the-box">What’s in the box</h2>
|
||
|
||
<ul>
|
||
<li>The laptop itself (it’s just a customized <a href="https://clevo-computer.com/en/laptops-configurator/purpose/business-and-office-solutions/5400/clevo-ns50mu-intel-core-11-gen.-tiger-lake/iris-xe-graphics-thunderbolt-4">Clevo NS50</a>)</li>
|
||
<li>A power cable (~ 2,80m from plug to computer)</li>
|
||
<li>A quickstart manual</li>
|
||
<li>A more complete manual (in german 🇩🇪, but helped me finding out the key to enter BIOS menu)</li>
|
||
<li>An USB key with TC’s Web fully automated installation (“WebFAI”) - <em>not tested</em></li>
|
||
<li>Some goodies : mouse pad, 2 pens, …</li>
|
||
</ul>
|
||
|
||
<p><img src="/assets/blog/screenshots/tuxedo-infinity/TUXEDO%20InfinityBook%20S%2015%20Gen6.jpg" alt="Tuxedo InfinityBook 15S" /></p>
|
||
|
||
<h2 id="tuxedo-customer-service--shipping-documentation-">Tuxedo customer service : shipping, documentation,. ..</h2>
|
||
|
||
<ul>
|
||
<li>At the difference of many comments I’ve seen around, my computer was shipped within a few days (around a week) - very statisfying</li>
|
||
<li><a href="https://tuxedocomputers.com">Their website</a> is annoying as it does not let you CTRL-click a link to open into a new tab : the current page will freeze (click event is probably registered in javascript in a wrong way :-()</li>
|
||
<li>At the time of writing, there is no dedicated help page for my device (<a href="https://www.tuxedocomputers.com/en/Infos/Help-Support/Help-for-my-device/TUXEDO-InfinityBook-Series.tuxedo">only for InfinityBook S14, not S15</a>)</li>
|
||
<li>One mandatory thing for me is to be able to tune memory, disks, CPU before ordering. Tuxedo’s website is very good at this. You can even <a href="https://www.youtube.com/watch?v=6wrwNaS5dw4&t=38">make your own keyboard</a> or <a href="https://www.tuxedocomputers.com/en/Individual-Keyboards.tuxedo">engrave a custom logo on the chassis</a>.</li>
|
||
</ul>
|
||
|
||
<h2 id="performance--fan-noise">Performance & fan noise</h2>
|
||
|
||
<p>I’m not a performance addict (I don’t play games, I don’t mine bitcoins, I don’t run do machine learning on my computer), so I have not run extended benchmarks.</p>
|
||
|
||
<p>However it’s obviously fast, it compiles docker images & runs multiple VM seamlessly ; as expected regarding the <a href="https://linux-hardware.org/?probe=aabe23e7a8">Intel Tiger Lake Core i7 CPU, 64GB 3200MHz RAM and NVMe PCIe 4.0 disk</a>.</p>
|
||
|
||
<p>As seen in many comments, I can confirm that Tuxedo computers have an unusual management of fan speed.
|
||
The fan is agressively activated whenever there is a CPU / GPU utilization increase.
|
||
This follows a sane logic but can make you nervous when it suddenly starts to blow as the computer goes to sleep or when you’re in the train, in the middle of quiet people…</p>
|
||
|
||
<p>Even with the most quiet profile (‘silent’, in the <em>Tuxedo control center</em>) it will be triggered very early.</p>
|
||
|
||
<h2 id="display">Display</h2>
|
||
|
||
<ul>
|
||
<li>I was worried looking at the poor display specifications but they don’t hold true : resolution and brightness are really fine. You will still have to forget about dark themes if you want to code under the sun but as far as I know it’s the case with most laptops out there.</li>
|
||
<li>16/9 allows for a 15”6 display, and even if it’s not the best ratio for coding, the resolution compensates by allowing enough text rows to be displayed within the given height. I don’t regret this 15”6 over the 14” version as it brings some comfort displaying documents side by side.</li>
|
||
<li>When working in stand up position, if your workbench is a bit low (e.g. 90 cm high), the lid does not open enough to get a comfortable 90° to the eyes. I would have appreciated it to open 15-20° more.</li>
|
||
</ul>
|
||
|
||
<h2 id="sound">Sound</h2>
|
||
|
||
<ul>
|
||
<li>Speakers are the worst I’ve ever encountered, without a doubt. Still, it proved enough for video conferencing (tested with <em>MS Teams</em>).</li>
|
||
<li>The problem is only with internal speakers, not the sound card, as sound quality is good if you use an external headset.</li>
|
||
<li><a href="https://github.com/tuxedocomputers/pulseeffects-presets">A suggested trick is to install PulseEffects</a> but it does not add any significant improvement with the given settings.</li>
|
||
<li>Allowing volume over 100% is probably your best bet to get the most of it : <code class="language-plaintext highlighter-rouge">dconf write /com/solus-project/budgie-raven/allow-volume-overdrive true</code></li>
|
||
</ul>
|
||
|
||
<h2 id="camera">Camera</h2>
|
||
|
||
<ul>
|
||
<li>The camera is also one of the poorest I’ve seen in years, it just seems to come from the past. Fortunately it’s not something I personally care about.</li>
|
||
<li>There is an infrared camera that can be used with <em>Windows Hello</em>, but that is not taken into account out of the box by <a href="https://github.com/boltgolt/howdy"><em>Howdy</em>, the Linux alternative</a>. Howdy works with the normal camera, though, although the configuration is not obvious at first.</li>
|
||
</ul>
|
||
|
||
<h2 id="keyboard-">Keyboard 🐧</h2>
|
||
|
||
<p>I have to say that the keyboard, ironically, turned out to be a major selling point for me, as most other Linux laptops distributors don’t support AZERTY layouts.</p>
|
||
|
||
<ul>
|
||
<li>Numeric keypad (it’s been a long time I haven’t used one) : it’s nice to have it but, in the end, I can live without it and I would prefer to have it removed and the room used to get larger keys on the right side (shift, enter, …) and/or the speakers enhanced</li>
|
||
<li>Black keys on black background is beautiful but not the best choice for the eyes : keys are faster to locate with silver/black combination for instance</li>
|
||
<li>By default, there is a ‘Tux’ key 🐧 instead of a ‘Windows ‘ or ‘Apple’ one, which is funny, but <a href="https://www.youtube.com/watch?v=nidnvlt6lzw&t=1">you could also have whatever symbols printed on all keys</a>. This may help reduce the learning curve but it seems impossible to get what the default keyboard would look like anyway.</li>
|
||
<li>Back-lit keyboard is also not the best technique to light keys. From my experience I find it more comfortable to light the keys from above (<a href="https://youtu.be/MH7o3Zb8HVg">ThinkPad™ had a ThinkLight™ embedded at the top of the lid</a>) : it enlightens all keys, their surface AND the touchpad (which is not, on the tux, making it tricky to find it or its fingerprint reader in the dark).</li>
|
||
<li>As seen in a few forums, I confirm that the keys lights comes both from around (their side) and from the characters, which are semi-transparent</li>
|
||
<li>This model can only have on color at a time (I couldn’t find a place where it’s stated). To change the color follow the procedure on TC’s website and reboot (it takes a kernel module to reload ; the doc is really hard to find (it’s <a href="https://www.tuxedocomputers.com/en/Infos/Help-Support/Instructions/Installation-of-keyboard-drivers-for-TUXEDO-Computers-models-with-RGB-keyboard-.tuxedo">here</a> and <a href="https://github.com/tuxedocomputers/tuxedo-keyboard">there</a>)). I’ve tried several values for the <code class="language-plaintext highlighter-rouge">mode=</code> parameter but it didn’t change anything ; however changing the mode with the keyboard shortcut seems to cycle through preconfigured colors</li>
|
||
<li>A visual <em>Num Lock</em> indicator would have been nice</li>
|
||
</ul>
|
||
|
||
<h2 id="touchpad">Touchpad</h2>
|
||
|
||
<ul>
|
||
<li>The touchpad is not good.</li>
|
||
<li>The slide sensation is not at the level I’m used to with Thinkpad and HP computers, resulting in a lower accuracy. It can be especially annoying when you need to do very small moves to put the cursor at a pixel-sized location. Maybe it can be fixed by configuration ?</li>
|
||
<li>It looks less durable than a HP Elitebook or Envy laptop for instance. Let’s see in a few years if it looks like the one of my old Thinkpad <img src="TODO" alt="Photo" /></li>
|
||
</ul>
|
||
|
||
<h2 id="chassis">Chassis</h2>
|
||
|
||
<ul>
|
||
<li>The chassis feels more heavy than I expected (compared to my old thinkpad <em>=> have to check the weight</em>)</li>
|
||
<li>It’s same width as a usual 15”6 but as short in depth as a 14”, which is great for transportation</li>
|
||
<li>When opening the lid, lift-up hinges raise the notebook a little bit from the rear, which is ergonomic for typing, but in turn prevent to fit over a docking station like their own <a href="https://www.tuxedocomputers.com/en/Linux-Hardware/Accessories-books-co-/USB-accessories/Universal-docking-station-for-all-TUXEDO-Books-Type-C-Type-A-USB-connection_1.tuxedo">Tuxedo Office Hub</a>… I’ve tried several positions but it doesn’t easily stay in place.</li>
|
||
<li>The lid (as well as most other parts) seem to be easily scratched and the material does not prevent finger marks at all (see photos below)</li>
|
||
</ul>
|
||
|
||
<p><img src="/assets/blog/screenshots/tuxedo-infinity/tuxinfinity_scratch.jpg" alt="Tuxedo InfinityBook scratched" />
|
||
<img src="/assets/blog/screenshots/tuxedo-infinity/tuxinfinity_fingermarks.jpg" alt="Tuxedo InfinityBook finger marks" /></p>
|
||
|
||
<h2 id="battery--charge">Battery & charge</h2>
|
||
|
||
<ul>
|
||
<li>Don’t trust the battery life advertized on TC’s website. It’s just a normal battery with normal life expectations. No more, no less.</li>
|
||
<li>The cable is long enough and the charger fairly small enough for transportation.</li>
|
||
<li>Charging with TC’s USB-C cable is as much efficient as with a classic cable. The USB-C port’s position seems a bit uncomfortable (in the middle - so it may be in the way sometimes, and not easy to plug without looking) but it has not annoyed me so far.</li>
|
||
<li>Both cables feel the same weight and size overall, but the USB-C may allows you to charge your smartphone or another computer with a compatible battery.</li>
|
||
<li>The <a href="https://www.tuxedocomputers.com/en/Infos/Help-Support/Frequently-asked-questions/What-is-Flexicharger-.tuxedo"><em>FlexiCharger</em></a> feature of Tuxedo is nice : it lets you preserve battery life (not autonomy) by preventing micro-charges. However when you need full capacity you have to reboot in order to deactivate it from the BIOS. This setting should be available from the OS (e.g. Tuxedo Control center) to really be called “flexible”.</li>
|
||
<li>FlexiCharger has bugs, too : the BIOS UI enters an infinite loop if you try to set up the ‘stop charge’ threshold below the ‘start charge’ one, and sometimes the charge does not start when the battery capacity reaches the configured threshold : you have to unplug the cable and plug it back.</li>
|
||
<li><em>Hibernate</em> menu does not work (I suspect it may be linked to the fact that I have 64 GB of RAM and no dedicated swap partition, but I haven’t investigated on this topic yet). Anyway hibernation has never worked out of the box with Ubuntu.</li>
|
||
</ul>
|
||
|
||
<h2 id="fingerprint-reader">Fingerprint reader</h2>
|
||
|
||
<p>It’s there but not working :</p>
|
||
<ul>
|
||
<li><a href="https://linux-hardware.org/?id=usb:04f3-0c63">linuxhardware probe says there’s no known driver</a></li>
|
||
<li>however seems to be supported with <a href="https://fprint.freedesktop.org/supported-devices.html"><em>f</em>print</a></li>
|
||
</ul>
|
||
|
||
<p>This does not make sense as it’s embedded on the touchpad’s surface so we would expect it to be useable… Maybe Tuxedo is hopping for a driver update ?</p>
|
||
|
||
<h2 id="tuxedos-webfai">Tuxedo’s WebFAI</h2>
|
||
|
||
<ul>
|
||
<li>I wanted to use the provided USB key to test several distributions, but it’s a pain because this so-called WebFAI requires a <em>wired</em> connection, forcing me to stay next to the Internet box (which is not in a cosy place) during the whole installation.</li>
|
||
<li>Otherwise, the USB key works (<a href="https://youtu.be/1TFMxbNtXyQ">Dominik said his was not</a>)</li>
|
||
</ul>
|
||
|
||
<h2 id="tuxedo-os--other-customizations">Tuxedo OS & other customizations</h2>
|
||
|
||
<p>I ordered the computer pre-installed with <em>Tuxedo OS</em>, a custom <em>Ubuntu Budgie</em> distribution: there are a few things that don’t work out of the box with this configuration.</p>
|
||
|
||
<ul>
|
||
<li>Some basic packages are missing (because of Ubuntu ?) ; e.g. <code class="language-plaintext highlighter-rouge">ifconfig</code></li>
|
||
<li>Some presets that could be provided : installed PulseEffects, disabling Intel ME, FlexiCharger enabled ?</li>
|
||
<li>Tuxedo Control Center has only a limited set of features, from which only the power profile is of some interest. From the reviews I read, I expected more. Also the tray icon is the only one in color…</li>
|
||
<li>The computer seems to suspend to RAM when the lid is closed, as expected, but stills consumes a lot of energy : from 61% battery remaining to only 9% in appromixately 9h. Applying <a href="https://www.tuxedocomputers.com/en/Infos/Help-Support/Instructions/Fine-tuning-of-power-management-with-suspend-standby.tuxedo">this</a> enhances battery life (from 31% to 21% in 7h30). There may be even better solutions.</li>
|
||
<li>Automatic or manual screen lock (<em><Super>+L</em>) does not work OOTB, you have to enable it : <code class="language-plaintext highlighter-rouge">dconf write /org/gnome/desktop/lockdown/disable-lock-screen false</code></li>
|
||
<li>When you ask for Tuxedo OS to be installed, in addition to the main partition, they also create the UEFI partition (512 MB FAT) and a swap partition at the end of the disk. But they made the swap partition 8 GB, whereas I have 64 GB of RAM…</li>
|
||
<li>Software center is used (comes from Ubuntu), but it’s just not useable (anybody uses it anyway ?). You get multiple identical entries with no clue about which one to choose. Most of the time the version is outdated. etc.</li>
|
||
<li>Some ‘autostart’ symlinks target missing executables (<code class="language-plaintext highlighter-rouge">/usr/local/bin/vboxinstall.sh</code>, <code class="language-plaintext highlighter-rouge">/usr/local/bin/cryptshutdown.sh</code>)</li>
|
||
</ul>
|
||
|
||
<h2 id="tuxedos-bios">Tuxedo’s BIOS</h2>
|
||
|
||
<p>Tuxedo ships computers with a custom BIOS.</p>
|
||
|
||
<p>I thought that was fine, because they could provide nice features like FlexiCharger, <strong>disabling Intel ME</strong> (which was a major point for me), …
|
||
However I later learned that they get BIOS updates from <em>Clevo</em> for which <a href="https://www.reddit.com/r/tuxedocomputers/comments/qbal7m/new_infinitybook_s15_bios/hhbvdgs/">they are not able to testify what’s inside</a>, which of course <strong>is a major issue for privacy !</strong></p>
|
||
|
||
<p>Unfortunately, this discredits all their work on the BIOS, and the best thing to do would probably be to <a href="https://www.tuxedocomputers.com/en/Infos/Help-Support/Frequently-asked-questions/Coreboot-on-TUXEDO-Computers-devices.tuxedo">switch to coreboot or alike instead</a>.</p>
|
||
|
||
<h2 id="wrapping-up">Wrapping up</h2>
|
||
|
||
<ul>
|
||
<li><strong>I’m not impressed</strong>.</li>
|
||
<li>I would rather <strong>trade the extended keys (numeric keypad and so) with better audio and larger ENTER and SHIFT keys</strong>.</li>
|
||
<li>The <strong>touchpad is not good</strong>.</li>
|
||
<li>The <strong>custom BIOS should be replaced with a more free-as-in-freedom one</strong>, just like <a href="https://www.coreboot.org/">coreboot</a>.</li>
|
||
<li>The default Ubuntu Budgie install is not for <em>power users</em>. Change it.</li>
|
||
<li>Still, <strong>it is an up-to-date computer for programmers</strong> and overall I don’t regret buying it as it’s ok for my daily usage.</li>
|
||
</ul>
|
||
|
||
<h2 id="references">References</h2>
|
||
|
||
<ul>
|
||
<li><a href="https://www.tuxedocomputers.com/en/Linux-Hardware/Linux-Notebooks/15-16-inch/TUXEDO-InfinityBook-S-15-Gen6.tuxedo">InfinityBook S 15 at Tuxedo’s</a></li>
|
||
<li>Tuxedo InfinityBook Pro 14 Gen 6 video review by Dominik : <a href="https://youtu.be/1TFMxbNtXyQ">Part 1</a> | <a href="https://youtu.be/_IQwZlNOxEQ">Part 2</a> | <a href="https://youtu.be/fRa9rF3yj4M">Bonus round</a></li>
|
||
<li><a href="https://www.reddit.com/r/tuxedocomputers/comments/m9vw43/infinitybook_s_14_gen_6_some_issues_questions_and/">reddit.com - InfinityBook S 14 Gen 6: some Issues, Questions and Short Review</a></li>
|
||
<li><a href="https://www.reddit.com/r/linuxhardware/comments/fvgu0h/review_of_tuxedo_inifitybook_s14_v5_or_clevo/">reddit.com - Review of Tuxedo InifityBook S14 v5 (or Clevo L141CU, Schenker Via 14, System76 Lemur Pro 14)</a></li>
|
||
</ul>]]></content><author><name>nicobo</name></author><category term="bios" /><category term="hardware" /><category term="laptop" /><category term="linux" /><category term="privacy" /><category term="review" /><category term="Ubuntu" /><summary type="html"><![CDATA[After almost ten years of good and loyal services 🎖, I had to give up on my Lenovo Thinkpad T520, which was getting too slow for things like intensive Docker building… Althought I still trust Lenovo for providing excellent Linux laptops, I wanted to try one of the newcomers in the Linux laptop market. I made up my mind on InfinityBook S 15 from Tuxedo Computers (‘TC’). What’s in the box The laptop itself (it’s just a customized Clevo NS50) A power cable (~ 2,80m from plug to computer) A quickstart manual A more complete manual (in german 🇩🇪, but helped me finding out the key to enter BIOS menu) An USB key with TC’s Web fully automated installation (“WebFAI”) - not tested Some goodies : mouse pad, 2 pens, … Tuxedo customer service : shipping, documentation,. .. At the difference of many comments I’ve seen around, my computer was shipped within a few days (around a week) - very statisfying Their website is annoying as it does not let you CTRL-click a link to open into a new tab : the current page will freeze (click event is probably registered in javascript in a wrong way :-() At the time of writing, there is no dedicated help page for my device (only for InfinityBook S14, not S15) One mandatory thing for me is to be able to tune memory, disks, CPU before ordering. Tuxedo’s website is very good at this. You can even make your own keyboard or engrave a custom logo on the chassis. Performance & fan noise I’m not a performance addict (I don’t play games, I don’t mine bitcoins, I don’t run do machine learning on my computer), so I have not run extended benchmarks. However it’s obviously fast, it compiles docker images & runs multiple VM seamlessly ; as expected regarding the Intel Tiger Lake Core i7 CPU, 64GB 3200MHz RAM and NVMe PCIe 4.0 disk. As seen in many comments, I can confirm that Tuxedo computers have an unusual management of fan speed. The fan is agressively activated whenever there is a CPU / GPU utilization increase. This follows a sane logic but can make you nervous when it suddenly starts to blow as the computer goes to sleep or when you’re in the train, in the middle of quiet people… Even with the most quiet profile (‘silent’, in the Tuxedo control center) it will be triggered very early. Display I was worried looking at the poor display specifications but they don’t hold true : resolution and brightness are really fine. You will still have to forget about dark themes if you want to code under the sun but as far as I know it’s the case with most laptops out there. 16/9 allows for a 15”6 display, and even if it’s not the best ratio for coding, the resolution compensates by allowing enough text rows to be displayed within the given height. I don’t regret this 15”6 over the 14” version as it brings some comfort displaying documents side by side. When working in stand up position, if your workbench is a bit low (e.g. 90 cm high), the lid does not open enough to get a comfortable 90° to the eyes. I would have appreciated it to open 15-20° more. Sound Speakers are the worst I’ve ever encountered, without a doubt. Still, it proved enough for video conferencing (tested with MS Teams). The problem is only with internal speakers, not the sound card, as sound quality is good if you use an external headset. A suggested trick is to install PulseEffects but it does not add any significant improvement with the given settings. Allowing volume over 100% is probably your best bet to get the most of it : dconf write /com/solus-project/budgie-raven/allow-volume-overdrive true Camera The camera is also one of the poorest I’ve seen in years, it just seems to come from the past. Fortunately it’s not something I personally care about. There is an infrared camera that can be used with Windows Hello, but that is not taken into account out of the box by Howdy, the Linux alternative. Howdy works with the normal camera, though, although the configuration is not obvious at first. Keyboard 🐧 I have to say that the keyboard, ironically, turned out to be a major selling point for me, as most other Linux laptops distributors don’t support AZERTY layouts. Numeric keypad (it’s been a long time I haven’t used one) : it’s nice to have it but, in the end, I can live without it and I would prefer to have it removed and the room used to get larger keys on the right side (shift, enter, …) and/or the speakers enhanced Black keys on black background is beautiful but not the best choice for the eyes : keys are faster to locate with silver/black combination for instance By default, there is a ‘Tux’ key 🐧 instead of a ‘Windows ‘ or ‘Apple’ one, which is funny, but you could also have whatever symbols printed on all keys. This may help reduce the learning curve but it seems impossible to get what the default keyboard would look like anyway. Back-lit keyboard is also not the best technique to light keys. From my experience I find it more comfortable to light the keys from above (ThinkPad™ had a ThinkLight™ embedded at the top of the lid) : it enlightens all keys, their surface AND the touchpad (which is not, on the tux, making it tricky to find it or its fingerprint reader in the dark). As seen in a few forums, I confirm that the keys lights comes both from around (their side) and from the characters, which are semi-transparent This model can only have on color at a time (I couldn’t find a place where it’s stated). To change the color follow the procedure on TC’s website and reboot (it takes a kernel module to reload ; the doc is really hard to find (it’s here and there)). I’ve tried several values for the mode= parameter but it didn’t change anything ; however changing the mode with the keyboard shortcut seems to cycle through preconfigured colors A visual Num Lock indicator would have been nice Touchpad The touchpad is not good. The slide sensation is not at the level I’m used to with Thinkpad and HP computers, resulting in a lower accuracy. It can be especially annoying when you need to do very small moves to put the cursor at a pixel-sized location. Maybe it can be fixed by configuration ? It looks less durable than a HP Elitebook or Envy laptop for instance. Let’s see in a few years if it looks like the one of my old Thinkpad Chassis The chassis feels more heavy than I expected (compared to my old thinkpad => have to check the weight) It’s same width as a usual 15”6 but as short in depth as a 14”, which is great for transportation When opening the lid, lift-up hinges raise the notebook a little bit from the rear, which is ergonomic for typing, but in turn prevent to fit over a docking station like their own Tuxedo Office Hub… I’ve tried several positions but it doesn’t easily stay in place. The lid (as well as most other parts) seem to be easily scratched and the material does not prevent finger marks at all (see photos below) Battery & charge Don’t trust the battery life advertized on TC’s website. It’s just a normal battery with normal life expectations. No more, no less. The cable is long enough and the charger fairly small enough for transportation. Charging with TC’s USB-C cable is as much efficient as with a classic cable. The USB-C port’s position seems a bit uncomfortable (in the middle - so it may be in the way sometimes, and not easy to plug without looking) but it has not annoyed me so far. Both cables feel the same weight and size overall, but the USB-C may allows you to charge your smartphone or another computer with a compatible battery. The FlexiCharger feature of Tuxedo is nice : it lets you preserve battery life (not autonomy) by preventing micro-charges. However when you need full capacity you have to reboot in order to deactivate it from the BIOS. This setting should be available from the OS (e.g. Tuxedo Control center) to really be called “flexible”. FlexiCharger has bugs, too : the BIOS UI enters an infinite loop if you try to set up the ‘stop charge’ threshold below the ‘start charge’ one, and sometimes the charge does not start when the battery capacity reaches the configured threshold : you have to unplug the cable and plug it back. Hibernate menu does not work (I suspect it may be linked to the fact that I have 64 GB of RAM and no dedicated swap partition, but I haven’t investigated on this topic yet). Anyway hibernation has never worked out of the box with Ubuntu. Fingerprint reader It’s there but not working : linuxhardware probe says there’s no known driver however seems to be supported with fprint This does not make sense as it’s embedded on the touchpad’s surface so we would expect it to be useable… Maybe Tuxedo is hopping for a driver update ? Tuxedo’s WebFAI I wanted to use the provided USB key to test several distributions, but it’s a pain because this so-called WebFAI requires a wired connection, forcing me to stay next to the Internet box (which is not in a cosy place) during the whole installation. Otherwise, the USB key works (Dominik said his was not) Tuxedo OS & other customizations I ordered the computer pre-installed with Tuxedo OS, a custom Ubuntu Budgie distribution: there are a few things that don’t work out of the box with this configuration. Some basic packages are missing (because of Ubuntu ?) ; e.g. ifconfig Some presets that could be provided : installed PulseEffects, disabling Intel ME, FlexiCharger enabled ? Tuxedo Control Center has only a limited set of features, from which only the power profile is of some interest. From the reviews I read, I expected more. Also the tray icon is the only one in color… The computer seems to suspend to RAM when the lid is closed, as expected, but stills consumes a lot of energy : from 61% battery remaining to only 9% in appromixately 9h. Applying this enhances battery life (from 31% to 21% in 7h30). There may be even better solutions. Automatic or manual screen lock (<Super>+L) does not work OOTB, you have to enable it : dconf write /org/gnome/desktop/lockdown/disable-lock-screen false When you ask for Tuxedo OS to be installed, in addition to the main partition, they also create the UEFI partition (512 MB FAT) and a swap partition at the end of the disk. But they made the swap partition 8 GB, whereas I have 64 GB of RAM… Software center is used (comes from Ubuntu), but it’s just not useable (anybody uses it anyway ?). You get multiple identical entries with no clue about which one to choose. Most of the time the version is outdated. etc. Some ‘autostart’ symlinks target missing executables (/usr/local/bin/vboxinstall.sh, /usr/local/bin/cryptshutdown.sh) Tuxedo’s BIOS Tuxedo ships computers with a custom BIOS. I thought that was fine, because they could provide nice features like FlexiCharger, disabling Intel ME (which was a major point for me), … However I later learned that they get BIOS updates from Clevo for which they are not able to testify what’s inside, which of course is a major issue for privacy ! Unfortunately, this discredits all their work on the BIOS, and the best thing to do would probably be to switch to coreboot or alike instead. Wrapping up I’m not impressed. I would rather trade the extended keys (numeric keypad and so) with better audio and larger ENTER and SHIFT keys. The touchpad is not good. The custom BIOS should be replaced with a more free-as-in-freedom one, just like coreboot. The default Ubuntu Budgie install is not for power users. Change it. Still, it is an up-to-date computer for programmers and overall I don’t regret buying it as it’s ok for my daily usage. References InfinityBook S 15 at Tuxedo’s Tuxedo InfinityBook Pro 14 Gen 6 video review by Dominik : Part 1 | Part 2 | Bonus round reddit.com - InfinityBook S 14 Gen 6: some Issues, Questions and Short Review reddit.com - Review of Tuxedo InifityBook S14 v5 (or Clevo L141CU, Schenker Via 14, System76 Lemur Pro 14)]]></summary></entry><entry><title type="html">Make a Raspberry Pi a Bluetooth speaker (part 1)</title><link href="https://www.nicolabs.net/2020/Make-RPi-bluetooth-speaker-part-1" rel="alternate" type="text/html" title="Make a Raspberry Pi a Bluetooth speaker (part 1)" /><published>2020-05-04T00:00:00+02:00</published><updated>2023-01-15T00:00:00+01:00</updated><id>https://www.nicolabs.net/2020/Make-RPi-bluetooth-speaker-part-1</id><content type="html" xml:base="https://www.nicolabs.net/2020/Make-RPi-bluetooth-speaker-part-1"><![CDATA[<p><img src="/assets/blog/3rdparty/logos/Bluetooth_FM_Color.png" alt="Bluetooth logo" height="128px" /></p>
|
||
|
||
<p>In this two-part article I describe the steps I had to take to make a <em>headless Raspberry Pi 4</em> a Bluetooth <a href="https://www.howtogeek.com/338750/whats-the-difference-between-bluetooth-a2dp-and-aptx/">A2DP</a> speaker.</p>
|
||
|
||
<p>My goal was to offer a user-friendly way for anyone in the same room to <strong>pair its Bluetooth smartphone with the Raspberry Pi and play music through it</strong>, while making sure the <strong>neighbors won’t be able to connect without approval</strong>.</p>
|
||
|
||
<p>To output music, you can <strong>connect a Hi-Fi system to the Raspberry Pi</strong> using the Jack plug or an audio add-on card : this part depends on your setup.</p>
|
||
|
||
<p><img class="plantuml" id="6db81ae42560b1e3a86d8afb5320a86d" alt="PlantUML diagram" src="/assets/uml/6db81ae42560b1e3a86d8afb5320a86d.svg" /></p>
|
||
|
||
<p>Allright, let’s dive into how Bluetooth works.</p>
|
||
|
||
<blockquote>
|
||
<p><em>This is a two-part article :</em></p>
|
||
<ol>
|
||
<li><em>How Bluetooth pairing works (this part)</em></li>
|
||
<li><em>Raspberry Pi as a Bluetooth A2DP receiver (soon available)</em></li>
|
||
</ol>
|
||
</blockquote>
|
||
|
||
<h2 id="how-bluetooth-pairing-works">How Bluetooth pairing works</h2>
|
||
|
||
<p>Bluetooth is quite a complex thing. Really. I haven’t realized before I started this mini project. Beside its original goal to be a wireless replacement for cables, Bluetooth actually includes <a href="https://en.wikipedia.org/wiki/Bluetooth#List_of_applications">a myriad of features</a>.</p>
|
||
|
||
<p>In order to understand how we should connect to our Raspberry Pi (<em>RPi</em>), let’s focus on some core aspects of Bluetooth.</p>
|
||
|
||
<h3 id="bluetooth-security-models">Bluetooth security models</h3>
|
||
|
||
<p>Being tightly coupled with hardware, Bluetooth has evolved a lot since its beginnings, following industry’s technical enhancements over the years.
|
||
This is why it has so many <em>security models</em> ; let’s try to understand how they compare.</p>
|
||
|
||
<h4 id="there-are-two-distinct-branches-in-bluetooth">There are two distinct “branches” in Bluetooth.</h4>
|
||
|
||
<p>The legacy Bluetooth branch, <strong>“Basic Rate” (BR)</strong> was the first and only protocol in the beginning. It was quickly complemented with <em>EDR (Enhanced Data Rate)</em> in Bluetooth 2.0, hence the name <strong>BR/EDR</strong>.</p>
|
||
|
||
<p>Bluetooth 4.0 introduced another, not backward-compatible protocol : <strong>“Bluetooth Low Energy” (abbreviated LE, or BLE)</strong>. This new Bluetooth “branch” requires less energy and fits smartphones and <em>IoT</em> better.</p>
|
||
|
||
<p>Althought <em>BR/EDR</em> and <em>BLE</em> are not compatible with each other, Bluetooth devices can actually implement both.</p>
|
||
|
||
<p>For the record there is also an additional “AMP” specification to achieve Wi-Fi class transfer rates, usually implemented by a secondary electronic chip.</p>
|
||
|
||
<p>Each branch has its own security and association models, even though they all follow the same logic :</p>
|
||
|
||
<p><img class="plantuml" id="066cc5d2b2fa5d69148f35ff812fb260" alt="PlantUML diagram" src="/assets/uml/066cc5d2b2fa5d69148f35ff812fb260.svg" /></p>
|
||
|
||
<h4 id="which-security-level-to-choose-">Which security level to choose ?</h4>
|
||
|
||
<p>The Bluetooth Core Specification<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> makes it clear that :</p>
|
||
|
||
<blockquote>
|
||
<p>Secure Connections Only Mode is sometimes called a “FIPS Mode”.
|
||
This mode should be used when it is more important for a device to have high security than it is for it to maintain backwards compatibility with devices that do not support Secure Connections.</p>
|
||
</blockquote>
|
||
|
||
<p>My feeling reading the specifications is that Bluetooth was not made with high expectations on security from the beginning. It has so many trade-offs at the benefit of usability that <em>Secure Connections</em>, whether for BR/EDR or LE, just looks to me like the bare minimum to have.</p>
|
||
|
||
<p><em>BR/EDR Legacy Pairing</em>’s security for instance <em>unavoidably depends</em> on the length of the PIN (which is often a small four-digit number, or even a fixed value) and provide little-to-none protection against <a href="https://en.wikipedia.org/wiki/Eavesdropping">eavesdropping</a> or <a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">man-in-the-middle (MITM) attacks</a>.
|
||
<em>Secure Simple Pairing</em> for its part only <em>“protects the user from MITM attacks with a goal of offering a 1 in 1,000,000 chance that a MITM could mount a successful attack<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup>“</em>. <strong>It strongly relies on human decision (based on warning messages in case of an attack) to mitigate risks and allows for configurations that <em>can</em> make it unsecure</strong>.
|
||
In short, it’s easy to configure it wrong and let the neighbors accidentally connect to your Bluetooth device and maybe gather personal informations.</p>
|
||
|
||
<p>Also, “LE is the new BR/EDR”. Indeed, most efforts seem to be put on Bluetooth LE as Bluetooh BR/EDR lacks behind, not keeping up with today’s requirements. For instance : with BR/EDR, cryptographic key generation is being made in lower, often hardware, layers, making it difficult to upgrade security algorithms.
|
||
<strong>This leaves us with a plethora of insecure devices in the wild.</strong></p>
|
||
|
||
<p><strong>👉 Wrapping up, this gives the “LE Secure Connections” mode my preference.</strong></p>
|
||
|
||
<h3 id="bluetooth-association-models">Bluetooth association models</h3>
|
||
|
||
<p>As advertised in the above diagram, each security model allows a number of <em>association models</em>.
|
||
There are four of them available since <em>Secure Simple Pairing</em> :</p>
|
||
|
||
<ul>
|
||
<li><strong>Numeric Comparison</strong> (since Bluetooth 4.2 for BLE)</li>
|
||
<li><strong>Just Works</strong></li>
|
||
<li><strong>Passkey entry</strong></li>
|
||
<li><strong>Out-of-Band (OOB)</strong></li>
|
||
</ul>
|
||
|
||
<p>For the sake of completeness we will also talk about <strong>BR/EDR Legacy pairing</strong>.</p>
|
||
|
||
<p>Let’s see how they work, and how well they would fit our use case.</p>
|
||
|
||
<h4 id="numeric-comparison">Numeric comparison</h4>
|
||
|
||
<p>The Bluetooth Core Specification<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup> has a very neat way to describe the <em>Numeric Comparison</em> model :</p>
|
||
|
||
<blockquote>
|
||
<p>The user is shown a six digit number (from “000000” to “999999”) on both
|
||
displays and then asked whether the numbers are the same on both devices. If
|
||
“yes” is entered on both devices, the pairing is successful.</p>
|
||
</blockquote>
|
||
|
||
<p>It is important to understand that <em>this number is not chosen</em> by any party : it is randomly computed on each connection attempt, as part of the pairing algorithm<sup id="fnref:4"><a href="#fn:4" class="footnote" rel="footnote" role="doc-noteref">4</a></sup>. <em>It is not a passcode</em> either : it just helps users check that they pair to the expected device by showing the same value on both sides. A malicious user trying to penetrate our home would just have to initiate pairing, hit “Yes” on its side and hope we would do the same, not really looking at the number.</p>
|
||
|
||
<p>The <em>Numeric Comparison</em> protocol also allows devices to skip user confirmation<sup id="fnref:4:1"><a href="#fn:4" class="footnote" rel="footnote" role="doc-noteref">4</a></sup>, implementing automatic pairing. In this case anyone within reach of such a device can connect. End.</p>
|
||
|
||
<p>As we’ll see later, you may not have a choice and be forced into a model due to devices limitations. In our case we will need to make sure the Raspberry Pi will not offer this kind of bypass.</p>
|
||
|
||
<h4 id="just-works">Just works</h4>
|
||
|
||
<p>The <em>Just Works</em> model is a specific case of <em>Numeric Comparison</em> designed for the case where at least one device in the pair has no human interface at all.
|
||
Therefore, it does not enforce any confirmation whatsoever.</p>
|
||
|
||
<p>Here is an excerpt from the specifications<sup id="fnref:3:1"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup> :</p>
|
||
|
||
<blockquote>
|
||
<p>The Just Works association model uses the Numeric Comparison protocol but
|
||
the user is never shown a number and the application may simply ask the user
|
||
to accept the connection (exact implementation is up to the end product
|
||
manufacturer).</p>
|
||
</blockquote>
|
||
|
||
<p>As for <em>Numeric Comparison</em>, it may still be a good candidate for our use case, provided that we add a mandatory confirmation step, as allowed.</p>
|
||
|
||
<h4 id="passkey-entry">Passkey Entry</h4>
|
||
|
||
<p><em>Passkey Entry</em> is used when one of the devices has input capabilities but no display (e.g. a keyboard).</p>
|
||
|
||
<p>A six-digit number is displayed on the device that can display and must be entered on the other one for the pairing to be successful.</p>
|
||
|
||
<p>At the difference of <em>Numeric Comparison</em>, this number is not only here to check that the devices are the ones we intend to pair, but it also serves as an input data <em>required</em> to authenticate and validate the association<sup id="fnref:4:2"><a href="#fn:4" class="footnote" rel="footnote" role="doc-noteref">4</a></sup> <sup id="fnref:5"><a href="#fn:5" class="footnote" rel="footnote" role="doc-noteref">5</a></sup>.</p>
|
||
|
||
<p>In contrast with <em>Numeric Comparison</em>, this model does not allow automatic connection because each side has to prove they know the <em>passkey</em> :</p>
|
||
|
||
<ul>
|
||
<li>the <em>display device</em> is the only one to know the number in the beginning ; it decides the way the <em>passkey</em> is revealed to the other one</li>
|
||
<li>the <em>input-only device</em> must enter the (supposedly secret) <em>passkey</em></li>
|
||
</ul>
|
||
|
||
<p>In the case of a headless Raspberry Pi :</p>
|
||
|
||
<ul>
|
||
<li>if it were the <em>display device</em>, we could plug a mini display on it, or make it <em>speak</em> the code through the Hi-Fi system, to provide it to the user</li>
|
||
<li>if it were the <em>input-only device</em>, we should find a way to get the number displayed on the other device entered into the RPi (maybe letting the user type it)</li>
|
||
</ul>
|
||
|
||
<p>This may not look trivial ; we’ll see what can be done later on…</p>
|
||
|
||
<h4 id="out-of-band-oob">Out of Band (OOB)</h4>
|
||
|
||
<p>With <a href="https://www.bluetooth.com/blog/bluetooth-pairing-part-5-legacy-pairing-out-of-band/">Out of Band</a>, the devices first discover (and optionally authenticate) themselves with a different mechanism than Bluetooth. It can be any protocol, like NFC or Wi-Fi for instance.</p>
|
||
|
||
<p>This fits well when both devices are known to share a common mechanism and are explicitly set up to work in this way. For instance a camera and its manufacturer’s mobile application will both be programmed to connect with NFC first, then share their “services” through Bluetooth.</p>
|
||
|
||
<p>But this does not fit our use case, as we want to allow most smartphones - with only standard applications - to connect.
|
||
Furthermore, we want to leverage on existing Bluetooth capabilites, not invent new ones…</p>
|
||
|
||
<h4 id="bredr-models">BR/EDR models</h4>
|
||
|
||
<p>The four previous models also apply to the BR/EDR side, with some subtle differences in their implementation (not covered here)…</p>
|
||
|
||
<p>The last model, <strong>BR/EDR Legacy pairing</strong>, only applies to BR/EDR. It is outdated but was the only association model before Bluetooth 2.1 and therefore is very probably still there because of older devices.</p>
|
||
|
||
<p>It requires the two devices to enter the same, 16-character maximum, secret PIN code.</p>
|
||
|
||
<p>Although it looks similar to <em>Passkey Entry</em>, it is far less secure because, here, the connection’s encryption directly depends on the complexity of the PIN. <a href="https://thesecurityfactory.be/password-cracking-speed/">Nowadays, passwords less than 7 characters (including special ones) can be cracked instantly, it requires a maximum of 4 hours and 100$ for a 16-<em>digit</em> PIN</a>…</p>
|
||
|
||
<p>What sounds like a practical idea to implement on headless devices with a static PIN, unfortunately reveals to be largely insecure. The underlying cryptography is just not strong enough to compensate weak PIN codes that have been hardcoded on existing devices…</p>
|
||
|
||
<p>It is therefore not considered a potential solution in this article.</p>
|
||
|
||
<h3 id="choosing-the-right-association-model">Choosing the right association model</h3>
|
||
|
||
<p>I’ve chosen the three following factors to compare BLE association models regarding my use case :</p>
|
||
|
||
<ol>
|
||
<li>User authentication but with simple interaction (e.g. no SSH login to type a passkey)</li>
|
||
<li>Must be able to control who can connect to the Raspberry Pi (i.e. only known device or manually approved ones)</li>
|
||
<li>Secure enough (as much as Bluetooth can)</li>
|
||
</ol>
|
||
|
||
<p>Let’s summarize what we’ve asserted in the previous chapter :</p>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th> </th>
|
||
<th>Numeric comparison*</th>
|
||
<th>Just Works</th>
|
||
<th>Passkey Entry</th>
|
||
<th>Out of Band</th>
|
||
<th>BR/EDR Legacy Pairing</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>User interaction needed</td>
|
||
<td>yes ✅</td>
|
||
<td>no ❌</td>
|
||
<td>yes ✅</td>
|
||
<td>possible ✅</td>
|
||
<td>yes ✅</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Control who can connect</td>
|
||
<td>no ❌<br />(random number)</td>
|
||
<td>no ❌</td>
|
||
<td>yes ✅<br />(shared passkey)</td>
|
||
<td>possible ✅</td>
|
||
<td>yes ✅</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Secure-enough protocol</td>
|
||
<td>yes ✅</td>
|
||
<td>yes ✅</td>
|
||
<td>yes ✅</td>
|
||
<td>yes** ✅</td>
|
||
<td>no ❌</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p><em>* without automatic pairing</em>
|
||
<em>** possibly more than others<sup id="fnref:6"><a href="#fn:6" class="footnote" rel="footnote" role="doc-noteref">6</a></sup></em></p>
|
||
|
||
<p>This tables depicts the fact that the only way to <em>control who can connect</em> is by requiring the user to enter some - not random - key. Cells indicating “no user interaction” imply that there is no approval.</p>
|
||
|
||
<p>As discussed before, <em>Out of Band</em> is eliminated because it requires an additional protocol and <em>BR/EDR Legacy Pairing</em> is irrelevant for security reasons.</p>
|
||
|
||
<p>👉 In order to get all our three requirements statisfied we may therefore use :</p>
|
||
|
||
<ul>
|
||
<li><strong>Numeric Comparison, but with a custom headless validation step</strong></li>
|
||
<li><strong>Just Works, but with additional custom authorization</strong></li>
|
||
<li><strong>Passkey Entry</strong> by implementing a headless mechanism to display and validate a 6-digit number</li>
|
||
</ul>
|
||
|
||
<p>Unfortunately, except for <em>BR/EDR Legacy Pairing</em> <strong>one cannot directly <em>choose</em> the association model : it is automatically asserted from the devices’ <a href="https://www.bluetooth.com/blog/bluetooth-pairing-part-1-pairing-feature-exchange/"><em>Input and Output capabilities (IO capabilities)</em></a><sup id="fnref:7"><a href="#fn:7" class="footnote" rel="footnote" role="doc-noteref">7</a></sup></strong>.</p>
|
||
|
||
<p>In order to make sure only approved workflows can be used, our RPi device must therefore advertise only the corresponding IO capabilites.</p>
|
||
|
||
<p>How ? There are full-blown tables<sup id="fnref:3:2"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup> mapping the available IO capabilities to the matching association models.</p>
|
||
|
||
<p>The <strong>input capabilites</strong> are :</p>
|
||
<ul>
|
||
<li><strong>No input</strong> : Device does not have the ability to indicate ‘yes’ or ‘no’</li>
|
||
<li><strong>Yes / No</strong> : Device provides the user a way to indicate either ‘yes’ or ‘no’</li>
|
||
<li><strong>Keyboard</strong> : Device allows the user to input numbers <em>and</em> to indicate ‘yes’ or ‘no’</li>
|
||
</ul>
|
||
|
||
<p>And the <strong>output capabilities</strong> are :</p>
|
||
<ul>
|
||
<li><strong>No output</strong> : Device does not have the ability to display or communicate a
|
||
6 digit decimal number</li>
|
||
<li><strong>Numeric output</strong> : Device has the ability to display or communicate a 6 digit decimal number</li>
|
||
</ul>
|
||
|
||
<p>Here is an overview of the <strong>IO capabilities mapping to the matching association models</strong> :</p>
|
||
|
||
<table>
|
||
<caption>Mapping of IO capabilities to key generation method (simplified)</caption>
|
||
<colgroup>
|
||
<col class="col-header" />
|
||
<col class="col-header" />
|
||
</colgroup>
|
||
<tr>
|
||
<td colspan="2" class="empty" />
|
||
<th colspan="5">Device A (Initiator)</th>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="2" class="empty" />
|
||
<th>
|
||
Display Only <br /><span class="small">
|
||
(No input + Numeric output) </span></th>
|
||
<th class="cell-selected">
|
||
Display YesNo <br /><span class="small">
|
||
(Yes/No + Numeric output) </span></th>
|
||
<th>
|
||
Keyboard Only <br /><span class="small">
|
||
(Keyboard + No output) </span></th>
|
||
<th class="cell-noinputnooutput">
|
||
NoInput NoOutput <br /><span class="small">
|
||
(No input or Yes/No + No output) </span></th>
|
||
<th class="cell-selected">
|
||
Keyboard Display <br /><span class="small">
|
||
(Keyboard + Numeric output) </span></th>
|
||
</tr>
|
||
<!-- Row for DisplayOnly -->
|
||
<tr>
|
||
<th class="vertical" rowspan="5"><span>Device B (Responder)</span></th>
|
||
<th class="vertical"><span>Display Only</span></th>
|
||
<td>Just Works</td>
|
||
<td class="cell-selected">Just Works</td>
|
||
<td>Passkey Entry : responder displays, initiator inputs</td>
|
||
<td class="cell-noinputnooutput">Just Works</td>
|
||
<td class="cell-selected">Passkey Entry : responder displays, initiator inputs</td>
|
||
</tr>
|
||
<!-- Row for DisplayYesNo -->
|
||
<tr>
|
||
<th class="vertical"><span>Display YesNo</span></th>
|
||
<td>Just Works</td>
|
||
<td class="cell-selected">Numeric Comparison</td>
|
||
<td>Passkey Entry : responder displays, initiator inputs</td>
|
||
<td class="cell-noinputnooutput">Just Works</td>
|
||
<td class="cell-selected">Numeric Comparison</td>
|
||
</tr>
|
||
<!-- Row for KeyboardOnly -->
|
||
<tr>
|
||
<th class="vertical"><span>Keyboard Only</span></th>
|
||
<td>Passkey Entry: initiator displays, responder inputs</td>
|
||
<td class="cell-selected">Passkey Entry: initiator displays, responder inputs</td>
|
||
<td>Passkey Entry: both input</td>
|
||
<td class="cell-noinputnooutput">Just Works</td>
|
||
<td class="cell-selected">Passkey Entry: initiator displays, responder inputs</td>
|
||
</tr>
|
||
<!-- Row for NoInputNoOutput -->
|
||
<tr>
|
||
<th class="vertical"><span>NoInput NoOutput</span></th>
|
||
<td class="cell-noinputnooutput">Just Works</td>
|
||
<td class="cell-selected cell-noinputnooutput">Just Works</td>
|
||
<td class="cell-noinputnooutput">Just Works</td>
|
||
<td class="cell-noinputnooutput">Just Works</td>
|
||
<td class="cell-selected cell-noinputnooutput">Just Works</td>
|
||
</tr>
|
||
<!-- Row for KeyboardDisplay -->
|
||
<tr>
|
||
<th class="vertical"><span>Keyboard Display</span></th>
|
||
<td>Passkey Entry: initiator displays, responder inputs</td>
|
||
<td class="cell-selected">Numeric Comparison</td>
|
||
<td>Passkey Entry: responder displays, initiator inputs</td>
|
||
<td class="cell-noinputnooutput">Just Works</td>
|
||
<td class="cell-selected">Numeric Comparison</td>
|
||
</tr>
|
||
</table>
|
||
<p><em>Source : Mapping of IO capabilities to key generation method<sup id="fnref:7:1"><a href="#fn:7" class="footnote" rel="footnote" role="doc-noteref">7</a></sup> (without OOB nor LE Legacy Pairing)</em></p>
|
||
|
||
<p>Assuming smartphones would advertise themselves either as <em>DisplayYesNo</em> or <em>KeyboardDisplay</em> (highlighted cells), the above matrix shows that we should prepare to connect using any association model of “Numeric Comparison”, “Just works” or “Passkey entry”.</p>
|
||
|
||
<p>Additionally, this table emphasizes that <strong>a device may enforce the <em>Just Works</em> model</strong> simply by advertising itself as <em>NoInputNoOutput</em>. Although this makes it easier for the Industry to build devices with limited or no interface, this is also a leverage for pirates ☠ to force our system into a lower security.</p>
|
||
|
||
<p>We have the possibility to deny any pairing in the <em>Just Works</em> workflow, but this may prevent some genuine devices to connect : we should rather enforce a validation step. The main difference between “Just Works + validation” and other workflows would be the use of a custom authentication mechanism instead of a six-digit number verification.</p>
|
||
|
||
<h3 id="putting-it-altogether-with-bluez">Putting it altogether with BlueZ</h3>
|
||
|
||
<p>Now that we know <em>what</em> we should do in our solution, let’s have an overiew of <em>how</em> to implement it.</p>
|
||
|
||
<p>Linux systems (which we will use for our Raspberry Pi) have a complex Bluetooth stack, but we will only need to focus on the following parts :</p>
|
||
|
||
<ul>
|
||
<li>the <a href="http://www.bluez.org/">BlueZ</a> system daemon will handle core Bluetooth features</li>
|
||
<li>modules will allow us to connect with specialized services : ALSA/PulseAudio in our case in order to receive and play sound from paired devices</li>
|
||
<li>a registration <strong>agent</strong> will handle the pairing part as we like <strong>=> this is where we will put any custom authorization step</strong></li>
|
||
</ul>
|
||
|
||
<p>Having the Bluez daemon and the audio modules work together is only a matter of configuration (which is already not trivial).</p>
|
||
|
||
<p>However I could not find a bluetooth agent matching my use case :</p>
|
||
<ul>
|
||
<li>the default agent <a href="https://unix.stackexchange.com/questions/352494/alternative-to-the-now-deprecated-rfcomm-binary-in-bluez#463502"><code class="language-plaintext highlighter-rouge">bt-agent</code> has been deprecated</a></li>
|
||
<li>the <code class="language-plaintext highlighter-rouge">bluetoothctl</code> command cannot easily be used in scripts</li>
|
||
<li>the quite common <code class="language-plaintext highlighter-rouge">simple-agent</code> sample script does not implement the right features…</li>
|
||
</ul>
|
||
|
||
<h4 id="conclusion">Conclusion</h4>
|
||
|
||
<p>Bluetooth does not provide a secure and automatic way to pair with headless devices out of the box.</p>
|
||
|
||
<p>The existence of several association models with complex selection rules make it easy to get it wrong.</p>
|
||
|
||
<p>We will use the <em>bluez</em> Linux stack to implement the basis of our solution and will need to create a custom agent to add secure-enough authorization to the existing pairing workflows.</p>
|
||
|
||
<p><strong>Part 1 is over, let’s see how to set up the whole thing in part 2 : “Raspberry Pi as a Bluetooth A2DP receiver” (soon available).</strong></p>
|
||
|
||
<h2 id="references">References</h2>
|
||
|
||
<ul>
|
||
<li>Top illustration : <a href="https://commons.wikimedia.org/wiki/File:Bluetooth_FM_Color.png">Bluetooth.svg by Skarr21</a> / <a href="https://creativecommons.org/licenses/by-sa/4.0">CC BY-SA</a></li>
|
||
<li><a href="https://www.bluetooth.com/blog/bluetooth-pairing-part-1-pairing-feature-exchange/">Bluetooth Pairing Part 1 – Pairing Feature Exchange</a></li>
|
||
<li><a href="https://www.bluetooth.com/blog/bluetooth-pairing-part-2-key-generation-methods/">Bluetooth Pairing Part 2 Key Generation Methods</a></li>
|
||
<li><a href="https://www.bluetooth.com/blog/bluetooth-pairing-passkey-entry/?utm_campaign=developer&utm_source=internal&utm_medium=blog&utm_content=bluetooth-pairing-part-4-LE-secure-connections-numeric-comparison">Bluetooth Pairing Part 3 – Low Energy Legacy Pairing Passkey Entry</a></li>
|
||
<li><a href="https://www.bluetooth.com/blog/bluetooth-pairing-part-4/?utm_campaign=developer&utm_source=internal&utm_medium=blog&utm_content=bluetooth-pairing-part-3-low-energy-legacy-pairing-passkey-entry">Bluetooth Pairing Part 4: Bluetooth Low Energy Secure Connections – Numeric Comparison</a></li>
|
||
<li><a href="https://www.bluetooth.com/specifications/bluetooth-core-specification/">Bluetooth Core Specification v5.2</a></li>
|
||
<li><a href="https://en.wikipedia.org/wiki/Bluetooth#Pairing_and_bonding">en.wikipedia.org/wiki/Bluetooth</a>, 2020-04-10</li>
|
||
</ul>
|
||
|
||
<h3 id="bluetooth-core-specification-inline-references">Bluetooth Core specification inline references</h3>
|
||
|
||
<div class="footnotes" role="doc-endnotes">
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>Bluetooth Core specification Vol 1, Part A, §5.3 “SECURE CONNECTIONS ONLY MODE” <a href="#fnref:1" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>Bluetooth Core specification Vol 1, Part A, §5.2 “BR/EDR SECURE SIMPLE PAIRING” <a href="#fnref:2" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:3">
|
||
<p>Bluetooth Core specification Vol 3, Part C, §5.2.2.4 “IO capabilities” <a href="#fnref:3" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:3:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a> <a href="#fnref:3:2" class="reversefootnote" role="doc-backlink">↩<sup>3</sup></a></p>
|
||
</li>
|
||
<li id="fn:4">
|
||
<p>Bluetooth Core specification Vol 2, Part F, §4.2 “SIMPLE PAIRING MESSAGE SEQUENCE CHARTS” <a href="#fnref:4" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:4:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a> <a href="#fnref:4:2" class="reversefootnote" role="doc-backlink">↩<sup>3</sup></a></p>
|
||
</li>
|
||
<li id="fn:5">
|
||
<p>Bluetooth Core specification Vol 2, Part H, §7.2.3 “Authentication stage 1: Passkey Entry protocol” <a href="#fnref:5" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:6">
|
||
<p>Bluetooth Core specification Vol 3, Part H, §2.3.5.4 “Out of band” <a href="#fnref:6" class="reversefootnote" role="doc-backlink">↩</a></p>
|
||
</li>
|
||
<li id="fn:7">
|
||
<p>Bluetooth Core specification Vol 3, Part H, §2.3.2 “IO capabilities” <a href="#fnref:7" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:7:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
|
||
</li>
|
||
</ol>
|
||
</div>]]></content><author><name>nicobo</name></author><category term="raspberry pi" /><category term="bluetooth" /><category term="Series : Make a Raspberry Pi a Bluetooth speaker" /><summary type="html"><![CDATA[In this two-part article I describe the steps I had to take to make a headless Raspberry Pi 4 a Bluetooth A2DP speaker. My goal was to offer a user-friendly way for anyone in the same room to pair its Bluetooth smartphone with the Raspberry Pi and play music through it, while making sure the neighbors won’t be able to connect without approval. To output music, you can connect a Hi-Fi system to the Raspberry Pi using the Jack plug or an audio add-on card : this part depends on your setup. Allright, let’s dive into how Bluetooth works. This is a two-part article : How Bluetooth pairing works (this part) Raspberry Pi as a Bluetooth A2DP receiver (soon available) How Bluetooth pairing works Bluetooth is quite a complex thing. Really. I haven’t realized before I started this mini project. Beside its original goal to be a wireless replacement for cables, Bluetooth actually includes a myriad of features. In order to understand how we should connect to our Raspberry Pi (RPi), let’s focus on some core aspects of Bluetooth. Bluetooth security models Being tightly coupled with hardware, Bluetooth has evolved a lot since its beginnings, following industry’s technical enhancements over the years. This is why it has so many security models ; let’s try to understand how they compare. There are two distinct “branches” in Bluetooth. The legacy Bluetooth branch, “Basic Rate” (BR) was the first and only protocol in the beginning. It was quickly complemented with EDR (Enhanced Data Rate) in Bluetooth 2.0, hence the name BR/EDR. Bluetooth 4.0 introduced another, not backward-compatible protocol : “Bluetooth Low Energy” (abbreviated LE, or BLE). This new Bluetooth “branch” requires less energy and fits smartphones and IoT better. Althought BR/EDR and BLE are not compatible with each other, Bluetooth devices can actually implement both. For the record there is also an additional “AMP” specification to achieve Wi-Fi class transfer rates, usually implemented by a secondary electronic chip. Each branch has its own security and association models, even though they all follow the same logic : Which security level to choose ? The Bluetooth Core Specification1 makes it clear that : Secure Connections Only Mode is sometimes called a “FIPS Mode”. This mode should be used when it is more important for a device to have high security than it is for it to maintain backwards compatibility with devices that do not support Secure Connections. My feeling reading the specifications is that Bluetooth was not made with high expectations on security from the beginning. It has so many trade-offs at the benefit of usability that Secure Connections, whether for BR/EDR or LE, just looks to me like the bare minimum to have. BR/EDR Legacy Pairing’s security for instance unavoidably depends on the length of the PIN (which is often a small four-digit number, or even a fixed value) and provide little-to-none protection against eavesdropping or man-in-the-middle (MITM) attacks. Secure Simple Pairing for its part only “protects the user from MITM attacks with a goal of offering a 1 in 1,000,000 chance that a MITM could mount a successful attack2“. It strongly relies on human decision (based on warning messages in case of an attack) to mitigate risks and allows for configurations that can make it unsecure. In short, it’s easy to configure it wrong and let the neighbors accidentally connect to your Bluetooth device and maybe gather personal informations. Also, “LE is the new BR/EDR”. Indeed, most efforts seem to be put on Bluetooth LE as Bluetooh BR/EDR lacks behind, not keeping up with today’s requirements. For instance : with BR/EDR, cryptographic key generation is being made in lower, often hardware, layers, making it difficult to upgrade security algorithms. This leaves us with a plethora of insecure devices in the wild. 👉 Wrapping up, this gives the “LE Secure Connections” mode my preference. Bluetooth association models As advertised in the above diagram, each security model allows a number of association models. There are four of them available since Secure Simple Pairing : Numeric Comparison (since Bluetooth 4.2 for BLE) Just Works Passkey entry Out-of-Band (OOB) For the sake of completeness we will also talk about BR/EDR Legacy pairing. Let’s see how they work, and how well they would fit our use case. Numeric comparison The Bluetooth Core Specification3 has a very neat way to describe the Numeric Comparison model : The user is shown a six digit number (from “000000” to “999999”) on both displays and then asked whether the numbers are the same on both devices. If “yes” is entered on both devices, the pairing is successful. It is important to understand that this number is not chosen by any party : it is randomly computed on each connection attempt, as part of the pairing algorithm4. It is not a passcode either : it just helps users check that they pair to the expected device by showing the same value on both sides. A malicious user trying to penetrate our home would just have to initiate pairing, hit “Yes” on its side and hope we would do the same, not really looking at the number. The Numeric Comparison protocol also allows devices to skip user confirmation4, implementing automatic pairing. In this case anyone within reach of such a device can connect. End. As we’ll see later, you may not have a choice and be forced into a model due to devices limitations. In our case we will need to make sure the Raspberry Pi will not offer this kind of bypass. Just works The Just Works model is a specific case of Numeric Comparison designed for the case where at least one device in the pair has no human interface at all. Therefore, it does not enforce any confirmation whatsoever. Here is an excerpt from the specifications3 : The Just Works association model uses the Numeric Comparison protocol but the user is never shown a number and the application may simply ask the user to accept the connection (exact implementation is up to the end product manufacturer). As for Numeric Comparison, it may still be a good candidate for our use case, provided that we add a mandatory confirmation step, as allowed. Passkey Entry Passkey Entry is used when one of the devices has input capabilities but no display (e.g. a keyboard). A six-digit number is displayed on the device that can display and must be entered on the other one for the pairing to be successful. At the difference of Numeric Comparison, this number is not only here to check that the devices are the ones we intend to pair, but it also serves as an input data required to authenticate and validate the association4 5. In contrast with Numeric Comparison, this model does not allow automatic connection because each side has to prove they know the passkey : the display device is the only one to know the number in the beginning ; it decides the way the passkey is revealed to the other one the input-only device must enter the (supposedly secret) passkey In the case of a headless Raspberry Pi : if it were the display device, we could plug a mini display on it, or make it speak the code through the Hi-Fi system, to provide it to the user if it were the input-only device, we should find a way to get the number displayed on the other device entered into the RPi (maybe letting the user type it) This may not look trivial ; we’ll see what can be done later on… Out of Band (OOB) With Out of Band, the devices first discover (and optionally authenticate) themselves with a different mechanism than Bluetooth. It can be any protocol, like NFC or Wi-Fi for instance. This fits well when both devices are known to share a common mechanism and are explicitly set up to work in this way. For instance a camera and its manufacturer’s mobile application will both be programmed to connect with NFC first, then share their “services” through Bluetooth. But this does not fit our use case, as we want to allow most smartphones - with only standard applications - to connect. Furthermore, we want to leverage on existing Bluetooth capabilites, not invent new ones… BR/EDR models The four previous models also apply to the BR/EDR side, with some subtle differences in their implementation (not covered here)… The last model, BR/EDR Legacy pairing, only applies to BR/EDR. It is outdated but was the only association model before Bluetooth 2.1 and therefore is very probably still there because of older devices. It requires the two devices to enter the same, 16-character maximum, secret PIN code. Although it looks similar to Passkey Entry, it is far less secure because, here, the connection’s encryption directly depends on the complexity of the PIN. Nowadays, passwords less than 7 characters (including special ones) can be cracked instantly, it requires a maximum of 4 hours and 100$ for a 16-digit PIN… What sounds like a practical idea to implement on headless devices with a static PIN, unfortunately reveals to be largely insecure. The underlying cryptography is just not strong enough to compensate weak PIN codes that have been hardcoded on existing devices… It is therefore not considered a potential solution in this article. Choosing the right association model I’ve chosen the three following factors to compare BLE association models regarding my use case : User authentication but with simple interaction (e.g. no SSH login to type a passkey) Must be able to control who can connect to the Raspberry Pi (i.e. only known device or manually approved ones) Secure enough (as much as Bluetooth can) Let’s summarize what we’ve asserted in the previous chapter : Numeric comparison* Just Works Passkey Entry Out of Band BR/EDR Legacy Pairing User interaction needed yes ✅ no ❌ yes ✅ possible ✅ yes ✅ Control who can connect no ❌(random number) no ❌ yes ✅(shared passkey) possible ✅ yes ✅ Secure-enough protocol yes ✅ yes ✅ yes ✅ yes** ✅ no ❌ * without automatic pairing ** possibly more than others6 This tables depicts the fact that the only way to control who can connect is by requiring the user to enter some - not random - key. Cells indicating “no user interaction” imply that there is no approval. As discussed before, Out of Band is eliminated because it requires an additional protocol and BR/EDR Legacy Pairing is irrelevant for security reasons. 👉 In order to get all our three requirements statisfied we may therefore use : Numeric Comparison, but with a custom headless validation step Just Works, but with additional custom authorization Passkey Entry by implementing a headless mechanism to display and validate a 6-digit number Unfortunately, except for BR/EDR Legacy Pairing one cannot directly choose the association model : it is automatically asserted from the devices’ Input and Output capabilities (IO capabilities)7. In order to make sure only approved workflows can be used, our RPi device must therefore advertise only the corresponding IO capabilites. How ? There are full-blown tables3 mapping the available IO capabilities to the matching association models. The input capabilites are : No input : Device does not have the ability to indicate ‘yes’ or ‘no’ Yes / No : Device provides the user a way to indicate either ‘yes’ or ‘no’ Keyboard : Device allows the user to input numbers and to indicate ‘yes’ or ‘no’ And the output capabilities are : No output : Device does not have the ability to display or communicate a 6 digit decimal number Numeric output : Device has the ability to display or communicate a 6 digit decimal number Here is an overview of the IO capabilities mapping to the matching association models : Mapping of IO capabilities to key generation method (simplified) Device A (Initiator) Display Only (No input + Numeric output) Display YesNo (Yes/No + Numeric output) Keyboard Only (Keyboard + No output) NoInput NoOutput (No input or Yes/No + No output) Keyboard Display (Keyboard + Numeric output) Device B (Responder) Display Only Just Works Just Works Passkey Entry : responder displays, initiator inputs Just Works Passkey Entry : responder displays, initiator inputs Display YesNo Just Works Numeric Comparison Passkey Entry : responder displays, initiator inputs Just Works Numeric Comparison Keyboard Only Passkey Entry: initiator displays, responder inputs Passkey Entry: initiator displays, responder inputs Passkey Entry: both input Just Works Passkey Entry: initiator displays, responder inputs NoInput NoOutput Just Works Just Works Just Works Just Works Just Works Keyboard Display Passkey Entry: initiator displays, responder inputs Numeric Comparison Passkey Entry: responder displays, initiator inputs Just Works Numeric Comparison Source : Mapping of IO capabilities to key generation method7 (without OOB nor LE Legacy Pairing) Assuming smartphones would advertise themselves either as DisplayYesNo or KeyboardDisplay (highlighted cells), the above matrix shows that we should prepare to connect using any association model of “Numeric Comparison”, “Just works” or “Passkey entry”. Additionally, this table emphasizes that a device may enforce the Just Works model simply by advertising itself as NoInputNoOutput. Although this makes it easier for the Industry to build devices with limited or no interface, this is also a leverage for pirates ☠ to force our system into a lower security. We have the possibility to deny any pairing in the Just Works workflow, but this may prevent some genuine devices to connect : we should rather enforce a validation step. The main difference between “Just Works + validation” and other workflows would be the use of a custom authentication mechanism instead of a six-digit number verification. Putting it altogether with BlueZ Now that we know what we should do in our solution, let’s have an overiew of how to implement it. Linux systems (which we will use for our Raspberry Pi) have a complex Bluetooth stack, but we will only need to focus on the following parts : the BlueZ system daemon will handle core Bluetooth features modules will allow us to connect with specialized services : ALSA/PulseAudio in our case in order to receive and play sound from paired devices a registration agent will handle the pairing part as we like => this is where we will put any custom authorization step Having the Bluez daemon and the audio modules work together is only a matter of configuration (which is already not trivial). However I could not find a bluetooth agent matching my use case : the default agent bt-agent has been deprecated the bluetoothctl command cannot easily be used in scripts the quite common simple-agent sample script does not implement the right features… Conclusion Bluetooth does not provide a secure and automatic way to pair with headless devices out of the box. The existence of several association models with complex selection rules make it easy to get it wrong. We will use the bluez Linux stack to implement the basis of our solution and will need to create a custom agent to add secure-enough authorization to the existing pairing workflows. Part 1 is over, let’s see how to set up the whole thing in part 2 : “Raspberry Pi as a Bluetooth A2DP receiver” (soon available). References Top illustration : Bluetooth.svg by Skarr21 / CC BY-SA Bluetooth Pairing Part 1 – Pairing Feature Exchange Bluetooth Pairing Part 2 Key Generation Methods Bluetooth Pairing Part 3 – Low Energy Legacy Pairing Passkey Entry Bluetooth Pairing Part 4: Bluetooth Low Energy Secure Connections – Numeric Comparison Bluetooth Core Specification v5.2 en.wikipedia.org/wiki/Bluetooth, 2020-04-10 Bluetooth Core specification inline references Bluetooth Core specification Vol 1, Part A, §5.3 “SECURE CONNECTIONS ONLY MODE” ↩ Bluetooth Core specification Vol 1, Part A, §5.2 “BR/EDR SECURE SIMPLE PAIRING” ↩ Bluetooth Core specification Vol 3, Part C, §5.2.2.4 “IO capabilities” ↩ ↩2 ↩3 Bluetooth Core specification Vol 2, Part F, §4.2 “SIMPLE PAIRING MESSAGE SEQUENCE CHARTS” ↩ ↩2 ↩3 Bluetooth Core specification Vol 2, Part H, §7.2.3 “Authentication stage 1: Passkey Entry protocol” ↩ Bluetooth Core specification Vol 3, Part H, §2.3.5.4 “Out of band” ↩ Bluetooth Core specification Vol 3, Part H, §2.3.2 “IO capabilities” ↩ ↩2]]></summary></entry><entry><title type="html">Bypassing GitHub’s Jekyll limitations</title><link href="https://www.nicolabs.net/2020/Bypassing-GitHub-Jekyll-limitations" rel="alternate" type="text/html" title="Bypassing GitHub’s Jekyll limitations" /><published>2020-04-13T00:00:00+02:00</published><updated>2020-04-13T00:00:00+02:00</updated><id>https://www.nicolabs.net/2020/Bypassing-GitHub-Jekyll-limitations</id><content type="html" xml:base="https://www.nicolabs.net/2020/Bypassing-GitHub-Jekyll-limitations"><![CDATA[<p><img src="https://github.com/jekyll/brand/raw/master/jekyll-logo-dark-solid.png" alt="Jekyll logo - CC-BY-4.0 License" width="100%" /></p>
|
||
<figcaption>Jekyll logo - CC-BY-4.0 License - https://github.com/jekyll/brand</figcaption>
|
||
|
||
<p>As I feared when I <a href="/2016/Migrating-from-Drupal-to-Jekyll">migrated to GitHub’s hosting</a>, it has become too complicated to overcome GitHub’s limitations on Jekyll plugins and features.</p>
|
||
|
||
<p>I just needed to create a <a href="https://jekyllrb.com/docs/collections/"><em>collection</em></a> to put my <a href="/2016/Migrating-from-Drupal-to-Jekyll">“live drafts”</a> into it, but the deprecated <em>jekyll-paginate</em> plugin provided with GitHub pages didn’t support collections.</p>
|
||
|
||
<p>I therefore switched to offline-building my site and pushing the generated static files to GitHub, which now serves them without Jekyll processing. I still use Jekyll to generate the final static files, which is perfectly ok.
|
||
The only thing I’m missing a bit is automatic build & deploy after a minor edit from my android smartphone (using <a href="https://f-droid.org/fr/packages/net.gsantner.markor/">Markor</a> to edit and <a href="https://f-droid.org/fr/packages/com.manichord.mgit/">MGit</a> to push to GitHub). It might be solved with some Travis CI automation I guess…</p>
|
||
|
||
<p><a href="https://help.github.com/en/github/working-with-github-pages/about-github-pages#static-site-generators">GitHub’s documentation about this</a> is not very clear on the way one can still use <em>an autonomous</em> Jekyll installation to build offline, without them building the site with <strong>their</strong> locked-down Jekyll pipeline.
|
||
I assumed that I had to consider the procedure that applied to other tools. I had to :</p>
|
||
|
||
<ul>
|
||
<li>create a <code class="language-plaintext highlighter-rouge">.nojekyll</code> file in the root of the repo</li>
|
||
<li>change <a href="https://jekyllrb.com/docs/configuration/options/">Jekyll’s output directory</a> from <code class="language-plaintext highlighter-rouge">_site</code> to <code class="language-plaintext highlighter-rouge">docs</code></li>
|
||
<li>use the standard Jekyll dependencies in my <em>Gemfile</em> and specify the full <a href="https://github.com/github/pages-gem/blob/master/lib/github-pages/plugins.rb">list of plugins previously overwritten by github-pages</a> in <code class="language-plaintext highlighter-rouge">Gemfile</code> & <code class="language-plaintext highlighter-rouge">_config.yml</code></li>
|
||
<li>import and commit the code for the submodule <em>mastodon-timeline-widget</em> inside this repo, not only leaving the <code class="language-plaintext highlighter-rouge">.gitmodules</code> file (static Javascript files that are used in the site, which were pulled automatically during GitHub’s processing)</li>
|
||
<li>make sure a <code class="language-plaintext highlighter-rouge">docs/CNAME</code> text file containing the domain to serve is present after each build (I discovered <a href="https://github.com/mkdocs/mkdocs/pull/1497/commits">it is created when the custom domain is enabled on GitHub</a> ; unfortunately it is in the output <code class="language-plaintext highlighter-rouge">docs/</code> directory, which may legitimately be deleted with a simple <code class="language-plaintext highlighter-rouge">jekyll clean</code>)</li>
|
||
<li>I also had to change the name of the repo from <em>nicolabs.github.io</em> to <em>nicolabs.net</em> so it is not recognized as a user/organization repo, which was preventing me to put the code in a <code class="language-plaintext highlighter-rouge">docs</code> subdirectory (I already had an <code class="language-plaintext highlighter-rouge">index.html</code> which had to be processed by Jekyll in the repo’s root, and therefore the website’s root could not be placed here)</li>
|
||
</ul>
|
||
|
||
<p>Overall it was very easy and quick to migrate !</p>]]></content><author><name>nicobo</name></author><category term="blogging" /><category term="jekyll" /><category term="github" /><summary type="html"><![CDATA[Jekyll logo - CC-BY-4.0 License - https://github.com/jekyll/brand As I feared when I migrated to GitHub’s hosting, it has become too complicated to overcome GitHub’s limitations on Jekyll plugins and features. I just needed to create a collection to put my “live drafts” into it, but the deprecated jekyll-paginate plugin provided with GitHub pages didn’t support collections. I therefore switched to offline-building my site and pushing the generated static files to GitHub, which now serves them without Jekyll processing. I still use Jekyll to generate the final static files, which is perfectly ok. The only thing I’m missing a bit is automatic build & deploy after a minor edit from my android smartphone (using Markor to edit and MGit to push to GitHub). It might be solved with some Travis CI automation I guess… GitHub’s documentation about this is not very clear on the way one can still use an autonomous Jekyll installation to build offline, without them building the site with their locked-down Jekyll pipeline. I assumed that I had to consider the procedure that applied to other tools. I had to : create a .nojekyll file in the root of the repo change Jekyll’s output directory from _site to docs use the standard Jekyll dependencies in my Gemfile and specify the full list of plugins previously overwritten by github-pages in Gemfile & _config.yml import and commit the code for the submodule mastodon-timeline-widget inside this repo, not only leaving the .gitmodules file (static Javascript files that are used in the site, which were pulled automatically during GitHub’s processing) make sure a docs/CNAME text file containing the domain to serve is present after each build (I discovered it is created when the custom domain is enabled on GitHub ; unfortunately it is in the output docs/ directory, which may legitimately be deleted with a simple jekyll clean) I also had to change the name of the repo from nicolabs.github.io to nicolabs.net so it is not recognized as a user/organization repo, which was preventing me to put the code in a docs subdirectory (I already had an index.html which had to be processed by Jekyll in the repo’s root, and therefore the website’s root could not be placed here) Overall it was very easy and quick to migrate !]]></summary></entry><entry><title type="html">My favorite tools I want to tell the world about</title><link href="https://www.nicolabs.net/2019/My-favorite-tools-I-want-to-tell-the-world" rel="alternate" type="text/html" title="My favorite tools I want to tell the world about" /><published>2019-04-27T00:00:00+02:00</published><updated>2022-09-04T00:00:00+02:00</updated><id>https://www.nicolabs.net/2019/My-favorite-tools-I-want-to-tell-the-world</id><content type="html" xml:base="https://www.nicolabs.net/2019/My-favorite-tools-I-want-to-tell-the-world"><![CDATA[<p>This page lists some tools I’ve been using with success for a while : they may fit your needs as well !</p>
|
||
|
||
<h2 id="sweet-home-3d">Sweet Home 3D</h2>
|
||
|
||
<p><img src="https://www.sweethome3d.com/images/SweetHome3DLogo.png" alt="Sweet Home 3D logo" /></p>
|
||
|
||
<blockquote>
|
||
<p><a href="https://www.sweethome3d.com">Sweet Home 3D</a> is a free interior design application which helps you draw the plan of your house, arrange furniture on it and visit the results in 3D.</p>
|
||
</blockquote>
|
||
|
||
<p>And it works. I’ve been using it for years and I can still open the models, edit them… This is the exact reason why to choose open source here. No compatibility issue, works on Windows, Mac, Linux.</p>
|
||
|
||
<h2 id="nextcloud">NextCloud</h2>
|
||
|
||
<p><img src="/assets/blog/3rdparty/logos/nextcloud.108x72.png" alt="NextCloud logo" /></p>
|
||
|
||
<p><a href="https://nextcloud.com/">NextCloud</a> (a fork of <a href="https://owncloud.org/">OwnCloud</a>) is a very promising software that aims to bring usual cloud services to the home.</p>
|
||
|
||
<p>However, it’s based on pluggable features that are not always stable. Here are the ones I’m using on a day-to-day basis :</p>
|
||
|
||
<ul>
|
||
<li>web interface to <strong>access my own files</strong> (however synchronization, backup and other features on files are not yet usable in my opinion)</li>
|
||
<li><strong>share files</strong> with others</li>
|
||
<li><strong>calendar</strong> (coupled with DAVDroid and any Android calendar it has all features Google Calendar has, except event import from/sharing to email)</li>
|
||
<li><strong>contacts</strong> (really excellent)</li>
|
||
<li><strong>news</strong> (use with a RSS/Atom reader on your mobile)</li>
|
||
</ul>
|
||
|
||
<h2 id="plantuml">PlantUML</h2>
|
||
|
||
<p><img src="/assets/blog/3rdparty/logos/plantuml.116x112.png" alt="PlantUML logo" /></p>
|
||
|
||
<p><a href="https://plantuml.com/">PlantUML</a> is a very simple <strong>textual language to create diagrams</strong>.
|
||
You describe your diagram as plain text and use any of the provided tool to automatically render a picture.</p>
|
||
|
||
<p>It is very easy to learn and has integrations with <a href="https://plantuml.com/fr/running">A LOT</a> of tools.
|
||
As the diagrams are simple text blocks, you can save them in a version control system, diff’ them, embed them in other documents, copy/paste them in online tools to view and edit, …
|
||
It has several renderers out of the box like PNG, SVG, LaTeX ; you can even generate ASCII art sequence diagrams !</p>
|
||
|
||
<p>I use it at work in <em>maven</em> builds to generate technical or inline documentation, in <em>Atom</em> or <em>Visual Studio Code</em> for writing specifications, you can live-code architectures with colleagues, build deployment diagrams on the fly within a web page, …
|
||
You will also find several other tools not referenced from the main site but using the same language.</p>
|
||
|
||
<p>The main drawback is that you don’t control the way figures are laid out.
|
||
Even with the few tweaks available you may not be able to get a clear view with the biggest diagrams.</p>
|
||
|
||
<h2 id="twidere">Twidere</h2>
|
||
|
||
<p><img src="/assets/blog/3rdparty/logos/twidere.512x512.png" alt="Twidere logo" height="128px" /></p>
|
||
|
||
<p><a href="https://github.com/TwidereProject/Twidere-Android">Twidere</a> is definitely the only one, perfect, <strong>Twitter</strong> Android client for me (and I’ve been searching a lot).
|
||
It’s open source. It handles every single feature I need (disclaimer : I’m only a casual Twitter user).</p>
|
||
|
||
<p>I’ve been using it for years… And since it happens to be very good also at <strong>Mastodon</strong> I do continue to use it every day.</p>
|
||
|
||
<h2 id="wallabag">Wallabag</h2>
|
||
|
||
<p><img src="/assets/blog/3rdparty/logos/wallabag.200x69.png" alt="Wallabag logo" /></p>
|
||
|
||
<p><a href="https://wallabag.org">Wallabag</a> is an open source alternative to <em>Pocket</em>, <em>Instapaper</em>, … to save articles from the web and <strong>read them later</strong>.
|
||
There are integrations with web browsers and smartphones.
|
||
I’ve been adding and reading articles with wallabag for years : you don’t need another tool !</p>
|
||
|
||
<h2 id="more-tools">More tools</h2>
|
||
|
||
<p>The following ones are part of my toolbox, they will get a small description each in the future :</p>
|
||
|
||
<ul>
|
||
<li>Passwordstore
|
||
<ul>
|
||
<li>warning ! <a href="https://github.com/android-password-store/Android-Password-Store/issues/648">The f-droid version is far out of date</a>. It’s kind of tough to get a seamless integration with all tools (e.g. you have to get the very latest Android to benefit from Firefox mobile integration) but the simplicity of the mechanism (it’s nothing else than GPG-encrypted files possibly versioned with git) make it universal. I’m only doubtful about the community looking smaller than the one of the more graphical KeePass, which is a risk to see it unsupported in the future.</li>
|
||
<li>it can use git to pull & push changes to remote devices (the safest and most portable way I’ve found : it works in all clients I’ve tested : qtpass, Android, iOS), but not all apps provide the same user experience (e.g. <em>passforios</em> does not pull/push automatically, it’s just a button but still annoying). The best option here - because we talk about critical data like passwords - is to use a private git repository, which unfortunately requires setting up a server</li>
|
||
<li>or you can use SyncThing for a seamless synchronization, with its (see below)</li>
|
||
<li>Available apps are not official and therefore suffer from a different maturity ; e.g. <em>passforios</em> cannot generate SSH nor PGP keys by itself : it must import them (and <a href="https://pgpro.app/">PGPro</a> only works on iOS 13+)</li>
|
||
</ul>
|
||
</li>
|
||
<li>SyncThing is a very useful and generic decentralized (server-less) synchronization system for all your devices. However I couldn’t install it on iPhone and you can’t go without conflict files on a regular basis (which are just ok to delete 99% of the time however, so it’s fine in the end because it could not be done better after thinking about it)</li>
|
||
<li>ForceDoze (Android)</li>
|
||
<li>K-9 Mail</li>
|
||
<li>Silence</li>
|
||
<li>VLC</li>
|
||
<li>Markor (Android) / Bear (iOS)</li>
|
||
<li>FastHub-Libre</li>
|
||
<li>RadioDroid</li>
|
||
<li>AntennaPod</li>
|
||
<li>F-Droid</li>
|
||
</ul>]]></content><author><name>nicobo</name></author><category term="android" /><category term="cloud" /><category term="diagrams" /><category term="mastodon" /><category term="uml" /><category term="social" /><category term="tooling" /><category term="twitter" /><summary type="html"><![CDATA[This page lists some tools I’ve been using with success for a while : they may fit your needs as well ! Sweet Home 3D Sweet Home 3D is a free interior design application which helps you draw the plan of your house, arrange furniture on it and visit the results in 3D. And it works. I’ve been using it for years and I can still open the models, edit them… This is the exact reason why to choose open source here. No compatibility issue, works on Windows, Mac, Linux. NextCloud NextCloud (a fork of OwnCloud) is a very promising software that aims to bring usual cloud services to the home. However, it’s based on pluggable features that are not always stable. Here are the ones I’m using on a day-to-day basis : web interface to access my own files (however synchronization, backup and other features on files are not yet usable in my opinion) share files with others calendar (coupled with DAVDroid and any Android calendar it has all features Google Calendar has, except event import from/sharing to email) contacts (really excellent) news (use with a RSS/Atom reader on your mobile) PlantUML PlantUML is a very simple textual language to create diagrams. You describe your diagram as plain text and use any of the provided tool to automatically render a picture. It is very easy to learn and has integrations with A LOT of tools. As the diagrams are simple text blocks, you can save them in a version control system, diff’ them, embed them in other documents, copy/paste them in online tools to view and edit, … It has several renderers out of the box like PNG, SVG, LaTeX ; you can even generate ASCII art sequence diagrams ! I use it at work in maven builds to generate technical or inline documentation, in Atom or Visual Studio Code for writing specifications, you can live-code architectures with colleagues, build deployment diagrams on the fly within a web page, … You will also find several other tools not referenced from the main site but using the same language. The main drawback is that you don’t control the way figures are laid out. Even with the few tweaks available you may not be able to get a clear view with the biggest diagrams. Twidere Twidere is definitely the only one, perfect, Twitter Android client for me (and I’ve been searching a lot). It’s open source. It handles every single feature I need (disclaimer : I’m only a casual Twitter user). I’ve been using it for years… And since it happens to be very good also at Mastodon I do continue to use it every day. Wallabag Wallabag is an open source alternative to Pocket, Instapaper, … to save articles from the web and read them later. There are integrations with web browsers and smartphones. I’ve been adding and reading articles with wallabag for years : you don’t need another tool ! More tools The following ones are part of my toolbox, they will get a small description each in the future : Passwordstore warning ! The f-droid version is far out of date. It’s kind of tough to get a seamless integration with all tools (e.g. you have to get the very latest Android to benefit from Firefox mobile integration) but the simplicity of the mechanism (it’s nothing else than GPG-encrypted files possibly versioned with git) make it universal. I’m only doubtful about the community looking smaller than the one of the more graphical KeePass, which is a risk to see it unsupported in the future. it can use git to pull & push changes to remote devices (the safest and most portable way I’ve found : it works in all clients I’ve tested : qtpass, Android, iOS), but not all apps provide the same user experience (e.g. passforios does not pull/push automatically, it’s just a button but still annoying). The best option here - because we talk about critical data like passwords - is to use a private git repository, which unfortunately requires setting up a server or you can use SyncThing for a seamless synchronization, with its (see below) Available apps are not official and therefore suffer from a different maturity ; e.g. passforios cannot generate SSH nor PGP keys by itself : it must import them (and PGPro only works on iOS 13+) SyncThing is a very useful and generic decentralized (server-less) synchronization system for all your devices. However I couldn’t install it on iPhone and you can’t go without conflict files on a regular basis (which are just ok to delete 99% of the time however, so it’s fine in the end because it could not be done better after thinking about it) ForceDoze (Android) K-9 Mail Silence VLC Markor (Android) / Bear (iOS) FastHub-Libre RadioDroid AntennaPod F-Droid]]></summary></entry><entry><title type="html">Migrating from Drupal to Jekyll</title><link href="https://www.nicolabs.net/2016/Migrating-from-Drupal-to-Jekyll" rel="alternate" type="text/html" title="Migrating from Drupal to Jekyll" /><published>2016-11-13T00:00:00+01:00</published><updated>2020-04-13T00:00:00+02:00</updated><id>https://www.nicolabs.net/2016/Migrating-from-Drupal-to-Jekyll</id><content type="html" xml:base="https://www.nicolabs.net/2016/Migrating-from-Drupal-to-Jekyll"><![CDATA[<p><img src="/assets/blog/nicobo-landscape.png" alt="Previous blog's banner background" /></p>
|
||
|
||
<h2 id="new-blog-concept-">New blog concept ?</h2>
|
||
|
||
<p>I write articles about things that required enough amount of work for them to be considered worth sharing.
|
||
Writing, in turn, also require a fair amount of work to be comprehensive and accurate enough.</p>
|
||
|
||
<p>I have to admit however that I don’t have time to write advanced articles as much as I would like to.
|
||
Many of them just stay unfinished in a draft state, never published…</p>
|
||
|
||
<p>Therefore this blog is going to show shorter (and some unfinished) articles !
|
||
The good news is that some content that was hidden, in draft state, is going to be live !</p>
|
||
|
||
<p>A first approach was to simply use a <em>git</em> branch to put drafts (usually named ‘develop’), then merge them into the ‘master’ branch ; but that would imply either to publish two blogs : ‘draft’ and ‘release’ or to create a mechanism to merge the two branches into the same blog.</p>
|
||
|
||
<p>I finally opted for a label in each article indicating its <em>maturity level</em> :</p>
|
||
|
||
<ul>
|
||
<li><span class="post-header"><span class="post-meta"><span class="maturity-label maturity-draft">draft</span></span></span> A <em>draft</em> label means something like “This article is in the process of being written, take it carefully as it may be wrong or change tomorrow”. <strong>I don’t endorse</strong> the content of such articles even if published, however one may find its content useful in some way…</li>
|
||
<li><span class="post-header"><span class="post-meta"><span class="maturity-label maturity-good">good</span></span></span> An article with a <em>good</em> maturity is one that I consider ready for publication, even if it has some minor flaws or missing parts.</li>
|
||
<li><span class="post-header"><span class="post-meta"><span class="maturity-label maturity-stable">stable</span></span></span> <em>Stable</em> articles are the ones that have been published for a long time or that I consider rock-solid.</li>
|
||
<li><span class="post-header"><span class="post-meta"><span class="maturity-label maturity-deprecated">deprecated</span></span></span> Some articles may explicitly be labeled as <em>deprecated</em> in order to emphasize the fact that they have deprecated content and should only be considered by people living in the past. Deprecation might not be a concept that suits perfectly within a maturity life cycle like previous labels, but for now I prefer keeping things simple and not using another tagging system.</li>
|
||
</ul>
|
||
|
||
<p>Please note that some articles may show a <em>stable</em> maturity while talking about <em>deprecated</em> things. This is because an article may still be relevant even when talking about supplanted technologies, and also because I’m not going to constantly review old articles to check if they’re still at the cutting edge… <a href="/articles/scaffolding-web-20">Scaffolding the Web 2.0</a> is a very good example of that case.</p>
|
||
|
||
<p>In order to get an idea of the freshness of an article, I therefore print both its <em>creation</em> and <em>last update</em> times, allowing people to judge by themselves if it’s likely to be up-to-date or not.</p>
|
||
|
||
<p>The paradigm I was fond of is therefore changing : a permanent URL on this blog still leads to the same article, but its content can definitely change (and break referring sources). In order to reference a content at a given fixed time, one can link to the original content on GitHub : there is a link to the full history of each article over their creation and update times labels (try with this one).</p>
|
||
|
||
<p>Lastly, I still use the <a href="https://jekyllrb.com/docs/drafts/">drafts feature of Jekyll</a> to prevent publishing of <em>very</em> early notes that are just ideas or not even readable… Those can still be viewed in GitHub sources, but are not publicly rendered (I have a special <span class="post-header"><span class="post-meta"><span class="maturity-label maturity-unpublished">unpublished</span></span></span> label for myself).</p>
|
||
|
||
<h2 id="migrating-paths">Migrating paths</h2>
|
||
|
||
<p>Beside changing the concept, I’m also changing the platform, moving from self-hosted Drupal to Jekyll on GitHub Pages.</p>
|
||
|
||
<p>During this migration I’ve tried to keep the old URLs still valid by keeping a way to make it through <em>HTTP redirects</em>. Mostly for fun.</p>
|
||
|
||
<ul>
|
||
<li>Assets (images) are moved to <code class="language-plaintext highlighter-rouge">/assets/blog/...</code> and specified as is in the markdown sources. I could have used Jekyll’s features to insert some variable but I did not want to add too much non-markdown (and framework-specific) code in the articles’ source. If the assets were to move again, it should be quite easy to replace all <code class="language-plaintext highlighter-rouge">/assets/blog/...</code> strings with the correct path.</li>
|
||
<li>I’ve used Jekyll’s <code class="language-plaintext highlighter-rouge">permalink</code> option to keep the short URL of the articles so I just have to add an <em>HTTP redirect</em> to serve the new blog under the old URLs.</li>
|
||
</ul>
|
||
|
||
<p>There is a screenshot of what the previous blog at <a href="http://nicobo.net">nicobo.net</a> was looking like : <a href="/assets/blog/screenshots/nicobo.net-screenshot-2019-10-26%2020-00-21.png">screenshot</a>.</p>
|
||
|
||
<h2 id="whats-lost">What’s lost</h2>
|
||
|
||
<p>From rich HTML to Markdown, I’ve lost some of the visual/semantic styles I was using : I had to merge or get rid of some of them.</p>
|
||
|
||
<p>Actually I must say that this does not really look like a bad thing : they were not <em>critical</em> to the meaning of the text and it’s easier to concentrate on the content itself.</p>
|
||
|
||
<ul>
|
||
<li>Lack of underlining in Markdown : I’ve used <em>normal</em> (*) or <strong>strong</strong> (**) emphasis</li>
|
||
<li><code class="language-plaintext highlighter-rouge">file names</code> and <code class="language-plaintext highlighter-rouge">commands</code> used to have separate styles : although I miss this one a bit, I am now enclosing both of them in back ticks (`) and saving some seconds thinking about which style to use here.</li>
|
||
<li>I used to have 2 types of block quotes : <em>notes</em> and <em>warnings</em>. I am now using markdown quotes (>) for both, emphasizing important words for <em>warnings</em> types</li>
|
||
<li>Pictures and text layout is now only a vertical flow : I don’t really care as it’s always been for pure visual left/right/center alignment and I used to spend a significant time building it.</li>
|
||
<li>Most of the visual helps I used to render with CSS are now back as indications in the text. E.g. I could emphasize portions of code to make the reader focus on them ; now I just describe them right before/after the code</li>
|
||
<li>I was using a <em>main tag</em> as a category : android, java, … Although <a href="https://jekyllrb.com/docs/posts/#categories-and-tags">jekyll supports categories</a>, I’m now using only one level of tags for the better : all tags are equals !</li>
|
||
<li>No custom excerpt and picture to advertise an article in the front page (<a href="https://jekyllrb.com/docs/posts/#post-excerpts">Jekyll has this kind of feature</a> but <a href="https://github.com/nicolabs/nicolabs.net/issues/14">it’s not working out-of-the-box for me</a>, so for now there is a short excerpt automatically extracted from the first paragraph that lacks some serious markdown parsing)</li>
|
||
<li>No integrated internationalization (<em>i18n</em>) but I have only few articles in french, all others are in English, and I feel it’s not going to be a lot of work to add this feature</li>
|
||
</ul>
|
||
|
||
<h2 id="what-i-like">What I like</h2>
|
||
|
||
<ul>
|
||
<li>Simplicity : the default theme, the generation mechanism, the Markdown language, everything is turned towards simplicity, allowing to concentrate on content.</li>
|
||
<li>This is really close to the ideal blogging platform I was looking for my ‘work in progress’ blog concept (i.e. even drafts are published and articles are always evolving)</li>
|
||
<li>Integrates very well with Atom and its <em>git</em> & <em>markdown preview</em> plugins</li>
|
||
<li>Last but not least, it is a very portable platform, since it’s just offline generation of HTML files and upload. GitHub automates the build so I don’t really upload generated files but to go over some limitations they put on <em>GitHub Pages</em> I may simply change hosting and then really push offline-generated content. That’s <a href="https://en.wikipedia.org/wiki/KISS_principle">KISS</a>. Also static site generation not limited to Jekyll, <a href="https://blog.jim-nielsen.com/2018/choosing-a-static-site-generator/">there are other</a> <a href="https://github.com/myles/awesome-static-generators#photography">very promising</a> engines, even distributed ones…</li>
|
||
</ul>
|
||
|
||
<h2 id="what-i-dont-like">What I don’t like</h2>
|
||
|
||
<ul>
|
||
<li>On GitHub Pages there is <em>only one</em> theme, <em>only one</em> markdown engine : GitHub surely needs to rationalize services it provides but on my side I hope it will not lead to dead ends and migration to another host…</li>
|
||
<li>No <em>autolink</em> feature for <code class="language-plaintext highlighter-rouge">kramdown</code>, the only supported markdown engine on GitHub Pages, which would have saved me from rewriting all links that had just their own URL as text. By the way I therefore rewrote the links’ text trimming the redundant “http://” or “www” parts, making the text more readable. For the record, I was able to do this with this single <em>regular expression</em> : <code class="language-plaintext highlighter-rouge">s/(https?:\/\/)(www\.)?([^\s$]+)/[$3]($1$2$3)/g</code></li>
|
||
</ul>]]></content><author><name>nicobo</name></author><category term="blogging" /><category term="drupal" /><category term="github" /><category term="jekyll" /><category term="web design" /><summary type="html"><![CDATA[New blog concept ? I write articles about things that required enough amount of work for them to be considered worth sharing. Writing, in turn, also require a fair amount of work to be comprehensive and accurate enough. I have to admit however that I don’t have time to write advanced articles as much as I would like to. Many of them just stay unfinished in a draft state, never published… Therefore this blog is going to show shorter (and some unfinished) articles ! The good news is that some content that was hidden, in draft state, is going to be live ! A first approach was to simply use a git branch to put drafts (usually named ‘develop’), then merge them into the ‘master’ branch ; but that would imply either to publish two blogs : ‘draft’ and ‘release’ or to create a mechanism to merge the two branches into the same blog. I finally opted for a label in each article indicating its maturity level : draft A draft label means something like “This article is in the process of being written, take it carefully as it may be wrong or change tomorrow”. I don’t endorse the content of such articles even if published, however one may find its content useful in some way… good An article with a good maturity is one that I consider ready for publication, even if it has some minor flaws or missing parts. stable Stable articles are the ones that have been published for a long time or that I consider rock-solid. deprecated Some articles may explicitly be labeled as deprecated in order to emphasize the fact that they have deprecated content and should only be considered by people living in the past. Deprecation might not be a concept that suits perfectly within a maturity life cycle like previous labels, but for now I prefer keeping things simple and not using another tagging system. Please note that some articles may show a stable maturity while talking about deprecated things. This is because an article may still be relevant even when talking about supplanted technologies, and also because I’m not going to constantly review old articles to check if they’re still at the cutting edge… Scaffolding the Web 2.0 is a very good example of that case. In order to get an idea of the freshness of an article, I therefore print both its creation and last update times, allowing people to judge by themselves if it’s likely to be up-to-date or not. The paradigm I was fond of is therefore changing : a permanent URL on this blog still leads to the same article, but its content can definitely change (and break referring sources). In order to reference a content at a given fixed time, one can link to the original content on GitHub : there is a link to the full history of each article over their creation and update times labels (try with this one). Lastly, I still use the drafts feature of Jekyll to prevent publishing of very early notes that are just ideas or not even readable… Those can still be viewed in GitHub sources, but are not publicly rendered (I have a special unpublished label for myself). Migrating paths Beside changing the concept, I’m also changing the platform, moving from self-hosted Drupal to Jekyll on GitHub Pages. During this migration I’ve tried to keep the old URLs still valid by keeping a way to make it through HTTP redirects. Mostly for fun. Assets (images) are moved to /assets/blog/... and specified as is in the markdown sources. I could have used Jekyll’s features to insert some variable but I did not want to add too much non-markdown (and framework-specific) code in the articles’ source. If the assets were to move again, it should be quite easy to replace all /assets/blog/... strings with the correct path. I’ve used Jekyll’s permalink option to keep the short URL of the articles so I just have to add an HTTP redirect to serve the new blog under the old URLs. There is a screenshot of what the previous blog at nicobo.net was looking like : screenshot. What’s lost From rich HTML to Markdown, I’ve lost some of the visual/semantic styles I was using : I had to merge or get rid of some of them. Actually I must say that this does not really look like a bad thing : they were not critical to the meaning of the text and it’s easier to concentrate on the content itself. Lack of underlining in Markdown : I’ve used normal (*) or strong (**) emphasis file names and commands used to have separate styles : although I miss this one a bit, I am now enclosing both of them in back ticks (`) and saving some seconds thinking about which style to use here. I used to have 2 types of block quotes : notes and warnings. I am now using markdown quotes (>) for both, emphasizing important words for warnings types Pictures and text layout is now only a vertical flow : I don’t really care as it’s always been for pure visual left/right/center alignment and I used to spend a significant time building it. Most of the visual helps I used to render with CSS are now back as indications in the text. E.g. I could emphasize portions of code to make the reader focus on them ; now I just describe them right before/after the code I was using a main tag as a category : android, java, … Although jekyll supports categories, I’m now using only one level of tags for the better : all tags are equals ! No custom excerpt and picture to advertise an article in the front page (Jekyll has this kind of feature but it’s not working out-of-the-box for me, so for now there is a short excerpt automatically extracted from the first paragraph that lacks some serious markdown parsing) No integrated internationalization (i18n) but I have only few articles in french, all others are in English, and I feel it’s not going to be a lot of work to add this feature What I like Simplicity : the default theme, the generation mechanism, the Markdown language, everything is turned towards simplicity, allowing to concentrate on content. This is really close to the ideal blogging platform I was looking for my ‘work in progress’ blog concept (i.e. even drafts are published and articles are always evolving) Integrates very well with Atom and its git & markdown preview plugins Last but not least, it is a very portable platform, since it’s just offline generation of HTML files and upload. GitHub automates the build so I don’t really upload generated files but to go over some limitations they put on GitHub Pages I may simply change hosting and then really push offline-generated content. That’s KISS. Also static site generation not limited to Jekyll, there are other very promising engines, even distributed ones… What I don’t like On GitHub Pages there is only one theme, only one markdown engine : GitHub surely needs to rationalize services it provides but on my side I hope it will not lead to dead ends and migration to another host… No autolink feature for kramdown, the only supported markdown engine on GitHub Pages, which would have saved me from rewriting all links that had just their own URL as text. By the way I therefore rewrote the links’ text trimming the redundant “http://” or “www” parts, making the text more readable. For the record, I was able to do this with this single regular expression : s/(https?:\/\/)(www\.)?([^\s$]+)/[$3]($1$2$3)/g]]></summary></entry></feed> |