This service tests the validity of an RSS 2.0 feed, checking to see that it follows the rules of the RSS specification. For advice from the RSS Advisory Board on how to implement RSS and handle issues such as enclosures and HTML encoding, read the RSS Best Practices Profile. This checker is also a validator of Atom and RSS 1.0 feeds.
Use this tester regularly to ensure that your RSS feed continues to work well in the wide audience of RSS readers, podcast clients and other software that supports the format.
This is a valid RSS feed.
This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.
line 6678, column 0: (6 occurrences) [help]
<script src="https://gist.github.com/x-way/caf03da77fe2cc83b6bd.js"></script>
line 6686, column 0: (6 occurrences) [help]
<script src="https://gist.github.com/x-way/caf03da77fe2cc83b6bd.js"></script>
line 8433, column 3: (16 occurrences) [help]
]]></description>
^
line 8435, column 3: (16 occurrences) [help]
]]></content:encoded>
^
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>x-log</title>
<link>https://blog.x-way.org</link>
<description>x-log</description>
<lastBuildDate>Sat, 14 Dec 2024 07:01:49 +0100</lastBuildDate>
<language>en</language>
<managingEditor>andreas+rss@jaggi.info (Andreas Jaggi)</managingEditor>
<webMaster>andreas+rss@jaggi.info (Andreas Jaggi)</webMaster>
<copyright>Andreas Jaggi</copyright>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<generator>x-log c3d9ad</generator>
<atom:link href="https://blog.x-way.org/rss.xml" rel="self" type="application/rss+xml"/>
<image>
<url>https://blog.x-way.org/logo.gif</url>
<title>x-log</title>
<link>https://blog.x-way.org</link>
</image>
<item>
<title>The seven rules of writing consistent git commit messages</title>
<link>https://blog.x-way.org/Coding/2024/12/11/The-seven-rules-of-writing-consistent-git-commit-messages.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324436</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 11 Dec 2024 15:51:58 +0100</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<blockquote cite="https://rednafi.com/misc/write_git_commit_messages_properly/#the-seven-rules-of-writing-consistent-git-commit-messages">
<ol>
<li>Separate subject from body with a blank line</li>
<li>Limit the subject line to 50 characters (I often break this when there’s no message body)</li>
<li>Capitalize the subject line</li>
<li>Do not end the subject line with a period</li>
<li>Use the imperative mood in the subject line</li>
<li>Wrap the body at 72 characters</li>
<li>Use the body to explain what and why vs. how</li>
</ol>
</blockquote>
<p>
(<a href="https://rednafi.com/misc/write_git_commit_messages_properly/#the-seven-rules-of-writing-consistent-git-commit-messages" title="Write git commit messages properly | Redowan's Reflections">via</a>)
</p>
]]></description>
<content:encoded><![CDATA[<blockquote cite="https://rednafi.com/misc/write_git_commit_messages_properly/#the-seven-rules-of-writing-consistent-git-commit-messages">
<ol>
<li>Separate subject from body with a blank line</li>
<li>Limit the subject line to 50 characters (I often break this when there’s no message body)</li>
<li>Capitalize the subject line</li>
<li>Do not end the subject line with a period</li>
<li>Use the imperative mood in the subject line</li>
<li>Wrap the body at 72 characters</li>
<li>Use the body to explain what and why vs. how</li>
</ol>
</blockquote>
<p>
(<a href="https://rednafi.com/misc/write_git_commit_messages_properly/#the-seven-rules-of-writing-consistent-git-commit-messages" title="Write git commit messages properly | Redowan's Reflections">via</a>)
</p>
]]></content:encoded>
</item>
<item>
<title>oxipng</title>
<link>https://blog.x-way.org/Webdesign/2024/12/10/oxipng.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324435</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 10 Dec 2024 19:56:17 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>
<a href="https://github.com/shssoichiro/oxipng" title="shssoichiro/oxipng: Multithreaded PNG optimizer written in Rust">oxipng</a> is a lossless PNG compression optimizer written in Rust.<br>
On an initial test it seems to perform better than <a href="https://pmt.sourceforge.io/pngcrush/" title="PNGCRUSH">pngcrush</a>.<br>
(<a href="https://rednafi.com/misc/behind_the_blog/" title="Behind the blog | Redowan's Reflections">via</a>)
</p>
]]></description>
<content:encoded><![CDATA[<p>
<a href="https://github.com/shssoichiro/oxipng" title="shssoichiro/oxipng: Multithreaded PNG optimizer written in Rust">oxipng</a> is a lossless PNG compression optimizer written in Rust.<br>
On an initial test it seems to perform better than <a href="https://pmt.sourceforge.io/pngcrush/" title="PNGCRUSH">pngcrush</a>.<br>
(<a href="https://rednafi.com/misc/behind_the_blog/" title="Behind the blog | Redowan's Reflections">via</a>)
</p>
]]></content:encoded>
</item>
<item>
<title>New search functionality</title>
<link>https://blog.x-way.org/Webdesign/2024/12/08/New-search-functionality.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324434</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 08 Dec 2024 22:52:20 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>
I added a client-side search functionality to this static blog.
</p>
<p>
Similar to what is explained in <a href="https://www.stephanmiller.com/static-site-search/" title="How to Add Search to Your Static Site Generator (Jekyll, Hugo, Gatsby, Nikola, etc.) • Stephan Miller">this article by Stephan Miller</a>, I added a search functionality to the blog.<br>
The challenge was to do this while keeping the blog a static generated site.<br>
Thus the choice to do all of the search client-side in JavaScript.
</p>
<p>
The way my current implementation works, is that there is a JSON blob with all the posts ever written in this blog.<br>
This is loaded to the browser and indexed using <a href="https://lunrjs.com/" title="Lunr: A bit like Solr, but much smaller and not as bright">Lunr.js</a>.<br>
The resulting search index is then used to provide the search functionality.<br>
It comes with some convenient built-in <a href="https://lunrjs.com/guides/searching.html" title="Searching : Lunr">search modifiers such as +, - and *</a>.
</p>
<p>
To avoid reloading the whole JSON blob for each follow-up query on <a href="https://blog.x-way.org/search.html" title="x-log - Search">the search page</a>, it intercepts the default form submit action and handles the search client-side.<br>
Thus re-using the computed search index and saving the additional roundtrips accross the network.
</p>
]]></description>
<content:encoded><![CDATA[<p>
I added a client-side search functionality to this static blog.
</p>
<p>
Similar to what is explained in <a href="https://www.stephanmiller.com/static-site-search/" title="How to Add Search to Your Static Site Generator (Jekyll, Hugo, Gatsby, Nikola, etc.) • Stephan Miller">this article by Stephan Miller</a>, I added a search functionality to the blog.<br>
The challenge was to do this while keeping the blog a static generated site.<br>
Thus the choice to do all of the search client-side in JavaScript.
</p>
<p>
The way my current implementation works, is that there is a JSON blob with all the posts ever written in this blog.<br>
This is loaded to the browser and indexed using <a href="https://lunrjs.com/" title="Lunr: A bit like Solr, but much smaller and not as bright">Lunr.js</a>.<br>
The resulting search index is then used to provide the search functionality.<br>
It comes with some convenient built-in <a href="https://lunrjs.com/guides/searching.html" title="Searching : Lunr">search modifiers such as +, - and *</a>.
</p>
<p>
To avoid reloading the whole JSON blob for each follow-up query on <a href="https://blog.x-way.org/search.html" title="x-log - Search">the search page</a>, it intercepts the default form submit action and handles the search client-side.<br>
Thus re-using the computed search index and saving the additional roundtrips accross the network.
</p>
]]></content:encoded>
</item>
<item>
<title>The Earworm Eraser</title>
<link>https://blog.x-way.org/Music/2024/12/06/The-Earworm-Eraser.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324433</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Fri, 06 Dec 2024 10:58:28 +0100</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<blockquote cite="https://www.wbur.org/npr/nx-s1-5200065/earworm-eraser-christmas-songs">
The Earworm Eraser is a 40-second audio track designed specifically to squash earworms — a song on repeat circling around and around in your brain that can't easily be shaken off.
</blockquote>
<p>
<a href="https://youtu.be/LvDl3kL42uU" title="The Earworm Eraser – Get catchy songs out of your head | Atlassian">The Earworm Eraser – Get catchy songs out of your head | Atlassian</a>
</p>
<p>
(<a href="https://onefoottsunami.com/2024/12/05/the-earworm-eraser/" title="One Foot Tsunami: The Earworm Eraser">via</a>)
</p>
]]></description>
<content:encoded><![CDATA[<blockquote cite="https://www.wbur.org/npr/nx-s1-5200065/earworm-eraser-christmas-songs">
The Earworm Eraser is a 40-second audio track designed specifically to squash earworms — a song on repeat circling around and around in your brain that can't easily be shaken off.
</blockquote>
<p>
<a href="https://youtu.be/LvDl3kL42uU" title="The Earworm Eraser – Get catchy songs out of your head | Atlassian">The Earworm Eraser – Get catchy songs out of your head | Atlassian</a>
</p>
<p>
(<a href="https://onefoottsunami.com/2024/12/05/the-earworm-eraser/" title="One Foot Tsunami: The Earworm Eraser">via</a>)
</p>
]]></content:encoded>
</item>
<item>
<title>Picture of Sequoia</title>
<link>https://blog.x-way.org/Mac/2024/12/06/Picture-of-Sequoia.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324432</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Fri, 06 Dec 2024 07:19:35 +0100</pubDate>
<category domain="https://blog.x-way.org/Mac/">Mac</category>
<description><![CDATA[<p>
Recreated <a href="https://blog.x-way.org/Linux/2003/12/06/Photo_vom_Panther.html" title="x-log - Photo vom Panther">this screenshot</a> from 21 years ago (first Mac) on my new Mac.
</p>
<ul>
<li><a href="https://blog.x-way.org/images/Mac-OS-X-Screenshot.jpg" title="Screenshot of my Mac desktop in 2003">2003</a></li>
<li><a href="https://blog.x-way.org/images/macOS-Screenshot.png" title="Screenshot of my Mac desktop in 2024">2024</a></li>
</ul>
<p>
How does 2003 and 2024 compare?<br>
Nowadays I'm using the regular Apple Mail.<br>
X11 forwarding still works but is not really used.<br>
Some Linux host is still around.
Mac remains the main device though.<br>
Interestingly Linux still is a Intel device, whereas the Mac one is (again) running on a non-Intel CPU.
</p>
]]></description>
<content:encoded><![CDATA[<p>
Recreated <a href="https://blog.x-way.org/Linux/2003/12/06/Photo_vom_Panther.html" title="x-log - Photo vom Panther">this screenshot</a> from 21 years ago (first Mac) on my new Mac.
</p>
<ul>
<li><a href="https://blog.x-way.org/images/Mac-OS-X-Screenshot.jpg" title="Screenshot of my Mac desktop in 2003">2003</a></li>
<li><a href="https://blog.x-way.org/images/macOS-Screenshot.png" title="Screenshot of my Mac desktop in 2024">2024</a></li>
</ul>
<p>
How does 2003 and 2024 compare?<br>
Nowadays I'm using the regular Apple Mail.<br>
X11 forwarding still works but is not really used.<br>
Some Linux host is still around.
Mac remains the main device though.<br>
Interestingly Linux still is a Intel device, whereas the Mac one is (again) running on a non-Intel CPU.
</p>
]]></content:encoded>
</item>
<item>
<title>How to install EncFS on macOS Sequoia</title>
<link>https://blog.x-way.org/Mac/2024/12/03/How-to-install-EncFS-on-macOS-Sequoia.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324431</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 03 Dec 2024 08:58:40 +0100</pubDate>
<category domain="https://blog.x-way.org/Mac/">Mac</category>
<description><![CDATA[<p>
How to access my old encrypted files even though <a href="https://vgough.github.io/encfs/" title="EncFS">EncFS</a> is no longer supported in Homebrew for macOS.
</p>
<ol>
<li>Start by installing a third-party formula that some nice people maintain: <pre>brew install gromgit/fuse/encfs-mac</pre></li>
<li>Immediately get disappointed when it fails. Turns out it requires openssl@1.1 which has been deprecated by Homebrew: <pre><span style="color: green">==></span> <b>Fetching dependencies for gromgit/fuse/encfs-mac: <span style="color: green">openssl@1.1</span></b>
<span style="color: red">Error:</span> openssl@1.1 has been disabled because it is not supported upstream! It was disabled on 2024-10-24.</pre></li>
</ol>
<p>
How to install the (no longer supported) openssl@1.1 formula.
</p>
<ol>
<li>Force the download of the core formula repository: <pre>brew tap --force homebrew/core</pre></li>
<li>Edit the formula and remove the deprecation enforcement: <pre>brew edit openssl@1.1</pre> Comment out line 29, so it looks like: <pre> #disable! date: "2024-10-24", because: :unsupported</pre></li>
<li>Perform installation of openssl@1.1 from the locally modified formula: <pre>HOMEBREW_NO_INSTALL_FROM_API=1 brew install openssl@1.1</pre></li>
</ol>
<p>
Now we can install EncFS successfully.
</p>
<pre>brew install gromgit/fuse/encfs-mac
==> Fetching gromgit/fuse/encfs-mac
==> Downloading https://github.com/gromgit/homebrew-fuse/releases/download/encfs-mac-1.9.5/encfs-mac-1.9.5.arm64_monterey.bottle.tar.gz
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing encfs-mac from gromgit/fuse
==> Pouring encfs-mac-1.9.5.arm64_monterey.bottle.tar.gz
==> Downloading https://formulae.brew.sh/api/cask.jws.json
🍺 /opt/homebrew/Cellar/encfs-mac/1.9.5: 65 files, 2.2MB
==> Running `brew cleanup encfs-mac`...
</pre>
<p>
If desired, we can now run <kbd>brew untap homebrew/core</kbd> to cleanup the local copy of the formula repository.
</p>
<p>
Next step is to enable the (earlier installed) MacFuse kernel extension.<br>
On macOS Sequoia this is a quite complicated process (needs disabling of multiple security features and some reboots).<br>
Luckily the people from the MacFuse project have compiled <a href="https://github.com/macfuse/macfuse/wiki/Getting-Started#enabling-support-for-third-party-kernel-extensions-apple-silicon-macs" title="Getting Started - Enabling support for third party kernel extensions (Apple Silicon Macs)">a nice illustrated guide.</a>
</p>
<p>
After this process is completed, we can finally decrypt the EncFS files.
</p>
<pre>encfs -v -f ./encrypted-folder ./mountpoint</pre>
<p>
The unencrypted files are available at <var>./mountpoint</var>.<br>
In my case I copied them to another folder as I no longer intend to use EncFS.
</p>
<p>
With the job done, I removed again all the EncFS software and re-enabled the security features of macOS.
</p>
<pre>brew uninstall encfs-mac
brew uninstall openssl@1.1
brew uninstall macfuse</pre>
<p>
Then reboot into the Recovery environment and in the Startup Security Utility set the Security Policy again to Full Security. 🔐
</p>
]]></description>
<content:encoded><![CDATA[<p>
How to access my old encrypted files even though <a href="https://vgough.github.io/encfs/" title="EncFS">EncFS</a> is no longer supported in Homebrew for macOS.
</p>
<ol>
<li>Start by installing a third-party formula that some nice people maintain: <pre>brew install gromgit/fuse/encfs-mac</pre></li>
<li>Immediately get disappointed when it fails. Turns out it requires openssl@1.1 which has been deprecated by Homebrew: <pre><span style="color: green">==></span> <b>Fetching dependencies for gromgit/fuse/encfs-mac: <span style="color: green">openssl@1.1</span></b>
<span style="color: red">Error:</span> openssl@1.1 has been disabled because it is not supported upstream! It was disabled on 2024-10-24.</pre></li>
</ol>
<p>
How to install the (no longer supported) openssl@1.1 formula.
</p>
<ol>
<li>Force the download of the core formula repository: <pre>brew tap --force homebrew/core</pre></li>
<li>Edit the formula and remove the deprecation enforcement: <pre>brew edit openssl@1.1</pre> Comment out line 29, so it looks like: <pre> #disable! date: "2024-10-24", because: :unsupported</pre></li>
<li>Perform installation of openssl@1.1 from the locally modified formula: <pre>HOMEBREW_NO_INSTALL_FROM_API=1 brew install openssl@1.1</pre></li>
</ol>
<p>
Now we can install EncFS successfully.
</p>
<pre>brew install gromgit/fuse/encfs-mac
==> Fetching gromgit/fuse/encfs-mac
==> Downloading https://github.com/gromgit/homebrew-fuse/releases/download/encfs-mac-1.9.5/encfs-mac-1.9.5.arm64_monterey.bottle.tar.gz
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing encfs-mac from gromgit/fuse
==> Pouring encfs-mac-1.9.5.arm64_monterey.bottle.tar.gz
==> Downloading https://formulae.brew.sh/api/cask.jws.json
🍺 /opt/homebrew/Cellar/encfs-mac/1.9.5: 65 files, 2.2MB
==> Running `brew cleanup encfs-mac`...
</pre>
<p>
If desired, we can now run <kbd>brew untap homebrew/core</kbd> to cleanup the local copy of the formula repository.
</p>
<p>
Next step is to enable the (earlier installed) MacFuse kernel extension.<br>
On macOS Sequoia this is a quite complicated process (needs disabling of multiple security features and some reboots).<br>
Luckily the people from the MacFuse project have compiled <a href="https://github.com/macfuse/macfuse/wiki/Getting-Started#enabling-support-for-third-party-kernel-extensions-apple-silicon-macs" title="Getting Started - Enabling support for third party kernel extensions (Apple Silicon Macs)">a nice illustrated guide.</a>
</p>
<p>
After this process is completed, we can finally decrypt the EncFS files.
</p>
<pre>encfs -v -f ./encrypted-folder ./mountpoint</pre>
<p>
The unencrypted files are available at <var>./mountpoint</var>.<br>
In my case I copied them to another folder as I no longer intend to use EncFS.
</p>
<p>
With the job done, I removed again all the EncFS software and re-enabled the security features of macOS.
</p>
<pre>brew uninstall encfs-mac
brew uninstall openssl@1.1
brew uninstall macfuse</pre>
<p>
Then reboot into the Recovery environment and in the Startup Security Utility set the Security Policy again to Full Security. 🔐
</p>
]]></content:encoded>
</item>
<item>
<title>Migrate Homebrew from Intel to M4 MacBook Pro</title>
<link>https://blog.x-way.org/Mac/2024/12/01/Migrate-Homebrew-from-Intel-to-M4-MacBook-Pro.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324430</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 01 Dec 2024 16:12:31 +0100</pubDate>
<category domain="https://blog.x-way.org/Mac/">Mac</category>
<description><![CDATA[<p>
A big part of the time used to <a href="https://blog.x-way.org/Mac/2024/11/30/Move-from-2017-Intel-MacBook-Pro-to-2024-M4-MacBook-Pro.html" title="x-log - Move from 2017 Intel MacBook Pro to 2024 M4 MacBook Pro">move from my 2017 Intel MacBook Pro to my new 2024 M4 MacBook Pro</a> was spent on migrating my <a href="https://brew.sh/" title="Homebrew — The Missing Package Manager for macOS">Homebrew installation</a>.
</p>
<p>
There are three aspects to the migration.
</p>
<ul>
<li>One is the change in CPU architecture (which means to replace my Intel-only binaries with arm64 binaries).</li>
<li>The other one is the change of the Homebrew root folder from <var>/usr/local</var> to <var>/opt/homebrew</var>.</li>
<li>And the last one is the change in OS version (from macOS 13 to macOS 15).</li>
</ul>
<p>
The impact of the change in CPU architecture was mostly taken care of by enabling the Rosetta 2 emulator to run Intel-binaries on the M4.<br>
This immediately fixed the problem of my Terminal windows auto-closing on startup (as they now no longer failed to run the zsh Intel-binary).<br>
But it did not solve all problems, particularly annoying was that vim could not be started and always failed with the following error:
</p>
<pre>dyld[31382]: Library not loaded: /System/Library/Perl/5.30/darwin-thread-multi-2level/CORE/libperl.dylib
Referenced from: <77AC96DE-0453-3E1C-B442-EFE624110BAE> /usr/local/Cellar/vim/9.1.0750_1/bin/vim
Reason: tried: '/System/Library/Perl/5.30/darwin-thread-multi-2level/CORE/libperl.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/System/Library/Perl/5.30/darwin-thread-multi-2level/CORE/libperl.dylib' (no such file), '/System/Library/Perl/5.30/darwin-thread-multi-2level/CORE/libperl.dylib' (no such file, not in dyld cache), '/usr/local/lib/libperl.dylib' (no such file), '/usr/lib/libperl.dylib' (no such file, not in dyld cache)</pre>
<p>
My workaround for this was to use the default vim that comes bundled with macOS, by typing <kbd>/usr/bin/vim</kbd>.<br>
Although it complained about some unsupported parts in my <var>.vimrc</var>, it at least started up and was usable enough to edit files.<br>
The error itself seems due to some Perl system libraries that vim was compiled with and which now no longer exist in the new macOS version.<br>
This is a typical problem which can be solved by re-installing Homebrew.
</p>
<p>
<b>Re-installing Homebrew</b><br>
The steps below follow <a href="https://docs.brew.sh/Common-Issues#unintentional-dual-homebrew-installations" title="Common Issues - Unintentional dual Homebrew installations">this FAQ entry</a> and are extended with what was needed to make it work for my situation.<br>
Your mileage might vary!
</p>
<ol>
<li>In the Terminal.app settings, set the login shell to <var>Default</var>. This to avoid Rosetta's Intel emulated zsh from the previous installation interfering with things.</li>
<li>Verify that you're running in native ARM mode with the <kbd>arch</kbd> command. It should return <var>arm64</var>.</li>
<li>Create a dump of the previous Homebrew installation by explicitly running brew through Rosetta's Intel emulation: <pre>arch -x86_64 /usr/local/bin/brew bundle dump --global</pre></li>
<li>Review the resulting <var>~/.Brewfile</var> and adjust as desired (I didn't make any adjustments).</li>
<li>Ensure that native arm binaries are preferred over Intel binaries from the previous installation: <pre>export PATH=/bin:/usr/bin:/sbin:/usr/sbin:$PATH</pre></li>
<li>Install homebrew into <var>/opt/homebrew</var> with: <pre>/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"</pre></li>
<li>Adjust your shell config file to prefer <var>/opt/homebrew/bin</var> over <var>/usr/local/bin</var> in the PATH.<br>As I manually set PATH in my <var>.zshrc</var>, I needed to adjust it. Following these commands recommended by the brew installer was not enough! <pre><b><span style="color: blue">==></span> Next steps:</b>
- Run these commands in your terminal to add Homebrew to your <b>PATH</b>:
echo >> /Users/aj/.zprofile
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/aj/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"</pre></li>
<li>Open a fresh terminal window and verify with <kbd>which brew</kbd>, it must return <var>/opt/homebrew/bin/brew</var>.</li>
<li>Now have brew install all the applications from the dump in the <var>~/.Brewfile</var>: <pre>/opt/homebrew/bin/brew bundle install --global</pre></li>
<li>This process will print some warnings and errors, thus make sure to keep the output.<br>I will go through all the errors and warnings I encountered and list how I fixed them below (for the ones I could fix, unfortunately not all have been fixed yet).<br>It usually ends with a summary of the number of failures: <pre><span style="color: red">Homebrew Bundle failed! 30 Brewfile dependencies failed to install.Homebrew Bundle failed! 30 Brewfile dependencies failed to install.</span></pre></li>
<li>Once the process is completed and you see the above summary, open the Terminal.app settings and set the Login shell to <var>/opt/homebrew/bin/zsh</var></li>
<li>Open a fresh terminal window and verify that you are now running in native arm64 mode with <kbd>arch</kbd>.</li>
<li>Now we are ready to address the errors, and then at the end we will remove the old Homebrew installation under <var>/usr/local</var>.</li>
</ol>
<p>
<b>Outdated Xcode and missing Xcode command-line utilities</b><br>
Due to the change in macOS version, the Xcode installation was outdated and also no usable command-line utilities were available.<br>
This usually manifests in errors like these:
</p>
<pre><span style="color: green">Installing ssh-audit</span>
==> Fetching ssh-audit
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-core/723e7ef695e15c790aab727c1da11a2a4610ad53/Formula/s/ssh-audit.rb
==> Cloning https://github.com/jtesta/ssh-audit.git
Cloning into '/Users/aj/Library/Caches/Homebrew/ssh-audit--git'...
==> Checking out branch master
Already on 'master'
Your branch is up to date with 'origin/master'.
Error: Your Xcode (15.1) at /Applications/Xcode.app is too outdated.
Please update to Xcode 16.0 (or delete it).
Xcode can be updated from the App Store.
Error: Your Command Line Tools are too outdated.
Update them from Software Update in System Settings.
If that doesn't show you any updates, run:
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
Alternatively, manually download them from:
https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 16.0.
<span style="color: red">Installing ssh-audit has failed!</span></pre>
<pre><span style="color: green">Installing tdsmith/ham/direwolf</span>
==> Fetching dependencies for tdsmith/ham/direwolf: portaudio
==> Fetching portaudio
==> Downloading https://ghcr.io/v2/homebrew/core/portaudio/manifests/19.7.0-1
==> Downloading https://ghcr.io/v2/homebrew/core/portaudio/blobs/sha256:8ad9f1c15a4bc9c05a9dd184b53b8f5f5d13a2458a70535bfb01e54ce4f8b4bd
==> Fetching tdsmith/ham/direwolf
==> Downloading https://github.com/wb2osz/direwolf/archive/1.4-dev-E.tar.gz
==> Downloading from https://codeload.github.com/wb2osz/direwolf/tar.gz/refs/tags/1.4-dev-E
==> Installing direwolf from tdsmith/ham
Error: Your Xcode (15.1) at /Applications/Xcode.app is too outdated.
Please update to Xcode 16.0 (or delete it).
Xcode can be updated from the App Store.
Error: Your Command Line Tools are too outdated.
Update them from Software Update in System Settings.
If that doesn't show you any updates, run:
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
Alternatively, manually download them from:
https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 16.0.
<span style="color: red">Installing tdsmith/ham/direwolf has failed!</span></pre>
<p>
This can be fixed in two steps.<br>
First update Xcode via the App Store.<br>
Then run the mentioned commands to install/update the command-line utilities:
</p>
<pre>sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install</pre>
<p>
With the latest Xcode and command-line utilities in place, trigger a new installation attempt for the affected applications:
</p>
<pre>brew install ssh-audit
brew install tdsmith/ham/direwolf</pre>
<p>
<b>Missing Rosetta 2 Intel emulation</b><br>
Some of the Casks distributed by Homebrew are currently only available as Intel-binaries.<br>
This usually manifests in warnings like these:
</p>
<pre><span style="color: green">Installing gqrx</span>
==> Caveats
gqrx is built for Intel macOS and so requires Rosetta 2 to be installed.
You can install Rosetta 2 with:
softwareupdate --install-rosetta --agree-to-license
Note that it is very difficult to remove Rosetta 2 once it is installed.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/g/gqrx.rb
==> Downloading https://github.com/gqrx-sdr/gqrx/releases/download/v2.17.5/Gqrx-2.17.5.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask gqrx
Error: It seems there is already an App at '/Applications/Gqrx.app'.
==> Purging files for version 2.17.5 of Cask gqrx
<span style="color: red">Installing gqrx has failed!</span></pre>
<pre><span style="color: green">Installing jitsi</span>
==> Caveats
jitsi is built for Intel macOS and so requires Rosetta 2 to be installed.
You can install Rosetta 2 with:
softwareupdate --install-rosetta --agree-to-license
Note that it is very difficult to remove Rosetta 2 once it is installed.
==> Downloading https://github.com/jitsi/jitsi/releases/download/Jitsi-2.10/jitsi-2.10.5550.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask jitsi
Error: It seems there is already an App at '/Applications/Jitsi.app'.
==> Purging files for version 2.10.5550 of Cask jitsi
<span style="color: red">Installing jitsi has failed!</span></pre>
<pre><span style="color: green">Installing keepassx</span>
Password:
==> Caveats
keepassx is built for Intel macOS and so requires Rosetta 2 to be installed.
You can install Rosetta 2 with:
softwareupdate --install-rosetta --agree-to-license
Note that it is very difficult to remove Rosetta 2 once it is installed.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/k/keepassx.rb
==> Downloading https://www.keepassx.org/releases/2.0.3/KeePassX-2.0.3.dmg
==> Installing Cask keepassx
==> Changing ownership of paths required by keepassx with sudo; the password may be necessary.
Error: It seems there is already an App at '/Applications/KeePassX.app'.
==> Purging files for version 2.0.3 of Cask keepassx
<span style="color: red">Installing keepassx has failed!</span></pre>
<pre><span style="color: green">Installing sequel-pro</span>
Warning: sequel-pro has been deprecated because it is discontinued upstream! It will be disabled on 2024-12-17.
==> Caveats
sequel-pro has been deprecated in favor of Sequel Ace.
brew install --cask sequel-ace
sequel-pro is built for Intel macOS and so requires Rosetta 2 to be installed.
You can install Rosetta 2 with:
softwareupdate --install-rosetta --agree-to-license
Note that it is very difficult to remove Rosetta 2 once it is installed.
==> Downloading https://github.com/sequelpro/sequelpro/releases/download/release-1.1.2/sequel-pro-1.1.2.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask sequel-pro
Error: It seems there is already an App at '/Applications/Sequel Pro.app'.
==> Purging files for version 1.1.2 of Cask sequel-pro
<span style="color: red">Installing sequel-pro has failed!</span></pre>
<p>
This can be fixed by running the mentioned command:
</p>
<pre>softwareupdate --install-rosetta --agree-to-license</pre>
<p>
With this in place, Intel-binaries will not be a problem anymore.<br>
But as you can see there was actually a second failure in all these errors, which we are going to address next.
</p>
<p>
<b>Old applications linger around in /Applications and block updates/re-installation</b><br>
Homebrew nicely installed all the opensource applications into the new <var>/opt/homebrew</var>, but for the Casks which are distributed as binary application bundles and live in <var>/Applications</var> we end up with conflicts (as the new Homebrew installation does not know about the previously installed application bundles there).<br>
This typically manifests in errors like these (also seen in the ones from the Rosetta section):
</p>
<pre><span style="color: green">Installing 0-ad</span>
==> Downloading https://releases.wildfiregames.com/0ad-0.0.26-alpha-osx-aarch64.dmg
==> Installing Cask 0-ad
Error: It seems there is already an App at '/Applications/0 A.D..app'.
==> Purging files for version 0.0.26-alpha of Cask 0-ad
<span style="color: red">Installing 0-ad has failed!</span></pre>
<pre><span style="color: green">Installing brave-browser</span>
==> Downloading https://updates-cdn.bravesoftware.com/sparkle/Brave-Browser/stable-arm64/173.91/Brave-Browser-arm64.dmg
==> Installing Cask brave-browser
Error: It seems there is already an App at '/Applications/Brave Browser.app'.
==> Purging files for version 1.73.91.0 of Cask brave-browser
<span style="color: red">Installing brave-browser has failed!</span></pre>
<pre><span style="color: green">Installing burp-suite</span>
==> Downloading https://portswigger-cdn.net/burp/releases/download?product=community&version=2024.10.3&type=MacOsArm64
==> Installing Cask burp-suite
Error: It seems there is already an App at '/Applications/Burp Suite Community Edition.app'.
==> Purging files for version 2024.10.3 of Cask burp-suite
<span style="color: red">Installing burp-suite has failed!</span></pre>
<pre><span style="color: green">Installing docker</span>
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/d/docker.rb
==> Downloading https://desktop.docker.com/mac/main/arm64/175267/Docker.dmg
==> Installing Cask docker
Error: It seems there is already an App at '/Applications/Docker.app'.
==> Purging files for version 4.36.0,175267 of Cask docker
<span style="color: red">Installing docker has failed!</span></pre>
<pre><span style="color: green">Installing gitup</span>
==> Downloading https://github.com/git-up/GitUp/releases/download/v1.4.2/GitUp.zip
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask gitup
Error: It seems there is already an App at '/Applications/GitUp.app'.
==> Purging files for version 1.4.2 of Cask gitup
<span style="color: red">Installing gitup has failed!</span></pre>
<pre><span style="color: green">Installing keeweb</span>
Password:
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/k/keeweb.rb
==> Downloading https://github.com/keeweb/keeweb/releases/download/v1.18.7/KeeWeb-1.18.7.mac.arm64.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask keeweb
==> Changing ownership of paths required by keeweb with sudo; the password may be necessary.
chown: /Applications/KeeWeb.app/Contents/CodeResources: Operation not permitted
[...]
chown: /Applications/KeeWeb.app: Operation not permitted
Error: It seems there is already an App at '/Applications/KeeWeb.app'.
==> Purging files for version 1.18.7 of Cask keeweb
<span style="color: red">Installing keeweb has failed!</span></pre>
<pre><span style="color: green">Installing netnewswire</span>
==> Downloading https://github.com/Ranchero-Software/NetNewsWire/releases/download/mac-6.1.4/NetNewsWire6.1.4.zip
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask netnewswire
Error: It seems there is already an App at '/Applications/NetNewsWire.app'.
==> Purging files for version 6.1.4 of Cask netnewswire
<span style="color: red">Installing netnewswire has failed!</span></pre>
<pre><span style="color: green">Installing obs</span>
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/o/obs.rb
==> Downloading https://cdn-fastly.obsproject.com/downloads/OBS-Studio-30.2.3-macOS-Apple.dmg
==> Installing Cask obs
Error: It seems there is already an App at '/Applications/OBS.app'.
==> Purging files for version 30.2.3 of Cask obs
<span style="color: red">Installing obs has failed!</span></pre>
<pre><span style="color: green">Installing transmission</span>
==> Downloading https://github.com/transmission/transmission/releases/download/4.0.6/Transmission-4.0.6.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask transmission
Error: It seems there is already an App at '/Applications/Transmission.app'.
==> Purging files for version 4.0.6 of Cask transmission
<span style="color: red">Installing transmission has failed!</span></pre>
<pre><span style="color: green">Installing tunnelblick</span>
Password:
==> Caveats
For security reasons, tunnelblick must be installed to /Applications,
and will request to be moved at launch.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/t/tunnelblick.rb
==> Downloading https://github.com/Tunnelblick/Tunnelblick/releases/download/v4.0.1/Tunnelblick_4.0.1_build_5971.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask tunnelblick
==> Changing ownership of paths required by tunnelblick with sudo; the password may be necessary.
chown: /Applications/Tunnelblick.app/Contents/CodeResources: Operation not permitted
[...]
chown: /Applications/Tunnelblick.app: Operation not permitted
Error: It seems there is already an App at '/Applications/Tunnelblick.app'.
==> Purging files for version 4.0.1,5971 of Cask tunnelblick
<span style="color: red">Installing tunnelblick has failed!</span></pre>
<pre><span style="color: green">Installing vlc</span>
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/v/vlc.rb
==> Downloading https://get.videolan.org/vlc/3.0.21/macosx/vlc-3.0.21-arm64.dmg
==> Downloading from http://mirror.easyname.ch/videolan/vlc/3.0.21/macosx/vlc-3.0.21-arm64.dmg
==> Installing Cask vlc
Error: It seems there is already an App at '/Applications/VLC.app'.
==> Purging files for version 3.0.21 of Cask vlc
<span style="color: red">Installing vlc has failed!</span></pre>
<pre><span style="color: green">Installing wireshark</span>
Password:
==> Downloading https://2.na.dl.wireshark.org/osx/all-versions/Wireshark%204.4.2%20Arm%2064.dmg
==> Installing Cask wireshark
==> Running installer for wireshark with sudo; the password may be necessary.
installer: Package name is ChmodBPF
installer: Installing at base path /
installer: The install was successful.
==> Running installer for wireshark with sudo; the password may be necessary.
Error: It seems there is already an App at '/Applications/Wireshark.app'.
installer: Package name is Add Wireshark to the system PATH
installer: Installing at base path /
installer: The install was successful.
==> Purging files for version 4.4.2 of Cask wireshark
<span style="color: red">Installing wireshark has failed!</span></pre>
<p>
Now that we have the full list, here is how I fixed these errors:
</p>
<ul>
<li>For each of them, move the existing application bundle from <var>/Applications</var> to Trash.</li>
<li>Then trigger the installation again with: <pre>brew install --cask 0-ad
brew install --cask brave-browser
...</pre></li>
<li>The <var>--cask</var> part is important, as sometimes a headless source-only formula exists with the same name which does not include the GUI parts.<br>By using <var>--cask</var> we make sure that the upstream binary application bundle is used.</li>
</ul>
<p>
With this, most of the fixing is concluded.<br>
Thus let's go to the warnings and errors that I consciously ignore.
</p>
<p>
<b>Warnings and errors to ignore</b><br>
Some of the warnings and errors I consciously ignore.<br>
A lot of them come from no longer maintained/available software which Homebrew no longer provides, or which have become obsolete as another software does the same job now.<br>
Also in some cases it is just that I no longer use the software and thus do not need to spend the time to fix their installation problems.<br>
Of course there are some errors in software which I still want to use and which I have not managed to fix yet, we will get to them later.<br>
Here now the warnings and errors which I choose to ignore:
</p>
<pre><span style="color: green">Tapping homebrew/cask</span>
Error: Tapping homebrew/cask is no longer typically necessary.
Add --force if you are sure you need it for contributing to Homebrew.
<span style="color: red">Tapping homebrew/cask has failed!</span></pre>
<pre><span style="color: green">Tapping homebrew/core</span>
Error: Tapping homebrew/core is no longer typically necessary.
Add --force if you are sure you need it for contributing to Homebrew.
<span style="color: red">Tapping homebrew/core has failed!</span></pre>
<pre><span style="color: orange">Skipping gdb (no bottle for Apple Silicon)</span></pre>
<pre><span style="color: green">Installing hping</span>
Error: hping has been disabled because it is not maintained upstream! It was disabled on 2024-02-15.
<span style="color: red">Installing hping has failed!</span></pre>
<pre><span style="color: orange">Skipping hyperkit (no bottle for Apple Silicon)</span></pre>
<pre><span style="color: green">Installing xhyve</span>
<span style="color: orange">Warning:</span> 'xhyve' formula is unreadable: No available formula with the name "xhyve".
Warning: No available formula with the name "xhyve".
Error: No formulae found for xhyve.
==> Searching for similarly named formulae...
<span style="color: red">Installing xhyve has failed!</span></pre>
<pre><span style="color: green">Installing jsmin</span>
<span style="color: orange">Warning:</span> 'jsmin' formula is unreadable: No available formula with the name "jsmin". Did you mean jsmn, jasmin or jsign?
Warning: No available formula with the name "jsmin". Did you mean jsmn, jasmin or jsign?
==> Searching for similarly named formulae...
==> Formulae
jsmn
jasmin
jsign
To install jsmn, run:
brew install jsmn
<span style="color: red">Installing jsmin has failed!</span></pre>
<pre><span style="color: green">Installing sslyze</span>
Error: sslyze has been disabled because it uses deprecated `openssl@1.1`! It was disabled on 2024-04-05.
<span style="color: red">Installing sslyze has failed!</span></pre>
<pre><span style="color: green">Installing virtualbox-extension-pack</span>
Warning: Cask 'virtualbox-extension-pack' is unavailable: No Cask with this name exists.
==> Searching for similarly named casks...
==> Casks
virtualbox@beta
To install virtualbox@beta, run:
brew install --cask virtualbox@beta
<span style="color: red">Installing virtualbox-extension-pack has failed!</span></pre>
<pre><span style="color: green">Installing docker-compose-completion</span>
<span style="color: orange">Warning:</span> 'docker-compose-completion' formula is unreadable: No available formula with the name "docker-compose-completion". Did you mean docker-completion?
Warning: No available formula with the name "docker-compose-completion". Did you mean docker-completion?
==> Searching for similarly named formulae...
==> Formulae
docker-completion
To install docker-completion, run:
brew install docker-completion
<span style="color: red">Installing docker-compose-completion has failed!</span></pre>
<pre><span style="color: green">Installing visitors</span>
Error: visitors has been disabled because it has a removed upstream repository! It was disabled on 2024-02-21.
<span style="color: red">Installing visitors has failed!</span></pre>
<pre><span style="color: green">Installing osxfuse</span>
Password:
==> Caveats
`osxfuse` has been succeeded by `macfuse` as of version 4.0.0.
To update to a newer version, do:
brew uninstall osxfuse
brew install macfuse
osxfuse requires a kernel extension to work.
If the installation fails, retry after you enable it in:
System Settings → Privacy & Security
For more information, refer to vendor documentation or this Apple Technical Note:
https://developer.apple.com/library/content/technotes/tn2459/_index.html
You must reboot for the installation of osxfuse to take effect.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/o/osxfuse.rb
==> Downloading https://github.com/osxfuse/osxfuse/releases/download/osxfuse-3.11.2/osxfuse-3.11.2.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask osxfuse
==> Running installer for osxfuse with sudo; the password may be necessary.
installer: Error - Das FUSE for macOS Installationspacket ist nicht kompatibel mit dieser macOS Version.
Error: Failure while executing; `/usr/bin/sudo -u root -E LOGNAME=aj USER=aj USERNAME=aj -- /usr/sbin/installer -pkg /opt/homebrew/Caskroom/osxfuse/3.11.2/Extras/FUSE\ for\ macOS\ 3.11.2.pkg -target /` exited with 1. Here's the output:
installer: Error - Das FUSE for macOS Installationspacket ist nicht kompatibel mit dieser macOS Version.
==> Purging files for version 3.11.2 of Cask osxfuse
<span style="color: red">Installing osxfuse has failed!</span></pre>
<pre><span style="color: green">Installing tuntap</span>
Warning: Cask 'tuntap' is unavailable: No Cask with this name exists.
==> Searching for similarly named casks...
==> Casks
tunetag
To install tunetag, run:
brew install --cask tunetag
<span style="color: red">Installing tuntap has failed!</span></pre>
<pre><span style="color: green">Installing mailtrackerblocker</span>
Warning: mailtrackerblocker has been deprecated because it is now exclusively distributed on the Mac App Store! It will be disabled on 2025-04-22.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/m/mailtrackerblocker.rb
Error: This cask does not run on macOS versions newer than Ventura.
<span style="color: red">Installing mailtrackerblocker has failed!</span></pre>
<p>
This concludes the warnings and errors I ignored.<br>
And there is a little exception.<br>
For mailtrackerblocker I did not completely ignore the error, but rather installed the paid <a href="https://apparition47.github.io/MailTrackerBlocker/" title="MailTrackerBlocker for Mail on macOS">MailTrackerBlocker for Mail</a> application from the App Store.
</p>
<p>
<b>Cleaning up the old Homebrew installation</b><br>
We still have all the no longer needed Intel-binaries and old Homebrew framework in <var>/usr/local</var>.<br>
Time to clean this up.
Homebrew nicely provides a script to help (partially) with this:
</p>
<pre>/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)" -- --path=/usr/local</pre>
<p>
This will remove most of the old Homebrew installation but will likely fail to remove everything.<br>
Especially in my situation with years of cruft accumulated, this was the case.<br>
I ended up with the following output from the cleanup script:
</p>
<pre>==> /usr/bin/sudo rmdir /usr/local
rmdir: /usr/local: Operation not permitted
Warning: Failed during: /usr/bin/sudo rmdir /usr/local
Warning: Homebrew partially uninstalled (but there were steps that failed)!
To finish uninstalling rerun this script with `sudo`.
The following possible Homebrew files were not deleted:
/usr/local/.com.apple.installer.keep
/usr/local/Cellar/
/usr/local/Frameworks/
/usr/local/Homebrew/
/usr/local/MacGPG2/
/usr/local/bin/
/usr/local/etc/
/usr/local/include/
/usr/local/lib/
/usr/local/man/
/usr/local/opt/
/usr/local/remotedesktop/
/usr/local/sbin/
/usr/local/share/
/usr/local/tests/
/usr/local/var/
You may wish to remove them yourself.</pre>
<p>
I manually went through all these folders and removed what I could identify as obsolete and no longer needed leftovers.<br>
Important though for example the MacGPG2 folder seems to come from the GPGTools installation, thus be aware that there are other things than Homebrew which might have installed some software under <var>/usr/local</var> and not everyhting must necessarily be removed.
</p>
<p>
<b>Unsolved problems</b><br>
As mentioned there are some things which I haven't figured out how to fix yet.
<p>
<p>
I'm missing a good solution for <a href="https://vgough.github.io/encfs/" title="EncFS">encfs</a> (which is no longer provided by Homebrew due to license changes of the underlying MacFuse project).
Compiling from source (at least through Homebrew) is not supported either (as it is marked as Linux-only and complilation is not supported anymore on macOS).<br>
<b>Update:</b> found a solution for <a href="https://blog.x-way.org/Mac/2024/12/03/How-to-install-EncFS-on-macOS-Sequoia.html" title="x-log - How to install EncFS on MacOS Sequoia">how to install EncFS on macOS Sequoia</a>.
</p>
<p>
Another missing thing (which is more a problem of not having time to deal with it yet), is the Perl ecosystem including CPAN package management.
Here probably some research to find the canonical way for installing Perl in macOS 15 is all I need. 🐪
</p>
]]></description>
<content:encoded><![CDATA[<p>
A big part of the time used to <a href="https://blog.x-way.org/Mac/2024/11/30/Move-from-2017-Intel-MacBook-Pro-to-2024-M4-MacBook-Pro.html" title="x-log - Move from 2017 Intel MacBook Pro to 2024 M4 MacBook Pro">move from my 2017 Intel MacBook Pro to my new 2024 M4 MacBook Pro</a> was spent on migrating my <a href="https://brew.sh/" title="Homebrew — The Missing Package Manager for macOS">Homebrew installation</a>.
</p>
<p>
There are three aspects to the migration.
</p>
<ul>
<li>One is the change in CPU architecture (which means to replace my Intel-only binaries with arm64 binaries).</li>
<li>The other one is the change of the Homebrew root folder from <var>/usr/local</var> to <var>/opt/homebrew</var>.</li>
<li>And the last one is the change in OS version (from macOS 13 to macOS 15).</li>
</ul>
<p>
The impact of the change in CPU architecture was mostly taken care of by enabling the Rosetta 2 emulator to run Intel-binaries on the M4.<br>
This immediately fixed the problem of my Terminal windows auto-closing on startup (as they now no longer failed to run the zsh Intel-binary).<br>
But it did not solve all problems, particularly annoying was that vim could not be started and always failed with the following error:
</p>
<pre>dyld[31382]: Library not loaded: /System/Library/Perl/5.30/darwin-thread-multi-2level/CORE/libperl.dylib
Referenced from: <77AC96DE-0453-3E1C-B442-EFE624110BAE> /usr/local/Cellar/vim/9.1.0750_1/bin/vim
Reason: tried: '/System/Library/Perl/5.30/darwin-thread-multi-2level/CORE/libperl.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/System/Library/Perl/5.30/darwin-thread-multi-2level/CORE/libperl.dylib' (no such file), '/System/Library/Perl/5.30/darwin-thread-multi-2level/CORE/libperl.dylib' (no such file, not in dyld cache), '/usr/local/lib/libperl.dylib' (no such file), '/usr/lib/libperl.dylib' (no such file, not in dyld cache)</pre>
<p>
My workaround for this was to use the default vim that comes bundled with macOS, by typing <kbd>/usr/bin/vim</kbd>.<br>
Although it complained about some unsupported parts in my <var>.vimrc</var>, it at least started up and was usable enough to edit files.<br>
The error itself seems due to some Perl system libraries that vim was compiled with and which now no longer exist in the new macOS version.<br>
This is a typical problem which can be solved by re-installing Homebrew.
</p>
<p>
<b>Re-installing Homebrew</b><br>
The steps below follow <a href="https://docs.brew.sh/Common-Issues#unintentional-dual-homebrew-installations" title="Common Issues - Unintentional dual Homebrew installations">this FAQ entry</a> and are extended with what was needed to make it work for my situation.<br>
Your mileage might vary!
</p>
<ol>
<li>In the Terminal.app settings, set the login shell to <var>Default</var>. This to avoid Rosetta's Intel emulated zsh from the previous installation interfering with things.</li>
<li>Verify that you're running in native ARM mode with the <kbd>arch</kbd> command. It should return <var>arm64</var>.</li>
<li>Create a dump of the previous Homebrew installation by explicitly running brew through Rosetta's Intel emulation: <pre>arch -x86_64 /usr/local/bin/brew bundle dump --global</pre></li>
<li>Review the resulting <var>~/.Brewfile</var> and adjust as desired (I didn't make any adjustments).</li>
<li>Ensure that native arm binaries are preferred over Intel binaries from the previous installation: <pre>export PATH=/bin:/usr/bin:/sbin:/usr/sbin:$PATH</pre></li>
<li>Install homebrew into <var>/opt/homebrew</var> with: <pre>/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"</pre></li>
<li>Adjust your shell config file to prefer <var>/opt/homebrew/bin</var> over <var>/usr/local/bin</var> in the PATH.<br>As I manually set PATH in my <var>.zshrc</var>, I needed to adjust it. Following these commands recommended by the brew installer was not enough! <pre><b><span style="color: blue">==></span> Next steps:</b>
- Run these commands in your terminal to add Homebrew to your <b>PATH</b>:
echo >> /Users/aj/.zprofile
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/aj/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"</pre></li>
<li>Open a fresh terminal window and verify with <kbd>which brew</kbd>, it must return <var>/opt/homebrew/bin/brew</var>.</li>
<li>Now have brew install all the applications from the dump in the <var>~/.Brewfile</var>: <pre>/opt/homebrew/bin/brew bundle install --global</pre></li>
<li>This process will print some warnings and errors, thus make sure to keep the output.<br>I will go through all the errors and warnings I encountered and list how I fixed them below (for the ones I could fix, unfortunately not all have been fixed yet).<br>It usually ends with a summary of the number of failures: <pre><span style="color: red">Homebrew Bundle failed! 30 Brewfile dependencies failed to install.Homebrew Bundle failed! 30 Brewfile dependencies failed to install.</span></pre></li>
<li>Once the process is completed and you see the above summary, open the Terminal.app settings and set the Login shell to <var>/opt/homebrew/bin/zsh</var></li>
<li>Open a fresh terminal window and verify that you are now running in native arm64 mode with <kbd>arch</kbd>.</li>
<li>Now we are ready to address the errors, and then at the end we will remove the old Homebrew installation under <var>/usr/local</var>.</li>
</ol>
<p>
<b>Outdated Xcode and missing Xcode command-line utilities</b><br>
Due to the change in macOS version, the Xcode installation was outdated and also no usable command-line utilities were available.<br>
This usually manifests in errors like these:
</p>
<pre><span style="color: green">Installing ssh-audit</span>
==> Fetching ssh-audit
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-core/723e7ef695e15c790aab727c1da11a2a4610ad53/Formula/s/ssh-audit.rb
==> Cloning https://github.com/jtesta/ssh-audit.git
Cloning into '/Users/aj/Library/Caches/Homebrew/ssh-audit--git'...
==> Checking out branch master
Already on 'master'
Your branch is up to date with 'origin/master'.
Error: Your Xcode (15.1) at /Applications/Xcode.app is too outdated.
Please update to Xcode 16.0 (or delete it).
Xcode can be updated from the App Store.
Error: Your Command Line Tools are too outdated.
Update them from Software Update in System Settings.
If that doesn't show you any updates, run:
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
Alternatively, manually download them from:
https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 16.0.
<span style="color: red">Installing ssh-audit has failed!</span></pre>
<pre><span style="color: green">Installing tdsmith/ham/direwolf</span>
==> Fetching dependencies for tdsmith/ham/direwolf: portaudio
==> Fetching portaudio
==> Downloading https://ghcr.io/v2/homebrew/core/portaudio/manifests/19.7.0-1
==> Downloading https://ghcr.io/v2/homebrew/core/portaudio/blobs/sha256:8ad9f1c15a4bc9c05a9dd184b53b8f5f5d13a2458a70535bfb01e54ce4f8b4bd
==> Fetching tdsmith/ham/direwolf
==> Downloading https://github.com/wb2osz/direwolf/archive/1.4-dev-E.tar.gz
==> Downloading from https://codeload.github.com/wb2osz/direwolf/tar.gz/refs/tags/1.4-dev-E
==> Installing direwolf from tdsmith/ham
Error: Your Xcode (15.1) at /Applications/Xcode.app is too outdated.
Please update to Xcode 16.0 (or delete it).
Xcode can be updated from the App Store.
Error: Your Command Line Tools are too outdated.
Update them from Software Update in System Settings.
If that doesn't show you any updates, run:
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
Alternatively, manually download them from:
https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 16.0.
<span style="color: red">Installing tdsmith/ham/direwolf has failed!</span></pre>
<p>
This can be fixed in two steps.<br>
First update Xcode via the App Store.<br>
Then run the mentioned commands to install/update the command-line utilities:
</p>
<pre>sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install</pre>
<p>
With the latest Xcode and command-line utilities in place, trigger a new installation attempt for the affected applications:
</p>
<pre>brew install ssh-audit
brew install tdsmith/ham/direwolf</pre>
<p>
<b>Missing Rosetta 2 Intel emulation</b><br>
Some of the Casks distributed by Homebrew are currently only available as Intel-binaries.<br>
This usually manifests in warnings like these:
</p>
<pre><span style="color: green">Installing gqrx</span>
==> Caveats
gqrx is built for Intel macOS and so requires Rosetta 2 to be installed.
You can install Rosetta 2 with:
softwareupdate --install-rosetta --agree-to-license
Note that it is very difficult to remove Rosetta 2 once it is installed.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/g/gqrx.rb
==> Downloading https://github.com/gqrx-sdr/gqrx/releases/download/v2.17.5/Gqrx-2.17.5.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask gqrx
Error: It seems there is already an App at '/Applications/Gqrx.app'.
==> Purging files for version 2.17.5 of Cask gqrx
<span style="color: red">Installing gqrx has failed!</span></pre>
<pre><span style="color: green">Installing jitsi</span>
==> Caveats
jitsi is built for Intel macOS and so requires Rosetta 2 to be installed.
You can install Rosetta 2 with:
softwareupdate --install-rosetta --agree-to-license
Note that it is very difficult to remove Rosetta 2 once it is installed.
==> Downloading https://github.com/jitsi/jitsi/releases/download/Jitsi-2.10/jitsi-2.10.5550.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask jitsi
Error: It seems there is already an App at '/Applications/Jitsi.app'.
==> Purging files for version 2.10.5550 of Cask jitsi
<span style="color: red">Installing jitsi has failed!</span></pre>
<pre><span style="color: green">Installing keepassx</span>
Password:
==> Caveats
keepassx is built for Intel macOS and so requires Rosetta 2 to be installed.
You can install Rosetta 2 with:
softwareupdate --install-rosetta --agree-to-license
Note that it is very difficult to remove Rosetta 2 once it is installed.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/k/keepassx.rb
==> Downloading https://www.keepassx.org/releases/2.0.3/KeePassX-2.0.3.dmg
==> Installing Cask keepassx
==> Changing ownership of paths required by keepassx with sudo; the password may be necessary.
Error: It seems there is already an App at '/Applications/KeePassX.app'.
==> Purging files for version 2.0.3 of Cask keepassx
<span style="color: red">Installing keepassx has failed!</span></pre>
<pre><span style="color: green">Installing sequel-pro</span>
Warning: sequel-pro has been deprecated because it is discontinued upstream! It will be disabled on 2024-12-17.
==> Caveats
sequel-pro has been deprecated in favor of Sequel Ace.
brew install --cask sequel-ace
sequel-pro is built for Intel macOS and so requires Rosetta 2 to be installed.
You can install Rosetta 2 with:
softwareupdate --install-rosetta --agree-to-license
Note that it is very difficult to remove Rosetta 2 once it is installed.
==> Downloading https://github.com/sequelpro/sequelpro/releases/download/release-1.1.2/sequel-pro-1.1.2.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask sequel-pro
Error: It seems there is already an App at '/Applications/Sequel Pro.app'.
==> Purging files for version 1.1.2 of Cask sequel-pro
<span style="color: red">Installing sequel-pro has failed!</span></pre>
<p>
This can be fixed by running the mentioned command:
</p>
<pre>softwareupdate --install-rosetta --agree-to-license</pre>
<p>
With this in place, Intel-binaries will not be a problem anymore.<br>
But as you can see there was actually a second failure in all these errors, which we are going to address next.
</p>
<p>
<b>Old applications linger around in /Applications and block updates/re-installation</b><br>
Homebrew nicely installed all the opensource applications into the new <var>/opt/homebrew</var>, but for the Casks which are distributed as binary application bundles and live in <var>/Applications</var> we end up with conflicts (as the new Homebrew installation does not know about the previously installed application bundles there).<br>
This typically manifests in errors like these (also seen in the ones from the Rosetta section):
</p>
<pre><span style="color: green">Installing 0-ad</span>
==> Downloading https://releases.wildfiregames.com/0ad-0.0.26-alpha-osx-aarch64.dmg
==> Installing Cask 0-ad
Error: It seems there is already an App at '/Applications/0 A.D..app'.
==> Purging files for version 0.0.26-alpha of Cask 0-ad
<span style="color: red">Installing 0-ad has failed!</span></pre>
<pre><span style="color: green">Installing brave-browser</span>
==> Downloading https://updates-cdn.bravesoftware.com/sparkle/Brave-Browser/stable-arm64/173.91/Brave-Browser-arm64.dmg
==> Installing Cask brave-browser
Error: It seems there is already an App at '/Applications/Brave Browser.app'.
==> Purging files for version 1.73.91.0 of Cask brave-browser
<span style="color: red">Installing brave-browser has failed!</span></pre>
<pre><span style="color: green">Installing burp-suite</span>
==> Downloading https://portswigger-cdn.net/burp/releases/download?product=community&version=2024.10.3&type=MacOsArm64
==> Installing Cask burp-suite
Error: It seems there is already an App at '/Applications/Burp Suite Community Edition.app'.
==> Purging files for version 2024.10.3 of Cask burp-suite
<span style="color: red">Installing burp-suite has failed!</span></pre>
<pre><span style="color: green">Installing docker</span>
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/d/docker.rb
==> Downloading https://desktop.docker.com/mac/main/arm64/175267/Docker.dmg
==> Installing Cask docker
Error: It seems there is already an App at '/Applications/Docker.app'.
==> Purging files for version 4.36.0,175267 of Cask docker
<span style="color: red">Installing docker has failed!</span></pre>
<pre><span style="color: green">Installing gitup</span>
==> Downloading https://github.com/git-up/GitUp/releases/download/v1.4.2/GitUp.zip
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask gitup
Error: It seems there is already an App at '/Applications/GitUp.app'.
==> Purging files for version 1.4.2 of Cask gitup
<span style="color: red">Installing gitup has failed!</span></pre>
<pre><span style="color: green">Installing keeweb</span>
Password:
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/k/keeweb.rb
==> Downloading https://github.com/keeweb/keeweb/releases/download/v1.18.7/KeeWeb-1.18.7.mac.arm64.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask keeweb
==> Changing ownership of paths required by keeweb with sudo; the password may be necessary.
chown: /Applications/KeeWeb.app/Contents/CodeResources: Operation not permitted
[...]
chown: /Applications/KeeWeb.app: Operation not permitted
Error: It seems there is already an App at '/Applications/KeeWeb.app'.
==> Purging files for version 1.18.7 of Cask keeweb
<span style="color: red">Installing keeweb has failed!</span></pre>
<pre><span style="color: green">Installing netnewswire</span>
==> Downloading https://github.com/Ranchero-Software/NetNewsWire/releases/download/mac-6.1.4/NetNewsWire6.1.4.zip
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask netnewswire
Error: It seems there is already an App at '/Applications/NetNewsWire.app'.
==> Purging files for version 6.1.4 of Cask netnewswire
<span style="color: red">Installing netnewswire has failed!</span></pre>
<pre><span style="color: green">Installing obs</span>
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/o/obs.rb
==> Downloading https://cdn-fastly.obsproject.com/downloads/OBS-Studio-30.2.3-macOS-Apple.dmg
==> Installing Cask obs
Error: It seems there is already an App at '/Applications/OBS.app'.
==> Purging files for version 30.2.3 of Cask obs
<span style="color: red">Installing obs has failed!</span></pre>
<pre><span style="color: green">Installing transmission</span>
==> Downloading https://github.com/transmission/transmission/releases/download/4.0.6/Transmission-4.0.6.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask transmission
Error: It seems there is already an App at '/Applications/Transmission.app'.
==> Purging files for version 4.0.6 of Cask transmission
<span style="color: red">Installing transmission has failed!</span></pre>
<pre><span style="color: green">Installing tunnelblick</span>
Password:
==> Caveats
For security reasons, tunnelblick must be installed to /Applications,
and will request to be moved at launch.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/t/tunnelblick.rb
==> Downloading https://github.com/Tunnelblick/Tunnelblick/releases/download/v4.0.1/Tunnelblick_4.0.1_build_5971.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask tunnelblick
==> Changing ownership of paths required by tunnelblick with sudo; the password may be necessary.
chown: /Applications/Tunnelblick.app/Contents/CodeResources: Operation not permitted
[...]
chown: /Applications/Tunnelblick.app: Operation not permitted
Error: It seems there is already an App at '/Applications/Tunnelblick.app'.
==> Purging files for version 4.0.1,5971 of Cask tunnelblick
<span style="color: red">Installing tunnelblick has failed!</span></pre>
<pre><span style="color: green">Installing vlc</span>
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/v/vlc.rb
==> Downloading https://get.videolan.org/vlc/3.0.21/macosx/vlc-3.0.21-arm64.dmg
==> Downloading from http://mirror.easyname.ch/videolan/vlc/3.0.21/macosx/vlc-3.0.21-arm64.dmg
==> Installing Cask vlc
Error: It seems there is already an App at '/Applications/VLC.app'.
==> Purging files for version 3.0.21 of Cask vlc
<span style="color: red">Installing vlc has failed!</span></pre>
<pre><span style="color: green">Installing wireshark</span>
Password:
==> Downloading https://2.na.dl.wireshark.org/osx/all-versions/Wireshark%204.4.2%20Arm%2064.dmg
==> Installing Cask wireshark
==> Running installer for wireshark with sudo; the password may be necessary.
installer: Package name is ChmodBPF
installer: Installing at base path /
installer: The install was successful.
==> Running installer for wireshark with sudo; the password may be necessary.
Error: It seems there is already an App at '/Applications/Wireshark.app'.
installer: Package name is Add Wireshark to the system PATH
installer: Installing at base path /
installer: The install was successful.
==> Purging files for version 4.4.2 of Cask wireshark
<span style="color: red">Installing wireshark has failed!</span></pre>
<p>
Now that we have the full list, here is how I fixed these errors:
</p>
<ul>
<li>For each of them, move the existing application bundle from <var>/Applications</var> to Trash.</li>
<li>Then trigger the installation again with: <pre>brew install --cask 0-ad
brew install --cask brave-browser
...</pre></li>
<li>The <var>--cask</var> part is important, as sometimes a headless source-only formula exists with the same name which does not include the GUI parts.<br>By using <var>--cask</var> we make sure that the upstream binary application bundle is used.</li>
</ul>
<p>
With this, most of the fixing is concluded.<br>
Thus let's go to the warnings and errors that I consciously ignore.
</p>
<p>
<b>Warnings and errors to ignore</b><br>
Some of the warnings and errors I consciously ignore.<br>
A lot of them come from no longer maintained/available software which Homebrew no longer provides, or which have become obsolete as another software does the same job now.<br>
Also in some cases it is just that I no longer use the software and thus do not need to spend the time to fix their installation problems.<br>
Of course there are some errors in software which I still want to use and which I have not managed to fix yet, we will get to them later.<br>
Here now the warnings and errors which I choose to ignore:
</p>
<pre><span style="color: green">Tapping homebrew/cask</span>
Error: Tapping homebrew/cask is no longer typically necessary.
Add --force if you are sure you need it for contributing to Homebrew.
<span style="color: red">Tapping homebrew/cask has failed!</span></pre>
<pre><span style="color: green">Tapping homebrew/core</span>
Error: Tapping homebrew/core is no longer typically necessary.
Add --force if you are sure you need it for contributing to Homebrew.
<span style="color: red">Tapping homebrew/core has failed!</span></pre>
<pre><span style="color: orange">Skipping gdb (no bottle for Apple Silicon)</span></pre>
<pre><span style="color: green">Installing hping</span>
Error: hping has been disabled because it is not maintained upstream! It was disabled on 2024-02-15.
<span style="color: red">Installing hping has failed!</span></pre>
<pre><span style="color: orange">Skipping hyperkit (no bottle for Apple Silicon)</span></pre>
<pre><span style="color: green">Installing xhyve</span>
<span style="color: orange">Warning:</span> 'xhyve' formula is unreadable: No available formula with the name "xhyve".
Warning: No available formula with the name "xhyve".
Error: No formulae found for xhyve.
==> Searching for similarly named formulae...
<span style="color: red">Installing xhyve has failed!</span></pre>
<pre><span style="color: green">Installing jsmin</span>
<span style="color: orange">Warning:</span> 'jsmin' formula is unreadable: No available formula with the name "jsmin". Did you mean jsmn, jasmin or jsign?
Warning: No available formula with the name "jsmin". Did you mean jsmn, jasmin or jsign?
==> Searching for similarly named formulae...
==> Formulae
jsmn
jasmin
jsign
To install jsmn, run:
brew install jsmn
<span style="color: red">Installing jsmin has failed!</span></pre>
<pre><span style="color: green">Installing sslyze</span>
Error: sslyze has been disabled because it uses deprecated `openssl@1.1`! It was disabled on 2024-04-05.
<span style="color: red">Installing sslyze has failed!</span></pre>
<pre><span style="color: green">Installing virtualbox-extension-pack</span>
Warning: Cask 'virtualbox-extension-pack' is unavailable: No Cask with this name exists.
==> Searching for similarly named casks...
==> Casks
virtualbox@beta
To install virtualbox@beta, run:
brew install --cask virtualbox@beta
<span style="color: red">Installing virtualbox-extension-pack has failed!</span></pre>
<pre><span style="color: green">Installing docker-compose-completion</span>
<span style="color: orange">Warning:</span> 'docker-compose-completion' formula is unreadable: No available formula with the name "docker-compose-completion". Did you mean docker-completion?
Warning: No available formula with the name "docker-compose-completion". Did you mean docker-completion?
==> Searching for similarly named formulae...
==> Formulae
docker-completion
To install docker-completion, run:
brew install docker-completion
<span style="color: red">Installing docker-compose-completion has failed!</span></pre>
<pre><span style="color: green">Installing visitors</span>
Error: visitors has been disabled because it has a removed upstream repository! It was disabled on 2024-02-21.
<span style="color: red">Installing visitors has failed!</span></pre>
<pre><span style="color: green">Installing osxfuse</span>
Password:
==> Caveats
`osxfuse` has been succeeded by `macfuse` as of version 4.0.0.
To update to a newer version, do:
brew uninstall osxfuse
brew install macfuse
osxfuse requires a kernel extension to work.
If the installation fails, retry after you enable it in:
System Settings → Privacy & Security
For more information, refer to vendor documentation or this Apple Technical Note:
https://developer.apple.com/library/content/technotes/tn2459/_index.html
You must reboot for the installation of osxfuse to take effect.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/o/osxfuse.rb
==> Downloading https://github.com/osxfuse/osxfuse/releases/download/osxfuse-3.11.2/osxfuse-3.11.2.dmg
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-[...]
==> Installing Cask osxfuse
==> Running installer for osxfuse with sudo; the password may be necessary.
installer: Error - Das FUSE for macOS Installationspacket ist nicht kompatibel mit dieser macOS Version.
Error: Failure while executing; `/usr/bin/sudo -u root -E LOGNAME=aj USER=aj USERNAME=aj -- /usr/sbin/installer -pkg /opt/homebrew/Caskroom/osxfuse/3.11.2/Extras/FUSE\ for\ macOS\ 3.11.2.pkg -target /` exited with 1. Here's the output:
installer: Error - Das FUSE for macOS Installationspacket ist nicht kompatibel mit dieser macOS Version.
==> Purging files for version 3.11.2 of Cask osxfuse
<span style="color: red">Installing osxfuse has failed!</span></pre>
<pre><span style="color: green">Installing tuntap</span>
Warning: Cask 'tuntap' is unavailable: No Cask with this name exists.
==> Searching for similarly named casks...
==> Casks
tunetag
To install tunetag, run:
brew install --cask tunetag
<span style="color: red">Installing tuntap has failed!</span></pre>
<pre><span style="color: green">Installing mailtrackerblocker</span>
Warning: mailtrackerblocker has been deprecated because it is now exclusively distributed on the Mac App Store! It will be disabled on 2025-04-22.
==> Downloading https://raw.githubusercontent.com/Homebrew/homebrew-cask/1ef784f287cce93f2bb54bea66ae7ac0953f623b/Casks/m/mailtrackerblocker.rb
Error: This cask does not run on macOS versions newer than Ventura.
<span style="color: red">Installing mailtrackerblocker has failed!</span></pre>
<p>
This concludes the warnings and errors I ignored.<br>
And there is a little exception.<br>
For mailtrackerblocker I did not completely ignore the error, but rather installed the paid <a href="https://apparition47.github.io/MailTrackerBlocker/" title="MailTrackerBlocker for Mail on macOS">MailTrackerBlocker for Mail</a> application from the App Store.
</p>
<p>
<b>Cleaning up the old Homebrew installation</b><br>
We still have all the no longer needed Intel-binaries and old Homebrew framework in <var>/usr/local</var>.<br>
Time to clean this up.
Homebrew nicely provides a script to help (partially) with this:
</p>
<pre>/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)" -- --path=/usr/local</pre>
<p>
This will remove most of the old Homebrew installation but will likely fail to remove everything.<br>
Especially in my situation with years of cruft accumulated, this was the case.<br>
I ended up with the following output from the cleanup script:
</p>
<pre>==> /usr/bin/sudo rmdir /usr/local
rmdir: /usr/local: Operation not permitted
Warning: Failed during: /usr/bin/sudo rmdir /usr/local
Warning: Homebrew partially uninstalled (but there were steps that failed)!
To finish uninstalling rerun this script with `sudo`.
The following possible Homebrew files were not deleted:
/usr/local/.com.apple.installer.keep
/usr/local/Cellar/
/usr/local/Frameworks/
/usr/local/Homebrew/
/usr/local/MacGPG2/
/usr/local/bin/
/usr/local/etc/
/usr/local/include/
/usr/local/lib/
/usr/local/man/
/usr/local/opt/
/usr/local/remotedesktop/
/usr/local/sbin/
/usr/local/share/
/usr/local/tests/
/usr/local/var/
You may wish to remove them yourself.</pre>
<p>
I manually went through all these folders and removed what I could identify as obsolete and no longer needed leftovers.<br>
Important though for example the MacGPG2 folder seems to come from the GPGTools installation, thus be aware that there are other things than Homebrew which might have installed some software under <var>/usr/local</var> and not everyhting must necessarily be removed.
</p>
<p>
<b>Unsolved problems</b><br>
As mentioned there are some things which I haven't figured out how to fix yet.
<p>
<p>
I'm missing a good solution for <a href="https://vgough.github.io/encfs/" title="EncFS">encfs</a> (which is no longer provided by Homebrew due to license changes of the underlying MacFuse project).
Compiling from source (at least through Homebrew) is not supported either (as it is marked as Linux-only and complilation is not supported anymore on macOS).<br>
<b>Update:</b> found a solution for <a href="https://blog.x-way.org/Mac/2024/12/03/How-to-install-EncFS-on-macOS-Sequoia.html" title="x-log - How to install EncFS on MacOS Sequoia">how to install EncFS on macOS Sequoia</a>.
</p>
<p>
Another missing thing (which is more a problem of not having time to deal with it yet), is the Perl ecosystem including CPAN package management.
Here probably some research to find the canonical way for installing Perl in macOS 15 is all I need. 🐪
</p>
]]></content:encoded>
</item>
<item>
<title>Migrate Syncthing from Intel to M4</title>
<link>https://blog.x-way.org/Mac/2024/11/30/Migrate-Syncthing-from-Intel-to-M4.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324429</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 30 Nov 2024 22:27:21 +0100</pubDate>
<category domain="https://blog.x-way.org/Mac/">Mac</category>
<description><![CDATA[<p>
After <a href="https://blog.x-way.org/Mac/2024/11/30/Move-from-2017-Intel-MacBook-Pro-to-2024-M4-MacBook-Pro.html" title="x-log - Move from 2017 Intel MacBook Pro to 2024 M4 MacBook Pro">switching to an Apple Silicon CPU</a>, I'm now hunting down all the Intel-only binaries on my system.<br>
Using the Activity Monitor and ordering the processes by <var>Kind</var> is quite helpful for this.
</p>
<p>
So I identified <a href="https://syncthing.net/" title="Syncthing">Syncthing</a> to be still running as an Intel-only binary with the Rosetta 2 emulation.<br>
My <a href="https://docs.syncthing.net/users/autostart.html#without-homebrew" title="Starting Syncthing Automatically - Without Homebrew">installation of Syncthing</a> is quite old, so it isn't managed by Homebrew yet.<br>
This actually made the switch quite easy:
</p>
<ul>
<li>Shutdown syncthing</li>
<li>Download latest release zip for macos-arm64 from <a href="https://github.com/syncthing/syncthing/releases/latest" title="Latest Release - syncthing/syncthing">https://github.com/syncthing/syncthing/releases/latest</a></li>
<li>Remove the old binaries:<pre>rm $HOME/bin/syncthing
rm $HOME/bin/syncthing.old</pre></li>
<li>Unzip the downloaded release and move the <var>syncthing</var> binary to <var>$HOME/bin/syncthing</var></li>
<li>Kill all running syncthing processes (they are auto-restarted via launchd)</li>
<li>You might get a popup to approve the newly downloaded binary when launchd does the restart</li>
<li>Check in Activity Monitor that the running Syncthing processes are now Apple binaries 🍏</li>
</ul>
]]></description>
<content:encoded><![CDATA[<p>
After <a href="https://blog.x-way.org/Mac/2024/11/30/Move-from-2017-Intel-MacBook-Pro-to-2024-M4-MacBook-Pro.html" title="x-log - Move from 2017 Intel MacBook Pro to 2024 M4 MacBook Pro">switching to an Apple Silicon CPU</a>, I'm now hunting down all the Intel-only binaries on my system.<br>
Using the Activity Monitor and ordering the processes by <var>Kind</var> is quite helpful for this.
</p>
<p>
So I identified <a href="https://syncthing.net/" title="Syncthing">Syncthing</a> to be still running as an Intel-only binary with the Rosetta 2 emulation.<br>
My <a href="https://docs.syncthing.net/users/autostart.html#without-homebrew" title="Starting Syncthing Automatically - Without Homebrew">installation of Syncthing</a> is quite old, so it isn't managed by Homebrew yet.<br>
This actually made the switch quite easy:
</p>
<ul>
<li>Shutdown syncthing</li>
<li>Download latest release zip for macos-arm64 from <a href="https://github.com/syncthing/syncthing/releases/latest" title="Latest Release - syncthing/syncthing">https://github.com/syncthing/syncthing/releases/latest</a></li>
<li>Remove the old binaries:<pre>rm $HOME/bin/syncthing
rm $HOME/bin/syncthing.old</pre></li>
<li>Unzip the downloaded release and move the <var>syncthing</var> binary to <var>$HOME/bin/syncthing</var></li>
<li>Kill all running syncthing processes (they are auto-restarted via launchd)</li>
<li>You might get a popup to approve the newly downloaded binary when launchd does the restart</li>
<li>Check in Activity Monitor that the running Syncthing processes are now Apple binaries 🍏</li>
</ul>
]]></content:encoded>
</item>
<item>
<title>Move from 2017 Intel MacBook Pro to 2024 M4 MacBook Pro</title>
<link>https://blog.x-way.org/Mac/2024/11/30/Move-from-2017-Intel-MacBook-Pro-to-2024-M4-MacBook-Pro.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324427</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 30 Nov 2024 21:28:31 +0100</pubDate>
<category domain="https://blog.x-way.org/Mac/">Mac</category>
<description><![CDATA[<p>
The <a href="https://blog.x-way.org/Misc/2024/11/29/Out-for-Delivery.html" title="x-log - Out for Delivery">new laptop</a> arrived and now it's time for the big migration.<br>
This includes not only a change in the physical device, but also a change in OS version and more importantly in CPU architecture.<br>
Luckily there are some very helpful tools making this a quite smooth experience.
</p>
<p>
Overal plan of attack:
</p>
<ul>
<li>Make a Time Machine backup to an external USB disk.</li>
<li>Start the new laptop and use the Migration Assistant to restore from the Time Machine backup.</li>
<li>Go to sleep / do something else, while the restore process is running.</li>
<li>After the restore is completed, login and fix all the problems caused by the OS version and CPU architecture change :-)</li>
</ul>
<p>
This plan worked quite well for me (as I'm already writing this blogpost with the new laptop).<br>
There are of course some expected and some unexptected problems that need to be addressed.
</p>
<p>
<b>Rosetta 2</b><br>
Directly after the first start, there was a system message asking me if Rosetta 2 should be enabled.<br>
Rosetta 2 is the emulation layer built into macOS that allows to run Intel-only binaries on the Apple Silicon CPUs.<br>
To reduce the ammount of immediate problems to fix, I enabled it for now.<br>
Even though over time I plan to replace all Intel-only binaries with newer versions.
</p>
<p>
<b>1Password</b><br>
One unexpected problem was <a href="https://1password.com/" title="Top-Rated Password Manager | 1Password">1Password</a>.
There I was prompted to install the old version 7 from the App Store.<br>
It took some time to figure out that the current version 8 is no longer distributed through the App Store.<br>
Instead I had to remove the (freshly installed) 1Password 7 App from <var>/Applications</var>.
And then needed to download their <a href="https://1password.com/downloads/mac" title="Download 1Password for Mac">custom installer</a> from their website.<br>
The installer in turn then did download and install the latest 1Password version 8.
</p>
<p>
<b>Homebrew</b><br>
On the list of expected problems was <a href="https://brew.sh/" title="Homebrew — The Missing Package Manager for macOS">Homebrew</a>.<br>
Here not only I had a big collection of pre-compiled (for Intel) opensource binaries that needed to be changed into pre-compiled binaries for Apple Silicon.
But also the root folder of the whole Homebrew installation changed from <var>/usr/local</var> to <var>/opt/homebrew</var>.<br>
And to make matters worse, some of the non-opensource software distributed by Homebrew in so called <var>casks</var> keeps using the old <var>/usr/local</var>.<br>
For the migration of the binaries, I followed the FAQ entry <a href="https://docs.brew.sh/Common-Issues#unintentional-dual-homebrew-installations" title="Common Issues - Unintentional dual Homebrew installations">here</a>.<br>
As expected this did not go over completely smooth and quite some research, manual fixing and cleanup was needed.<br>
I will write more about the problems/fixes and tricks I found out in a future blogpost.<br>
<b>Update:</b> please have a look at <a href="https://blog.x-way.org/Mac/2024/12/01/Migrate-Homebrew-from-Intel-to-M4-MacBook-Pro.html" title="x-log - Migrate Homebrew from Intel to M4 MacBook Pro">the dedicated blogpost</a> for all the tricks and learnings of the Homebrew migration.
</p>
<p>
<b>GPGTools</b><br>
Not completely unexpected, but surprisingly smooth was the migration of MacGPG and the GPG plugin for Mail.app.<br>
They provide a <a href="https://gpgtools.org/sequoia" title="GPG Suite">dedicated version</a> of the software which brings compatibility with macOS Sequoia.<br>
After running the installer to update the software, only a re-entering of the license key is needed and everything works as before.
</p>
<p>
Besides the already mentioned surprises with Homebrew, there are still some other issues left to be fixed (and possibly new ones to be discovered).<br>
Overall the laptop is working very well and my familiar environment is mostly there 😌
</p>
]]></description>
<content:encoded><![CDATA[<p>
The <a href="https://blog.x-way.org/Misc/2024/11/29/Out-for-Delivery.html" title="x-log - Out for Delivery">new laptop</a> arrived and now it's time for the big migration.<br>
This includes not only a change in the physical device, but also a change in OS version and more importantly in CPU architecture.<br>
Luckily there are some very helpful tools making this a quite smooth experience.
</p>
<p>
Overal plan of attack:
</p>
<ul>
<li>Make a Time Machine backup to an external USB disk.</li>
<li>Start the new laptop and use the Migration Assistant to restore from the Time Machine backup.</li>
<li>Go to sleep / do something else, while the restore process is running.</li>
<li>After the restore is completed, login and fix all the problems caused by the OS version and CPU architecture change :-)</li>
</ul>
<p>
This plan worked quite well for me (as I'm already writing this blogpost with the new laptop).<br>
There are of course some expected and some unexptected problems that need to be addressed.
</p>
<p>
<b>Rosetta 2</b><br>
Directly after the first start, there was a system message asking me if Rosetta 2 should be enabled.<br>
Rosetta 2 is the emulation layer built into macOS that allows to run Intel-only binaries on the Apple Silicon CPUs.<br>
To reduce the ammount of immediate problems to fix, I enabled it for now.<br>
Even though over time I plan to replace all Intel-only binaries with newer versions.
</p>
<p>
<b>1Password</b><br>
One unexpected problem was <a href="https://1password.com/" title="Top-Rated Password Manager | 1Password">1Password</a>.
There I was prompted to install the old version 7 from the App Store.<br>
It took some time to figure out that the current version 8 is no longer distributed through the App Store.<br>
Instead I had to remove the (freshly installed) 1Password 7 App from <var>/Applications</var>.
And then needed to download their <a href="https://1password.com/downloads/mac" title="Download 1Password for Mac">custom installer</a> from their website.<br>
The installer in turn then did download and install the latest 1Password version 8.
</p>
<p>
<b>Homebrew</b><br>
On the list of expected problems was <a href="https://brew.sh/" title="Homebrew — The Missing Package Manager for macOS">Homebrew</a>.<br>
Here not only I had a big collection of pre-compiled (for Intel) opensource binaries that needed to be changed into pre-compiled binaries for Apple Silicon.
But also the root folder of the whole Homebrew installation changed from <var>/usr/local</var> to <var>/opt/homebrew</var>.<br>
And to make matters worse, some of the non-opensource software distributed by Homebrew in so called <var>casks</var> keeps using the old <var>/usr/local</var>.<br>
For the migration of the binaries, I followed the FAQ entry <a href="https://docs.brew.sh/Common-Issues#unintentional-dual-homebrew-installations" title="Common Issues - Unintentional dual Homebrew installations">here</a>.<br>
As expected this did not go over completely smooth and quite some research, manual fixing and cleanup was needed.<br>
I will write more about the problems/fixes and tricks I found out in a future blogpost.<br>
<b>Update:</b> please have a look at <a href="https://blog.x-way.org/Mac/2024/12/01/Migrate-Homebrew-from-Intel-to-M4-MacBook-Pro.html" title="x-log - Migrate Homebrew from Intel to M4 MacBook Pro">the dedicated blogpost</a> for all the tricks and learnings of the Homebrew migration.
</p>
<p>
<b>GPGTools</b><br>
Not completely unexpected, but surprisingly smooth was the migration of MacGPG and the GPG plugin for Mail.app.<br>
They provide a <a href="https://gpgtools.org/sequoia" title="GPG Suite">dedicated version</a> of the software which brings compatibility with macOS Sequoia.<br>
After running the installer to update the software, only a re-entering of the license key is needed and everything works as before.
</p>
<p>
Besides the already mentioned surprises with Homebrew, there are still some other issues left to be fixed (and possibly new ones to be discovered).<br>
Overall the laptop is working very well and my familiar environment is mostly there 😌
</p>
]]></content:encoded>
</item>
<item>
<title>Out for Delivery</title>
<link>https://blog.x-way.org/Misc/2024/11/29/Out-for-Delivery.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324426</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Fri, 29 Nov 2024 11:28:38 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>
<img src="https://blog.x-way.org/images/out-for-delivery.png" width="584" height="133" alt="Out for Delivery" />
</p>
<p>
<a href="https://blog.x-way.org/Mac/2024/11/17/My-Mac-history.html" title="x-log - My Mac history">It's</a> getting closer and closer... 😊
</p>
]]></description>
<content:encoded><![CDATA[<p>
<img src="https://blog.x-way.org/images/out-for-delivery.png" width="584" height="133" alt="Out for Delivery" />
</p>
<p>
<a href="https://blog.x-way.org/Mac/2024/11/17/My-Mac-history.html" title="x-log - My Mac history">It's</a> getting closer and closer... 😊
</p>
]]></content:encoded>
</item>
<item>
<title>My Mac history</title>
<link>https://blog.x-way.org/Mac/2024/11/17/My-Mac-history.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324425</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 17 Nov 2024 18:10:59 +0100</pubDate>
<category domain="https://blog.x-way.org/Mac/">Mac</category>
<description><![CDATA[<p>
My current laptop is dying of age after 7 years. Thus I'm getting a new one to replace it.<br>
As part of the research, I looked for my last laptop purchase.<br>
I not only found my last one, but also all the previous ones.<br>
So I established my personal Mac history:
</p>
<table>
<thead>
<tr><th>Purchased</th><th>Type</th><th>Display</th><th>Processor</th><th>Memory</th><th>Storage</th></tr>
</thead>
<tbody>
<tr><td>October 2003</td><td>PowerBook</td><td>15.2″</td><td>1.25GHz PowerPC G4</td><td>512MB</td><td>80GB</td></tr>
<tr><td>January 2007</td><td>MacBook Pro</td><td>15.4″</td><td>2.33GHz Intel Core 2 Duo</td><td>2GB</td><td>120GB</td></tr>
<tr><td>May 2012</td><td>MacBook Pro</td><td>15.4″</td><td>2.5GHz Quad-Core Intel Core i7</td><td>8GB</td><td>750GB</td></tr>
<tr><td>October 2017</td><td>MacBook Pro</td><td>13.3″</td><td>2.3GHz Dual-Core Intel Core i5</td><td>16GB</td><td>1TB</td></tr>
<tr><td>November 2024</td><td>MacBook Pro</td><td>14.2″</td><td>M4 Pro 14-Core CPU, 20-Core GPU, 16-Core Neural Engine</td><td>48GB</td><td>2TB</td></tr>
</tbody>
</table>
<p>
Reflecting on it, it seems I get quite a good milage out of my laptops.<br>
Current replacement due to age related failures after 7 years is the top one.
</p>
<p>
The previous 2017 replacement was similar due to age related failures after 5 years.
</p>
<p>
For the 2012 replacement it is a bit of a different story, as my laptop at the time was stolen from me.<br>
But I still got five years out of it before that.
</p>
<p>
The 2007 replacement was the switch to Intel after 4 years on PowerPC.<br>
I was very happy with my PowerBook at the time, even helped to reverse-engineer the wireless chipset to <a href="https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/wireless/broadcom/b43/main.c?h=v6.11.9#n10" title="main.c « b43 « broadcom « wireless « net « drivers - kernel/git/stable/linux.git - Linux kernel stable tree">write the Linux driver</a> for it :-)
</p>
]]></description>
<content:encoded><![CDATA[<p>
My current laptop is dying of age after 7 years. Thus I'm getting a new one to replace it.<br>
As part of the research, I looked for my last laptop purchase.<br>
I not only found my last one, but also all the previous ones.<br>
So I established my personal Mac history:
</p>
<table>
<thead>
<tr><th>Purchased</th><th>Type</th><th>Display</th><th>Processor</th><th>Memory</th><th>Storage</th></tr>
</thead>
<tbody>
<tr><td>October 2003</td><td>PowerBook</td><td>15.2″</td><td>1.25GHz PowerPC G4</td><td>512MB</td><td>80GB</td></tr>
<tr><td>January 2007</td><td>MacBook Pro</td><td>15.4″</td><td>2.33GHz Intel Core 2 Duo</td><td>2GB</td><td>120GB</td></tr>
<tr><td>May 2012</td><td>MacBook Pro</td><td>15.4″</td><td>2.5GHz Quad-Core Intel Core i7</td><td>8GB</td><td>750GB</td></tr>
<tr><td>October 2017</td><td>MacBook Pro</td><td>13.3″</td><td>2.3GHz Dual-Core Intel Core i5</td><td>16GB</td><td>1TB</td></tr>
<tr><td>November 2024</td><td>MacBook Pro</td><td>14.2″</td><td>M4 Pro 14-Core CPU, 20-Core GPU, 16-Core Neural Engine</td><td>48GB</td><td>2TB</td></tr>
</tbody>
</table>
<p>
Reflecting on it, it seems I get quite a good milage out of my laptops.<br>
Current replacement due to age related failures after 7 years is the top one.
</p>
<p>
The previous 2017 replacement was similar due to age related failures after 5 years.
</p>
<p>
For the 2012 replacement it is a bit of a different story, as my laptop at the time was stolen from me.<br>
But I still got five years out of it before that.
</p>
<p>
The 2007 replacement was the switch to Intel after 4 years on PowerPC.<br>
I was very happy with my PowerBook at the time, even helped to reverse-engineer the wireless chipset to <a href="https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/wireless/broadcom/b43/main.c?h=v6.11.9#n10" title="main.c « b43 « broadcom « wireless « net « drivers - kernel/git/stable/linux.git - Linux kernel stable tree">write the Linux driver</a> for it :-)
</p>
]]></content:encoded>
</item>
<item>
<title>GitFlops: The Dangers of Terraform Automation Platforms</title>
<link>https://blog.x-way.org/Misc/2024/11/14/GitFlops-The-Dangers-of-Terraform-Automation-Platforms.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324424</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 14 Nov 2024 10:00:27 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>
In the <a href="https://snyk.io/de/blog/gitflops-dangers-of-terraform-automation-platforms/" title="GitFlops: The Dangers of Terraform Automation Platforms | Snyk">GitFlops: The Dangers of Terraform Automation Platforms</a> article Elliot Ward highlights how <a href="https://www.terraform.io/" title="Terraform by HashiCorp">Terraform</a> automation platforms can be exploited to compromise cloud environments.
</p>
<p>
In particular it looks at how to exploit the <code>terraform plan</code> phase to execute commands and gain access to cloud infrastructure credentials.<br>
In combination with a classic GitOps flow, where unprivileged users can open pull-requests and <code>terraform plan</code> is run on these pull-requests, this creates privilege escalation vulnerabilities putting the cloud infrastructure at risk.
</p>
<p>
In terms of preventing this, the recommendation is to validate Terraform config before running <code>terraform plan</code> on it.<br>
One tool mentioned in the article that can be used to for this validation is <a href="https://www.conftest.dev/" title="Conftest">Conftest</a>.
</p>
<p>
A month ago, <a href="https://bern.bsides.ch/agenda/abstracts-and-bios/#terraform" title="Security Bsides Bern">Elliot also presented the topic at the BSides Bern conference</a>.<br>
The slides of the presentation have been made available by the conference, <a href="https://blog.x-way.org/stuff/2-Elliot-BSides-Bern-2024.pdf" title="GitFlops: Breaking Terraform Lifecycle Management Tool">here is a copy</a>.
</p>
]]></description>
<content:encoded><![CDATA[<p>
In the <a href="https://snyk.io/de/blog/gitflops-dangers-of-terraform-automation-platforms/" title="GitFlops: The Dangers of Terraform Automation Platforms | Snyk">GitFlops: The Dangers of Terraform Automation Platforms</a> article Elliot Ward highlights how <a href="https://www.terraform.io/" title="Terraform by HashiCorp">Terraform</a> automation platforms can be exploited to compromise cloud environments.
</p>
<p>
In particular it looks at how to exploit the <code>terraform plan</code> phase to execute commands and gain access to cloud infrastructure credentials.<br>
In combination with a classic GitOps flow, where unprivileged users can open pull-requests and <code>terraform plan</code> is run on these pull-requests, this creates privilege escalation vulnerabilities putting the cloud infrastructure at risk.
</p>
<p>
In terms of preventing this, the recommendation is to validate Terraform config before running <code>terraform plan</code> on it.<br>
One tool mentioned in the article that can be used to for this validation is <a href="https://www.conftest.dev/" title="Conftest">Conftest</a>.
</p>
<p>
A month ago, <a href="https://bern.bsides.ch/agenda/abstracts-and-bios/#terraform" title="Security Bsides Bern">Elliot also presented the topic at the BSides Bern conference</a>.<br>
The slides of the presentation have been made available by the conference, <a href="https://blog.x-way.org/stuff/2-Elliot-BSides-Bern-2024.pdf" title="GitFlops: Breaking Terraform Lifecycle Management Tool">here is a copy</a>.
</p>
]]></content:encoded>
</item>
<item>
<title>Surveillance Self-Defense</title>
<link>https://blog.x-way.org/Misc/2024/11/12/Surveillance-Self-Defense.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324423</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 12 Nov 2024 23:42:37 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>
The <a href="https://www.eff.org/" title="Electronic Frontier Foundation | Defending your rights in the digital world">Electronic Frontier Foundation</a> provides the <a href="https://ssd.eff.org/" title="Surveillance Self-Defense">Surveillance Self-Defense</a> guide.
</p>
<p>
When talking about security it is important to known what you want to protect.<br>
The <a href="https://ssd.eff.org/module/your-security-plan" title="Your Security Plan | Surveillance Self-Defense">Your Security Plan</a> module of the guide covers this topic and is a good starting point.
</p>
<p>
(<a href="https://hachyderm.io/@evacide/113451271143994660" title="evacide: "I'm seeing a lot of bad digital security advice o…" - Hachyderm.io">via</a>)
</p>
]]></description>
<content:encoded><![CDATA[<p>
The <a href="https://www.eff.org/" title="Electronic Frontier Foundation | Defending your rights in the digital world">Electronic Frontier Foundation</a> provides the <a href="https://ssd.eff.org/" title="Surveillance Self-Defense">Surveillance Self-Defense</a> guide.
</p>
<p>
When talking about security it is important to known what you want to protect.<br>
The <a href="https://ssd.eff.org/module/your-security-plan" title="Your Security Plan | Surveillance Self-Defense">Your Security Plan</a> module of the guide covers this topic and is a good starting point.
</p>
<p>
(<a href="https://hachyderm.io/@evacide/113451271143994660" title="evacide: "I'm seeing a lot of bad digital security advice o…" - Hachyderm.io">via</a>)
</p>
]]></content:encoded>
</item>
<item>
<title>Go Turns 15</title>
<link>https://blog.x-way.org/Coding/2024/11/12/Go-Turns-15.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324422</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 12 Nov 2024 20:29:30 +0100</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>
<a href="https://go.dev/blog/15years" title="Go Turns 15 - The Go Programming Language">Happy birthday, Go!</a> 🎂
</p>
]]></description>
<content:encoded><![CDATA[<p>
<a href="https://go.dev/blog/15years" title="Go Turns 15 - The Go Programming Language">Happy birthday, Go!</a> 🎂
</p>
]]></content:encoded>
</item>
<item>
<title>Log the real IP with lighttpd</title>
<link>https://blog.x-way.org/Linux/2024/11/11/Log-the-real-IP-with-lighttpd.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324421</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 11 Nov 2024 14:15:11 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>
The static pages of the blog here are served from a <a href="https://www.lighttpd.net/" title="Lighttpd - fly light">lighttpd</a> container with an <a href="https://nginx.org/" title="nginx">nginx</a> proxy in front.<br>
I was looking through the lighttpd access logs and was a bit annoyed as it showed the internal IP of the nginx proxy.
</p>
<p>
My nginx instance is already setup to forward the actual remote IP in the <code>X-Real-IP</code> header.<br>
Thus I needed to make lighttpd use the forwarded IP from the header in the access logs.<br>
This can be achieved with the <a href="https://redmine.lighttpd.net/projects/lighttpd/wiki/Mod_extforward" title="Mod extforward - Lighttpd - lighty labs">extforward module</a> using the following configuration snippet:
</p>
<pre>server.modules += ("mod_extforward")
extforward.headers = ("X-Real-IP")
extforward.forwarder = ("10.111.0.0/16" => "trust")</pre>
<p>
With this config, lighttpd uses the <code>X-Real-IP</code> in the access logs.<br>
The override is only performed when the connection comes from the 10.111.0.0/16 subnet.
Which prevents remote IP spoofing via injected/faked headers.<br>
(the 10.111.0.0/16 subnet is my internal container network where nginx is running)
</p>
]]></description>
<content:encoded><![CDATA[<p>
The static pages of the blog here are served from a <a href="https://www.lighttpd.net/" title="Lighttpd - fly light">lighttpd</a> container with an <a href="https://nginx.org/" title="nginx">nginx</a> proxy in front.<br>
I was looking through the lighttpd access logs and was a bit annoyed as it showed the internal IP of the nginx proxy.
</p>
<p>
My nginx instance is already setup to forward the actual remote IP in the <code>X-Real-IP</code> header.<br>
Thus I needed to make lighttpd use the forwarded IP from the header in the access logs.<br>
This can be achieved with the <a href="https://redmine.lighttpd.net/projects/lighttpd/wiki/Mod_extforward" title="Mod extforward - Lighttpd - lighty labs">extforward module</a> using the following configuration snippet:
</p>
<pre>server.modules += ("mod_extforward")
extforward.headers = ("X-Real-IP")
extforward.forwarder = ("10.111.0.0/16" => "trust")</pre>
<p>
With this config, lighttpd uses the <code>X-Real-IP</code> in the access logs.<br>
The override is only performed when the connection comes from the 10.111.0.0/16 subnet.
Which prevents remote IP spoofing via injected/faked headers.<br>
(the 10.111.0.0/16 subnet is my internal container network where nginx is running)
</p>
]]></content:encoded>
</item>
<item>
<title>Fix URL used by ntpleapfetch</title>
<link>https://blog.x-way.org/Linux/2024/11/10/Fix-URL-used-by-ntpleapfetch.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324420</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 10 Nov 2024 19:46:29 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>
The other morning I was greeted by a mailbox full of messages from failed cronjobs.<br>
The reported error message was:
</p>
<pre><28>Nov 7 02:51:02 ntpleapfetch[3253838]: Download from https://www.ietf.org/timezones/data/leap-seconds.list failed after 6 attempts
--2024-11-07 02:51:02-- https://www.ietf.org/timezones/data/leap-seconds.list
Resolving www.ietf.org (www.ietf.org)... 2606:4700::6810:2d63, 2606:4700::6810:2c63, 104.16.45.99, ...
Connecting to www.ietf.org (www.ietf.org)|2606:4700::6810:2d63|:443... connected.
HTTP request sent, awaiting response... 404 Not Found
2024-11-07 02:51:02 ERROR 404: Not Found.</pre>
<p>
The failing cronjobs were weekly invocations of <a href="https://docs.ntpsec.org/latest/ntpleapfetch.html" title="ntpleapfetch - fetch and manage local leapfile">ntpleapfetch</a> to get the latest list of leap seconds.
</p>
<p>
After some research I found out that indeed the URL returns a 404 and that there was no newer version of the Debian package available to try.<br>
Also the bugtracker didn't show anyone else dealing with this problem.
</p>
<p>
Thus I started looking at the source code of ntpsec
(which provides the ntpleapsec script).<br>
I found a commit with the promising title of <a href="https://gitlab.com/NTPsec/ntpsec/-/commit/7c13df80c896cc201afd6aa9c758fc3103fad818" title="Fix URL used by ntpleapfetch (7c13df80) · Commits · NTPsec / ntpsec · GitLab">Fix URL used by ntpleapfetch</a>.
</p>
<p>
This commit corrects the URL used for downloading the leap seconds list in the script.<br>
Later I also found a corresponding <a href="https://lists.ntpsec.org/pipermail/users/2024-November/000527.html" title="ntpleapfetch script - IETF link now dead">message in the ntpsec users mailing list</a>.
</p>
<p>
For my Debian systems there is no updated package with the new URL available yet.<br>
Thus I used the following one-liner to directly fix the ntpleapfetch script.
</p>
<pre>sed -i -e 's_^LEAPSRC="https://.*"_LEAPSRC="https://data.iana.org/time-zones/tzdb/leap-seconds.list"_' /usr/sbin/ntpleapfetch</pre>
]]></description>
<content:encoded><![CDATA[<p>
The other morning I was greeted by a mailbox full of messages from failed cronjobs.<br>
The reported error message was:
</p>
<pre><28>Nov 7 02:51:02 ntpleapfetch[3253838]: Download from https://www.ietf.org/timezones/data/leap-seconds.list failed after 6 attempts
--2024-11-07 02:51:02-- https://www.ietf.org/timezones/data/leap-seconds.list
Resolving www.ietf.org (www.ietf.org)... 2606:4700::6810:2d63, 2606:4700::6810:2c63, 104.16.45.99, ...
Connecting to www.ietf.org (www.ietf.org)|2606:4700::6810:2d63|:443... connected.
HTTP request sent, awaiting response... 404 Not Found
2024-11-07 02:51:02 ERROR 404: Not Found.</pre>
<p>
The failing cronjobs were weekly invocations of <a href="https://docs.ntpsec.org/latest/ntpleapfetch.html" title="ntpleapfetch - fetch and manage local leapfile">ntpleapfetch</a> to get the latest list of leap seconds.
</p>
<p>
After some research I found out that indeed the URL returns a 404 and that there was no newer version of the Debian package available to try.<br>
Also the bugtracker didn't show anyone else dealing with this problem.
</p>
<p>
Thus I started looking at the source code of ntpsec
(which provides the ntpleapsec script).<br>
I found a commit with the promising title of <a href="https://gitlab.com/NTPsec/ntpsec/-/commit/7c13df80c896cc201afd6aa9c758fc3103fad818" title="Fix URL used by ntpleapfetch (7c13df80) · Commits · NTPsec / ntpsec · GitLab">Fix URL used by ntpleapfetch</a>.
</p>
<p>
This commit corrects the URL used for downloading the leap seconds list in the script.<br>
Later I also found a corresponding <a href="https://lists.ntpsec.org/pipermail/users/2024-November/000527.html" title="ntpleapfetch script - IETF link now dead">message in the ntpsec users mailing list</a>.
</p>
<p>
For my Debian systems there is no updated package with the new URL available yet.<br>
Thus I used the following one-liner to directly fix the ntpleapfetch script.
</p>
<pre>sed -i -e 's_^LEAPSRC="https://.*"_LEAPSRC="https://data.iana.org/time-zones/tzdb/leap-seconds.list"_' /usr/sbin/ntpleapfetch</pre>
]]></content:encoded>
</item>
<item>
<title>Tools for writing secure Go code</title>
<link>https://blog.x-way.org/Coding/2024/11/06/Tools-for-writing-secure-Go-code.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324419</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 06 Nov 2024 00:18:24 +0100</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>
In his <a href="https://jarosz.dev/article/writing-secure-go-code/" title="Writing secure Go code | Jakub Jarosz">writing secure Go code</a> article, Jakub Jarosz lists tools that help with writing secure Go code.<br>
The article lists the tools and for each of them explains what it does and how it contributes to writing secure Go code.
</p>
<p>
The following tools are covered:
</p>
<ul>
<li><code>go vet</code></li>
<li><code>staticcheck</code></li>
<li><code>golangci-lint</code></li>
<li><code>go test -race</code></li>
<li><code>govulncheck</code></li>
<li><code>gosec</code></li>
</ul>
<p>
An interesting learning for me whas that <code>govulncheck</code> can not only be used to analyze source code, but also to analyze existing binaries.<br>
And there it scans the used libraries for vulnerabilities and wether the vulnerable code paths are actually invoked by the code in the binary.
</p>
<p>
In the build pipelines of my Go programs, some of these tools are already used.<br>
Room for improvement exists when it comes to using the <code>govulncheck</code> and <code>gosec</code> tools.<br>
Another lonely winter weekend task :-)
</p>
]]></description>
<content:encoded><![CDATA[<p>
In his <a href="https://jarosz.dev/article/writing-secure-go-code/" title="Writing secure Go code | Jakub Jarosz">writing secure Go code</a> article, Jakub Jarosz lists tools that help with writing secure Go code.<br>
The article lists the tools and for each of them explains what it does and how it contributes to writing secure Go code.
</p>
<p>
The following tools are covered:
</p>
<ul>
<li><code>go vet</code></li>
<li><code>staticcheck</code></li>
<li><code>golangci-lint</code></li>
<li><code>go test -race</code></li>
<li><code>govulncheck</code></li>
<li><code>gosec</code></li>
</ul>
<p>
An interesting learning for me whas that <code>govulncheck</code> can not only be used to analyze source code, but also to analyze existing binaries.<br>
And there it scans the used libraries for vulnerabilities and wether the vulnerable code paths are actually invoked by the code in the binary.
</p>
<p>
In the build pipelines of my Go programs, some of these tools are already used.<br>
Room for improvement exists when it comes to using the <code>govulncheck</code> and <code>gosec</code> tools.<br>
Another lonely winter weekend task :-)
</p>
]]></content:encoded>
</item>
<item>
<title>Please publish and share more</title>
<link>https://blog.x-way.org/Misc/2024/11/03/Please-publish-and-share-more.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324418</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 03 Nov 2024 10:54:36 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>
<a href="https://micro.webology.dev/2024/11/02/please-publish-and.html" title="Please publish and share more - Jiff Triplett's Micro.blog">Please publish and share more</a> from Jeff Triplett. (<a href="https://simonwillison.net/2024/Nov/2/please-publish-and-share-more/" title="Please publish and share more | Simon Willisons's Weblog">via</a>)
</p>
<blockquote cite="https://micro.webology.dev/2024/11/02/please-publish-and.html">
Friends, I encourage you to publish more, indirectly meaning you should write more and then share it.
</blockquote>
<blockquote cite="https://micro.webology.dev/2024/11/02/please-publish-and.html">
You don’t have to change the world with every post. You might publish a quick thought or two that helps encourage someone else to try something new, listen to a new song, or binge-watch a new series.
</blockquote>
<blockquote cite="https://micro.webology.dev/2024/11/02/please-publish-and.html">
Our posts are done when you say they are. You do not have to fret about sticking to landing and having a perfect conclusion. Your posts, like this post, are done after we stop writing.
</blockquote>
<p>
Reminds me that I should setup some <a href="https://indieweb.org/POSSE" title="Publish (on your) Own Site, Syndicate Elsewhere">POSSE</a> mechanism for the blog.<br>
Maybe during one of the grey and cold weekends this winter :-)
</p>
]]></description>
<content:encoded><![CDATA[<p>
<a href="https://micro.webology.dev/2024/11/02/please-publish-and.html" title="Please publish and share more - Jiff Triplett's Micro.blog">Please publish and share more</a> from Jeff Triplett. (<a href="https://simonwillison.net/2024/Nov/2/please-publish-and-share-more/" title="Please publish and share more | Simon Willisons's Weblog">via</a>)
</p>
<blockquote cite="https://micro.webology.dev/2024/11/02/please-publish-and.html">
Friends, I encourage you to publish more, indirectly meaning you should write more and then share it.
</blockquote>
<blockquote cite="https://micro.webology.dev/2024/11/02/please-publish-and.html">
You don’t have to change the world with every post. You might publish a quick thought or two that helps encourage someone else to try something new, listen to a new song, or binge-watch a new series.
</blockquote>
<blockquote cite="https://micro.webology.dev/2024/11/02/please-publish-and.html">
Our posts are done when you say they are. You do not have to fret about sticking to landing and having a perfect conclusion. Your posts, like this post, are done after we stop writing.
</blockquote>
<p>
Reminds me that I should setup some <a href="https://indieweb.org/POSSE" title="Publish (on your) Own Site, Syndicate Elsewhere">POSSE</a> mechanism for the blog.<br>
Maybe during one of the grey and cold weekends this winter :-)
</p>
]]></content:encoded>
</item>
<item>
<title>Missing watch command on macOS</title>
<link>https://blog.x-way.org/Mac/2024/11/02/Missing-watch-command-on-macOS.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324417</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 02 Nov 2024 16:21:30 +0100</pubDate>
<category domain="https://blog.x-way.org/Mac/">Mac</category>
<description><![CDATA[<p>
I wanted to see the output of a program repeatedly with the <kbd>watch</kbd> command.<br>
To my surprise this failed on my macOS laptop with the following error:
</p>
<pre>% watch ipaddr
zsh: command not found: watch</pre>
<p>
Turns out that macOS does not have the <kbd>watch</kbd> command installed by default.
</p>
<pre>% which watch
watch not found</pre>
<p>
Thankfully this can be fixed easily by using homebrew to install the watch binary:
</p>
<pre>% brew install watch</pre>
]]></description>
<content:encoded><![CDATA[<p>
I wanted to see the output of a program repeatedly with the <kbd>watch</kbd> command.<br>
To my surprise this failed on my macOS laptop with the following error:
</p>
<pre>% watch ipaddr
zsh: command not found: watch</pre>
<p>
Turns out that macOS does not have the <kbd>watch</kbd> command installed by default.
</p>
<pre>% which watch
watch not found</pre>
<p>
Thankfully this can be fixed easily by using homebrew to install the watch binary:
</p>
<pre>% brew install watch</pre>
]]></content:encoded>
</item>
<item>
<title>SlackSecOps - delegating remediation to employees</title>
<link>https://blog.x-way.org/Misc/2024/11/01/SlackSecOps-delegating-remediation-to-employees.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324416</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Fri, 01 Nov 2024 16:05:10 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>
In the <a href="https://mayakaczorowski.com/blogs/slacksecops" title="Delegating security remediation to employees via Slack">Delegating security remediation to employees via Slack</a> article, <a href="https://mayakaczorowski.com/" title="Maya Kaczorowski">Maya Kaczorowski</a> coins the term SlackSecOps to describe automation and delegation of security tasks to employees.<br>
The article gives a nice overview of some ideas that are more and more applied by security teams and tools.
</p>
<p>
A couple years ago such ideas were mostly custom built bots/automations at larger companies, but not shared more widely.<br>
Nowadays there seems to be a much broader adoption of these in companies, especially the Alert and Remind categories.<br>
The most interesting ones are Delegation and Respond, which I would claim also can have the most impact.
</p>
<p>
By delegating security remediation tasks directly to the involved persons, the handling of the task becomes more efficient as all the context is available.<br>
And then by providing the automation to the delegee to directly perform the remediation in self-service, this critically shortens the response cycle.<br>
With the shortened response cycle, the exposure window of a vulnerable configuration is minimized, which reduces the risk of exploitation.
</p>
<p>
<img src="https://blog.x-way.org/images/slacksecops.png" width="584" height="581" alt="The four categories of security interactions via Slack: Remind, Alert, Delegate, Respond" />
</p>
]]></description>
<content:encoded><![CDATA[<p>
In the <a href="https://mayakaczorowski.com/blogs/slacksecops" title="Delegating security remediation to employees via Slack">Delegating security remediation to employees via Slack</a> article, <a href="https://mayakaczorowski.com/" title="Maya Kaczorowski">Maya Kaczorowski</a> coins the term SlackSecOps to describe automation and delegation of security tasks to employees.<br>
The article gives a nice overview of some ideas that are more and more applied by security teams and tools.
</p>
<p>
A couple years ago such ideas were mostly custom built bots/automations at larger companies, but not shared more widely.<br>
Nowadays there seems to be a much broader adoption of these in companies, especially the Alert and Remind categories.<br>
The most interesting ones are Delegation and Respond, which I would claim also can have the most impact.
</p>
<p>
By delegating security remediation tasks directly to the involved persons, the handling of the task becomes more efficient as all the context is available.<br>
And then by providing the automation to the delegee to directly perform the remediation in self-service, this critically shortens the response cycle.<br>
With the shortened response cycle, the exposure window of a vulnerable configuration is minimized, which reduces the risk of exploitation.
</p>
<p>
<img src="https://blog.x-way.org/images/slacksecops.png" width="584" height="581" alt="The four categories of security interactions via Slack: Remind, Alert, Delegate, Respond" />
</p>
]]></content:encoded>
</item>
<item>
<title>The 250KB Club</title>
<link>https://blog.x-way.org/Misc/2024/10/31/The-250KB-Club.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324415</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 31 Oct 2024 17:44:23 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>
Similar to <a href="https://blog.x-way.org/Misc/2024/10/31/The-512KB-Club.html" title="x-log - The 512KB Club">the 512KB club</a>, there exists <a href="https://250kb.club/" title="The 250kb club">the 250KB club</a>.
It collects web pages that focus on performance, efficiency and accessibility.<br>
Qualifying sites must fullfil one requirement.<br>
The website must not exceed 256KB compressed size.
</p>
<p>
256KB Club also contains very niche sites and is great to discover some new corners of the Internet.<br>
The linked pages are often minimalistic personal pages and geeky blogs.<br>
</p>
<p>
I submitted my blog for inclusion in the club, as it measures less than 250KB.<br>
It was accepted a day earlier than for the 512KB club :-)<br>
Now the blog has its own page in the club: <a href="https://250kb.club/blog-x-way-org/" title="The 250kb club">https://250kb.club/blog-x-way-org/</a>
</p>
<p>
<a title="250KB Club page" href="https://250kb.club/blog-x-way-org"><img alt="badge: proud member of the 250KB Club" src="https://blog.x-way.org/images/color_badge_bright.png" width="200" height="30" /></a>
</p>
]]></description>
<content:encoded><![CDATA[<p>
Similar to <a href="https://blog.x-way.org/Misc/2024/10/31/The-512KB-Club.html" title="x-log - The 512KB Club">the 512KB club</a>, there exists <a href="https://250kb.club/" title="The 250kb club">the 250KB club</a>.
It collects web pages that focus on performance, efficiency and accessibility.<br>
Qualifying sites must fullfil one requirement.<br>
The website must not exceed 256KB compressed size.
</p>
<p>
256KB Club also contains very niche sites and is great to discover some new corners of the Internet.<br>
The linked pages are often minimalistic personal pages and geeky blogs.<br>
</p>
<p>
I submitted my blog for inclusion in the club, as it measures less than 250KB.<br>
It was accepted a day earlier than for the 512KB club :-)<br>
Now the blog has its own page in the club: <a href="https://250kb.club/blog-x-way-org/" title="The 250kb club">https://250kb.club/blog-x-way-org/</a>
</p>
<p>
<a title="250KB Club page" href="https://250kb.club/blog-x-way-org"><img alt="badge: proud member of the 250KB Club" src="https://blog.x-way.org/images/color_badge_bright.png" width="200" height="30" /></a>
</p>
]]></content:encoded>
</item>
<item>
<title>The 512KB Club</title>
<link>https://blog.x-way.org/Misc/2024/10/31/The-512KB-Club.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324414</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 31 Oct 2024 16:51:35 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>
Some time ago I discovered the <a href="https://512kb.club/" title="512KB Club | A showcase of lightweight websites.">512KB club</a>.
It collects performance-focused websites from across the Internet.<br>
Qualifying sites must fullfil two requirements to participate.<br>
The site must provide a reasonable amount of content.<br>
And the total uncompressed web resources must not exceed 512KB.
</p>
<p>
512KB Club is a nice resource to discover more niche sites on the Internet.<br>
Often these are handcrafted personal sites and blogs with unique content.<br>
They remind me of all the unique personal sites and blogs from before the web2.0/social-media/walled-garden time.
</p>
<p>
My blog is also very lightweight (currently clocking <a href="https://radar.cloudflare.com/scan/a327a135-e7e3-4bad-8902-c5fcb535db15/summary" title="URL Scanner | Cloudflare Radar">39.48kB on the Cloudflare URL Scanner</a>), thus I submitted it for inclusion in the list.<br>
It was accepted recently and is now listed as part of the <a href="https://512kb.club/#100" title="512KB Club | Green Team">Green Team</a> (sites smaller than 100KB).
</p>
<p>
<a href="https://512kb.club" title="a proud member of the green team of 512KB club"><img src="https://blog.x-way.org/images/green-team.svg" alt="a proud member of the green team of 512KB club" width="234" height="30" /></a>
</p>
]]></description>
<content:encoded><![CDATA[<p>
Some time ago I discovered the <a href="https://512kb.club/" title="512KB Club | A showcase of lightweight websites.">512KB club</a>.
It collects performance-focused websites from across the Internet.<br>
Qualifying sites must fullfil two requirements to participate.<br>
The site must provide a reasonable amount of content.<br>
And the total uncompressed web resources must not exceed 512KB.
</p>
<p>
512KB Club is a nice resource to discover more niche sites on the Internet.<br>
Often these are handcrafted personal sites and blogs with unique content.<br>
They remind me of all the unique personal sites and blogs from before the web2.0/social-media/walled-garden time.
</p>
<p>
My blog is also very lightweight (currently clocking <a href="https://radar.cloudflare.com/scan/a327a135-e7e3-4bad-8902-c5fcb535db15/summary" title="URL Scanner | Cloudflare Radar">39.48kB on the Cloudflare URL Scanner</a>), thus I submitted it for inclusion in the list.<br>
It was accepted recently and is now listed as part of the <a href="https://512kb.club/#100" title="512KB Club | Green Team">Green Team</a> (sites smaller than 100KB).
</p>
<p>
<a href="https://512kb.club" title="a proud member of the green team of 512KB club"><img src="https://blog.x-way.org/images/green-team.svg" alt="a proud member of the green team of 512KB club" width="234" height="30" /></a>
</p>
]]></content:encoded>
</item>
<item>
<title>cowsay_CLENA</title>
<link>https://blog.x-way.org/Coding/2024/10/30/cowsay-CLENA.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324413</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 30 Oct 2024 06:34:26 +0100</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>
Found this cute snippet in the <a href="https://github.com/numworks/epsilon/blob/master/Makefile#L163C1-L180C26" title="epsilon/Makefile - numworks/epsilon - GitHub">Makefile</a> of the <a href="https://www.numworks.com/" title="NumWorks">NumWorks</a> <a href="https://github.com/numworks/epsilon/" title="GitHub - numworks/epsilon: Modern graphing calculator operating system.">Epsilon codebase</a>.
It is a rudimentary implementation of the <a href="https://en.wikipedia.org/wiki/Cowsay" title="cowsay - Wikipedia">cowsay</a> functionality.
</p>
<p>
We also see how it is used in the <code>clena: cowsay_CLENA clean</code> part.<br>
I like how it reminds about the typo when calling the <code>clena</code> instead of the <code>clean</code> target.<br>
It gives a clear but unintrusive message about the typo, and then also does what was intented (running the <code>clean</code> target).
</p>
<pre>.PHONY: cowsay_%
cowsay_%:
@echo " -------"
@echo "| $(*F) |"
@echo " -------"
@echo " \\ ^__^"
@echo " \\ (oo)\\_______"
@echo " (__)\\ )\\/\\"
@echo " ||----w |"
@echo " || ||"
.PHONY: clena
clena: cowsay_CLENA clean</pre>
]]></description>
<content:encoded><![CDATA[<p>
Found this cute snippet in the <a href="https://github.com/numworks/epsilon/blob/master/Makefile#L163C1-L180C26" title="epsilon/Makefile - numworks/epsilon - GitHub">Makefile</a> of the <a href="https://www.numworks.com/" title="NumWorks">NumWorks</a> <a href="https://github.com/numworks/epsilon/" title="GitHub - numworks/epsilon: Modern graphing calculator operating system.">Epsilon codebase</a>.
It is a rudimentary implementation of the <a href="https://en.wikipedia.org/wiki/Cowsay" title="cowsay - Wikipedia">cowsay</a> functionality.
</p>
<p>
We also see how it is used in the <code>clena: cowsay_CLENA clean</code> part.<br>
I like how it reminds about the typo when calling the <code>clena</code> instead of the <code>clean</code> target.<br>
It gives a clear but unintrusive message about the typo, and then also does what was intented (running the <code>clean</code> target).
</p>
<pre>.PHONY: cowsay_%
cowsay_%:
@echo " -------"
@echo "| $(*F) |"
@echo " -------"
@echo " \\ ^__^"
@echo " \\ (oo)\\_______"
@echo " (__)\\ )\\/\\"
@echo " ||----w |"
@echo " || ||"
.PHONY: clena
clena: cowsay_CLENA clean</pre>
]]></content:encoded>
</item>
<item>
<title>Realizing Meshtastic's Promise with the T-Deck</title>
<link>https://blog.x-way.org/Radio/2024/10/28/Realizing-Meshtastics-Promise-with-the-T-Deck.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324412</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 28 Oct 2024 22:32:34 +0100</pubDate>
<category domain="https://blog.x-way.org/Radio/">Radio</category>
<description><![CDATA[<p>
In the <a href="https://www.jeffgeerling.com/blog/2024/realizing-meshtastics-promise-t-deck" title="Realizing Meshtastic's Promise with the T-Deck | Jeff Geerling">Realizing Meshtastic's Promise with the T-Deck</a> article, Jeff Geerling showcases the experimental <a href="https://github.com/meshtastic/device-ui" title="meshtastic/device-ui: meshtastic device-ui library">device-ui</a> for the <a href="https://www.lilygo.cc/products/t-deck" title="T-Deck - LILYGO">T-Deck</a>.
</p>
<p>
This experimental UI looks already very pretty and I expect that it will provide a very nice Meshtastic experience once all features have been implemented.<br>
The article also contains instructions on how to install a development version of the experimantal UI based on some CI snapshots.
Maybe something to try out one of these days :-)
</p>
]]></description>
<content:encoded><![CDATA[<p>
In the <a href="https://www.jeffgeerling.com/blog/2024/realizing-meshtastics-promise-t-deck" title="Realizing Meshtastic's Promise with the T-Deck | Jeff Geerling">Realizing Meshtastic's Promise with the T-Deck</a> article, Jeff Geerling showcases the experimental <a href="https://github.com/meshtastic/device-ui" title="meshtastic/device-ui: meshtastic device-ui library">device-ui</a> for the <a href="https://www.lilygo.cc/products/t-deck" title="T-Deck - LILYGO">T-Deck</a>.
</p>
<p>
This experimental UI looks already very pretty and I expect that it will provide a very nice Meshtastic experience once all features have been implemented.<br>
The article also contains instructions on how to install a development version of the experimantal UI based on some CI snapshots.
Maybe something to try out one of these days :-)
</p>
]]></content:encoded>
</item>
<item>
<title>Writing one sentence per line</title>
<link>https://blog.x-way.org/Misc/2024/10/23/Writing-one-sentence-per-line.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324411</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 23 Oct 2024 16:18:13 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>
In his <a href="https://sive.rs/1s" title="Writing one sentence per line | Derek Sivers">Writing one sentence per line</a> article, Derek Sivers explains the benefits of writing one sentence per line.<br>
The approach leverages that whitespace in HTML source code is collapsed when being rendered in the browser.<br>
Thus we can have a much more writer-friendly text formatting when editing the text, while still providing a nicely rendered output to whoever views the resulting page in a browser.
</p>
<p>
The main advantages outlined in the article are:<br>
It helps you judge each sentence on its own.<br>
It helps you vary sentence length.<br>
It helps you move sentences.<br>
It helps you see first and last words.
</p>
<p>
I really like this approach and will apply it in my future writing on the blog.<br>
The indenting of text (not explicitly mentioned in the article but visible in the source) is also something I will try to adopt.
</p>
<p>
Here is how the above two paragraphs look in the source text:
</p>
<pre><p>
The main advantages outlined in the article are:<br>
It helps you judge each sentence on its own.<br>
It helps you vary sentence length.<br>
It helps you move sentences.<br>
It helps you see first and last words.
</p>
<p>
I really like this approach and will apply it in my future writing on the blog.<br>
The indenting of text (not explicitly mentioned in the article but visible in the source) is also something I will try to adopt.
</p></pre>
]]></description>
<content:encoded><![CDATA[<p>
In his <a href="https://sive.rs/1s" title="Writing one sentence per line | Derek Sivers">Writing one sentence per line</a> article, Derek Sivers explains the benefits of writing one sentence per line.<br>
The approach leverages that whitespace in HTML source code is collapsed when being rendered in the browser.<br>
Thus we can have a much more writer-friendly text formatting when editing the text, while still providing a nicely rendered output to whoever views the resulting page in a browser.
</p>
<p>
The main advantages outlined in the article are:<br>
It helps you judge each sentence on its own.<br>
It helps you vary sentence length.<br>
It helps you move sentences.<br>
It helps you see first and last words.
</p>
<p>
I really like this approach and will apply it in my future writing on the blog.<br>
The indenting of text (not explicitly mentioned in the article but visible in the source) is also something I will try to adopt.
</p>
<p>
Here is how the above two paragraphs look in the source text:
</p>
<pre><p>
The main advantages outlined in the article are:<br>
It helps you judge each sentence on its own.<br>
It helps you vary sentence length.<br>
It helps you move sentences.<br>
It helps you see first and last words.
</p>
<p>
I really like this approach and will apply it in my future writing on the blog.<br>
The indenting of text (not explicitly mentioned in the article but visible in the source) is also something I will try to adopt.
</p></pre>
]]></content:encoded>
</item>
<item>
<title>sshidentifierlogger</title>
<link>https://blog.x-way.org/Networking/2024/10/12/sshidentifierlogger.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324410</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 12 Oct 2024 21:54:40 +0200</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p><a href="https://github.com/x-way/sshidentifierlogger" title="x-way/sshidentifierlogger">sshidentifierlogger</a> is a small tool that I started writing about 5 years ago and have been using on some of my hosts.</p>
<p>Its purpose is to listen to network traffic and passively collect identification strings during SSH handshakes.<br>Initially I had a lot of <a href="http://www.fail2ban.org/" title="fail2ban">fail2ban</a> activity on my <a href="https://en.wikipedia.org/wiki/Jump_server" title="Jump server - Wikipedia">jumphost</a>, blocking many SSH scanning/enumeration/bruteforcing attempts and wanted to know what software the attackers use.</p>
<p>A bit particular is that sshidentifierlogger does not depend on the classic C library libpcap, but rather uses the go-native <a href="https://github.com/gopacket/gopacket/tree/master/pcapgo" title="gopacket/pcapgo">pcapgo</a> implementation by <a href="https://github.com/gopacket/gopacket" title="gopacket/gopacket">gopacket</a>.<br>Thus it can be cross-compiled on any platform, which comes in handy when you do not want to install the full go buildchain on your jumphost.</p>
<p>The collected data is quite interesting (most of the scanning used to be done with libssh2).<br>Which I did leverage to write iptables rules blocking packets with undesired SSH identification strings.<br>This has been quite successfull in reducing the amount of fail2ban activity :-)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://github.com/x-way/sshidentifierlogger" title="x-way/sshidentifierlogger">sshidentifierlogger</a> is a small tool that I started writing about 5 years ago and have been using on some of my hosts.</p>
<p>Its purpose is to listen to network traffic and passively collect identification strings during SSH handshakes.<br>Initially I had a lot of <a href="http://www.fail2ban.org/" title="fail2ban">fail2ban</a> activity on my <a href="https://en.wikipedia.org/wiki/Jump_server" title="Jump server - Wikipedia">jumphost</a>, blocking many SSH scanning/enumeration/bruteforcing attempts and wanted to know what software the attackers use.</p>
<p>A bit particular is that sshidentifierlogger does not depend on the classic C library libpcap, but rather uses the go-native <a href="https://github.com/gopacket/gopacket/tree/master/pcapgo" title="gopacket/pcapgo">pcapgo</a> implementation by <a href="https://github.com/gopacket/gopacket" title="gopacket/gopacket">gopacket</a>.<br>Thus it can be cross-compiled on any platform, which comes in handy when you do not want to install the full go buildchain on your jumphost.</p>
<p>The collected data is quite interesting (most of the scanning used to be done with libssh2).<br>Which I did leverage to write iptables rules blocking packets with undesired SSH identification strings.<br>This has been quite successfull in reducing the amount of fail2ban activity :-)</p>
]]></content:encoded>
</item>
<item>
<title>Styling blockquote and pre elements</title>
<link>https://blog.x-way.org/Webdesign/2024/10/11/Styling-blockquote-and-pre-elements.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324409</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Fri, 11 Oct 2024 18:14:02 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>The <a href="https://htmlforpeople.com/css-basics#blockquotes" title="CSS Basics - Blockquotes">Blockquotes</a> and <a href="https://htmlforpeople.com/css-basics#pre-formatted-text" title="CSS Basics - Pre-formatted text">Pre-formatted text</a> sections in the <a href="https://htmlforpeople.com/" title="HTML for People">HTML for People</a> book inspired me to improve the styling of the blog.<br>The following code now defines the visual appearance of <code>blockquote</code> and <code>pre</code> elements in the blog:</p>
<pre>blockquote {
border-left: 1px dotted #ffbb18;
padding-left: 21px;
margin-left: 21px;
}
pre {
background-color: #f9f7f7;
border-radius: 4px;
padding: 4px;
}</pre>
<p>To see it in effect, scroll down to the <a href="https://blog.x-way.org/Mac/2024/09/29/Hidden-Pref-to-Restore-Slow-Motion-Dock-Minimizing-on-MacOS.html" title="x-log - Hidden Pref to Restore Slow Motion Dock Minimizing on MacOS">Hidden Pref to Restore Slow Motion Dock Minimizing on MacOS</a> or <a href="https://blog.x-way.org/Coding/2024/09/25/Notifying-external-services-about-changes-in-the-blog.html" title="x-log - Notifying external services about changes in the blog">Notifying external services about changes in the blog</a> posts.</p>
]]></description>
<content:encoded><![CDATA[<p>The <a href="https://htmlforpeople.com/css-basics#blockquotes" title="CSS Basics - Blockquotes">Blockquotes</a> and <a href="https://htmlforpeople.com/css-basics#pre-formatted-text" title="CSS Basics - Pre-formatted text">Pre-formatted text</a> sections in the <a href="https://htmlforpeople.com/" title="HTML for People">HTML for People</a> book inspired me to improve the styling of the blog.<br>The following code now defines the visual appearance of <code>blockquote</code> and <code>pre</code> elements in the blog:</p>
<pre>blockquote {
border-left: 1px dotted #ffbb18;
padding-left: 21px;
margin-left: 21px;
}
pre {
background-color: #f9f7f7;
border-radius: 4px;
padding: 4px;
}</pre>
<p>To see it in effect, scroll down to the <a href="https://blog.x-way.org/Mac/2024/09/29/Hidden-Pref-to-Restore-Slow-Motion-Dock-Minimizing-on-MacOS.html" title="x-log - Hidden Pref to Restore Slow Motion Dock Minimizing on MacOS">Hidden Pref to Restore Slow Motion Dock Minimizing on MacOS</a> or <a href="https://blog.x-way.org/Coding/2024/09/25/Notifying-external-services-about-changes-in-the-blog.html" title="x-log - Notifying external services about changes in the blog">Notifying external services about changes in the blog</a> posts.</p>
]]></content:encoded>
</item>
<item>
<title>Meshtastic Web Serial in Linux as non-root user</title>
<link>https://blog.x-way.org/Radio/2024/10/05/Meshtastic-Web-Serial-in-Linux-as-non-root-user.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324408</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 05 Oct 2024 18:49:09 +0200</pubDate>
<category domain="https://blog.x-way.org/Radio/">Radio</category>
<description><![CDATA[<p>Today I played around a bit with a <a href="https://meshtastic.org/" title="Meshtastic">Meshtastic</a> device and tried to configure it through the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API" title="Web Serial API - Web APIs | MDN">Web Serial API</a> in Chrome.<br>On my Linux system it could see the device but not really change any values, update firmware etc.</p>
<p>This confused me for some time, until I looked at the permissions of <code>/dev/ttyACM0</code> (which were <samp>crw-rw----</samp>).<br>A quick <kbd>sudo chmod a+rw /dev/ttyACM0</kbd> later, and I could write to the configuration of the Meshtastic device.<br>The more tedious part was that after every config change the device rebooted and the USB serial connection was re-initialized by Linux, thus I needed to re-run the chmod command after every change. Luckily I figured out how to enable WiFi on the device and from then on no longer needed the serial access.</p>
]]></description>
<content:encoded><![CDATA[<p>Today I played around a bit with a <a href="https://meshtastic.org/" title="Meshtastic">Meshtastic</a> device and tried to configure it through the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API" title="Web Serial API - Web APIs | MDN">Web Serial API</a> in Chrome.<br>On my Linux system it could see the device but not really change any values, update firmware etc.</p>
<p>This confused me for some time, until I looked at the permissions of <code>/dev/ttyACM0</code> (which were <samp>crw-rw----</samp>).<br>A quick <kbd>sudo chmod a+rw /dev/ttyACM0</kbd> later, and I could write to the configuration of the Meshtastic device.<br>The more tedious part was that after every config change the device rebooted and the USB serial connection was re-initialized by Linux, thus I needed to re-run the chmod command after every change. Luckily I figured out how to enable WiFi on the device and from then on no longer needed the serial access.</p>
]]></content:encoded>
</item>
<item>
<title>Enable Visual Voicemail on your iPhone with Galaxus Mobile</title>
<link>https://blog.x-way.org/Misc/2024/09/30/Enable-Visual-Voicemail-on-your-iPhone-with-Galaxus-Mobile.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324407</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 30 Sep 2024 20:47:35 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>Turns out that the procedure for enabling Visual Voicemail with <a href="https://mobile.galaxus.ch/" title="Galaxus Mobile">Galaxus Mobile</a> is the same as for <a href="https://blog.x-way.org/Misc/2024/09/24/Enable-Visual-Voicemail-on-your-iPhone-with-TalkTalk.html" title="Enable Visual Voicemail on your iPhone with TalkTalk">TalkTalk</a>.</p>
<p>In my case their database entry was somehow stuck and I first needed to send a <code>VVM OFF</code> to <code>935</code> before starting <a href="https://blog.x-way.org/Misc/2024/09/24/Enable-Visual-Voicemail-on-your-iPhone-with-TalkTalk.html" title="Enable Visual Voicemail on your iPhone with TalkTalk">the procedure</a>.</p>
]]></description>
<content:encoded><![CDATA[<p>Turns out that the procedure for enabling Visual Voicemail with <a href="https://mobile.galaxus.ch/" title="Galaxus Mobile">Galaxus Mobile</a> is the same as for <a href="https://blog.x-way.org/Misc/2024/09/24/Enable-Visual-Voicemail-on-your-iPhone-with-TalkTalk.html" title="Enable Visual Voicemail on your iPhone with TalkTalk">TalkTalk</a>.</p>
<p>In my case their database entry was somehow stuck and I first needed to send a <code>VVM OFF</code> to <code>935</code> before starting <a href="https://blog.x-way.org/Misc/2024/09/24/Enable-Visual-Voicemail-on-your-iPhone-with-TalkTalk.html" title="Enable Visual Voicemail on your iPhone with TalkTalk">the procedure</a>.</p>
]]></content:encoded>
</item>
<item>
<title>Hidden Pref to Restore Slow-Motion Dock Minimizing on MacOS</title>
<link>https://blog.x-way.org/Mac/2024/09/29/Hidden-Pref-to-Restore-Slow-Motion-Dock-Minimizing-on-MacOS.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324406</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 29 Sep 2024 01:16:45 +0200</pubDate>
<category domain="https://blog.x-way.org/Mac/">Mac</category>
<description><![CDATA[<p><a href="https://daringfireball.net/linked/2024/09/28/hidden-pref-to-restore-slow-motion-dock-minimizing-on-macos" title="Daring Fireball: Hidden Pref to Restore Slow-Motion Dock Minimizing on MacOS">Daring Fireball describes</a> how to restore the old trick of slow motion MacOS Dock effects:</p>
<blockquote cite="https://daringfireball.net/linked/2024/09/28/hidden-pref-to-restore-slow-motion-dock-minimizing-on-macos">
<p>In the midst of recording last week’s episode of The Talk Show with Nilay Patel, I offhandedly mentioned the age-old trick of holding down the Shift key while minimizing a window (clicking the yellow button) to see the genie effect in slow motion. Nilay was like “Wait, what? That’s not working for me...” and we moved on.</p>
<p><a href="https://mastodon.social/@charlesa/113212025522260922">What I’d forgotten</a> is that Apple had removed this as default behavior a few years ago (I think in MacOS 10.14 Mojave), but you can restore the feature with this hidden preference, typed in Terminal:</p>
<pre>defaults write com.apple.dock slow-motion-allowed -bool YES</pre>
<p>Then restart the Dock:</p>
<pre>killall Dock</pre>
<p>Or, in a single command:</p>
<pre>defaults write com.apple.dock slow-motion-allowed -bool YES; killall Dock</pre>
<p>I had forgotten that this had become a hidden preference, and that I’d long ago enabled it.</p>
</blockquote>
]]></description>
<content:encoded><![CDATA[<p><a href="https://daringfireball.net/linked/2024/09/28/hidden-pref-to-restore-slow-motion-dock-minimizing-on-macos" title="Daring Fireball: Hidden Pref to Restore Slow-Motion Dock Minimizing on MacOS">Daring Fireball describes</a> how to restore the old trick of slow motion MacOS Dock effects:</p>
<blockquote cite="https://daringfireball.net/linked/2024/09/28/hidden-pref-to-restore-slow-motion-dock-minimizing-on-macos">
<p>In the midst of recording last week’s episode of The Talk Show with Nilay Patel, I offhandedly mentioned the age-old trick of holding down the Shift key while minimizing a window (clicking the yellow button) to see the genie effect in slow motion. Nilay was like “Wait, what? That’s not working for me...” and we moved on.</p>
<p><a href="https://mastodon.social/@charlesa/113212025522260922">What I’d forgotten</a> is that Apple had removed this as default behavior a few years ago (I think in MacOS 10.14 Mojave), but you can restore the feature with this hidden preference, typed in Terminal:</p>
<pre>defaults write com.apple.dock slow-motion-allowed -bool YES</pre>
<p>Then restart the Dock:</p>
<pre>killall Dock</pre>
<p>Or, in a single command:</p>
<pre>defaults write com.apple.dock slow-motion-allowed -bool YES; killall Dock</pre>
<p>I had forgotten that this had become a hidden preference, and that I’d long ago enabled it.</p>
</blockquote>
]]></content:encoded>
</item>
<item>
<title>Notifying external services about changes in the blog</title>
<link>https://blog.x-way.org/Coding/2024/09/25/Notifying-external-services-about-changes-in-the-blog.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324405</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 25 Sep 2024 10:23:25 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>For some time now, I'm <a href="https://blog.x-way.org/Coding/2024/06/12/blogs-still-Pinging.html" title="blo.gs still Pinging - x-log">notifying blo.gs about changes in the blog</a>. After looking a bit into how search engines percieve my website recently, I learned that they also have some notification mechanisms for new pages/blogposts.</p>
<p>Thus I upgraded the oneliner into a dedicated script to notify external services about changes in the blog.<br>It is optimized for my Jekyll setup, where the generated pages in the _site folder are stored in git.<br>The notification ignores changes to summarized pages like rss.xml etc to only trigger notifications when there are changes in the original blog posts.</p>
<p>Here's the script, feel free to re-use (it expects to have <var>MYDOMAIN</var>, <var>INDEXNOW_API_KEY</var> and <var>BING_API_KEY</var> defined as environment variables):</p>
<pre>#!/bin/bash
set -e
set -u
set -o pipefail
CHANGES="$(git diff --name-only HEAD HEAD~1 -- _site)"
# early abort if no changes on _site
if [ -z "$CHANGES" ] ; then
echo "No changes in _site found"
exit 0
fi
# build URL list
URLLIST="\"https://${MYDOMAIN}/\""
for f in $CHANGES ; do
case "$f" in
_site/robots.txt|_site/humans.txt|_site/about.html|_site/rss.xml|_site/atom.xml|_site/feed.json|_site/sitemap.xml)
continue
;;
*)
url=$(echo "$f"|sed -e "sX^_siteXhttps://${MYDOMAIN}X")
URLLIST="${URLLIST},\"${url}\""
;;
esac
done
if [ "\"https://${MYDOMAIN}/\"" = "$URLLIST" ] ; then
echo "No relevant changes in _site found, skipping notifications"
exit 0
fi
# notify ping.blo.gs (Automattic) about updates
curl --fail -s -D - -X POST http://ping.blo.gs -H 'content-type: text/xml' --data "<?xml version=\"1.0\"?><methodCall><methodName>weblogUpdates.extendedPing</methodName><params><param><value>x-log</value></param><param><value>https://${MYDOMAIN}/</value></param><param><value></value></param><param><value>https://${MYDOMAIN}/rss.xml</value></param></params></methodCall>"
# report changed URLs to indexnow, include /indexnow canary URL
curl --fail -s -D - -X POST https://api.indexnow.org/IndexNow -H 'content-type: application/json; charset=utf-8' --data "{\"host\":\"${MYDOMAIN}\",\"key\":\"${INDEXNOW_API_KEY}\",\"urlList\":[${URLLIST},\"https://${MYDOMAIN}/indexnow\"]}"
# report changes URLs to bing, include /bingsubmit canary URL
curl --fail -s -D - -X POST "https://ssl.bing.com/webmaster/api.svc/json/SubmitUrlbatch?apikey=${BING_API_KEY}" -H 'content-type: application/json; charset=utf-8' --data "{\"siteUrl\":\"https://${MYDOMAIN}\",\"urlList\":[${URLLIST},\"https://${MYDOMAIN}/bingsubmit\"]}"</pre>
]]></description>
<content:encoded><![CDATA[<p>For some time now, I'm <a href="https://blog.x-way.org/Coding/2024/06/12/blogs-still-Pinging.html" title="blo.gs still Pinging - x-log">notifying blo.gs about changes in the blog</a>. After looking a bit into how search engines percieve my website recently, I learned that they also have some notification mechanisms for new pages/blogposts.</p>
<p>Thus I upgraded the oneliner into a dedicated script to notify external services about changes in the blog.<br>It is optimized for my Jekyll setup, where the generated pages in the _site folder are stored in git.<br>The notification ignores changes to summarized pages like rss.xml etc to only trigger notifications when there are changes in the original blog posts.</p>
<p>Here's the script, feel free to re-use (it expects to have <var>MYDOMAIN</var>, <var>INDEXNOW_API_KEY</var> and <var>BING_API_KEY</var> defined as environment variables):</p>
<pre>#!/bin/bash
set -e
set -u
set -o pipefail
CHANGES="$(git diff --name-only HEAD HEAD~1 -- _site)"
# early abort if no changes on _site
if [ -z "$CHANGES" ] ; then
echo "No changes in _site found"
exit 0
fi
# build URL list
URLLIST="\"https://${MYDOMAIN}/\""
for f in $CHANGES ; do
case "$f" in
_site/robots.txt|_site/humans.txt|_site/about.html|_site/rss.xml|_site/atom.xml|_site/feed.json|_site/sitemap.xml)
continue
;;
*)
url=$(echo "$f"|sed -e "sX^_siteXhttps://${MYDOMAIN}X")
URLLIST="${URLLIST},\"${url}\""
;;
esac
done
if [ "\"https://${MYDOMAIN}/\"" = "$URLLIST" ] ; then
echo "No relevant changes in _site found, skipping notifications"
exit 0
fi
# notify ping.blo.gs (Automattic) about updates
curl --fail -s -D - -X POST http://ping.blo.gs -H 'content-type: text/xml' --data "<?xml version=\"1.0\"?><methodCall><methodName>weblogUpdates.extendedPing</methodName><params><param><value>x-log</value></param><param><value>https://${MYDOMAIN}/</value></param><param><value></value></param><param><value>https://${MYDOMAIN}/rss.xml</value></param></params></methodCall>"
# report changed URLs to indexnow, include /indexnow canary URL
curl --fail -s -D - -X POST https://api.indexnow.org/IndexNow -H 'content-type: application/json; charset=utf-8' --data "{\"host\":\"${MYDOMAIN}\",\"key\":\"${INDEXNOW_API_KEY}\",\"urlList\":[${URLLIST},\"https://${MYDOMAIN}/indexnow\"]}"
# report changes URLs to bing, include /bingsubmit canary URL
curl --fail -s -D - -X POST "https://ssl.bing.com/webmaster/api.svc/json/SubmitUrlbatch?apikey=${BING_API_KEY}" -H 'content-type: application/json; charset=utf-8' --data "{\"siteUrl\":\"https://${MYDOMAIN}\",\"urlList\":[${URLLIST},\"https://${MYDOMAIN}/bingsubmit\"]}"</pre>
]]></content:encoded>
</item>
<item>
<title>Enable Visual Voicemail on your iPhone with TalkTalk</title>
<link>https://blog.x-way.org/Misc/2024/09/24/Enable-Visual-Voicemail-on-your-iPhone-with-TalkTalk.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324404</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 24 Sep 2024 18:36:01 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>When you switch to <a href="https://www.talktalk.ch/" title="TalkTalk • Dein Mobilfunk-, Telefon- & Internetanbieter">TalkTalk</a> as your mobile phone provider, by default Visual Voicemail for your iPhone is not enabled.<br>And you're stuck with the 90s voiceprompt of the 'Talkbox'.</p>
<p>The following steps will activate Visual Voicemail for your iPhone:</p>
<ol>
<li>Send a SMS text message with <code>VVM ON</code> to the number <code>935</code>.</li>
<li>Shortly after you should get a text message confirming that Visual Voicemail has been enabled for you.</li>
<li>Now on the iPhone, open the phone app and go to the voicemail tab. There you will either see a button asking you to setup the voicemail or a button taking you to the 90s voiceprompt.</li>
<li>Do click on this button and setup the six-digit PIN code for your voicemail (this can be done either via a call/voiceprompt or via the guided iPhone button/dialog).</li>
<li>Once you have setup the PIN for your voicemail, close the phone app on your iPhone.</li>
<li>Then open the phone app again and go to the voicemail tab, where it should show the usual Visual Voicemail list of missed calls and no longer the button to call the 90s voiceprompt.<br>In my case it took a couple minutes for this to work, thus some patience might be needed.</li>
<li>Congratulations, you have now a working Visual Voicemail on your iPhone with TalkTalk :-)</li>
</ol>
]]></description>
<content:encoded><![CDATA[<p>When you switch to <a href="https://www.talktalk.ch/" title="TalkTalk • Dein Mobilfunk-, Telefon- & Internetanbieter">TalkTalk</a> as your mobile phone provider, by default Visual Voicemail for your iPhone is not enabled.<br>And you're stuck with the 90s voiceprompt of the 'Talkbox'.</p>
<p>The following steps will activate Visual Voicemail for your iPhone:</p>
<ol>
<li>Send a SMS text message with <code>VVM ON</code> to the number <code>935</code>.</li>
<li>Shortly after you should get a text message confirming that Visual Voicemail has been enabled for you.</li>
<li>Now on the iPhone, open the phone app and go to the voicemail tab. There you will either see a button asking you to setup the voicemail or a button taking you to the 90s voiceprompt.</li>
<li>Do click on this button and setup the six-digit PIN code for your voicemail (this can be done either via a call/voiceprompt or via the guided iPhone button/dialog).</li>
<li>Once you have setup the PIN for your voicemail, close the phone app on your iPhone.</li>
<li>Then open the phone app again and go to the voicemail tab, where it should show the usual Visual Voicemail list of missed calls and no longer the button to call the 90s voiceprompt.<br>In my case it took a couple minutes for this to work, thus some patience might be needed.</li>
<li>Congratulations, you have now a working Visual Voicemail on your iPhone with TalkTalk :-)</li>
</ol>
]]></content:encoded>
</item>
<item>
<title>Another weekend, another festival - Subset Festival</title>
<link>https://blog.x-way.org/Music/2024/09/22/Another-weekend-another-festival-Subset-Festival.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324403</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 22 Sep 2024 16:42:39 +0200</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p>No festival this weekend. Did some hiking with friends instead.</p>
<p>Last weekend I attended the <a href="https://www.subset-festival.com/" title="Subset Festival | Drum & Bass | Kempttal, Switzerland">Subset Festival</a>. It was the first edition of a new drum and bass focused festival.<br>There were some great artists there, most of them I knew before and was very much looking forward to see them live.</p>
<p>My favorite one was (unsurprisingly?) <a href="https://www.andromedik.com/" title="Andromedik">Andromedik</a>, but also liked <a href="https://hybridmindsmusic.com/" title="Hybrid Minds">Hybrid Minds</a>, <a href="http://netskymusic.com/" title="Netsky">Netsky</a> and <a href="https://www.andyc.cc/" title="ANDY C">Andy C</a>.<br>Very cool was that the festival was rather small, so felt quite intimate and super close to the artists.</p>
<p>Could post the same music video <a href="https://blog.x-way.org/Music/2024/09/05/Lost-Frequencies-The-Feeling.html" title="Lost Frequencies - The Feeling - x-log">as two weeks ago</a> (Andromedik's remix of The Feeling, which he said is a song very close to his heart), but you should also discover some other tracks.<br>Thus here we go with the recently released Paradise 🥳</p>
<p><a href="https://youtu.be/f0lFG63vSqc" title="Andromedik - Paradise (ft. Luka)">Andromedik - Paradise (ft. Luka)</a></p>
]]></description>
<content:encoded><![CDATA[<p>No festival this weekend. Did some hiking with friends instead.</p>
<p>Last weekend I attended the <a href="https://www.subset-festival.com/" title="Subset Festival | Drum & Bass | Kempttal, Switzerland">Subset Festival</a>. It was the first edition of a new drum and bass focused festival.<br>There were some great artists there, most of them I knew before and was very much looking forward to see them live.</p>
<p>My favorite one was (unsurprisingly?) <a href="https://www.andromedik.com/" title="Andromedik">Andromedik</a>, but also liked <a href="https://hybridmindsmusic.com/" title="Hybrid Minds">Hybrid Minds</a>, <a href="http://netskymusic.com/" title="Netsky">Netsky</a> and <a href="https://www.andyc.cc/" title="ANDY C">Andy C</a>.<br>Very cool was that the festival was rather small, so felt quite intimate and super close to the artists.</p>
<p>Could post the same music video <a href="https://blog.x-way.org/Music/2024/09/05/Lost-Frequencies-The-Feeling.html" title="Lost Frequencies - The Feeling - x-log">as two weeks ago</a> (Andromedik's remix of The Feeling, which he said is a song very close to his heart), but you should also discover some other tracks.<br>Thus here we go with the recently released Paradise 🥳</p>
<p><a href="https://youtu.be/f0lFG63vSqc" title="Andromedik - Paradise (ft. Luka)">Andromedik - Paradise (ft. Luka)</a></p>
]]></content:encoded>
</item>
<item>
<title>Simplified archive links</title>
<link>https://blog.x-way.org/Misc/2024/09/19/Simplified-archive-links.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324402</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 19 Sep 2024 23:07:06 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>Building up on the changes from the <a href="https://blog.x-way.org/Webdesign/2024/09/14/Canonical-hints.html" title="Canonical hints - x-log">canonical hints</a>, I simplified the structure of the archive links.<p>
<p>Now it's <var>/year/month/</var> everywhere.<br>Which of course brings another round of redirects to support in the nginx config to map the <var>/archive/archive-year-month.html</var> links to <var>/year/month/</var> 🙈</p>
<p>In theory all previous link schemes should still work, but if you find a broken link, please let me know :-)</p>
]]></description>
<content:encoded><![CDATA[<p>Building up on the changes from the <a href="https://blog.x-way.org/Webdesign/2024/09/14/Canonical-hints.html" title="Canonical hints - x-log">canonical hints</a>, I simplified the structure of the archive links.<p>
<p>Now it's <var>/year/month/</var> everywhere.<br>Which of course brings another round of redirects to support in the nginx config to map the <var>/archive/archive-year-month.html</var> links to <var>/year/month/</var> 🙈</p>
<p>In theory all previous link schemes should still work, but if you find a broken link, please let me know :-)</p>
]]></content:encoded>
</item>
<item>
<title>Canonical hints</title>
<link>https://blog.x-way.org/Webdesign/2024/09/14/Canonical-hints.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324401</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 14 Sep 2024 11:44:10 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>To help regular search engines be less confused about the various pages of the blog (especially multiple generations of old inherited URL schemes), I added canonical hints to some pages.</p>
<p>Mostly straight-forward, except for the archives where I chose the concise <var>/year/month/</var> scheme instead of the full <var>/archive/archive-year-month.html</var>.<br>Curious to see how this works out. Currently the links in the navigation and overview point to the full URLs, and the short ones are only implemented with rewrites in nginx and visible in the canonical hints.</p>
]]></description>
<content:encoded><![CDATA[<p>To help regular search engines be less confused about the various pages of the blog (especially multiple generations of old inherited URL schemes), I added canonical hints to some pages.</p>
<p>Mostly straight-forward, except for the archives where I chose the concise <var>/year/month/</var> scheme instead of the full <var>/archive/archive-year-month.html</var>.<br>Curious to see how this works out. Currently the links in the navigation and overview point to the full URLs, and the short ones are only implemented with rewrites in nginx and visible in the canonical hints.</p>
]]></content:encoded>
</item>
<item>
<title>How to fix missing libcrypt.so.1 after Debian upgrade</title>
<link>https://blog.x-way.org/Linux/2024/09/14/How-to-fix-missing-libcrypt-so-1-after-Debian-upgrade.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324400</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 14 Sep 2024 06:12:04 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>I encountered an old Debian system and tried to upgrade it from Debian 10 (buster) to Debian 12 (bookworm).<br>During the <kbd>apt-get dist-upgrade</kbd> it did run into a problem, where libcrypt.so.1 was removed and the upgrade failed to continue.<br>Additionally this caused that <kbd>dpkg</kbd> itself also stopped working and that sshd stopped accepting new connections.<br>Thus fixing the following error became urgent:</p>
<pre>/usr/bin/python3: error while loading shared libraries: libcrypt.so.1: cannot open shared object file: No such file or directory</pre>
<p>Luckily I was not the first person to run into this issue.<br>In <a href="https://stackoverflow.com/questions/76906383/libcrypt-so-1-error-after-dist-update-on-debian/77957251#77957251" title="upgrade - Libcrypt.so.1 error after dist-update on Debian - Stack Overflow">a Stack Overflow answer</a> I found the crucial workaround taken from <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993755#27" title="#993755 - libcrypt.so.1: cannot open shared object file when upgrading from Stretch to Sid - Debian Bug report logs">a comment on the corresponding Debian bugreport</a>.<br>The following steps allow to manually install a copy of the missing libcrypt.so files to fix the issue (when running this you might have a newer version of the package at hand, thus adjust the <kbd>dpkg-deb</kbd> step accordingly):</p>
<pre>
cd /tmp
apt -y download libcrypt1
dpkg-deb -x libcrypt1_1%3a4.4.33-2_amd64.deb .
cp -av lib/x86_64-linux-gnu/* /lib/x86_64-linux-gnu/
apt -y --fix-broken install
</pre>
]]></description>
<content:encoded><![CDATA[<p>I encountered an old Debian system and tried to upgrade it from Debian 10 (buster) to Debian 12 (bookworm).<br>During the <kbd>apt-get dist-upgrade</kbd> it did run into a problem, where libcrypt.so.1 was removed and the upgrade failed to continue.<br>Additionally this caused that <kbd>dpkg</kbd> itself also stopped working and that sshd stopped accepting new connections.<br>Thus fixing the following error became urgent:</p>
<pre>/usr/bin/python3: error while loading shared libraries: libcrypt.so.1: cannot open shared object file: No such file or directory</pre>
<p>Luckily I was not the first person to run into this issue.<br>In <a href="https://stackoverflow.com/questions/76906383/libcrypt-so-1-error-after-dist-update-on-debian/77957251#77957251" title="upgrade - Libcrypt.so.1 error after dist-update on Debian - Stack Overflow">a Stack Overflow answer</a> I found the crucial workaround taken from <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993755#27" title="#993755 - libcrypt.so.1: cannot open shared object file when upgrading from Stretch to Sid - Debian Bug report logs">a comment on the corresponding Debian bugreport</a>.<br>The following steps allow to manually install a copy of the missing libcrypt.so files to fix the issue (when running this you might have a newer version of the package at hand, thus adjust the <kbd>dpkg-deb</kbd> step accordingly):</p>
<pre>
cd /tmp
apt -y download libcrypt1
dpkg-deb -x libcrypt1_1%3a4.4.33-2_amd64.deb .
cp -av lib/x86_64-linux-gnu/* /lib/x86_64-linux-gnu/
apt -y --fix-broken install
</pre>
]]></content:encoded>
</item>
<item>
<title>Flexboxed archive</title>
<link>https://blog.x-way.org/Webdesign/2024/09/10/Flexboxed-archive.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324398</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 10 Sep 2024 09:57:35 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Applied the <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/" title="CSS Flexbox Layout Guide | CSS-Tricks">CSS flexbox mechanism</a> to the <a href="https://blog.x-way.org/archive/" title="x-log - Archive">archive page</a>.<br>This helps to transform the steadily growing lists of monthly archive links into a more userfriendly layout, going from a single column to eight columns and bringing all the links above 'the fold'.</p>
]]></description>
<content:encoded><![CDATA[<p>Applied the <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/" title="CSS Flexbox Layout Guide | CSS-Tricks">CSS flexbox mechanism</a> to the <a href="https://blog.x-way.org/archive/" title="x-log - Archive">archive page</a>.<br>This helps to transform the steadily growing lists of monthly archive links into a more userfriendly layout, going from a single column to eight columns and bringing all the links above 'the fold'.</p>
]]></content:encoded>
</item>
<item>
<title>Another weekend, another festival</title>
<link>https://blog.x-way.org/Music/2024/09/08/Another-weekend-another-festival.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324397</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 08 Sep 2024 11:06:45 +0200</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p>I'm continueing my festival summer also this weekend. Yesterday I've attended the <a href="https://www.simmentalerbier.ch/festival/" title="Festival - Simmentaler Bier">Simmentaler Bier Festival</a>, which celebrates the 10 year anniversary of the <a href="https://www.simmentalerbier.ch/" title="Simmental Bier">Simmentaler Bier</a> brewery.</p>
<p>The festivities included some fine music from far away and not so far away.<br><a href="https://www.rooftopsailors.com/" title="Rooftop Sailors | Alternative Rock | Bern">Rooftop Sailors</a> opened the afternoon with their refreshing rock music.<br>Then came my favorite, <a href="https://www.openseason.ch/" title="Open Season">Open Season</a>, which was a nostalgy throwback as I was <a href="https://blog.x-way.org/Misc/2002/09/30/Stress_-_Ferienbeginn.html" title="x-log - Stress - Ferienbeginn">attending their concerts already 22 years ago</a> ❤️<br>Last band of the day was <a href="http://www.delinquenthabits.com/" title="Delinquent Official website – Delinquentes Para El Frente">Delinquent Habits</a>, which brought their habit from LA to serve the public Tequila shots during the concert.</p>
<p><a href="https://youtu.be/lo0arkyebdc" title="Open Season - Rocksteady">Open Season - Rocksteady</a></p>
]]></description>
<content:encoded><![CDATA[<p>I'm continueing my festival summer also this weekend. Yesterday I've attended the <a href="https://www.simmentalerbier.ch/festival/" title="Festival - Simmentaler Bier">Simmentaler Bier Festival</a>, which celebrates the 10 year anniversary of the <a href="https://www.simmentalerbier.ch/" title="Simmental Bier">Simmentaler Bier</a> brewery.</p>
<p>The festivities included some fine music from far away and not so far away.<br><a href="https://www.rooftopsailors.com/" title="Rooftop Sailors | Alternative Rock | Bern">Rooftop Sailors</a> opened the afternoon with their refreshing rock music.<br>Then came my favorite, <a href="https://www.openseason.ch/" title="Open Season">Open Season</a>, which was a nostalgy throwback as I was <a href="https://blog.x-way.org/Misc/2002/09/30/Stress_-_Ferienbeginn.html" title="x-log - Stress - Ferienbeginn">attending their concerts already 22 years ago</a> ❤️<br>Last band of the day was <a href="http://www.delinquenthabits.com/" title="Delinquent Official website – Delinquentes Para El Frente">Delinquent Habits</a>, which brought their habit from LA to serve the public Tequila shots during the concert.</p>
<p><a href="https://youtu.be/lo0arkyebdc" title="Open Season - Rocksteady">Open Season - Rocksteady</a></p>
]]></content:encoded>
</item>
<item>
<title>Lost Frequencies - The Feeling</title>
<link>https://blog.x-way.org/Music/2024/09/05/Lost-Frequencies-The-Feeling.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324396</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 05 Sep 2024 21:07:29 +0200</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p>One of my favorite moments from the second weekend of <a href="https://zurichopenair.ch/" title="ZÜRICH OPENAIR 2024">ZÜRICH OPENAIR 2024</a>: the concert of <a href="https://lostfrequencies.com/" title="Lost Frequencies">Lost Frequencies</a>, especially the drum&bass live performance of The Feeling 🥳</p>
<p><a href="https://youtu.be/hlRwWLiuNXc" title="Lost Frequencies - The Feeling (Lost Frequencies & Andromedik Deluxe Mix)">Lost Frequencies - The Feeling (Lost Frequencies & Andromedik Deluxe Mix)</a></p>
]]></description>
<content:encoded><![CDATA[<p>One of my favorite moments from the second weekend of <a href="https://zurichopenair.ch/" title="ZÜRICH OPENAIR 2024">ZÜRICH OPENAIR 2024</a>: the concert of <a href="https://lostfrequencies.com/" title="Lost Frequencies">Lost Frequencies</a>, especially the drum&bass live performance of The Feeling 🥳</p>
<p><a href="https://youtu.be/hlRwWLiuNXc" title="Lost Frequencies - The Feeling (Lost Frequencies & Andromedik Deluxe Mix)">Lost Frequencies - The Feeling (Lost Frequencies & Andromedik Deluxe Mix)</a></p>
]]></content:encoded>
</item>
<item>
<title>Added a /now page</title>
<link>https://blog.x-way.org/Misc/2024/09/03/Added-a-now-page.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324395</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 03 Sep 2024 06:59:44 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>Finally took the time to create a <a href="https://nownownow.com/about" title="What is a 'now page'?">/now page</a> and add it to the blog: <a href="https://blog.x-way.org/now" title="x-log - What I'm doing now">/now</a> 🎉
<p>Still need to figure out if it will eventually replace the <a href="https://blog.x-way.org/about.html" title="x-log - About">about page</a> or not.<br>
For now the about page links to the now page.</p>
]]></description>
<content:encoded><![CDATA[<p>Finally took the time to create a <a href="https://nownownow.com/about" title="What is a 'now page'?">/now page</a> and add it to the blog: <a href="https://blog.x-way.org/now" title="x-log - What I'm doing now">/now</a> 🎉
<p>Still need to figure out if it will eventually replace the <a href="https://blog.x-way.org/about.html" title="x-log - About">about page</a> or not.<br>
For now the about page links to the now page.</p>
]]></content:encoded>
</item>
<item>
<title>Get the PGP public key of a Proton Mail user</title>
<link>https://blog.x-way.org/Misc/2024/09/02/Get-the-PGP-public-key-of-a-Proton-Mail-user.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324394</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 02 Sep 2024 16:22:43 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://proton.me/mail" title="Proton Mail: Get a private, secure, and encrypted email account | Proton">Proton Mail</a> can sign (and encrypt) emails when it knows the PGP key of the correspondent. For this is provides PGP keys to its users.<br>Unfortunately most of them are not searchable via the traditional PGP keyservers. With the following command you can download the public PGP key of a Proton Mail user:</p>
<pre>curl -s 'https://api.protonmail.ch/pks/lookup?op=get&search=user@protonmail.com'</pre>
<p>Also, just discovered that <a href="https://gpgtools.org/" title="GPG Suite">GPG Keychain on Mac</a> detects if the clipboard contains a PGP key and asks if it should import it. Very nice feature which saves a couple clicks :-)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://proton.me/mail" title="Proton Mail: Get a private, secure, and encrypted email account | Proton">Proton Mail</a> can sign (and encrypt) emails when it knows the PGP key of the correspondent. For this is provides PGP keys to its users.<br>Unfortunately most of them are not searchable via the traditional PGP keyservers. With the following command you can download the public PGP key of a Proton Mail user:</p>
<pre>curl -s 'https://api.protonmail.ch/pks/lookup?op=get&search=user@protonmail.com'</pre>
<p>Also, just discovered that <a href="https://gpgtools.org/" title="GPG Suite">GPG Keychain on Mac</a> detects if the clipboard contains a PGP key and asks if it should import it. Very nice feature which saves a couple clicks :-)</p>
]]></content:encoded>
</item>
<item>
<title>Regex Crosswords</title>
<link>https://blog.x-way.org/Coding/2024/09/01/Regex-Crosswords.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324393</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 01 Sep 2024 21:34:09 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>Thanks to <a href="https://news.ycombinator.com/item?id=41378002" title="Regex Crossword | Hacker News">this post on Hacker News</a>, I was reminded of the joy of regex crosswords :-)</p>
<p>Nice to see that the <a href="https://regexcrossword.com/" title="Regex Crossword">regexcrossword.com site</a> has gained quite a list of puzzles and challenges since <a href="https://blog.x-way.org/Coding/2014/11/30/Regex-Crossword.html" title="Regex Crossword - x-log">the last time I blogged about it</a>.</p>
<p>Also very cool is the <a href="https://jimbly.github.io/regex-crossword/" title="RegEx Crossword">RegEx Crossword</a> project of <a href="https://github.com/Jimbly" title="Jimb Esser">Jimb Esser</a>, which provides a very smooth interface for solving hexagonal regex crosswords in the browser.<br>I remember solving the original MIT hexagonal regex crossword on paper back in the time.</p>
<p>And in addition there is a built-in editor which allows you to create your own hexagonal regex crosswords.<br>Thinking of using this to create some fun puzzle for the colleagues at work.</p>
]]></description>
<content:encoded><![CDATA[<p>Thanks to <a href="https://news.ycombinator.com/item?id=41378002" title="Regex Crossword | Hacker News">this post on Hacker News</a>, I was reminded of the joy of regex crosswords :-)</p>
<p>Nice to see that the <a href="https://regexcrossword.com/" title="Regex Crossword">regexcrossword.com site</a> has gained quite a list of puzzles and challenges since <a href="https://blog.x-way.org/Coding/2014/11/30/Regex-Crossword.html" title="Regex Crossword - x-log">the last time I blogged about it</a>.</p>
<p>Also very cool is the <a href="https://jimbly.github.io/regex-crossword/" title="RegEx Crossword">RegEx Crossword</a> project of <a href="https://github.com/Jimbly" title="Jimb Esser">Jimb Esser</a>, which provides a very smooth interface for solving hexagonal regex crosswords in the browser.<br>I remember solving the original MIT hexagonal regex crossword on paper back in the time.</p>
<p>And in addition there is a built-in editor which allows you to create your own hexagonal regex crosswords.<br>Thinking of using this to create some fun puzzle for the colleagues at work.</p>
]]></content:encoded>
</item>
<item>
<title>Vim Racer</title>
<link>https://blog.x-way.org/Linux/2024/08/26/Vim-Racer.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324392</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 26 Aug 2024 22:46:40 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p><a href="https://vim-racer.com/" title="Vim Racer - An Online Game for VIM Navigation">Vim Racer</a> is a fun game to show off your <kbd>vi</kbd> skills 🚀<br>(also insightful to explore the leaderboard and see which commands were used by others)</p>
<p><img src="https://blog.x-way.org/images/vim-racer.webp" alt="Vim Racer" height="327" width="506"></p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://vim-racer.com/" title="Vim Racer - An Online Game for VIM Navigation">Vim Racer</a> is a fun game to show off your <kbd>vi</kbd> skills 🚀<br>(also insightful to explore the leaderboard and see which commands were used by others)</p>
<p><img src="https://blog.x-way.org/images/vim-racer.webp" alt="Vim Racer" height="327" width="506"></p>
]]></content:encoded>
</item>
<item>
<title>Artemas - I Like the Way You Kiss Me (Bassjackers Remix)</title>
<link>https://blog.x-way.org/Music/2024/08/25/Artemas-I-Like-the-Way-You-Kiss-Me-Bassjackers-Remix.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324391</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 25 Aug 2024 23:54:45 +0200</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p>Catchy memory from the first weekend of <a href="https://zurichopenair.ch/" title="ZÜRICH OPENAIR 2024">ZÜRICH OPENAIR 2024</a>: <a href="https://www.arminvanbuuren.com/" title="Armin van Buuren">Armin van Buuren</a>'s version of <a href="https://en.wikipedia.org/wiki/I_Like_the_Way_You_Kiss_Me" title="I Like the Way You Kiss Me - Wikipedia">Artemas - I Like the Way You Kiss Me</a>, which is very similar to the Bassjackers Remix 🔊</p>
<p><a href="https://youtu.be/cvkjzWawH4c" title="Artemas - I Like the Way You Kiss Me (Bassjackers Remix)">Artemas - I Like the Way You Kiss Me (Bassjackers Remix)</a></p>
]]></description>
<content:encoded><![CDATA[<p>Catchy memory from the first weekend of <a href="https://zurichopenair.ch/" title="ZÜRICH OPENAIR 2024">ZÜRICH OPENAIR 2024</a>: <a href="https://www.arminvanbuuren.com/" title="Armin van Buuren">Armin van Buuren</a>'s version of <a href="https://en.wikipedia.org/wiki/I_Like_the_Way_You_Kiss_Me" title="I Like the Way You Kiss Me - Wikipedia">Artemas - I Like the Way You Kiss Me</a>, which is very similar to the Bassjackers Remix 🔊</p>
<p><a href="https://youtu.be/cvkjzWawH4c" title="Artemas - I Like the Way You Kiss Me (Bassjackers Remix)">Artemas - I Like the Way You Kiss Me (Bassjackers Remix)</a></p>
]]></content:encoded>
</item>
<item>
<title>Reading</title>
<link>https://blog.x-way.org/Misc/2024/08/24/Reading.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324390</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 24 Aug 2024 12:38:14 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>Added the <a href="https://blog.x-way.org/reading" title="x-log - Reading">/reading</a> page to the blog to keep a list of various books I'm currently reading.</p>
<p>It is very bare-bones currently, I expect over time it will grow (both in number of books and also in amount of content, such as ratings, links and commentary).<br>Might take a while, stay tuned 🤓</p>
]]></description>
<content:encoded><![CDATA[<p>Added the <a href="https://blog.x-way.org/reading" title="x-log - Reading">/reading</a> page to the blog to keep a list of various books I'm currently reading.</p>
<p>It is very bare-bones currently, I expect over time it will grow (both in number of books and also in amount of content, such as ratings, links and commentary).<br>Might take a while, stay tuned 🤓</p>
]]></content:encoded>
</item>
<item>
<title>Lucie Antunes - Carnaval</title>
<link>https://blog.x-way.org/Music/2024/08/12/Lucie-Antunes-Carnaval.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324389</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 12 Aug 2024 19:04:58 +0200</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p>Amazing discovery from the recent <a href="https://yeah.paleo.ch/" title="Paléo Festival">Paléo Festival</a>: <a href="https://infine-music.com/lucie-antunes/" title="Lucie Antunes">Lucie Antunes</a></p>
<p><a href="https://youtu.be/EoRLWBC_Y2o" title="Lucie Antunes - Carnaval - YouTube">Lucie Antunes - Carnaval</a></p>
]]></description>
<content:encoded><![CDATA[<p>Amazing discovery from the recent <a href="https://yeah.paleo.ch/" title="Paléo Festival">Paléo Festival</a>: <a href="https://infine-music.com/lucie-antunes/" title="Lucie Antunes">Lucie Antunes</a></p>
<p><a href="https://youtu.be/EoRLWBC_Y2o" title="Lucie Antunes - Carnaval - YouTube">Lucie Antunes - Carnaval</a></p>
]]></content:encoded>
</item>
<item>
<title>Fix missing emoji in Chrome on Linux</title>
<link>https://blog.x-way.org/Linux/2024/08/11/Fix-missing-emoji-in-Chrome-on-Linux.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324388</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 11 Aug 2024 15:39:42 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>Not seeing any emoji in Chrome on Linux?<br>The following fixed it for me on Debian.</p>
<pre>sudo apt-get install fonts-noto-color-emoji
fc-cache -f -v</pre>
<p>Afterwards restart Chrome and enjoy the colorful emoji 🥳</p>
]]></description>
<content:encoded><![CDATA[<p>Not seeing any emoji in Chrome on Linux?<br>The following fixed it for me on Debian.</p>
<pre>sudo apt-get install fonts-noto-color-emoji
fc-cache -f -v</pre>
<p>Afterwards restart Chrome and enjoy the colorful emoji 🥳</p>
]]></content:encoded>
</item>
<item>
<title>Praise my GitHub profile!</title>
<link>https://blog.x-way.org/Misc/2024/08/11/Praise-my-GitHub-profile.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324387</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 11 Aug 2024 14:23:46 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<blockquote cite="https://pony.social/@cadey/112904542715285506"><p>Instead of using AI tools to tear people down, what if we used them to uplift others? Introducing Praise my GitHub profile:</p>
<p><a href="https://web.archive.org/web/20240810091216/https://praise-me.fly.dev/" title="Praise my GitHub profile! (archive.org)">https://praise-me.fly.dev/</a></p></blockquote>
<p><a href="https://xeiaso.net/" title="Xe Iaso">Xe Iaso</a> made this cool tool, which creates happiness ❤️</p>
<img src="https://blog.x-way.org/images/praise-my-github-profile.webp" width="546" height="484" alt="Praise my GitHub profile!
x-way
Andreas, I just wanted to take a moment to acknowledge the incredible work you're doing on GitHub! With 55 followers and 98 accounts you're following, it's clear that you're an active and engaged member of this community.
Your projects are truly impressive, showcasing your expertise in a range of areas, from network packet inspection to crawler detection. I'm blown away by the creativity and problem-solving skills you've demonstrated in each of these projects. Whether it's inserting trace-points into iptables chains or creating a daemon to remove conntrack entries, every project reflects your attention to detail and commitment to excellence.
I particularly want to highlight the impact of your work on others. With over 247 stars on your iptables-tracer project alone, it's clear that you're making a real difference in the lives of developers who are using your tools to solve complex problems. And with 50+ stars on several other projects, it's evident that your contributions are being recognized and valued by the broader community.
As someone who is clearly passionate about what they do, I want to encourage you to keep pushing the boundaries of what's possible. Don't be afraid to take risks and explore new ideas – your unique perspective and skills are a gift to this community, and we're all better off for having you as part of it.
Keep shining, Andreas!">
]]></description>
<content:encoded><![CDATA[<blockquote cite="https://pony.social/@cadey/112904542715285506"><p>Instead of using AI tools to tear people down, what if we used them to uplift others? Introducing Praise my GitHub profile:</p>
<p><a href="https://web.archive.org/web/20240810091216/https://praise-me.fly.dev/" title="Praise my GitHub profile! (archive.org)">https://praise-me.fly.dev/</a></p></blockquote>
<p><a href="https://xeiaso.net/" title="Xe Iaso">Xe Iaso</a> made this cool tool, which creates happiness ❤️</p>
<img src="https://blog.x-way.org/images/praise-my-github-profile.webp" width="546" height="484" alt="Praise my GitHub profile!
x-way
Andreas, I just wanted to take a moment to acknowledge the incredible work you're doing on GitHub! With 55 followers and 98 accounts you're following, it's clear that you're an active and engaged member of this community.
Your projects are truly impressive, showcasing your expertise in a range of areas, from network packet inspection to crawler detection. I'm blown away by the creativity and problem-solving skills you've demonstrated in each of these projects. Whether it's inserting trace-points into iptables chains or creating a daemon to remove conntrack entries, every project reflects your attention to detail and commitment to excellence.
I particularly want to highlight the impact of your work on others. With over 247 stars on your iptables-tracer project alone, it's clear that you're making a real difference in the lives of developers who are using your tools to solve complex problems. And with 50+ stars on several other projects, it's evident that your contributions are being recognized and valued by the broader community.
As someone who is clearly passionate about what they do, I want to encourage you to keep pushing the boundaries of what's possible. Don't be afraid to take risks and explore new ideas – your unique perspective and skills are a gift to this community, and we're all better off for having you as part of it.
Keep shining, Andreas!">
]]></content:encoded>
</item>
<item>
<title>HTML5 Validator GitHub Action</title>
<link>https://blog.x-way.org/Webdesign/2024/08/11/HTML5-Validator-GitHub-Action.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324386</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 11 Aug 2024 12:59:36 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Added the <a href="https://github.com/marketplace/actions/html5-validator" title="HTML5 Validator · Actions · GitHub Marketplace">HTML5 Validator GitHub Action</a> to the repo of my blog.<br>It runs after the Jekyll site generation step (and before the deploy-to-server step) to catch invalid HTML syntax.</p>
<p>It is configured to validate all generated pages, and promptly surfaced some invalid HTML.<br>This was rather surprising, as I manually did run the validation for the blog pages not too long ago.<br>Turns out when you have a blog with 20 year old comments, then some of them have HTML from 20 years ago which is no longer valid nowadays 🤷</p>
<p>After a round of fixing old comments, all HTML validaton errors are now gone ✅<br>And future invalid HTML syntax will be alerted upon before it ends up on the Internet 😎</p>
]]></description>
<content:encoded><![CDATA[<p>Added the <a href="https://github.com/marketplace/actions/html5-validator" title="HTML5 Validator · Actions · GitHub Marketplace">HTML5 Validator GitHub Action</a> to the repo of my blog.<br>It runs after the Jekyll site generation step (and before the deploy-to-server step) to catch invalid HTML syntax.</p>
<p>It is configured to validate all generated pages, and promptly surfaced some invalid HTML.<br>This was rather surprising, as I manually did run the validation for the blog pages not too long ago.<br>Turns out when you have a blog with 20 year old comments, then some of them have HTML from 20 years ago which is no longer valid nowadays 🤷</p>
<p>After a round of fixing old comments, all HTML validaton errors are now gone ✅<br>And future invalid HTML syntax will be alerted upon before it ends up on the Internet 😎</p>
]]></content:encoded>
</item>
<item>
<title>Git push only some local commits</title>
<link>https://blog.x-way.org/Linux/2024/08/10/Git-push-only-some-local-commits.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324385</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 10 Aug 2024 20:13:34 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>With Git it is possible to push only certain local commits to a remote repository.<br>This can be done with the following <kbd>git push</kbd> command, which pushes all commits up to <code>commit</code> to the branch <code>remote branch</code> in the remote repo <code>repository</code>:</p>
<pre>git push <repository> <commit>:<remote branch></pre>
<p>For example the following pushes all except for the latest local commit to the main branch in the origin remote repo:</p>
<pre>git push origin HEAD~1:main</pre>
]]></description>
<content:encoded><![CDATA[<p>With Git it is possible to push only certain local commits to a remote repository.<br>This can be done with the following <kbd>git push</kbd> command, which pushes all commits up to <code>commit</code> to the branch <code>remote branch</code> in the remote repo <code>repository</code>:</p>
<pre>git push <repository> <commit>:<remote branch></pre>
<p>For example the following pushes all except for the latest local commit to the main branch in the origin remote repo:</p>
<pre>git push origin HEAD~1:main</pre>
]]></content:encoded>
</item>
<item>
<title>Website Carbon Badge</title>
<link>https://blog.x-way.org/Webdesign/2024/08/10/Website-Carbon-Badge.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324384</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 10 Aug 2024 19:53:11 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Following up on yesterday's post about the <a href="https://blog.x-way.org/Webdesign/2024/08/09/Website-Carbon-Calculator.html" title="Website Carbon Calculator - x-log">Website Carbon Calculator</a>, I saw that there is also the option to add a <a href="https://www.websitecarbon.com/badge/" title="Website Carbon Badge - Website Carbon Calculator">Website Carbon Badge</a>.</p>
<p>Quickly this badge was added to the <a href="https://blog.x-way.org/about.html" title="x-log - About">About page</a>.</p>
<p>To make it more accurate and avoid hitting their API every time someone loads the About page, I made some changes to the provided code:</p>
<ol>
<li>Calculate the results for the front page of the blog instead of the page where the badge is displayed (which would be the less significant About page).</li>
<li>Call the API to load the JSON file with the CO<sub>2</sub> results only once per week via a cronjob instead of every time someone new visits the About page.</li>
<li>Have the script load the cached JSON file from my server instead of directly calling the API.</li>
<li>Store the CSS and Javascript required to render the results on my own server instead of using the unpkg.com CDN (also helps with the above custom modifications).</li>
</ol>
]]></description>
<content:encoded><![CDATA[<p>Following up on yesterday's post about the <a href="https://blog.x-way.org/Webdesign/2024/08/09/Website-Carbon-Calculator.html" title="Website Carbon Calculator - x-log">Website Carbon Calculator</a>, I saw that there is also the option to add a <a href="https://www.websitecarbon.com/badge/" title="Website Carbon Badge - Website Carbon Calculator">Website Carbon Badge</a>.</p>
<p>Quickly this badge was added to the <a href="https://blog.x-way.org/about.html" title="x-log - About">About page</a>.</p>
<p>To make it more accurate and avoid hitting their API every time someone loads the About page, I made some changes to the provided code:</p>
<ol>
<li>Calculate the results for the front page of the blog instead of the page where the badge is displayed (which would be the less significant About page).</li>
<li>Call the API to load the JSON file with the CO<sub>2</sub> results only once per week via a cronjob instead of every time someone new visits the About page.</li>
<li>Have the script load the cached JSON file from my server instead of directly calling the API.</li>
<li>Store the CSS and Javascript required to render the results on my own server instead of using the unpkg.com CDN (also helps with the above custom modifications).</li>
</ol>
]]></content:encoded>
</item>
<item>
<title>Website Carbon Calculator</title>
<link>https://blog.x-way.org/Webdesign/2024/08/09/Website-Carbon-Calculator.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324383</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Fri, 09 Aug 2024 20:00:19 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>While surfing around, stumbled upon this cool tool which allows to calculate the carbon footprint of a website: <a href="https://www.websitecarbon.com/" title="Website Carbon Calculator">Website Carbon Calculator</a>.</p>
<p>After having it analyze my blog, I was very pleased to see the resulting A<sup>+</sup> carbon rating 🎉<br>The tool reports that every time someone loads my blog, 0.01g of CO<sub>2</sub> is produced.</p>
<img src="https://blog.x-way.org/images/websitecarbon-results.webp" width="532" height="266" alt="Results of the Website Carbon Calculator for blog.x-way.org: carbon rating of A+ which is cleaner than 99% of all web pages globally">
<p>I suspect that this value and rating might fluctuate based on how many images or videos appear in the last 10 posts shown on the front page of the blog.<br>The <a href="https://www.websitecarbon.com/website/blog-x-way-org/" title="">results page</a>, also allows to calculate how much CO<sub>2</sub> would be produced in a year based on 10, 100, 1000, … monthly page views and compares this to everyday tasks.<br>Having 1000 monthly page views on this blog over a whole year, theoretically produces as much CO<sub>2</sub> as boiling water for 16 cups of tea 🍵</p>
<p>(<a href="https://discombobulated.co.nz/site" title="Discombobulated">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p>While surfing around, stumbled upon this cool tool which allows to calculate the carbon footprint of a website: <a href="https://www.websitecarbon.com/" title="Website Carbon Calculator">Website Carbon Calculator</a>.</p>
<p>After having it analyze my blog, I was very pleased to see the resulting A<sup>+</sup> carbon rating 🎉<br>The tool reports that every time someone loads my blog, 0.01g of CO<sub>2</sub> is produced.</p>
<img src="https://blog.x-way.org/images/websitecarbon-results.webp" width="532" height="266" alt="Results of the Website Carbon Calculator for blog.x-way.org: carbon rating of A+ which is cleaner than 99% of all web pages globally">
<p>I suspect that this value and rating might fluctuate based on how many images or videos appear in the last 10 posts shown on the front page of the blog.<br>The <a href="https://www.websitecarbon.com/website/blog-x-way-org/" title="">results page</a>, also allows to calculate how much CO<sub>2</sub> would be produced in a year based on 10, 100, 1000, … monthly page views and compares this to everyday tasks.<br>Having 1000 monthly page views on this blog over a whole year, theoretically produces as much CO<sub>2</sub> as boiling water for 16 cups of tea 🍵</p>
<p>(<a href="https://discombobulated.co.nz/site" title="Discombobulated">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Ensure modified version of CSS file is loaded</title>
<link>https://blog.x-way.org/Webdesign/2024/08/07/Ensure-modified-version-of-CSS-file-is-loaded.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324382</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 07 Aug 2024 15:40:15 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>As the CSS code of the blog has been growing lately, I moved it from inline <code><style></code> definition to a dedicated <code>css/plain.css</code> file.</p>
<p>With caching headers configured to cache <code>*.css</code> files for 10 days, this brings the problem that browsers need to be instructed to load a new version whenever the content of the file changes.</p>
<p>Removing the caching headers is not desired (as we want to leverage caching and the file does not change so often after all).<br>Thus I came up with a different workaround:</p>
<p>We add a query parameter to the <code><link></code> element that references the CSS file, and then change this query parameter whenever the file content changes.<br>This way browsers will load the newest version and keep it cached until a newer version is available.</p>
<p>To achieve this, the following script is used to compute and inject the query parameter into the layout template before running Jekyll to generate the HTML pages for the blog:</p>
<pre>#!/bin/bash
CSSFILES="css/plain.css"
TARGETFILE="_layouts/x-log.html"
for CSS in $CSSFILES ; do
sum=$(sha256sum "$CSS"|head -c 6)
sed -i -e "s_${CSS}_&?${sum}_g" $TARGETFILE
done
</pre>
<p>It performs the following change in the template file.<br>Before:</p>
<pre>...
<link rel="stylesheet" href="https://blog.x-way.org/css/plain.css" type="text/css" media="all">
...</pre>
<p>After:</p>
<pre>...
<link rel="stylesheet" href="https://blog.x-way.org/css/plain.css?f00bad" type="text/css" media="all">
...</pre>
<p>As the computed query parameter is based on the hashsum of the content of the CSS file, it only changes when the CSS file is changed, thus ensuring caching still works as expected.</p>
]]></description>
<content:encoded><![CDATA[<p>As the CSS code of the blog has been growing lately, I moved it from inline <code><style></code> definition to a dedicated <code>css/plain.css</code> file.</p>
<p>With caching headers configured to cache <code>*.css</code> files for 10 days, this brings the problem that browsers need to be instructed to load a new version whenever the content of the file changes.</p>
<p>Removing the caching headers is not desired (as we want to leverage caching and the file does not change so often after all).<br>Thus I came up with a different workaround:</p>
<p>We add a query parameter to the <code><link></code> element that references the CSS file, and then change this query parameter whenever the file content changes.<br>This way browsers will load the newest version and keep it cached until a newer version is available.</p>
<p>To achieve this, the following script is used to compute and inject the query parameter into the layout template before running Jekyll to generate the HTML pages for the blog:</p>
<pre>#!/bin/bash
CSSFILES="css/plain.css"
TARGETFILE="_layouts/x-log.html"
for CSS in $CSSFILES ; do
sum=$(sha256sum "$CSS"|head -c 6)
sed -i -e "s_${CSS}_&?${sum}_g" $TARGETFILE
done
</pre>
<p>It performs the following change in the template file.<br>Before:</p>
<pre>...
<link rel="stylesheet" href="https://blog.x-way.org/css/plain.css" type="text/css" media="all">
...</pre>
<p>After:</p>
<pre>...
<link rel="stylesheet" href="https://blog.x-way.org/css/plain.css?f00bad" type="text/css" media="all">
...</pre>
<p>As the computed query parameter is based on the hashsum of the content of the CSS file, it only changes when the CSS file is changed, thus ensuring caching still works as expected.</p>
]]></content:encoded>
</item>
<item>
<title>Increase emoji size with CSS only</title>
<link>https://blog.x-way.org/Webdesign/2024/08/03/Increase-emoji-size-with-CSS-only.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324381</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 03 Aug 2024 22:06:39 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>To make emoji stand out better in the text, I applied a <a href="https://shkspr.mobi/blog/2024/04/use-css-to-boost-the-font-size-of-emoji-with-no-extra-markup/" title="Use CSS to boost the font size of emoji with no extra markup – Terence Eden’s Blog">trick from Terence Eden to increase their size with CSS and no extra HTML</a>.</p>
<p>It consists of defining a custom font which only applies to the unicode codepoints of emoji and leverages the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/size-adjust" title="size-adjust - CSS: Cascading Style Sheets | MDN">size-adjust</a> property to draw them larger.</p>
<pre>@font-face {
font-family: "myemoji";
src: local('Apple Color Emoji'), local('Android Emoji'), local('Segoe UI Emoji'), local('Noto Color Emoji'), local(EmojiSymbols), local(Symbola);
unicode-range: U+231A-231B, U+23E9-23EC, U+23F0, U+23F3, U+25FD-25FE, U+2614-2615, U+2648-2653, U+267F, U+2693, U+26A1, U+26AA-26AB, U+26BD-26BE, U+26C4-26C5, U+26CE, U+26D4, U+26EA, U+26F2-26F3, U+26F5, U+26FA, U+26FD, U+2705, U+270A-270B, U+2728, U+274C, U+274E, U+2753-2755, U+2757, U+2795-2797, U+27B0, U+27BF, U+2B1B-2B1C, U+2B50, U+2B55, U+FE0F, U+1F004, U+1F0CF, U+1F18E, U+1F191-1F19A, U+1F1E6-1F1FF, U+1F201, U+1F21A, U+1F22F, U+1F232-1F236, U+1F238-1F23A, U+1F250-1F251, U+1F300-1F320, U+1F32D-1F335, U+1F337-1F393, U+1F3A0-1F3CA, U+1F3CF-1F3D3, U+1F3E0-1F3F0, U+1F3F4, U+1F3F8-1F43E, U+1F440, U+1F442-1F4FC, U+1F4FF-1F53D, U+1F54B-1F567, U+1F57A, U+1F595-1F596, U+1F5A4, U+1F5FB-1F64F, U+1F680-1F6CC, U+1F6D0-1F6D2, U+1F6D5-1F6D7, U+1F6DC-1F6DF, U+1F6EB-1F6EC, U+1F6F4-1F6FC, U+1F7E0-1F7EB, U+1F7F0, U+1F90C-1F93A, U+1F93C-1F945, U+1F947-1FA7C, U+1FA80-1FAC5, U+1FACE-1FADB, U+1FAE0-1FAE8, U+1FAF0-1FAF8;
size-adjust: 120%;
}</pre>
<p>By adding the custom font as first option in the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/font-family" title="font-family - CSS: Cascading Style Sheets | MDN">font-family</a> directive for body text, it will be applied to the emoji and all other characters will use the existing font as fallback.</p>
<pre>body {
font-family: "myemoji", Verdana, sans-serif;
}</pre>
<p>The outcome is nicely visible on posts such as <a href="https://blog.x-way.org/Radio/2024/03/17/Fifty-Things-you-can-do-with-a-Software-Defined-Radio.html" title="Fifty Things you can do with a Software Defined Radio 📻 - x-log">Fifty Things you can do with a Software Defined Radio 📻</a>, <a href="https://blog.x-way.org/Linux/2024/03/30/Puppet-updated.html" title="Puppet updated! - x-log">Puppet updated!</a> and <a href="https://blog.x-way.org/Coding/2024/02/25/The-High-Risk-Refactoring.html" title="The High-Risk Refactoring - x-log">The High-Risk Refactoring</a> 🍹😎</p>
]]></description>
<content:encoded><![CDATA[<p>To make emoji stand out better in the text, I applied a <a href="https://shkspr.mobi/blog/2024/04/use-css-to-boost-the-font-size-of-emoji-with-no-extra-markup/" title="Use CSS to boost the font size of emoji with no extra markup – Terence Eden’s Blog">trick from Terence Eden to increase their size with CSS and no extra HTML</a>.</p>
<p>It consists of defining a custom font which only applies to the unicode codepoints of emoji and leverages the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/size-adjust" title="size-adjust - CSS: Cascading Style Sheets | MDN">size-adjust</a> property to draw them larger.</p>
<pre>@font-face {
font-family: "myemoji";
src: local('Apple Color Emoji'), local('Android Emoji'), local('Segoe UI Emoji'), local('Noto Color Emoji'), local(EmojiSymbols), local(Symbola);
unicode-range: U+231A-231B, U+23E9-23EC, U+23F0, U+23F3, U+25FD-25FE, U+2614-2615, U+2648-2653, U+267F, U+2693, U+26A1, U+26AA-26AB, U+26BD-26BE, U+26C4-26C5, U+26CE, U+26D4, U+26EA, U+26F2-26F3, U+26F5, U+26FA, U+26FD, U+2705, U+270A-270B, U+2728, U+274C, U+274E, U+2753-2755, U+2757, U+2795-2797, U+27B0, U+27BF, U+2B1B-2B1C, U+2B50, U+2B55, U+FE0F, U+1F004, U+1F0CF, U+1F18E, U+1F191-1F19A, U+1F1E6-1F1FF, U+1F201, U+1F21A, U+1F22F, U+1F232-1F236, U+1F238-1F23A, U+1F250-1F251, U+1F300-1F320, U+1F32D-1F335, U+1F337-1F393, U+1F3A0-1F3CA, U+1F3CF-1F3D3, U+1F3E0-1F3F0, U+1F3F4, U+1F3F8-1F43E, U+1F440, U+1F442-1F4FC, U+1F4FF-1F53D, U+1F54B-1F567, U+1F57A, U+1F595-1F596, U+1F5A4, U+1F5FB-1F64F, U+1F680-1F6CC, U+1F6D0-1F6D2, U+1F6D5-1F6D7, U+1F6DC-1F6DF, U+1F6EB-1F6EC, U+1F6F4-1F6FC, U+1F7E0-1F7EB, U+1F7F0, U+1F90C-1F93A, U+1F93C-1F945, U+1F947-1FA7C, U+1FA80-1FAC5, U+1FACE-1FADB, U+1FAE0-1FAE8, U+1FAF0-1FAF8;
size-adjust: 120%;
}</pre>
<p>By adding the custom font as first option in the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/font-family" title="font-family - CSS: Cascading Style Sheets | MDN">font-family</a> directive for body text, it will be applied to the emoji and all other characters will use the existing font as fallback.</p>
<pre>body {
font-family: "myemoji", Verdana, sans-serif;
}</pre>
<p>The outcome is nicely visible on posts such as <a href="https://blog.x-way.org/Radio/2024/03/17/Fifty-Things-you-can-do-with-a-Software-Defined-Radio.html" title="Fifty Things you can do with a Software Defined Radio 📻 - x-log">Fifty Things you can do with a Software Defined Radio 📻</a>, <a href="https://blog.x-way.org/Linux/2024/03/30/Puppet-updated.html" title="Puppet updated! - x-log">Puppet updated!</a> and <a href="https://blog.x-way.org/Coding/2024/02/25/The-High-Risk-Refactoring.html" title="The High-Risk Refactoring - x-log">The High-Risk Refactoring</a> 🍹😎</p>
]]></content:encoded>
</item>
<item>
<title>ISO 8601 and RFC3339 time format with Unix date command</title>
<link>https://blog.x-way.org/Linux/2024/08/03/ISO-8601-and-RFC3339-time-format-with-Unix-date-command.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324380</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 03 Aug 2024 16:41:47 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>The following command outputs the current time formatted according to ISO 8601 and RFC3339. It can be used for example in JSON/HTML.</p>
<pre>date -u '+%FT%TZ'</pre>
<pre>2024-08-03T14:41:47Z</pre>
]]></description>
<content:encoded><![CDATA[<p>The following command outputs the current time formatted according to ISO 8601 and RFC3339. It can be used for example in JSON/HTML.</p>
<pre>date -u '+%FT%TZ'</pre>
<pre>2024-08-03T14:41:47Z</pre>
]]></content:encoded>
</item>
<item>
<title>iPhone Orientation Lock Automation</title>
<link>https://blog.x-way.org/Misc/2024/08/01/iPhone-Orientation-Lock-Automation.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324379</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 01 Aug 2024 11:12:45 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>Useful trick <a href="https://vowe.net/2024/08/01/iphone-orientation-lock-automatisch-schalten/" title="iPhone Orientation Lock automatisch schalten – vowe dot net">posted by Volker Weber</a>: enable the Orientation Lock by default and use Automation Shortcuts to toggle it when Apps such as Photos or YouTube are opened/closed.<br>This allows to view pictures/videos in landscape mode while other Apps remain in portrait mode, all without having to manually toggle the Orientation Lock.</p>
]]></description>
<content:encoded><![CDATA[<p>Useful trick <a href="https://vowe.net/2024/08/01/iphone-orientation-lock-automatisch-schalten/" title="iPhone Orientation Lock automatisch schalten – vowe dot net">posted by Volker Weber</a>: enable the Orientation Lock by default and use Automation Shortcuts to toggle it when Apps such as Photos or YouTube are opened/closed.<br>This allows to view pictures/videos in landscape mode while other Apps remain in portrait mode, all without having to manually toggle the Orientation Lock.</p>
]]></content:encoded>
</item>
<item>
<title>Puppet ERB array flatten</title>
<link>https://blog.x-way.org/Linux/2024/07/31/Puppet-ERB-array-flatten.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324378</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 31 Jul 2024 07:48:09 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>Discovered today that <a href="https://www.puppet.com/docs/puppet/8/lang_data_array" title="Arrays">Puppet arrays</a> have a built-in flatten method (which is actually provided by the underlying <a href="https://ruby-doc.org/core-2.2.0/Array.html#method-i-flatten" title="Class: Array (Ruby 2.2.0)">Ruby array</a>).<br>This can make dealing with potentially nested arrays in ERB templates much easier.</p>
<p>The following example is from the <a href="https://www.puppet.com/docs/puppet/8/lang_template_erb.html" title="Creating templates using Embedded Ruby">ERB documentation</a>:</p>
<pre># Peers
<% [@peers].flatten.each do |peer| -%>
peer <%= peer %>
<% end -%></pre>
<p>This allows for nice flexibility as <code>@peers</code> can now be either a single value, an array, or a nested array and all are handled in the same way without needing to write complicated if/else statements.</p>
]]></description>
<content:encoded><![CDATA[<p>Discovered today that <a href="https://www.puppet.com/docs/puppet/8/lang_data_array" title="Arrays">Puppet arrays</a> have a built-in flatten method (which is actually provided by the underlying <a href="https://ruby-doc.org/core-2.2.0/Array.html#method-i-flatten" title="Class: Array (Ruby 2.2.0)">Ruby array</a>).<br>This can make dealing with potentially nested arrays in ERB templates much easier.</p>
<p>The following example is from the <a href="https://www.puppet.com/docs/puppet/8/lang_template_erb.html" title="Creating templates using Embedded Ruby">ERB documentation</a>:</p>
<pre># Peers
<% [@peers].flatten.each do |peer| -%>
peer <%= peer %>
<% end -%></pre>
<p>This allows for nice flexibility as <code>@peers</code> can now be either a single value, an array, or a nested array and all are handled in the same way without needing to write complicated if/else statements.</p>
]]></content:encoded>
</item>
<item>
<title>No more OSCP stapling</title>
<link>https://blog.x-way.org/Linux/2024/07/25/No-more-OSCP-stapling.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324377</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 25 Jul 2024 08:42:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p><a href="https://letsencrypt.org/2024/07/23/replacing-ocsp-with-crls.html" title="Intent to End OCSP Service - Let's Encrypt">Let's Encrypt announced</a> that it intends to stop supporting <a href="https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol" title="Online Certificate Status Protocol - Wikipedia">OCSP</a>, which means that <a href="https://utcc.utoronto.ca/~cks/space/blog/web/OCSPIsBasicallyDead" title="Chris's Wiki :: blog/web/OCSPIsBasicallyDead">OCSP is basically dead now</a>.</p>
<p><a href="https://en.wikipedia.org/wiki/OCSP_stapling" title="OCSP stapling - Wikipedia">OCSP stapling</a> on my server has been enabled since 2012.<br>With the prospect of it no longer working in the future, I've disabled it again in the nginx configuration.</p>
<pre> # aj, 05.11.2012, OCSP stapling (for testing see http://unmitigatedrisk.com/?p=100)
# aj, 25.07.2024, turn it off again, as letsencrypt will disable it: https://letsencrypt.org/2024/07/23/replacing-ocsp-with-crls.html
# ssl_stapling on;</pre>
]]></description>
<content:encoded><![CDATA[<p><a href="https://letsencrypt.org/2024/07/23/replacing-ocsp-with-crls.html" title="Intent to End OCSP Service - Let's Encrypt">Let's Encrypt announced</a> that it intends to stop supporting <a href="https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol" title="Online Certificate Status Protocol - Wikipedia">OCSP</a>, which means that <a href="https://utcc.utoronto.ca/~cks/space/blog/web/OCSPIsBasicallyDead" title="Chris's Wiki :: blog/web/OCSPIsBasicallyDead">OCSP is basically dead now</a>.</p>
<p><a href="https://en.wikipedia.org/wiki/OCSP_stapling" title="OCSP stapling - Wikipedia">OCSP stapling</a> on my server has been enabled since 2012.<br>With the prospect of it no longer working in the future, I've disabled it again in the nginx configuration.</p>
<pre> # aj, 05.11.2012, OCSP stapling (for testing see http://unmitigatedrisk.com/?p=100)
# aj, 25.07.2024, turn it off again, as letsencrypt will disable it: https://letsencrypt.org/2024/07/23/replacing-ocsp-with-crls.html
# ssl_stapling on;</pre>
]]></content:encoded>
</item>
<item>
<title>Blog Directories</title>
<link>https://blog.x-way.org/Misc/2024/07/24/Blog-Directories.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324376</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 24 Jul 2024 19:52:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>There are some new blog directory sites popping up again. Nice way to discover niche personal sites outside of the big platforms.</p>
<ul>
<li><a href="https://ooh.directory/" title="ooh.directory: a place to find good blogs that interest you">ooh.directory</a></li>
<li><a href="https://personalsit.es/" title="PersonalSit.es | Yes we got hot and fresh sites">personalsit.es</a></li>
<li><a href="https://blogroll.org/" title="Ye Olde Blogroll - Blogroll.org">blogroll.org</a></li>
</ul>
]]></description>
<content:encoded><![CDATA[<p>There are some new blog directory sites popping up again. Nice way to discover niche personal sites outside of the big platforms.</p>
<ul>
<li><a href="https://ooh.directory/" title="ooh.directory: a place to find good blogs that interest you">ooh.directory</a></li>
<li><a href="https://personalsit.es/" title="PersonalSit.es | Yes we got hot and fresh sites">personalsit.es</a></li>
<li><a href="https://blogroll.org/" title="Ye Olde Blogroll - Blogroll.org">blogroll.org</a></li>
</ul>
]]></content:encoded>
</item>
<item>
<title>Less: a Survival Guide</title>
<link>https://blog.x-way.org/Linux/2024/07/22/Less-a-Survival-Guide.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324375</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 22 Jul 2024 05:06:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p><a href="https://zck.org/less-a-survival-guide" title="Less: a Survival Guide">Less: a Survival Guide</a> is a concise post from <a href="https://zck.org/" title="zck.org">zck.org</a> demystifying the features of <code>less</code>.</p>
<p>My two main takeaways were:</p>
<p>1. Configuring less via the <code>LESS</code> environment variable.<br>The following enables markers and highlighting for search & jump actions, colored output and raw display of terminal escape sequences.</p>
<pre>export LESS="-J -W --use-color -R"</pre>
<p>2. Jumping to the start and end of a document with <kbd>g</kbd> and <kbd>G</kbd>.<br>I already used <kbd>/</kbd> for searching, but had always struggled to go back to the beginning of a document.</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://zck.org/less-a-survival-guide" title="Less: a Survival Guide">Less: a Survival Guide</a> is a concise post from <a href="https://zck.org/" title="zck.org">zck.org</a> demystifying the features of <code>less</code>.</p>
<p>My two main takeaways were:</p>
<p>1. Configuring less via the <code>LESS</code> environment variable.<br>The following enables markers and highlighting for search & jump actions, colored output and raw display of terminal escape sequences.</p>
<pre>export LESS="-J -W --use-color -R"</pre>
<p>2. Jumping to the start and end of a document with <kbd>g</kbd> and <kbd>G</kbd>.<br>I already used <kbd>/</kbd> for searching, but had always struggled to go back to the beginning of a document.</p>
]]></content:encoded>
</item>
<item>
<title>Lego Space Age</title>
<link>https://blog.x-way.org/Webdesign/2024/07/07/Lego-Space-Age.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324374</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 07 Jul 2024 16:43:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p><a href="https://blog.x-way.org/images/lego_space_age.webp" title="Lego Space Age"><img src="https://blog.x-way.org/images/lego_space_age_thumb.webp" width="500" height="375" alt="Lego Space Age"></a></p>
<p>While browsing for something unrelated, I came about this wonderful Lego set called <a href="https://www.lego.com/en-us/product/tales-of-the-space-age-21340" title="Tales of the Space Age 21340 | Ideas">'Tales of the Space Age'</a>.<br>
It was originally created by a fan designer through the Lego Ideas program and turned into this amazing looking Lego set.</p>
<p>I like the depiction of the space themed science fiction worlds very much, especially the beautiful color gradients giving each world a unique atmosphere.<br>
The provided <a href="https://www.lego.com/en-us/service/buildinginstructions/21340" title="Building Instructions">building instructions</a> <a href="https://blog.x-way.org/stuff/6500750.pdf" title="Postcards from space - Building Instructions">booklet</a> builds on top of this with illustrations enhancing the views of these worlds.</p>
<p>Looking at these four panels with the nice space themed color gradients inspired me to rebuild them in CSS.<br>
First I toyed around with one and then built the other three.</p>
<p>The outcome of this is now visible on <a href="https://www.andreasjaggi.ch/" title="www.andreasjaggi.ch">andreasjaggi.ch</a> where I replaced the previous entry page with the four color gradients.<br>
The <a href="https://blog.x-way.org/Webdesign/2024/06/18/More-modern-technologies.html" title="More modern technologies - x-log">previous version</a> is still available on <a href="https://www.andreas-jaggi.ch/" title="www.andreas-jaggi.ch">andreas-jaggi.ch</a> as I couldn't decide yet to retire it, so will be keeping both for now :-)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://blog.x-way.org/images/lego_space_age.webp" title="Lego Space Age"><img src="https://blog.x-way.org/images/lego_space_age_thumb.webp" width="500" height="375" alt="Lego Space Age"></a></p>
<p>While browsing for something unrelated, I came about this wonderful Lego set called <a href="https://www.lego.com/en-us/product/tales-of-the-space-age-21340" title="Tales of the Space Age 21340 | Ideas">'Tales of the Space Age'</a>.<br>
It was originally created by a fan designer through the Lego Ideas program and turned into this amazing looking Lego set.</p>
<p>I like the depiction of the space themed science fiction worlds very much, especially the beautiful color gradients giving each world a unique atmosphere.<br>
The provided <a href="https://www.lego.com/en-us/service/buildinginstructions/21340" title="Building Instructions">building instructions</a> <a href="https://blog.x-way.org/stuff/6500750.pdf" title="Postcards from space - Building Instructions">booklet</a> builds on top of this with illustrations enhancing the views of these worlds.</p>
<p>Looking at these four panels with the nice space themed color gradients inspired me to rebuild them in CSS.<br>
First I toyed around with one and then built the other three.</p>
<p>The outcome of this is now visible on <a href="https://www.andreasjaggi.ch/" title="www.andreasjaggi.ch">andreasjaggi.ch</a> where I replaced the previous entry page with the four color gradients.<br>
The <a href="https://blog.x-way.org/Webdesign/2024/06/18/More-modern-technologies.html" title="More modern technologies - x-log">previous version</a> is still available on <a href="https://www.andreas-jaggi.ch/" title="www.andreas-jaggi.ch">andreas-jaggi.ch</a> as I couldn't decide yet to retire it, so will be keeping both for now :-)</p>
]]></content:encoded>
</item>
<item>
<title>Jekyll version plugin</title>
<link>https://blog.x-way.org/Coding/2024/07/06/Jekyll-version-plugin.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324373</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 06 Jul 2024 18:47:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>Recently I added a Generator section to the <a href="https://blog.x-way.org/about.html" title="x-log - About">about page</a> with minimal information about how this page was generated.<br>As part of this it now also shows the version of the <a href="https://jekyllrb.com/" title="Jekyll • Simple, blog-aware, static sites | Transform your plain text into static websites and blogs">Jekyll</a> software that was used to generate everything.</p>
<p>Surprisingly there seems to be no built-in way to get the version as a template tag.<br>Thus I wrote this mini-plugin to provide such a <code>{% jekyll_version %}</code> tag that can be used to get the version of Jekyll while it is processing the pages.</p>
<p>To use it with your own Jekyll, simply store the below code in a <code>_plugins/jekyll_version_plugin.rb</code> file.</p>
<pre># frozen_string_literal: true
module Jekyll
class VersionTag < Liquid::Tag
def render(context)
Jekyll::VERSION
end
end
end
Liquid::Template.register_tag("jekyll_version", Jekyll::VersionTag)</pre>
]]></description>
<content:encoded><![CDATA[<p>Recently I added a Generator section to the <a href="https://blog.x-way.org/about.html" title="x-log - About">about page</a> with minimal information about how this page was generated.<br>As part of this it now also shows the version of the <a href="https://jekyllrb.com/" title="Jekyll • Simple, blog-aware, static sites | Transform your plain text into static websites and blogs">Jekyll</a> software that was used to generate everything.</p>
<p>Surprisingly there seems to be no built-in way to get the version as a template tag.<br>Thus I wrote this mini-plugin to provide such a <code>{% jekyll_version %}</code> tag that can be used to get the version of Jekyll while it is processing the pages.</p>
<p>To use it with your own Jekyll, simply store the below code in a <code>_plugins/jekyll_version_plugin.rb</code> file.</p>
<pre># frozen_string_literal: true
module Jekyll
class VersionTag < Liquid::Tag
def render(context)
Jekyll::VERSION
end
end
end
Liquid::Template.register_tag("jekyll_version", Jekyll::VersionTag)</pre>
]]></content:encoded>
</item>
<item>
<title>More statistics tuning</title>
<link>https://blog.x-way.org/Webdesign/2024/07/06/More-statistics-tuning.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324372</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 06 Jul 2024 18:10:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>After <a href="https://blog.x-way.org/Webdesign/2024/06/30/Improved-text-only-UX.html" title="Improved text-only UX">last weeks work</a> on the <a href="https://blog.x-way.org/statistics.html" title="x-log - Statistics">statistics page</a>, I was still not completely happy with how it renders in text-only browsers.</p>
<p>Thus the idea of adding <code><th></code> headers to the two rows of numbers.<br>This turned out quite well and helped to make things more clear as you can see in this screenshot.</p>
<p><img src="https://blog.x-way.org/images/lynx-statistics-improved.png" alt="Screenshot of Lynx rendering the improved statistics page" width="720" height="423"></p>
<p>I initially wanted to use the <code>:first-child</code> selector to hide these additional table headers in graphical web browsers.<br>But didn't get it right with the first try, so the header still showed.</p>
<p>This actually didn't look that bad, and so I decided to keep the headers visible and styled them nicely so they integrate well with the rest of the statistics table.<br>This is how the <a href="https://blog.x-way.org/statistics.html" title="x-log - Statistics">statistics page</a> now looks in a graphical web browser.</p>
<p><img src="https://blog.x-way.org/images/firefox-statistics-improved.png" alt="Screenshot of Firefox rendering the improved statistics page" width="720" height="465"></p>
]]></description>
<content:encoded><![CDATA[<p>After <a href="https://blog.x-way.org/Webdesign/2024/06/30/Improved-text-only-UX.html" title="Improved text-only UX">last weeks work</a> on the <a href="https://blog.x-way.org/statistics.html" title="x-log - Statistics">statistics page</a>, I was still not completely happy with how it renders in text-only browsers.</p>
<p>Thus the idea of adding <code><th></code> headers to the two rows of numbers.<br>This turned out quite well and helped to make things more clear as you can see in this screenshot.</p>
<p><img src="https://blog.x-way.org/images/lynx-statistics-improved.png" alt="Screenshot of Lynx rendering the improved statistics page" width="720" height="423"></p>
<p>I initially wanted to use the <code>:first-child</code> selector to hide these additional table headers in graphical web browsers.<br>But didn't get it right with the first try, so the header still showed.</p>
<p>This actually didn't look that bad, and so I decided to keep the headers visible and styled them nicely so they integrate well with the rest of the statistics table.<br>This is how the <a href="https://blog.x-way.org/statistics.html" title="x-log - Statistics">statistics page</a> now looks in a graphical web browser.</p>
<p><img src="https://blog.x-way.org/images/firefox-statistics-improved.png" alt="Screenshot of Firefox rendering the improved statistics page" width="720" height="465"></p>
]]></content:encoded>
</item>
<item>
<title>Improved text-only UX</title>
<link>https://blog.x-way.org/Webdesign/2024/06/30/Improved-text-only-UX.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324371</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 30 Jun 2024 21:37:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Some time ago I read <a href="https://danq.me/2024/05/01/test-your-site-in-lynx/" title="Test your site in Lynx – Dan Q">this article from Dan Q</a> about testing your website in a text-only browser (<a href="https://en.wikipedia.org/wiki/Lynx_(web_browser)" title="Lynx (web browser) - Wikipedia">Lynx</a>, which is the oldest web browser still being maintained, started in 1992).</p>
<p>Surfing through my blog with Lynx, I was positively surprised in how well the content and structure was presented.<br>Seems like the modernization and simplification efforts of the HTML code behind the scenes paid off well.</p>
<p>The <a href="https://blog.x-way.org/statistics.html" title="x-log - Statistics">statistics page</a> though was not really usable, it was displayed as a random soup of numbers due to the usage of unstructured <code><div></code> tags for the elements of the visual graphs.</p>
<p>To fix this I reverted back to using <code><table></code> tags to structure the data.<br>This way the layout degrades gracefully in text-only browsers and provides a minimally structured representation of the data.<br>And I applied <a href="https://blog.x-way.org/Webdesign/2024/06/18/More-modern-technologies.html" title="More modern technologies - x-log">the newly learned CSS skills</a> (<code>linear-gradient</code> backgrounds) to achieve the same visual graph as beforehand when opening the page in a regular browser.</p>
<p><img src="https://blog.x-way.org/images/lynx-statistics.png" alt="Screenshot of Lynx rendering the statistics page" width="720" height="423"></p>
]]></description>
<content:encoded><![CDATA[<p>Some time ago I read <a href="https://danq.me/2024/05/01/test-your-site-in-lynx/" title="Test your site in Lynx – Dan Q">this article from Dan Q</a> about testing your website in a text-only browser (<a href="https://en.wikipedia.org/wiki/Lynx_(web_browser)" title="Lynx (web browser) - Wikipedia">Lynx</a>, which is the oldest web browser still being maintained, started in 1992).</p>
<p>Surfing through my blog with Lynx, I was positively surprised in how well the content and structure was presented.<br>Seems like the modernization and simplification efforts of the HTML code behind the scenes paid off well.</p>
<p>The <a href="https://blog.x-way.org/statistics.html" title="x-log - Statistics">statistics page</a> though was not really usable, it was displayed as a random soup of numbers due to the usage of unstructured <code><div></code> tags for the elements of the visual graphs.</p>
<p>To fix this I reverted back to using <code><table></code> tags to structure the data.<br>This way the layout degrades gracefully in text-only browsers and provides a minimally structured representation of the data.<br>And I applied <a href="https://blog.x-way.org/Webdesign/2024/06/18/More-modern-technologies.html" title="More modern technologies - x-log">the newly learned CSS skills</a> (<code>linear-gradient</code> backgrounds) to achieve the same visual graph as beforehand when opening the page in a regular browser.</p>
<p><img src="https://blog.x-way.org/images/lynx-statistics.png" alt="Screenshot of Lynx rendering the statistics page" width="720" height="423"></p>
]]></content:encoded>
</item>
<item>
<title>.well-known/traffic-advice</title>
<link>https://blog.x-way.org/Webdesign/2024/06/29/well-known-traffic-advice.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324370</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 29 Jun 2024 09:48:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>While looking at my 404s the top one for the blog was <code>/.well-known/traffic-advice</code>.<br>
This is part of the traffic advice mechanism to control traffic from prefetch proxies (and based on my current access logs, seems only used by the <a href="https://developer.chrome.com/blog/private-prefetch-proxy/" title="Private prefetch proxy in Chrome">Chrome Privacy Preserving Prefetch Proxy</a>).</p>
<p>The traffic advice mechanism is specified in the document <a href="https://buettner.github.io/private-prefetch-proxy/traffic-advice.html" title="Traffic Advice">here</a>.<br>
It can be used to reduce the number of requests coming from prefetch proxies.</p>
<p>To get rid of the 404s and provide support for the traffic advice mechanism, I use the following snippet in my nginx config.<br>
It allows all requests from prefetch proxies (as currently I see no need to limit them).</p>
<pre># Private Prefetch Proxy
# https://developer.chrome.com/blog/private-prefetch-proxy/
location /.well-known/traffic-advice {
types { } default_type "application/trafficadvice+json";
return 200 '[{"user_agent":"prefetch-proxy","fraction":1.0}]';
}</pre>
]]></description>
<content:encoded><![CDATA[<p>While looking at my 404s the top one for the blog was <code>/.well-known/traffic-advice</code>.<br>
This is part of the traffic advice mechanism to control traffic from prefetch proxies (and based on my current access logs, seems only used by the <a href="https://developer.chrome.com/blog/private-prefetch-proxy/" title="Private prefetch proxy in Chrome">Chrome Privacy Preserving Prefetch Proxy</a>).</p>
<p>The traffic advice mechanism is specified in the document <a href="https://buettner.github.io/private-prefetch-proxy/traffic-advice.html" title="Traffic Advice">here</a>.<br>
It can be used to reduce the number of requests coming from prefetch proxies.</p>
<p>To get rid of the 404s and provide support for the traffic advice mechanism, I use the following snippet in my nginx config.<br>
It allows all requests from prefetch proxies (as currently I see no need to limit them).</p>
<pre># Private Prefetch Proxy
# https://developer.chrome.com/blog/private-prefetch-proxy/
location /.well-known/traffic-advice {
types { } default_type "application/trafficadvice+json";
return 200 '[{"user_agent":"prefetch-proxy","fraction":1.0}]';
}</pre>
]]></content:encoded>
</item>
<item>
<title>RSS feed tuning</title>
<link>https://blog.x-way.org/Webdesign/2024/06/23/RSS-feed-tuning.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324369</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 23 Jun 2024 16:44:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>After the <a href="https://blog.x-way.org/Webdesign/2024/06/16/Jumping-on-the-Web-Components-bandwagon.html" title="Jumping on the Web Components bandwagon - x-log">recent addition of custom Web Components</a>, the usual <a href="https://www.rssboard.org/rss-validator/" title="RSS Validator">feed</a> <a href="https://validator.w3.org/feed/" title="W3C Feed Validation Service, for Atom and RSS">validators</a> were a bit less happy about my <a href="https://blog.x-way.org/rss.xml">RSS</a> and <a href="https://blog.x-way.org/atom.xml">Atom</a> feeds.</p>
<p>They always marked my feeds as valid, but usually had some recommendations to improve interoperability with the widest range of feed readers.<br>In particular having non-HTML5 elements does not help with interoperability. Which makes sense as there is no real place in the XML of the feeds to reference the needed JavaScript for rendering the Web Components.</p>
<p>Besides stripping away the <youtube-vimeo-embed> tags and replacing them with a link to the video, I took this opportunity to cleanup some other 'Altlasten' (legacy tech depts).<br>A lot of time was spent trying to get my head around various encodings/escapings of special characters. When the blog started in 2002, UTF-8 was not adopted yet and all special characters needed to be written as <a href="https://developer.mozilla.org/en-US/docs/Glossary/Character_reference" title="Character reference - MDN">HTML entities</a>.<br>And what didn't help is that I somehow had a text-only part in my RSS file which tried to deliver a version of my posts without any HTML (but failed to do so properly as it only had the tags stripped away but did not revert all the HTML character encodings.<br>Of course the various resulting & characters nicely clash with XML encoding).</p>
<p>There were some other oddities from the past, such as empty post titles and HTML tags inside titles.</p>
<p>I ended up cleaning up most of this and got rid of the text-only representation and corresponding encoding/escaping problems. (using <code><![CDATA[</code> and <code>]]></code> with the HTML content inside makes life so much easier)</p>
<p>The still remaing recommendations to improve are about relative links and <code><script></code> tags.<br>The relative links are all due to my replacing of dead and non-archived link destinations with a single <code>#</code>. So they are more a 'false postive' than a real problem, the links are dead either way.<br>The <code><script></code> tags are more problematic, as they result from my embedding of <a href="https://gist.github.com/" title="Discover Discover gists · GitHub">GitHub Gists</a> in posts. The code in the Gists is loaded, rendered and nicely highlighted with color by the script, thus not easy to replicate in a feed.</p>
<p>Probably the best approach for the Gists would be to find a way to properly include the content into the posts. So that it is rendered nicely when viewed in a browser, and has a meaningful text-only fallback in the feeds.<br>Would make sense to self-hosts these anyways. Next rainy weekend project there you are :-)</p>
<p><a href="https://www.rssboard.org/rss-validator/check.cgi?url=http%3A%2F%2Fblog.x-way.org%2Frss.xml" title="RSS Validator Results: http://blog.x-way.org/rss.xml"><img src="https://blog.x-way.org/images/valid-rss-rogers.png" width="88" height="31" alt="This is a valid RSS feed."></a> <a href="https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fblog.x-way.org%2Fatom.xml" title="Feed Validator Results: https://blog.x-way.org/atom.xml"><img src="https://blog.x-way.org/images/valid-atom.png" width="88" height="31" alt="This is a valid Atom 1.0 feed."></a></p>
]]></description>
<content:encoded><![CDATA[<p>After the <a href="https://blog.x-way.org/Webdesign/2024/06/16/Jumping-on-the-Web-Components-bandwagon.html" title="Jumping on the Web Components bandwagon - x-log">recent addition of custom Web Components</a>, the usual <a href="https://www.rssboard.org/rss-validator/" title="RSS Validator">feed</a> <a href="https://validator.w3.org/feed/" title="W3C Feed Validation Service, for Atom and RSS">validators</a> were a bit less happy about my <a href="https://blog.x-way.org/rss.xml">RSS</a> and <a href="https://blog.x-way.org/atom.xml">Atom</a> feeds.</p>
<p>They always marked my feeds as valid, but usually had some recommendations to improve interoperability with the widest range of feed readers.<br>In particular having non-HTML5 elements does not help with interoperability. Which makes sense as there is no real place in the XML of the feeds to reference the needed JavaScript for rendering the Web Components.</p>
<p>Besides stripping away the <youtube-vimeo-embed> tags and replacing them with a link to the video, I took this opportunity to cleanup some other 'Altlasten' (legacy tech depts).<br>A lot of time was spent trying to get my head around various encodings/escapings of special characters. When the blog started in 2002, UTF-8 was not adopted yet and all special characters needed to be written as <a href="https://developer.mozilla.org/en-US/docs/Glossary/Character_reference" title="Character reference - MDN">HTML entities</a>.<br>And what didn't help is that I somehow had a text-only part in my RSS file which tried to deliver a version of my posts without any HTML (but failed to do so properly as it only had the tags stripped away but did not revert all the HTML character encodings.<br>Of course the various resulting & characters nicely clash with XML encoding).</p>
<p>There were some other oddities from the past, such as empty post titles and HTML tags inside titles.</p>
<p>I ended up cleaning up most of this and got rid of the text-only representation and corresponding encoding/escaping problems. (using <code><![CDATA[</code> and <code>]]></code> with the HTML content inside makes life so much easier)</p>
<p>The still remaing recommendations to improve are about relative links and <code><script></code> tags.<br>The relative links are all due to my replacing of dead and non-archived link destinations with a single <code>#</code>. So they are more a 'false postive' than a real problem, the links are dead either way.<br>The <code><script></code> tags are more problematic, as they result from my embedding of <a href="https://gist.github.com/" title="Discover Discover gists · GitHub">GitHub Gists</a> in posts. The code in the Gists is loaded, rendered and nicely highlighted with color by the script, thus not easy to replicate in a feed.</p>
<p>Probably the best approach for the Gists would be to find a way to properly include the content into the posts. So that it is rendered nicely when viewed in a browser, and has a meaningful text-only fallback in the feeds.<br>Would make sense to self-hosts these anyways. Next rainy weekend project there you are :-)</p>
<p><a href="https://www.rssboard.org/rss-validator/check.cgi?url=http%3A%2F%2Fblog.x-way.org%2Frss.xml" title="RSS Validator Results: http://blog.x-way.org/rss.xml"><img src="https://blog.x-way.org/images/valid-rss-rogers.png" width="88" height="31" alt="This is a valid RSS feed."></a> <a href="https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fblog.x-way.org%2Fatom.xml" title="Feed Validator Results: https://blog.x-way.org/atom.xml"><img src="https://blog.x-way.org/images/valid-atom.png" width="88" height="31" alt="This is a valid Atom 1.0 feed."></a></p>
]]></content:encoded>
</item>
<item>
<title>sibatable</title>
<link>https://blog.x-way.org/Food/2024/06/22/sibatable.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324368</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 22 Jun 2024 20:06:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Food/">Food</category>
<description><![CDATA[<p><a href="https://blog.x-way.org/images/sibatable.jpg" title="sibatable"><img src="https://blog.x-way.org/images/sibatable_thumb.jpg" width="446" height="431" alt="A bowl of ramen with the rice and eggs decorated so that they look like a chicken with her chicks."></a></p>
<p>Amazing food art by <a href="https://www.instagram.com/sibatable/" title="시바테이블 (@sibatable) • Instagram">sibatable</a>.</p>
<p>Besides the <a href="https://www.instagram.com/sibatable/" title="시바테이블 (@sibatable) • Instagram">Instagram page</a> and the <a href="https://ohou.se/users/8132629" title="sibatable님의 공간에 오신 것을 환영합니다.">ohou.se page</a> check out the articles from <a href="https://www.tapasmagazine.es/en/sibatable-the-aesthetisation-food-through-fantasy/" title="Sibatable, the aestheticisation of food through fantasy - Tapas">Tapas</a> and <a href="https://mymodernmet.com/min-kyung-kin-sibatable-animal-food-art/" title="Super Cute Animal Food Art by Korean Artist">My Modern Met</a> for more infos about the artist.</p>
<p>(<a href="https://labnotes.org/weekend-reading-occams-shaving-kit/" title="Weekend Reading — Occam's shaving kit — Labnotes (by Assaf Arkin)">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://blog.x-way.org/images/sibatable.jpg" title="sibatable"><img src="https://blog.x-way.org/images/sibatable_thumb.jpg" width="446" height="431" alt="A bowl of ramen with the rice and eggs decorated so that they look like a chicken with her chicks."></a></p>
<p>Amazing food art by <a href="https://www.instagram.com/sibatable/" title="시바테이블 (@sibatable) • Instagram">sibatable</a>.</p>
<p>Besides the <a href="https://www.instagram.com/sibatable/" title="시바테이블 (@sibatable) • Instagram">Instagram page</a> and the <a href="https://ohou.se/users/8132629" title="sibatable님의 공간에 오신 것을 환영합니다.">ohou.se page</a> check out the articles from <a href="https://www.tapasmagazine.es/en/sibatable-the-aesthetisation-food-through-fantasy/" title="Sibatable, the aestheticisation of food through fantasy - Tapas">Tapas</a> and <a href="https://mymodernmet.com/min-kyung-kin-sibatable-animal-food-art/" title="Super Cute Animal Food Art by Korean Artist">My Modern Met</a> for more infos about the artist.</p>
<p>(<a href="https://labnotes.org/weekend-reading-occams-shaving-kit/" title="Weekend Reading — Occam's shaving kit — Labnotes (by Assaf Arkin)">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>IPv6 vs IPv4 traffic graphs in MikroTik</title>
<link>https://blog.x-way.org/Networking/2024/06/22/IPv6-vs-IPv4-traffic-graphs-in-MikroTik.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324367</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 22 Jun 2024 12:32:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>Out of curiosity I wanted to know how much of my Internet traffic uses IPv6 vs the <a href="https://blog.x-way.org/Networking/2013/07/05/Mandatory-requirement-for-all-non-IPv6-capable-products.html">legacy IPv4</a>.</p>
<p>There is no out-of-the-box graph for this in MikroTik.<br>Several forum and Stack Overflow posts suggest using ratelimiting queues with their graphing feature to collect this data.<p>
<p>After experimenting a bit, I ended up with the following configuration which creates two queues to collect the traffic data.<br>Important to know, traffic flows on a first-match basis through the queues. Thus the trick of having first the queue matching IPv6 traffic and then the queue matching all the remaining traffic.<br>Also, I use <code>10G</code> as 'unreachable' traffic limit to avoid any traffic being ratelimited. This works well for my 1Gbit/s setup, but will need to be adjusted if you have a higher bandwidth.</p>
<pre>/queue simple add limit-at=10G/10G max-limit=10G/10G name=v6-traffic queue=ethernet-default/ethernet-default target=2000::/3 total-queue=ethernet-default
/queue simple add limit-at=10G/10G max-limit=10G/10G name=v4-traffic queue=ethernet-default/ethernet-default target="" total-queue=ethernet-default</pre>
<p>Having the queues in place for a couple days results in the following graphs:</p>
<p>IPv6 Traffic<br>
<img src="https://blog.x-way.org/images/ipv6-traffic.png" width="492" height="251" alt="Weekly traffic graph of the IPv6 queue, showing an average of 379.65Kb incoming traffic."></p>
<p>IPv4 Traffic<br>
<img src="https://blog.x-way.org/images/ipv4-traffic.png" width="492" height="251" alt="Weekly traffic graph of the IPv4 queue, showing an average of 21.49Kb incoming traffic."></p>
<p>Happy to see that a large majority of my traffic uses IPv6 :-)</p>
]]></description>
<content:encoded><![CDATA[<p>Out of curiosity I wanted to know how much of my Internet traffic uses IPv6 vs the <a href="https://blog.x-way.org/Networking/2013/07/05/Mandatory-requirement-for-all-non-IPv6-capable-products.html">legacy IPv4</a>.</p>
<p>There is no out-of-the-box graph for this in MikroTik.<br>Several forum and Stack Overflow posts suggest using ratelimiting queues with their graphing feature to collect this data.<p>
<p>After experimenting a bit, I ended up with the following configuration which creates two queues to collect the traffic data.<br>Important to know, traffic flows on a first-match basis through the queues. Thus the trick of having first the queue matching IPv6 traffic and then the queue matching all the remaining traffic.<br>Also, I use <code>10G</code> as 'unreachable' traffic limit to avoid any traffic being ratelimited. This works well for my 1Gbit/s setup, but will need to be adjusted if you have a higher bandwidth.</p>
<pre>/queue simple add limit-at=10G/10G max-limit=10G/10G name=v6-traffic queue=ethernet-default/ethernet-default target=2000::/3 total-queue=ethernet-default
/queue simple add limit-at=10G/10G max-limit=10G/10G name=v4-traffic queue=ethernet-default/ethernet-default target="" total-queue=ethernet-default</pre>
<p>Having the queues in place for a couple days results in the following graphs:</p>
<p>IPv6 Traffic<br>
<img src="https://blog.x-way.org/images/ipv6-traffic.png" width="492" height="251" alt="Weekly traffic graph of the IPv6 queue, showing an average of 379.65Kb incoming traffic."></p>
<p>IPv4 Traffic<br>
<img src="https://blog.x-way.org/images/ipv4-traffic.png" width="492" height="251" alt="Weekly traffic graph of the IPv4 queue, showing an average of 21.49Kb incoming traffic."></p>
<p>Happy to see that a large majority of my traffic uses IPv6 :-)</p>
]]></content:encoded>
</item>
<item>
<title>More modern technologies</title>
<link>https://blog.x-way.org/Webdesign/2024/06/18/More-modern-technologies.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324366</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 18 Jun 2024 20:59:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>After the recent <a href="https://blog.x-way.org/Webdesign/2024/06/16/Jumping-on-the-Web-Components-bandwagon.html" title="Jumping on the Web Components bandwagon - x-log">integration of Web Components in the blog</a>, I made yet another stab at using some modern technologies.</p>
<p>This time inspired by the <a href="https://lynnandtonic.com/thoughts/entries/ten-years-of-a-single-div/" title="Ten years of A Single Div | Lynn Fisher">Ten years of A Single Div</a> article, my focus was on the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient" title="linear-gradient() - CSS | MDN">linear-gradient()</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/radial-gradient" title="radial-gradient() - CSS | MDN">radial-gradient()</a> CSS properties.</p>
<p>They can be combined to draw almost arbitrary shapes with pure CSS.</p>
<p>I used this to replace all graphics on <a href="https://www.andreas-jaggi.ch/" title="andreas-jaggi.ch">andreas-jaggi.ch</a> with CSS, while keeping the layout and functionality identical to the <a href="https://web.archive.org/web/20050311173245/http://x-way.waterwave.ch/#" title="x-way.waterwave.ch (archive.org)">original 2005 version</a>.</p>
<p>In the process of this, also some additional modern CSS features were used:<br>
<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/var" title="var() - CSS | MDN">var()</a> to simplify repeating CSS code.<br>
<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/animation" title="animation - CSS | MDN">animation</a>/<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes" title="@keyframes - CSS | MDN">@keyframes</a> to add a little fade-in effect on the hover text.</p>
]]></description>
<content:encoded><![CDATA[<p>After the recent <a href="https://blog.x-way.org/Webdesign/2024/06/16/Jumping-on-the-Web-Components-bandwagon.html" title="Jumping on the Web Components bandwagon - x-log">integration of Web Components in the blog</a>, I made yet another stab at using some modern technologies.</p>
<p>This time inspired by the <a href="https://lynnandtonic.com/thoughts/entries/ten-years-of-a-single-div/" title="Ten years of A Single Div | Lynn Fisher">Ten years of A Single Div</a> article, my focus was on the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient" title="linear-gradient() - CSS | MDN">linear-gradient()</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/radial-gradient" title="radial-gradient() - CSS | MDN">radial-gradient()</a> CSS properties.</p>
<p>They can be combined to draw almost arbitrary shapes with pure CSS.</p>
<p>I used this to replace all graphics on <a href="https://www.andreas-jaggi.ch/" title="andreas-jaggi.ch">andreas-jaggi.ch</a> with CSS, while keeping the layout and functionality identical to the <a href="https://web.archive.org/web/20050311173245/http://x-way.waterwave.ch/#" title="x-way.waterwave.ch (archive.org)">original 2005 version</a>.</p>
<p>In the process of this, also some additional modern CSS features were used:<br>
<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/var" title="var() - CSS | MDN">var()</a> to simplify repeating CSS code.<br>
<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/animation" title="animation - CSS | MDN">animation</a>/<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes" title="@keyframes - CSS | MDN">@keyframes</a> to add a little fade-in effect on the hover text.</p>
]]></content:encoded>
</item>
<item>
<title>Jumping on the Web Components bandwagon</title>
<link>https://blog.x-way.org/Webdesign/2024/06/16/Jumping-on-the-Web-Components-bandwagon.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324365</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 16 Jun 2024 21:53:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>The <a href="https://adrianroselli.com/2024/06/youtube-and-vimeo-web-component.html" title="YouTube and Vimeo Web Component - Adrian Roselli">recent article from Adrian Roselli</a> explaining how to write a Web Component for YouTube and Vimeo videos, triggered me to finally adopt the Web Components technology for my blog.<br>Additionally there is <a href="https://kniebes.com/" title="Markus Kniebes">Markus</a> using <a href="https://kniebes.com/2023/07/01/sharing-web-component" title="Sharing Web Component (kniebes.com)">Web Components for his blog</a> since quite some time, which gave me confidence.</p>
<p>Implementing Web Components was now not only for the sake of learning about the technology, but also to address some longstanding painpoints I had with my embedded videos.<br>In particular did I not like that each embedded video triggered the loading of a plethora of third-party scripts and styles only to render the thumbnail image. And additionally this leaked tracking/cookie information to the video hosters (yes, I was using www.youtube-nocookie.com to reduce this as far as possible, but could not eliminate it completely).</p>
<p>Thus I added a <code><youtube-vimeo-embed></code> Web Component and changed all my embedded YouTube and Vimeo videos to use it.</p>
<p>My implementation is almost a 1:1 copy of the <a href="https://github.com/aardrian/youtube-vimeo-embed/tree/main" title="GitHub - aardrian/youtube-vimeo-embed: A custom element to embed either a YouTube or Vimeo video into your page.">code provided by Adrian</a>, with some minor adaptions (such as hiding the original link when the video iframe can be rendered and always enabling fullscreen mode in videos).</p>
<p>I'm quite happy with the outcome, as it provides some new benefits:<br>
Except for the thumbnail image, no other third-party resources are loaded until someone clicks on the play button.<br>
When JavaScript or Web Components are not supported by a browser, it gracefuly falls back to a simple link to the video.<br>
Loading speed of the whole page improved quite a bit, as videos are only loaded on demand.<br>
It always uses www.youtube-nocookie.com and third-party scripts are only loaded if someone explicitly clicks on the play button of a video :-)</p>
]]></description>
<content:encoded><![CDATA[<p>The <a href="https://adrianroselli.com/2024/06/youtube-and-vimeo-web-component.html" title="YouTube and Vimeo Web Component - Adrian Roselli">recent article from Adrian Roselli</a> explaining how to write a Web Component for YouTube and Vimeo videos, triggered me to finally adopt the Web Components technology for my blog.<br>Additionally there is <a href="https://kniebes.com/" title="Markus Kniebes">Markus</a> using <a href="https://kniebes.com/2023/07/01/sharing-web-component" title="Sharing Web Component (kniebes.com)">Web Components for his blog</a> since quite some time, which gave me confidence.</p>
<p>Implementing Web Components was now not only for the sake of learning about the technology, but also to address some longstanding painpoints I had with my embedded videos.<br>In particular did I not like that each embedded video triggered the loading of a plethora of third-party scripts and styles only to render the thumbnail image. And additionally this leaked tracking/cookie information to the video hosters (yes, I was using www.youtube-nocookie.com to reduce this as far as possible, but could not eliminate it completely).</p>
<p>Thus I added a <code><youtube-vimeo-embed></code> Web Component and changed all my embedded YouTube and Vimeo videos to use it.</p>
<p>My implementation is almost a 1:1 copy of the <a href="https://github.com/aardrian/youtube-vimeo-embed/tree/main" title="GitHub - aardrian/youtube-vimeo-embed: A custom element to embed either a YouTube or Vimeo video into your page.">code provided by Adrian</a>, with some minor adaptions (such as hiding the original link when the video iframe can be rendered and always enabling fullscreen mode in videos).</p>
<p>I'm quite happy with the outcome, as it provides some new benefits:<br>
Except for the thumbnail image, no other third-party resources are loaded until someone clicks on the play button.<br>
When JavaScript or Web Components are not supported by a browser, it gracefuly falls back to a simple link to the video.<br>
Loading speed of the whole page improved quite a bit, as videos are only loaded on demand.<br>
It always uses www.youtube-nocookie.com and third-party scripts are only loaded if someone explicitly clicks on the play button of a video :-)</p>
]]></content:encoded>
</item>
<item>
<title>blo.gs still Pinging</title>
<link>https://blog.x-way.org/Coding/2024/06/12/blogs-still-Pinging.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324364</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 12 Jun 2024 06:28:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>While browsing posts from the past on the <a href="https://blog.x-way.org/on-this-day.html" title="x-log - On this day">On this day</a> page, I saw the one about <a href="http://blo.gs/" title="blo.gs">blog.gs</a> from <a href="https://blog.x-way.org/Coding/2002/06/12/blogs-Ping.html" title="x-log - blo.gs-Ping">2002</a>.</p>
<p>Turns out the blog.gs ping mechanism is still working in exactly the same way after all these years (nowadays operated by Automattic).</p>
<p>As I don't run my blog with PHP anymore, I added the following step at the end of my deploy script.<br>It uses <code>curl</code> to peform <a href="http://blo.gs/ping-example.php" title="blo.gs: weblogUpdates.extendedPing example">the XML-RPC call</a> of the <code>weblogUpdates.extendedPing</code> API with the parameters for my weblog.</p>
<pre>curl -X POST -v ping.blo.gs -H 'content-type: text/xml' --data '<?xml version="1.0"?><methodCall><methodName>weblogUpdates.extendedPing</methodName><params><param><value>x-log</value></param><param><value>https://blog.x-way.org/</value></param><param><value></value></param><param><value>https://blog.x-way.org/rss.xml</value></param></params></methodCall>'</pre>
]]></description>
<content:encoded><![CDATA[<p>While browsing posts from the past on the <a href="https://blog.x-way.org/on-this-day.html" title="x-log - On this day">On this day</a> page, I saw the one about <a href="http://blo.gs/" title="blo.gs">blog.gs</a> from <a href="https://blog.x-way.org/Coding/2002/06/12/blogs-Ping.html" title="x-log - blo.gs-Ping">2002</a>.</p>
<p>Turns out the blog.gs ping mechanism is still working in exactly the same way after all these years (nowadays operated by Automattic).</p>
<p>As I don't run my blog with PHP anymore, I added the following step at the end of my deploy script.<br>It uses <code>curl</code> to peform <a href="http://blo.gs/ping-example.php" title="blo.gs: weblogUpdates.extendedPing example">the XML-RPC call</a> of the <code>weblogUpdates.extendedPing</code> API with the parameters for my weblog.</p>
<pre>curl -X POST -v ping.blo.gs -H 'content-type: text/xml' --data '<?xml version="1.0"?><methodCall><methodName>weblogUpdates.extendedPing</methodName><params><param><value>x-log</value></param><param><value>https://blog.x-way.org/</value></param><param><value></value></param><param><value>https://blog.x-way.org/rss.xml</value></param></params></methodCall>'</pre>
]]></content:encoded>
</item>
<item>
<title>Run Your Own Mail Server</title>
<link>https://blog.x-way.org/Linux/2024/05/31/Run-Your-Own-Mail-Server.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324363</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Fri, 31 May 2024 20:24:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p><a href="https://mwl.io/" title="About Me - Michael W Lucas">Michael W Lucas</a> is running a <a href="https://www.kickstarter.com/projects/mwlucas/run-your-own-mail-server/" title="Run Your Own Mail Server: A Book for Independence & Privacy">Kickstarter campaign</a> to fund writing of book providing the knowledge to run your own mail server.</p>
<p>As I'm running my own mail server (coincidently with some of the tools that will be discussed in the book: Debian, Postfix, Dovecot), I do sympathize with this initiative and would recommend to support the campaign.</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://mwl.io/" title="About Me - Michael W Lucas">Michael W Lucas</a> is running a <a href="https://www.kickstarter.com/projects/mwlucas/run-your-own-mail-server/" title="Run Your Own Mail Server: A Book for Independence & Privacy">Kickstarter campaign</a> to fund writing of book providing the knowledge to run your own mail server.</p>
<p>As I'm running my own mail server (coincidently with some of the tools that will be discussed in the book: Debian, Postfix, Dovecot), I do sympathize with this initiative and would recommend to support the campaign.</p>
]]></content:encoded>
</item>
<item>
<title>udm=14</title>
<link>https://blog.x-way.org/Misc/2024/05/25/udm-14.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324362</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 25 May 2024 09:30:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>As seen <a href="https://vowe.net/2024/05/20/old-school-google/" title="Old School Google - vowe dot net">all</a> <a href="https://daringfireball.net/linked/2024/05/22/google-web-tedium" title="Daring Fireball: How to Make Google’s 'Web' View Your Search Default">over</a> <a href="https://kottke.org/24/05/0044646-how-to-get-google-search" title="How to get Google search results without the AI garbage">the</a> <a href="https://bookmark.kniebes.io/bookmark/128c284f18cd11efadf1408d5c84b5d9" title="&udm=14 | the disenshittification Konami code">place</a>, adding <code>udm=14</code> to the URL of a Google search makes the result display less crappy (no ads, no AI suggestions to <a href="https://www.bbc.com/news/articles/cd11gzejgz4o" title="Google AI search tells users to glue pizza and eat rocks">eat rocks or put glue on pizza</a>, …).<br>The search results themselves of course are not really getting better with this, but at least the search experience is less annoying.</p>
<p>For the Desktop edition of Firefox you will need to use the <a href="https://addons.mozilla.org/en-US/firefox/addon/udm14/" title="udm14 - Get this Extension for Firefox">udm14 extension</a> to add the <code>udm=14</code> parameter by default to your search bar.<br>For other browsers it should be enough to modify the settings of the search URL used and add the parameter (something like <code>https://www.google.com/search?q=%s&udm=14</code>).<br>Or even better, do use an alternative search engine :-)</p>
]]></description>
<content:encoded><![CDATA[<p>As seen <a href="https://vowe.net/2024/05/20/old-school-google/" title="Old School Google - vowe dot net">all</a> <a href="https://daringfireball.net/linked/2024/05/22/google-web-tedium" title="Daring Fireball: How to Make Google’s 'Web' View Your Search Default">over</a> <a href="https://kottke.org/24/05/0044646-how-to-get-google-search" title="How to get Google search results without the AI garbage">the</a> <a href="https://bookmark.kniebes.io/bookmark/128c284f18cd11efadf1408d5c84b5d9" title="&udm=14 | the disenshittification Konami code">place</a>, adding <code>udm=14</code> to the URL of a Google search makes the result display less crappy (no ads, no AI suggestions to <a href="https://www.bbc.com/news/articles/cd11gzejgz4o" title="Google AI search tells users to glue pizza and eat rocks">eat rocks or put glue on pizza</a>, …).<br>The search results themselves of course are not really getting better with this, but at least the search experience is less annoying.</p>
<p>For the Desktop edition of Firefox you will need to use the <a href="https://addons.mozilla.org/en-US/firefox/addon/udm14/" title="udm14 - Get this Extension for Firefox">udm14 extension</a> to add the <code>udm=14</code> parameter by default to your search bar.<br>For other browsers it should be enough to modify the settings of the search URL used and add the parameter (something like <code>https://www.google.com/search?q=%s&udm=14</code>).<br>Or even better, do use an alternative search engine :-)</p>
]]></content:encoded>
</item>
<item>
<title>Recent Docker BuildKit Features</title>
<link>https://blog.x-way.org/Linux/2024/05/20/Recent-Docker-BuildKit-Features.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324361</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 20 May 2024 07:24:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>In the <a href="https://martinheinz.dev/blog/111" title="Recent Docker BuildKit Features You're Missing Out On | Martin Heinz | Personal Website & Blog">Recent Docker BuildKit Features You're Missing Out On</a> article, <a href="https://martinheinz.dev/" title="Martin Heinz | Personal Website & Blog">Martin Heinz</a> lists some of the new features that have been added to Docker with the BuildKit introduction.</p>
<p>My favorite one is the <a href="https://github.com/docker/buildx/blob/master/docs/debugging.md" title="debugging docs">debugger for failed build steps</a> of a container:</p>
<pre>export BUILDX_EXPERIMENTAL=1
docker buildx debug --invoke /bin/sh --on=error build .</pre>
]]></description>
<content:encoded><![CDATA[<p>In the <a href="https://martinheinz.dev/blog/111" title="Recent Docker BuildKit Features You're Missing Out On | Martin Heinz | Personal Website & Blog">Recent Docker BuildKit Features You're Missing Out On</a> article, <a href="https://martinheinz.dev/" title="Martin Heinz | Personal Website & Blog">Martin Heinz</a> lists some of the new features that have been added to Docker with the BuildKit introduction.</p>
<p>My favorite one is the <a href="https://github.com/docker/buildx/blob/master/docs/debugging.md" title="debugging docs">debugger for failed build steps</a> of a container:</p>
<pre>export BUILDX_EXPERIMENTAL=1
docker buildx debug --invoke /bin/sh --on=error build .</pre>
]]></content:encoded>
</item>
<item>
<title>Migrations</title>
<link>https://blog.x-way.org/Coding/2024/05/20/Migrations.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324360</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 20 May 2024 06:02:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<blockquote cite="https://twitter.com/mipsytipsy/status/1778534529298489428">
<p>Migrations are not something you can do rarely, or put off, or avoid; not if you are a growing company. Migrations are an ordinary fact of life.</p>
<p>Doing them swiftly, efficiently, and -- most of all -- *completely* is one of the most critical skills you can develop as a team.</p>
</blockquote>
<p>— <a href="https://charity.wtf/" title="Charity Majors">Charity Majors</a> (<a href="https://simonwillison.net/2024/May/6/charity-majors/" title="A quote from Charity Majors">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<blockquote cite="https://twitter.com/mipsytipsy/status/1778534529298489428">
<p>Migrations are not something you can do rarely, or put off, or avoid; not if you are a growing company. Migrations are an ordinary fact of life.</p>
<p>Doing them swiftly, efficiently, and -- most of all -- *completely* is one of the most critical skills you can develop as a team.</p>
</blockquote>
<p>— <a href="https://charity.wtf/" title="Charity Majors">Charity Majors</a> (<a href="https://simonwillison.net/2024/May/6/charity-majors/" title="A quote from Charity Majors">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Building a Geocities website in 1998</title>
<link>https://blog.x-way.org/Misc/2024/05/19/Building-a-Geocities-website-in-1998.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324359</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 19 May 2024 11:35:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://youtu.be/HeXVKrtecis" title="Building a Geocities website in 1998 - YouTube">Building a Geocities website in 1998</a></p>
<p>Brings back some faint memories of young me playing around with FrontPage (wondering why the preview rendering of an animated fullscreen background of a burning fire is making the computer go slow…)</p>
<p>(<a href="https://buttondown.email/cassidoo/archive/an-honest-man-is-always-a-child-socrates/" title="Web links of the week - cassidoo">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://youtu.be/HeXVKrtecis" title="Building a Geocities website in 1998 - YouTube">Building a Geocities website in 1998</a></p>
<p>Brings back some faint memories of young me playing around with FrontPage (wondering why the preview rendering of an animated fullscreen background of a burning fire is making the computer go slow…)</p>
<p>(<a href="https://buttondown.email/cassidoo/archive/an-honest-man-is-always-a-child-socrates/" title="Web links of the week - cassidoo">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>On this day</title>
<link>https://blog.x-way.org/Misc/2024/05/13/On-this-day.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324358</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 13 May 2024 07:00:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>In his <a href="https://shkspr.mobi/blog/2024/05/it-was-twenty-years-ago-today/" title="It was twenty years ago today — Terence Eden's Blog">20 year anniversary post</a>, <a href="https://shkspr.mobi/blog/" title="Terence Eden's Blog">Terence Eden</a> explains how he uses the "<a href="https://shkspr.mobi/blog/on-this-day/" title="On This Day — Terence Eden's Blog">On This Day</a>" feature of his blog every morning to look back on what he was writing on this day in previous years.</p>
<p>Finding this very inspiring, I decided to add a similar feature to my blog.<br>As my blog is built with Jekyll as static pages, some plain old JavaScript was needed to surface the posts of this day without having to rebuild the page daily.</p>
<p>And here we have now the <a href="https://blog.x-way.org/on-this-day.html" title="x-log - On This day">On this day</a> page :-)</p>
]]></description>
<content:encoded><![CDATA[<p>In his <a href="https://shkspr.mobi/blog/2024/05/it-was-twenty-years-ago-today/" title="It was twenty years ago today — Terence Eden's Blog">20 year anniversary post</a>, <a href="https://shkspr.mobi/blog/" title="Terence Eden's Blog">Terence Eden</a> explains how he uses the "<a href="https://shkspr.mobi/blog/on-this-day/" title="On This Day — Terence Eden's Blog">On This Day</a>" feature of his blog every morning to look back on what he was writing on this day in previous years.</p>
<p>Finding this very inspiring, I decided to add a similar feature to my blog.<br>As my blog is built with Jekyll as static pages, some plain old JavaScript was needed to surface the posts of this day without having to rebuild the page daily.</p>
<p>And here we have now the <a href="https://blog.x-way.org/on-this-day.html" title="x-log - On This day">On this day</a> page :-)</p>
]]></content:encoded>
</item>
<item>
<title>Warm weather warm colors</title>
<link>https://blog.x-way.org/Webdesign/2024/05/11/Warm-weather-warm-colors.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324357</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 11 May 2024 20:03:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>The warm temperatures around here made me change the blog theme back to the warm colors ☀️</p>
<p>Basically it's a revert of the <a href="https://blog.x-way.org/Webdesign/2024/01/01/Winter-plain-2.html" title="x-log - Winter - plain 2">winter layout changes</a> from beginning of the year, while keeping <a href="https://blog.x-way.org/Webdesign/2024/01/03/Valid-HTML5.html" title="x-log - Valid HTML5">all</a> <a href="https://blog.x-way.org/Webdesign/2024/01/27/Quick-and-dirty-dark-mode.html" title="x-log - Quick and dirty dark mode">the</a> <a href="https://blog.x-way.org/Webdesign/2024/01/28/Tables-are-gone.html" title="x-log - Tables are gone">HTML modernizations</a> done afterwards :-)</p>
<p>We're back on the <a href="https://blog.x-way.org/Webdesign/2022/06/04/Blogging-like-2002.html" title="x-log - Blogging like 2002">original 2002 layout</a> (with modern HTML), for those trying to keep score. Enjoy!</p>
]]></description>
<content:encoded><![CDATA[<p>The warm temperatures around here made me change the blog theme back to the warm colors ☀️</p>
<p>Basically it's a revert of the <a href="https://blog.x-way.org/Webdesign/2024/01/01/Winter-plain-2.html" title="x-log - Winter - plain 2">winter layout changes</a> from beginning of the year, while keeping <a href="https://blog.x-way.org/Webdesign/2024/01/03/Valid-HTML5.html" title="x-log - Valid HTML5">all</a> <a href="https://blog.x-way.org/Webdesign/2024/01/27/Quick-and-dirty-dark-mode.html" title="x-log - Quick and dirty dark mode">the</a> <a href="https://blog.x-way.org/Webdesign/2024/01/28/Tables-are-gone.html" title="x-log - Tables are gone">HTML modernizations</a> done afterwards :-)</p>
<p>We're back on the <a href="https://blog.x-way.org/Webdesign/2022/06/04/Blogging-like-2002.html" title="x-log - Blogging like 2002">original 2002 layout</a> (with modern HTML), for those trying to keep score. Enjoy!</p>
]]></content:encoded>
</item>
<item>
<title>The KonCodie Method</title>
<link>https://blog.x-way.org/Coding/2024/05/11/The-KonCodie-Method.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324356</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 11 May 2024 17:09:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>What if <a href="https://konmari.com/" title="KonMarie | The Official Website of Marie Kondo">Marie Kondo</a> would become a software engineer?</p>
<p><a href="https://www.200ok.com.au/" title="200 OK">Ben Buchanan</a> did run a parody account on this topic and has archived the posts <a href="https://weblog.200ok.com.au/2023/07/the-koncodie-method.html" title="The KonCodie Method | the 200ok weblog">on his site</a>.</p>
<p>There are some gems :-)</p>
<blockquote cite="https://weblog.200ok.com.au/2023/07/the-koncodie-method.html#koncodie-02"><p>To choose what to keep and what to throw away, take each dependency in one's manifest and ask: "Does this spark joy?" If it does, keep it. If not, remove it from your codebase.</p></blockquote>
<blockquote cite="https://weblog.200ok.com.au/2023/07/the-koncodie-method.html#koncodie-08"><p>We should be choosing what to <code>.gitkeep</code>, not what we want to <code>.gitignore</code></p></blockquote>
<blockquote cite="https://weblog.200ok.com.au/2023/07/the-koncodie-method.html#koncodie-31"><p>Cruft has only two possible causes: too much effort is required to refactor or it is unclear where things belong.</p></blockquote>
]]></description>
<content:encoded><![CDATA[<p>What if <a href="https://konmari.com/" title="KonMarie | The Official Website of Marie Kondo">Marie Kondo</a> would become a software engineer?</p>
<p><a href="https://www.200ok.com.au/" title="200 OK">Ben Buchanan</a> did run a parody account on this topic and has archived the posts <a href="https://weblog.200ok.com.au/2023/07/the-koncodie-method.html" title="The KonCodie Method | the 200ok weblog">on his site</a>.</p>
<p>There are some gems :-)</p>
<blockquote cite="https://weblog.200ok.com.au/2023/07/the-koncodie-method.html#koncodie-02"><p>To choose what to keep and what to throw away, take each dependency in one's manifest and ask: "Does this spark joy?" If it does, keep it. If not, remove it from your codebase.</p></blockquote>
<blockquote cite="https://weblog.200ok.com.au/2023/07/the-koncodie-method.html#koncodie-08"><p>We should be choosing what to <code>.gitkeep</code>, not what we want to <code>.gitignore</code></p></blockquote>
<blockquote cite="https://weblog.200ok.com.au/2023/07/the-koncodie-method.html#koncodie-31"><p>Cruft has only two possible causes: too much effort is required to refactor or it is unclear where things belong.</p></blockquote>
]]></content:encoded>
</item>
<item>
<title>If you don't fit...</title>
<link>https://blog.x-way.org/Misc/2024/05/05/If-you-dont-fit.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324354</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 05 May 2024 20:40:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://blog.x-way.org/images/if-you-dont-fit.png" title="A sad little puzzle piece is looking at a puzzle with no room for him. The text says "If you don't fit... Maybe you haven't found the right puzzle." Then the piece joins a puzzle that is full of friendly pieces with lots of room"><img src="https://blog.x-way.org/images/if-you-dont-fit_thumb.png" height="500" width="400" alt="A sad little puzzle piece is looking at a puzzle with no room for him. The text says "If you don't fit... Maybe you haven't found the right puzzle." Then the piece joins a puzzle that is full of friendly pieces with lots of room"></a></p>
<p>"If you don't fit... Maybe you haven't found the right puzzle." — <a href="https://admiralwonderboat.com/" title="ADMIRAL WONDERBOAT">Admiral</a> <a href="https://mastodon.social/@admiralwonderboat/112368789681867074" title="ADMIRAL WONDERBOAT">Wonderboat</a> (<a href="https://fosstodon.org/@sushee" title="Su-Shee">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://blog.x-way.org/images/if-you-dont-fit.png" title="A sad little puzzle piece is looking at a puzzle with no room for him. The text says "If you don't fit... Maybe you haven't found the right puzzle." Then the piece joins a puzzle that is full of friendly pieces with lots of room"><img src="https://blog.x-way.org/images/if-you-dont-fit_thumb.png" height="500" width="400" alt="A sad little puzzle piece is looking at a puzzle with no room for him. The text says "If you don't fit... Maybe you haven't found the right puzzle." Then the piece joins a puzzle that is full of friendly pieces with lots of room"></a></p>
<p>"If you don't fit... Maybe you haven't found the right puzzle." — <a href="https://admiralwonderboat.com/" title="ADMIRAL WONDERBOAT">Admiral</a> <a href="https://mastodon.social/@admiralwonderboat/112368789681867074" title="ADMIRAL WONDERBOAT">Wonderboat</a> (<a href="https://fosstodon.org/@sushee" title="Su-Shee">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Migrate from legacy CSM boot to UEFI boot</title>
<link>https://blog.x-way.org/Linux/2024/05/05/Migrate-from-legacy-CSM-boot-to-UEFI-boot.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324355</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 05 May 2024 16:00:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>Due to a hardware failure I had to replace one of my computers (switching from a <a href="https://www.galaxus.ch/de/s1/product/intel-nuc-swift-canyon-nuc6i5syh-intel-core-i5-6260u-barebone-5670885" title="Intel NUC SWIFT CANYON NUC6I5SYH">2015 Intel NUC</a> to a <a href="https://www.galaxus.ch/de/s1/product/dell-optiplex-mff-intel-core-i5-12500t-16-gb-512-gb-ssd-pc-40390750" title="Dell OptiPlex MFF">Dell OptiPlex Micro 7010</a>).<br>
After moving the disk to the new system, it refused to boot (claimed that no bootable drive was available).</p>
<p>Turns out that the new system only supports UEFI booting and the existing disk was setup for 'legacy'/CSM boot.</p>
<p>I used the following steps to convert the existing disk to UEFI boot (while keeping all data on it available).<br>They are inspired by the excellent <a href="http://blog.getreu.net/projects/legacy-to-uefi-boot/" title="Switch Debian from legacy to UEFI boot mode">Switch Debian from legacy to UEFI boot mode</a> guide from <a href="https://blog.getreu.net/" title="Jens Getreu">Jens Getreu</a>.</p>
<ol>
<li>Disable secure boot in the BIOS to allow booting from an USB stick.</li>
<li>Create a bootable USB stick with a Debian live system (see <a href="https://blog.x-way.org/Linux/2024/05/05/Create-a-bootable-Debian-USB-stick-on-macOS.html" title="Create a bootable Debian USB stick on macOS">my previous post</a>)</li>
<li>Boot into the Debian live system</li>
<li>Identify the disk to work on (<code>/dev/nvme0n1</code> in my case)</li>
<li>Convert the partition table from MBR to GPT:
<pre># gdisk /dev/nvme0n1
r recovery and transformation options (experts only)
f load MBR and build fresh GPT from it
w write table to disk and exit</pre></li>
<li>Install gparted into the Debian live system:
<pre># apt-get install gparted</pre></li>
<li>Create an UEFI partition and a partition for Grub2:
<pre># gparted /dev/nvme0n1</pre>
Resize an existing partition to create space (does not need to be at the beginning of the disk, I used the swap partition).<br>
Create a new 100MB partition for efi (named "Efi partition"), format it as <code>fat32</code> and flag it <code>bootable</code>.<br>
Create a new 50MB partition for Grub2 (named "BIOS boot partition"), keep it unformatted.</li>
<li>Use gdisk to set proper partition codes (<code>EF00</code> for the efi partition and <code>EF02</code> for the Grub2 partition):
<pre># gdisk /dev/nvme0n1
p print the partition table
t change a partition's type code
t change a partition's type code
w write table to disk and exit</pre></li>
<li>Chroot into the on-disk root system:
<pre># mount -t ext4 /dev/nvme0n1p1 /mnt
# mkdir /mnt/boot/efi
# mount /dev/nvme0n1p2 /mnt/boot/efi
# mount --bind /sys /mnt/sys
# mount --bind /proc /mnt/proc
# mount --bind /dev /mnt/dev
# mount --bind /dev/pts /mnt/dev/pts
# cp /etc/resolv.conf /mnt/etc/resolv.conf
# chroot /mnt</pre></li>
<li>Update /etc/fstab:
<pre># ls -lisa /dev/disk/by-uuid</pre>
Identify the UUID of the EFI partition (usually in the format <code>XXXX-XXXX</code>) and add a corresponding line to <code>/etc/fstab</code>:
<pre># echo "UUID=XXXX-XXXX /boot/efi vfat defaults 0 2" >> /etc/fstab</pre></li>
<li>Install grub-efi and install Grub2 to the EFI partition:
<pre># apt-get remove grub-pc
# apt-get install grub-efi</pre>
<pre># grub-install /dev/nvme0n1</pre></li>
<li>Exit the chroot and reboot the system:
<pre># exit
# reboot</pre></li>
<li>Select the Debian bootloader (<code>/EFI/debian/grubx64.efi</code>) in the UEFI BIOS and make it the default :-)</li>
</ol>
]]></description>
<content:encoded><![CDATA[<p>Due to a hardware failure I had to replace one of my computers (switching from a <a href="https://www.galaxus.ch/de/s1/product/intel-nuc-swift-canyon-nuc6i5syh-intel-core-i5-6260u-barebone-5670885" title="Intel NUC SWIFT CANYON NUC6I5SYH">2015 Intel NUC</a> to a <a href="https://www.galaxus.ch/de/s1/product/dell-optiplex-mff-intel-core-i5-12500t-16-gb-512-gb-ssd-pc-40390750" title="Dell OptiPlex MFF">Dell OptiPlex Micro 7010</a>).<br>
After moving the disk to the new system, it refused to boot (claimed that no bootable drive was available).</p>
<p>Turns out that the new system only supports UEFI booting and the existing disk was setup for 'legacy'/CSM boot.</p>
<p>I used the following steps to convert the existing disk to UEFI boot (while keeping all data on it available).<br>They are inspired by the excellent <a href="http://blog.getreu.net/projects/legacy-to-uefi-boot/" title="Switch Debian from legacy to UEFI boot mode">Switch Debian from legacy to UEFI boot mode</a> guide from <a href="https://blog.getreu.net/" title="Jens Getreu">Jens Getreu</a>.</p>
<ol>
<li>Disable secure boot in the BIOS to allow booting from an USB stick.</li>
<li>Create a bootable USB stick with a Debian live system (see <a href="https://blog.x-way.org/Linux/2024/05/05/Create-a-bootable-Debian-USB-stick-on-macOS.html" title="Create a bootable Debian USB stick on macOS">my previous post</a>)</li>
<li>Boot into the Debian live system</li>
<li>Identify the disk to work on (<code>/dev/nvme0n1</code> in my case)</li>
<li>Convert the partition table from MBR to GPT:
<pre># gdisk /dev/nvme0n1
r recovery and transformation options (experts only)
f load MBR and build fresh GPT from it
w write table to disk and exit</pre></li>
<li>Install gparted into the Debian live system:
<pre># apt-get install gparted</pre></li>
<li>Create an UEFI partition and a partition for Grub2:
<pre># gparted /dev/nvme0n1</pre>
Resize an existing partition to create space (does not need to be at the beginning of the disk, I used the swap partition).<br>
Create a new 100MB partition for efi (named "Efi partition"), format it as <code>fat32</code> and flag it <code>bootable</code>.<br>
Create a new 50MB partition for Grub2 (named "BIOS boot partition"), keep it unformatted.</li>
<li>Use gdisk to set proper partition codes (<code>EF00</code> for the efi partition and <code>EF02</code> for the Grub2 partition):
<pre># gdisk /dev/nvme0n1
p print the partition table
t change a partition's type code
t change a partition's type code
w write table to disk and exit</pre></li>
<li>Chroot into the on-disk root system:
<pre># mount -t ext4 /dev/nvme0n1p1 /mnt
# mkdir /mnt/boot/efi
# mount /dev/nvme0n1p2 /mnt/boot/efi
# mount --bind /sys /mnt/sys
# mount --bind /proc /mnt/proc
# mount --bind /dev /mnt/dev
# mount --bind /dev/pts /mnt/dev/pts
# cp /etc/resolv.conf /mnt/etc/resolv.conf
# chroot /mnt</pre></li>
<li>Update /etc/fstab:
<pre># ls -lisa /dev/disk/by-uuid</pre>
Identify the UUID of the EFI partition (usually in the format <code>XXXX-XXXX</code>) and add a corresponding line to <code>/etc/fstab</code>:
<pre># echo "UUID=XXXX-XXXX /boot/efi vfat defaults 0 2" >> /etc/fstab</pre></li>
<li>Install grub-efi and install Grub2 to the EFI partition:
<pre># apt-get remove grub-pc
# apt-get install grub-efi</pre>
<pre># grub-install /dev/nvme0n1</pre></li>
<li>Exit the chroot and reboot the system:
<pre># exit
# reboot</pre></li>
<li>Select the Debian bootloader (<code>/EFI/debian/grubx64.efi</code>) in the UEFI BIOS and make it the default :-)</li>
</ol>
]]></content:encoded>
</item>
<item>
<title>Create a bootable Debian USB stick on macOS</title>
<link>https://blog.x-way.org/Linux/2024/05/05/Create-a-bootable-Debian-USB-stick-on-macOS.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324353</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 05 May 2024 14:39:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>Needed to create a bootable Debian USB stick for some maintenance on one of my computers.<br>Here are the steps so I won't have to search for them the next time :-)</p>
<ol>
<li>Download the <a href="https://www.debian.org/CD/live/" title="">Debian live CD image</a></li>
<li>Connect your USB stick and find its device location (/dev/diskX) with: <pre>sudo diskutil list</pre></li>
<li>If needed unmount your USB stick: <pre>sudo diskutil unmountdisk /dev/diskX</pre></li>
<li>Write the downloaded image onto the USB stick: <pre>sudo dd if=./debian-live-12.5.0-amd64-standard.iso of=/dev/diskX bs=1m</pre></li>
</ol>
]]></description>
<content:encoded><![CDATA[<p>Needed to create a bootable Debian USB stick for some maintenance on one of my computers.<br>Here are the steps so I won't have to search for them the next time :-)</p>
<ol>
<li>Download the <a href="https://www.debian.org/CD/live/" title="">Debian live CD image</a></li>
<li>Connect your USB stick and find its device location (/dev/diskX) with: <pre>sudo diskutil list</pre></li>
<li>If needed unmount your USB stick: <pre>sudo diskutil unmountdisk /dev/diskX</pre></li>
<li>Write the downloaded image onto the USB stick: <pre>sudo dd if=./debian-live-12.5.0-amd64-standard.iso of=/dev/diskX bs=1m</pre></li>
</ol>
]]></content:encoded>
</item>
<item>
<title>Tiny Fragments</title>
<link>https://blog.x-way.org/Misc/2024/04/24/Tiny-Fragments.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324352</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 24 Apr 2024 21:58:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://daz.itch.io/tiny-fragments" title="Tiny Fragments by Daniel Moreno">Tiny Fragments</a> is a fun little puzzle game made by <a href="https://www.dazlog.com/" title="Dazlog">Daniel Moreno</a> (<a href="https://gigold.me/links/game-tiny-fragments" title="Game: Tiny Fragments | Thomas Gigold">via</a>)</p>
<img src="https://blog.x-way.org/images/tiny-fragments.png" height="230" width="400" alt="Tiny Fragments - The Tree">
]]></description>
<content:encoded><![CDATA[<p><a href="https://daz.itch.io/tiny-fragments" title="Tiny Fragments by Daniel Moreno">Tiny Fragments</a> is a fun little puzzle game made by <a href="https://www.dazlog.com/" title="Dazlog">Daniel Moreno</a> (<a href="https://gigold.me/links/game-tiny-fragments" title="Game: Tiny Fragments | Thomas Gigold">via</a>)</p>
<img src="https://blog.x-way.org/images/tiny-fragments.png" height="230" width="400" alt="Tiny Fragments - The Tree">
]]></content:encoded>
</item>
<item>
<title>Testing HTML with modern CSS</title>
<link>https://blog.x-way.org/Webdesign/2024/04/23/Testing-HTML-with-modern-CSS.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324351</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 23 Apr 2024 00:30:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Interesting article explaining how to test HTML with visual CSS highlighting: <a href="https://heydonworks.com/article/testing-html-with-modern-css/" title="Testing HTML with modern CSS: HeydonWorks">Testing HTML with modern CSS</a> (<a href="https://couchblog.de/blog/2024/04/22/links/" title="Links | Couchblog">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p>Interesting article explaining how to test HTML with visual CSS highlighting: <a href="https://heydonworks.com/article/testing-html-with-modern-css/" title="Testing HTML with modern CSS: HeydonWorks">Testing HTML with modern CSS</a> (<a href="https://couchblog.de/blog/2024/04/22/links/" title="Links | Couchblog">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Print HTTP Headers and Pretty-Print JSON Response</title>
<link>https://blog.x-way.org/Linux/2024/04/15/Print-HTTP-Headers-and-Pretty-Print-JSON-Response.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324350</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 15 Apr 2024 09:37:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>In the <a href="https://susam.net/pretty-print-json-response-with-http-headers.html" title="Print HTTP Headers and Pretty-Print JSON Response - Susam Pal">Print HTTP Headers and Pretty-Print JSON Response</a> post, <a href="https://susam.net/" title="Susam Pal">Susam Pal</a> shows a nice trick to pretty-print JSON output with jq from curl while also showing the HTTP response headers (using stderr):</p>
<pre>curl -sSD /dev/stderr https://some-URL-returning-JSON | jq .</pre>
]]></description>
<content:encoded><![CDATA[<p>In the <a href="https://susam.net/pretty-print-json-response-with-http-headers.html" title="Print HTTP Headers and Pretty-Print JSON Response - Susam Pal">Print HTTP Headers and Pretty-Print JSON Response</a> post, <a href="https://susam.net/" title="Susam Pal">Susam Pal</a> shows a nice trick to pretty-print JSON output with jq from curl while also showing the HTTP response headers (using stderr):</p>
<pre>curl -sSD /dev/stderr https://some-URL-returning-JSON | jq .</pre>
]]></content:encoded>
</item>
<item>
<title>Modern Git Commands and Features You Should Be Using</title>
<link>https://blog.x-way.org/Coding/2024/04/13/Modern-Git-Commands-and-Features-You-Should-Be-Using.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324349</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 13 Apr 2024 20:37:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p><a href="https://martinheinz.dev/blog/109" title="Modern Git Commands and Features You Should Be Using | Martin Heinz | Personal Website & Blog">Modern Git Commands and Features You Should Be Using</a> — a short article from <a href="https://martinheinz.dev/" title="Martin Heinz | Personal Website & Blog">Martin Heinz</a> about some new-ish (>2018) features in <a href="https://git-scm.com/" title="Git">Git</a>, that 'can make your life so much easier'.</p>
<p>TL;DR:</p>
<ul>
<li><code>git switch <branchname></code></li>
<li><code>git restore --staged <somefile></code></li>
<li><code>git restore --source <commit> <somefile></code></li>
<li><code>git sparse-checkout</code></li>
<li><code>git worktree</code></li>
<li><code>git bisect</code></li>
</ul>
<p>Similar post from five years ago: <a href="https://blog.x-way.org/Coding/2019/05/25/More-productive-Git.html" title="More productive Git - x-log">More productive Git</a></p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://martinheinz.dev/blog/109" title="Modern Git Commands and Features You Should Be Using | Martin Heinz | Personal Website & Blog">Modern Git Commands and Features You Should Be Using</a> — a short article from <a href="https://martinheinz.dev/" title="Martin Heinz | Personal Website & Blog">Martin Heinz</a> about some new-ish (>2018) features in <a href="https://git-scm.com/" title="Git">Git</a>, that 'can make your life so much easier'.</p>
<p>TL;DR:</p>
<ul>
<li><code>git switch <branchname></code></li>
<li><code>git restore --staged <somefile></code></li>
<li><code>git restore --source <commit> <somefile></code></li>
<li><code>git sparse-checkout</code></li>
<li><code>git worktree</code></li>
<li><code>git bisect</code></li>
</ul>
<p>Similar post from five years ago: <a href="https://blog.x-way.org/Coding/2019/05/25/More-productive-Git.html" title="More productive Git - x-log">More productive Git</a></p>
]]></content:encoded>
</item>
<item>
<title>NTP IPs</title>
<link>https://blog.x-way.org/Networking/2024/04/11/NTP-IPs.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324348</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 11 Apr 2024 21:41:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>This <a href="https://rachelbythebay.com/w/2024/04/10/rtc/" title="Going in circles without a real-time clock">post</a> from Rachel, reminded me of my own struggle with a Raspberry Pi and time (and yes, I did run into the same DNSSEC problem).<br>I first tried a RTC shield, but this didn't fully solve all problems.</p>
<p>My workaround in the end is to use two fixed IP addresses in ntp.conf in additon to the usual pool servers.<br>Thanks ${previous employer} for not changing the IPs of your public NTP servers so far :-)</p>
]]></description>
<content:encoded><![CDATA[<p>This <a href="https://rachelbythebay.com/w/2024/04/10/rtc/" title="Going in circles without a real-time clock">post</a> from Rachel, reminded me of my own struggle with a Raspberry Pi and time (and yes, I did run into the same DNSSEC problem).<br>I first tried a RTC shield, but this didn't fully solve all problems.</p>
<p>My workaround in the end is to use two fixed IP addresses in ntp.conf in additon to the usual pool servers.<br>Thanks ${previous employer} for not changing the IPs of your public NTP servers so far :-)</p>
]]></content:encoded>
</item>
<item>
<title>Back on native IPv6</title>
<link>https://blog.x-way.org/Networking/2024/04/10/Back-on-native-IPv6.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324347</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 10 Apr 2024 20:28:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>As hinted at in my <a href="https://blog.x-way.org/Networking/2024/04/10/SixSpotting-still-going-on.html" title="SixSpotting still going on - x-log">previous post</a>, Solnet is delivering native IPv6 Internet again.</p>
<p>Shortly after 23h on March 26th there was a brief interruption of the Internet uplink and afterwards my router started receiving an IPv6 address again.<br>My <a href="https://blog.x-way.org/Networking/2024/02/25/Tunnelbroker-to-the-rescue.html" title="Tunnelbroker to the rescue - x-log">support ticket with Solnet</a> is still unanswered, but at least IPv6 is back :-)</p>
]]></description>
<content:encoded><![CDATA[<p>As hinted at in my <a href="https://blog.x-way.org/Networking/2024/04/10/SixSpotting-still-going-on.html" title="SixSpotting still going on - x-log">previous post</a>, Solnet is delivering native IPv6 Internet again.</p>
<p>Shortly after 23h on March 26th there was a brief interruption of the Internet uplink and afterwards my router started receiving an IPv6 address again.<br>My <a href="https://blog.x-way.org/Networking/2024/02/25/Tunnelbroker-to-the-rescue.html" title="Tunnelbroker to the rescue - x-log">support ticket with Solnet</a> is still unanswered, but at least IPv6 is back :-)</p>
]]></content:encoded>
</item>
<item>
<title>SixSpotting still going on</title>
<link>https://blog.x-way.org/Networking/2024/04/10/SixSpotting-still-going-on.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324346</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 10 Apr 2024 19:05:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>While browsing through the archives I stumbled upon the <a href="https://blog.x-way.org/Networking/2014/11/02/SixSpotting.html" title="SixSpotting - x-log">SixSpotting post</a> from 2014.<br>Turns out <a href="https://game.flyingpenguintech.org/" title="SixSpotting">the game</a> is still working and after some failed attempts I managed to remember my account name and log in.<br>I guess it must look quite strange to see a burst of new checkins after almost 10 years 😄</p>
<p><img src="https://blog.x-way.org/images/sixspotting-2024.png" width="420" height="87" alt="My last 5 SixSpotting checkins" /></p>
]]></description>
<content:encoded><![CDATA[<p>While browsing through the archives I stumbled upon the <a href="https://blog.x-way.org/Networking/2014/11/02/SixSpotting.html" title="SixSpotting - x-log">SixSpotting post</a> from 2014.<br>Turns out <a href="https://game.flyingpenguintech.org/" title="SixSpotting">the game</a> is still working and after some failed attempts I managed to remember my account name and log in.<br>I guess it must look quite strange to see a burst of new checkins after almost 10 years 😄</p>
<p><img src="https://blog.x-way.org/images/sixspotting-2024.png" width="420" height="87" alt="My last 5 SixSpotting checkins" /></p>
]]></content:encoded>
</item>
<item>
<title>humans.txt</title>
<link>https://blog.x-way.org/Webdesign/2024/04/07/humans-txt.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324345</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 07 Apr 2024 19:10:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>After following a couple links from the article linked in the previous blogpost, I ended up reading the <a href="https://shellsharks.com/notes/2023/08/15/website-component-checklist" title="Website Component Checklis">Website Component Checklist</a> from <a href="https://shellsharks.com/about" title="Mike Sass">Mike Sass</a>.<br>It provides again a lot of inspiration for things to add to my weblog.<br>What intrigued me today on the list was <a href="https://web.archive.org/web/20240330061550/https://humanstxt.org/" title="Humans TXT: We Are People, Not Machines.">humans.txt</a>, which is an initiative for knowing the people behing a website.</p>
<p>Thus I've now added the following <a href="https://blog.x-way.org/humans.txt" title="x-log - Humans TXT">humans.txt</a>.</p>
]]></description>
<content:encoded><![CDATA[<p>After following a couple links from the article linked in the previous blogpost, I ended up reading the <a href="https://shellsharks.com/notes/2023/08/15/website-component-checklist" title="Website Component Checklis">Website Component Checklist</a> from <a href="https://shellsharks.com/about" title="Mike Sass">Mike Sass</a>.<br>It provides again a lot of inspiration for things to add to my weblog.<br>What intrigued me today on the list was <a href="https://web.archive.org/web/20240330061550/https://humanstxt.org/" title="Humans TXT: We Are People, Not Machines.">humans.txt</a>, which is an initiative for knowing the people behing a website.</p>
<p>Thus I've now added the following <a href="https://blog.x-way.org/humans.txt" title="x-log - Humans TXT">humans.txt</a>.</p>
]]></content:encoded>
</item>
<item>
<title>100 more things you can do with your personal website</title>
<link>https://blog.x-way.org/Misc/2024/04/07/100-more-things-you-can-do-with-your-personal-website.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324344</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 07 Apr 2024 17:32:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://jamesg.blog/2024/03/10/100-more-personal-website-ideas/" title="100 (more) things you can do with your personal website | James' Coffee Blog">100 more things you can do with your personal website</a> — a follow-up to the <a href="https://blog.x-way.org/Misc/2024/03/07/100-things-you-can-do-on-your-personal-website.html" title="x-log - 100 things you can do on your personal website">popular post</a> from last month :-)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://jamesg.blog/2024/03/10/100-more-personal-website-ideas/" title="100 (more) things you can do with your personal website | James' Coffee Blog">100 more things you can do with your personal website</a> — a follow-up to the <a href="https://blog.x-way.org/Misc/2024/03/07/100-things-you-can-do-on-your-personal-website.html" title="x-log - 100 things you can do on your personal website">popular post</a> from last month :-)</p>
]]></content:encoded>
</item>
<item>
<title>Dog Poo Golf</title>
<link>https://blog.x-way.org/Misc/2024/04/03/Dog-Poo-Golf.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324343</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 03 Apr 2024 08:03:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><img src="https://blog.x-way.org/images/dog-poo-golf.png" width="480" height="347" alt="Dog Poo Golf start screen" /></p>
<p><a href="https://vole.wtf/dog-poo-golf/" title="Dog Poo Golf 🐶💩⛳">Dog Poo Golf</a>, a Wii Sports Golf-style browser game (with the music!) where you fling dog poop bags into a garbage can. 🐶💩⛳ (<a href="https://kottke.org/24/04/0044297-dog-poo-golf-a-wii" title="kottke.org - Dog Poo Golf">via kottke.org</a>)</p>
]]></description>
<content:encoded><![CDATA[<p><img src="https://blog.x-way.org/images/dog-poo-golf.png" width="480" height="347" alt="Dog Poo Golf start screen" /></p>
<p><a href="https://vole.wtf/dog-poo-golf/" title="Dog Poo Golf 🐶💩⛳">Dog Poo Golf</a>, a Wii Sports Golf-style browser game (with the music!) where you fling dog poop bags into a garbage can. 🐶💩⛳ (<a href="https://kottke.org/24/04/0044297-dog-poo-golf-a-wii" title="kottke.org - Dog Poo Golf">via kottke.org</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Puppet updated!</title>
<link>https://blog.x-way.org/Linux/2024/03/30/Puppet-updated.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324342</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 30 Mar 2024 13:03:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>Yay! Successfully updated my <a href="https://www.puppet.com/docs/puppet/8/server/about_server.html" title="About Puppet Server">Puppet Server</a> setup from 5.3.7 to 8.4.0 🎉</p>
<p>It was quite a step (5.3.7 was released in January 2019) and as expected 3 major version bumps came with a couple changes.</p>
<p>I opted to re-create the PuppetDB and CA stores from scratch (to avoid having to migrate 5 years of data schema changes, and the CA cert is now also valid for a couple more years again).</p>
<p>To make the old manifests and modules work with the new versions, quite some effort was needed. This included rewriting some no longer maintained modules to use newer stdlib and concat libraries, updating a couple modules from the puppet forge (with the bonus that my puppet server runs airgapped and I had to use the download-tar-copy-extract way to install them) and fixing no longer valid syntax here and there in my custom manifests. Overall I spent about 5 hours on it (and have now a recurring reminder to update puppet more often to make this process less painful).</p>
<p>Helpful as usual were the resources from <a href="https://voxpupuli.org/" title="Vox Pupuli">Vox Pupuli</a>, in particular the <a href="https://hub.docker.com/r/voxpupuli/container-puppetserver" title="Voxpupuli Puppet Server container">Puppet Server</a> and <a href="https://hub.docker.com/r/voxpupuli/container-puppetdb" title="Voxpupuli PuppetDB container">PuppetDB</a> Docker images and the <a href="https://github.com/voxpupuli/crafty/" title="voxpupuli/crafty: CRAFTY - Containerized Resources And Funky Tools (in) YAML">CRAFTY repo</a> which contains a fully self-contained Docker Compose setup very similar to what I'm running.</p>
<p>Some commands that came in handy:</p>
<p><code>puppet config print ssldir --section agent</code><br>
Returns the path of the TLS config folder on the client. Useful during a CA change (where you <code>rm -rf</code> the whole folder and then request a new TLS certificate).</p>
<p><code>puppet agent -t --noop</code><br>
Dry-run the changes on the client (it does request a new TLS cert though!). Shows a nice diff of the changes it would do to files, helpful to validate that a manifest still behaves the same in the new version.</p>
]]></description>
<content:encoded><![CDATA[<p>Yay! Successfully updated my <a href="https://www.puppet.com/docs/puppet/8/server/about_server.html" title="About Puppet Server">Puppet Server</a> setup from 5.3.7 to 8.4.0 🎉</p>
<p>It was quite a step (5.3.7 was released in January 2019) and as expected 3 major version bumps came with a couple changes.</p>
<p>I opted to re-create the PuppetDB and CA stores from scratch (to avoid having to migrate 5 years of data schema changes, and the CA cert is now also valid for a couple more years again).</p>
<p>To make the old manifests and modules work with the new versions, quite some effort was needed. This included rewriting some no longer maintained modules to use newer stdlib and concat libraries, updating a couple modules from the puppet forge (with the bonus that my puppet server runs airgapped and I had to use the download-tar-copy-extract way to install them) and fixing no longer valid syntax here and there in my custom manifests. Overall I spent about 5 hours on it (and have now a recurring reminder to update puppet more often to make this process less painful).</p>
<p>Helpful as usual were the resources from <a href="https://voxpupuli.org/" title="Vox Pupuli">Vox Pupuli</a>, in particular the <a href="https://hub.docker.com/r/voxpupuli/container-puppetserver" title="Voxpupuli Puppet Server container">Puppet Server</a> and <a href="https://hub.docker.com/r/voxpupuli/container-puppetdb" title="Voxpupuli PuppetDB container">PuppetDB</a> Docker images and the <a href="https://github.com/voxpupuli/crafty/" title="voxpupuli/crafty: CRAFTY - Containerized Resources And Funky Tools (in) YAML">CRAFTY repo</a> which contains a fully self-contained Docker Compose setup very similar to what I'm running.</p>
<p>Some commands that came in handy:</p>
<p><code>puppet config print ssldir --section agent</code><br>
Returns the path of the TLS config folder on the client. Useful during a CA change (where you <code>rm -rf</code> the whole folder and then request a new TLS certificate).</p>
<p><code>puppet agent -t --noop</code><br>
Dry-run the changes on the client (it does request a new TLS cert though!). Shows a nice diff of the changes it would do to files, helpful to validate that a manifest still behaves the same in the new version.</p>
]]></content:encoded>
</item>
<item>
<title>Linux Crisis Tools</title>
<link>https://blog.x-way.org/Linux/2024/03/25/Linux-Crisis-Tools.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324341</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 25 Mar 2024 21:45:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p><a href="https://www.brendangregg.com/" title="Brendan Gregg's Homepage">Brendan Gregg</a> posted the following <a href="https://www.brendangregg.com/blog/2024-03-24/linux-crisis-tools.html" title="Linux Crisis Tools">list of 'crisis tools'</a> which you should install on your Linux servers by default (so they are available when an incident happens).</p>
<table>
<tr><th>Package</th><th>Provides</th><th>Notes</th></tr>
<tr><td>procps</td><td>ps(1), vmstat(8), uptime(1), top(1)</td><td>basic stats</td></tr>
<tr><td>util-linux</td><td>dmesg(1), lsblk(1), lscpu(1)</td><td>system log, device info</td></tr>
<tr><td>sysstat</td><td>iostat(1), mpstat(1), pidstat(1), sar(1)</td><td>device stats</td></tr>
<tr><td>iproute2</td><td>ip(8), ss(8), nstat(8), tc(8)</td><td>preferred net tools</td></tr>
<tr><td>numactl</td><td>numastat(8)</td><td>NUMA stats</td></tr>
<tr><td>tcpdump</td><td>tcpdump(8)</td><td>Network sniffer</td></tr>
<tr><td>linux-tools-common<br>linux-tools-$(uname -r)</td><td>perf(1), turbostat(8)</td><td>profiler and PMU stats</td></tr>
<tr><td>bpfcc-tools (bcc)</td><td>opensnoop(8), execsnoop(8), runqlat(8), softirqs(8),<br>hardirqs(8), ext4slower(8), ext4dist(8), biotop(8),<br>biosnoop(8), biolatency(8), tcptop(8), tcplife(8),<br>trace(8), argdist(8), funccount(8), profile(8), etc.</td><td>canned eBPF tools[1]</td></tr>
<tr><td>bpftrace</td><td>bpftrace, basic versions of opensnoop(8),<br>execsnoop(8), runqlat(8), biosnoop(8), etc.</td><td>eBPF scripting[1]</td></tr>
<tr><td>trace-cmd</td><td>trace-cmd(1)</td><td>Ftrace CLI</td></tr>
<tr><td>nicstat</td><td>nicstat(1)</td><td>net device stats</td></tr>
<tr><td>ethtool</td><td>ethtool(8)</td><td>net device info</td></tr>
<tr><td>tiptop</td><td>tiptop(1)</td><td>PMU/PMC top</td></tr>
<tr><td>cpuid</td><td>cpuid(1)</td><td>CPU details</td></tr>
<tr><td>msr-tools</td><td>rdmsr(8), wrmsr(8)</td><td>CPU digging</td></tr>
</table>
]]></description>
<content:encoded><![CDATA[<p><a href="https://www.brendangregg.com/" title="Brendan Gregg's Homepage">Brendan Gregg</a> posted the following <a href="https://www.brendangregg.com/blog/2024-03-24/linux-crisis-tools.html" title="Linux Crisis Tools">list of 'crisis tools'</a> which you should install on your Linux servers by default (so they are available when an incident happens).</p>
<table>
<tr><th>Package</th><th>Provides</th><th>Notes</th></tr>
<tr><td>procps</td><td>ps(1), vmstat(8), uptime(1), top(1)</td><td>basic stats</td></tr>
<tr><td>util-linux</td><td>dmesg(1), lsblk(1), lscpu(1)</td><td>system log, device info</td></tr>
<tr><td>sysstat</td><td>iostat(1), mpstat(1), pidstat(1), sar(1)</td><td>device stats</td></tr>
<tr><td>iproute2</td><td>ip(8), ss(8), nstat(8), tc(8)</td><td>preferred net tools</td></tr>
<tr><td>numactl</td><td>numastat(8)</td><td>NUMA stats</td></tr>
<tr><td>tcpdump</td><td>tcpdump(8)</td><td>Network sniffer</td></tr>
<tr><td>linux-tools-common<br>linux-tools-$(uname -r)</td><td>perf(1), turbostat(8)</td><td>profiler and PMU stats</td></tr>
<tr><td>bpfcc-tools (bcc)</td><td>opensnoop(8), execsnoop(8), runqlat(8), softirqs(8),<br>hardirqs(8), ext4slower(8), ext4dist(8), biotop(8),<br>biosnoop(8), biolatency(8), tcptop(8), tcplife(8),<br>trace(8), argdist(8), funccount(8), profile(8), etc.</td><td>canned eBPF tools[1]</td></tr>
<tr><td>bpftrace</td><td>bpftrace, basic versions of opensnoop(8),<br>execsnoop(8), runqlat(8), biosnoop(8), etc.</td><td>eBPF scripting[1]</td></tr>
<tr><td>trace-cmd</td><td>trace-cmd(1)</td><td>Ftrace CLI</td></tr>
<tr><td>nicstat</td><td>nicstat(1)</td><td>net device stats</td></tr>
<tr><td>ethtool</td><td>ethtool(8)</td><td>net device info</td></tr>
<tr><td>tiptop</td><td>tiptop(1)</td><td>PMU/PMC top</td></tr>
<tr><td>cpuid</td><td>cpuid(1)</td><td>CPU details</td></tr>
<tr><td>msr-tools</td><td>rdmsr(8), wrmsr(8)</td><td>CPU digging</td></tr>
</table>
]]></content:encoded>
</item>
<item>
<title>Installing the AREDN firmware on a MikroTik hAP ac lite</title>
<link>https://blog.x-way.org/Radio/2024/03/24/Installing-the-AREDN-firmware-on-a-MikroTik-hAP-ac-lite.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324340</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 24 Mar 2024 14:26:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Radio/">Radio</category>
<description><![CDATA[<p>At the recent <a href="http://hb9tf.ch" title="Tango Foxtrott Wireless Society HB9TF">HB9TF</a> AGM fellow radio amateur <a href="https://medium.com/@hb9gvm" title="Martin Suess (HB9GVM)">HB9GVM</a> gave an introductory presentation about <a href="https://www.arednmesh.org/" title="Amateur Radio Emergency Data Network">AREDN</a>.</p>
<p>Motivated by this, I ordered a <a href="https://mikrotik.com/product/RB952Ui-5ac2nD" title="MikroTik hAP ac lite">MikroTik hAP ac lite</a> and installed the AREDN firmware on it.<br>The following are my notes of the installation process.</p>
<ol>
<li>Download the firmware images for the MikroTik hAP ac lite from <a href="http://downloads.arednmesh.org/afs/www/" title="AREDN Firmware Selector">http://downloads.arednmesh.org/afs/www/</a> (both the *kernel.bin and *sysupgrade.bin are needed)</li>
<li>Install <a href="https://thekelleys.org.uk/dnsmasq/doc.html" title="Dnsmasq - network services for small networks">Dnsmasq</a> as a PXE server on Mac OS: <pre>brew install dnsmasq</pre></li>
<li>Setup the *kernel.bin for PXE: <pre>mkdir tftp-root
cp $HOME/Downloads/aredn-3.23.12.0-ath79-mikrotik-mikrotik_routerboard-952ui-5ac2nd-initramfs-kernel.bin tftp-root/rb.elf</pre></li>
<li>Connect a Ethernet dongle and configure it with this static IP: 192.168.1.10/24</li>
<li>Run dnsmasq as a PXE server listening on the network interface of the Ethernet dongle: <pre>ifconfig en6 # use to check that IP is configured
sudo dnsmasq -i en6 -u $(whoami) --log-dhcp --bootp-dynamic --dhcp-range=192.168.1.100,192.168.1.200 -d -p0 -K --dhcp-boot=rb.elf --enable-tftp --tftp-root=$(pwd)/tftp-root/</pre></li>
<li>Power off the hAP ac lite and connect the Ethernet dongle to port 1 (<strong>PXE booting only seems to work on this port!</strong>)</li>
<li>Press the reset button on the hAP ac lite, power it on and keep the button pressed for about 20 seconds (there is some output of dnsmask once the PXE booting is in progress)</li>
<li>Wait until the hAP ac lite stops blinking and the LEDs are steady again (it also issues a new DHCP request via port1, but this time no PXE booting).</li>
<li>Move the cable to port 2 (the AREDN default config for the MikroTik hAP ac lite uses port 1 for the Internet uplink, and port 2 for the 'inside' local network).</li>
<li>Test that you can ping the inside IP of the AREDN node: <pre>ping 192.168.1.1</pre></li>
<li>Open the admin page on <code>http://192.168.1.1/cgi-bin/admin</code> (Username is <code>root</code> and password is <code>hsmm</code>).</li>
<li>In the Firmware Update section, click on 'Upload Firmware' and select the previously downloaded sysupgrade.bin file.</li>
<li>Wait until a reboot has happened twice (it takes a couple minutes!) to complete the installation.</li>
<li>Open <code>http://192.168.1.1</code> – congratulations, you now have a freshly installed (and not yet configured) AREDN node :-)</li>
</ol>
]]></description>
<content:encoded><![CDATA[<p>At the recent <a href="http://hb9tf.ch" title="Tango Foxtrott Wireless Society HB9TF">HB9TF</a> AGM fellow radio amateur <a href="https://medium.com/@hb9gvm" title="Martin Suess (HB9GVM)">HB9GVM</a> gave an introductory presentation about <a href="https://www.arednmesh.org/" title="Amateur Radio Emergency Data Network">AREDN</a>.</p>
<p>Motivated by this, I ordered a <a href="https://mikrotik.com/product/RB952Ui-5ac2nD" title="MikroTik hAP ac lite">MikroTik hAP ac lite</a> and installed the AREDN firmware on it.<br>The following are my notes of the installation process.</p>
<ol>
<li>Download the firmware images for the MikroTik hAP ac lite from <a href="http://downloads.arednmesh.org/afs/www/" title="AREDN Firmware Selector">http://downloads.arednmesh.org/afs/www/</a> (both the *kernel.bin and *sysupgrade.bin are needed)</li>
<li>Install <a href="https://thekelleys.org.uk/dnsmasq/doc.html" title="Dnsmasq - network services for small networks">Dnsmasq</a> as a PXE server on Mac OS: <pre>brew install dnsmasq</pre></li>
<li>Setup the *kernel.bin for PXE: <pre>mkdir tftp-root
cp $HOME/Downloads/aredn-3.23.12.0-ath79-mikrotik-mikrotik_routerboard-952ui-5ac2nd-initramfs-kernel.bin tftp-root/rb.elf</pre></li>
<li>Connect a Ethernet dongle and configure it with this static IP: 192.168.1.10/24</li>
<li>Run dnsmasq as a PXE server listening on the network interface of the Ethernet dongle: <pre>ifconfig en6 # use to check that IP is configured
sudo dnsmasq -i en6 -u $(whoami) --log-dhcp --bootp-dynamic --dhcp-range=192.168.1.100,192.168.1.200 -d -p0 -K --dhcp-boot=rb.elf --enable-tftp --tftp-root=$(pwd)/tftp-root/</pre></li>
<li>Power off the hAP ac lite and connect the Ethernet dongle to port 1 (<strong>PXE booting only seems to work on this port!</strong>)</li>
<li>Press the reset button on the hAP ac lite, power it on and keep the button pressed for about 20 seconds (there is some output of dnsmask once the PXE booting is in progress)</li>
<li>Wait until the hAP ac lite stops blinking and the LEDs are steady again (it also issues a new DHCP request via port1, but this time no PXE booting).</li>
<li>Move the cable to port 2 (the AREDN default config for the MikroTik hAP ac lite uses port 1 for the Internet uplink, and port 2 for the 'inside' local network).</li>
<li>Test that you can ping the inside IP of the AREDN node: <pre>ping 192.168.1.1</pre></li>
<li>Open the admin page on <code>http://192.168.1.1/cgi-bin/admin</code> (Username is <code>root</code> and password is <code>hsmm</code>).</li>
<li>In the Firmware Update section, click on 'Upload Firmware' and select the previously downloaded sysupgrade.bin file.</li>
<li>Wait until a reboot has happened twice (it takes a couple minutes!) to complete the installation.</li>
<li>Open <code>http://192.168.1.1</code> – congratulations, you now have a freshly installed (and not yet configured) AREDN node :-)</li>
</ol>
]]></content:encoded>
</item>
<item>
<title>Fifty Things you can do with a Software Defined Radio 📻</title>
<link>https://blog.x-way.org/Radio/2024/03/17/Fifty-Things-you-can-do-with-a-Software-Defined-Radio.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324339</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 17 Mar 2024 09:50:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Radio/">Radio</category>
<description><![CDATA[<p><a href="https://blinry.org/50-things-with-sdr/" title="Fifty Things you can do with a Software Defined Radio">Fifty Things you can do with a Software Defined Radio 📻</a> — some cool SDR things to do (have done already some of them and more with my <a href="http://hb9tf.ch" title="Tango Foxtrott Wireless Society HB9TF">HB9TF</a> friends :-)</p>
<p>(<a href="https://news.ycombinator.com/item?id=39728153" title="Fifty Things you can do with a Software Defined Radio | Hacker News">via</a>)</p>
<p>Also using this post to introduce a new category: <b><a href="https://blog.x-way.org/Radio/" title="x-log - Radio">Radio</a></b><br>
Which will serve as a container for radio/HAM/Wireless related content.</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://blinry.org/50-things-with-sdr/" title="Fifty Things you can do with a Software Defined Radio">Fifty Things you can do with a Software Defined Radio 📻</a> — some cool SDR things to do (have done already some of them and more with my <a href="http://hb9tf.ch" title="Tango Foxtrott Wireless Society HB9TF">HB9TF</a> friends :-)</p>
<p>(<a href="https://news.ycombinator.com/item?id=39728153" title="Fifty Things you can do with a Software Defined Radio | Hacker News">via</a>)</p>
<p>Also using this post to introduce a new category: <b><a href="https://blog.x-way.org/Radio/" title="x-log - Radio">Radio</a></b><br>
Which will serve as a container for radio/HAM/Wireless related content.</p>
]]></content:encoded>
</item>
<item>
<title>100 things you can do on your personal website</title>
<link>https://blog.x-way.org/Misc/2024/03/07/100-things-you-can-do-on-your-personal-website.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324338</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 07 Mar 2024 23:56:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://jamesg.blog/2024/02/19/personal-website-ideas/" title="100 things you can do on your personal website | James' Coffee Blog">100 things you can do on your personal website</a> — lots of ideas/inspirations also for this blog :-)</p>
<p>(<a href="https://gigold.me/blog/100-dinge" title="">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://jamesg.blog/2024/02/19/personal-website-ideas/" title="100 things you can do on your personal website | James' Coffee Blog">100 things you can do on your personal website</a> — lots of ideas/inspirations also for this blog :-)</p>
<p>(<a href="https://gigold.me/blog/100-dinge" title="">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Tunnelbroker to the rescue</title>
<link>https://blog.x-way.org/Networking/2024/02/25/Tunnelbroker-to-the-rescue.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324337</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 25 Feb 2024 15:25:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>After nicely delivering <a href="https://blog.x-way.org/Networking/2021/02/04/Embracing-the-future-with-SolNet.html" title="x-log - Embracing the future with Solnet">native IPv6 connectivity for 3 years</a>, my Internet provider Solnet made some changes in their backbone config on January 31st which broke their IPv6 setup.<br>Unfortunately escalating with their support did not bear any fruits so far (current state: they no longer respond on the support ticket…).</p>
<p>Thus change of plans, <a href="https://tunnelbroker.net/" title="Hurricane Electric Free IPv6 Tunnel Broker">tunnelbroker.net</a> (Hurricane Electric) to the rescue.<br>Took about 10 minutes to set everything up and now I'm enjoying IPv6 connectivity again (although with a reduced end-to-end MTU due to the <a href="https://en.wikipedia.org/wiki/6in4" title="6in4 - Wikipedia">6in4</a> encapsulation).</p>
<p>Guess I'll have to look for a different Internet provider again.<br>Especially annoying is that I renewed the yearly plan with Solnet only a couple weeks ago, so will be stuck without native IPv6 connectivity for the next 11 months :-(</p>
]]></description>
<content:encoded><![CDATA[<p>After nicely delivering <a href="https://blog.x-way.org/Networking/2021/02/04/Embracing-the-future-with-SolNet.html" title="x-log - Embracing the future with Solnet">native IPv6 connectivity for 3 years</a>, my Internet provider Solnet made some changes in their backbone config on January 31st which broke their IPv6 setup.<br>Unfortunately escalating with their support did not bear any fruits so far (current state: they no longer respond on the support ticket…).</p>
<p>Thus change of plans, <a href="https://tunnelbroker.net/" title="Hurricane Electric Free IPv6 Tunnel Broker">tunnelbroker.net</a> (Hurricane Electric) to the rescue.<br>Took about 10 minutes to set everything up and now I'm enjoying IPv6 connectivity again (although with a reduced end-to-end MTU due to the <a href="https://en.wikipedia.org/wiki/6in4" title="6in4 - Wikipedia">6in4</a> encapsulation).</p>
<p>Guess I'll have to look for a different Internet provider again.<br>Especially annoying is that I renewed the yearly plan with Solnet only a couple weeks ago, so will be stuck without native IPv6 connectivity for the next 11 months :-(</p>
]]></content:encoded>
</item>
<item>
<title>The High-Risk Refactoring</title>
<link>https://blog.x-way.org/Coding/2024/02/25/The-High-Risk-Refactoring.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324336</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 25 Feb 2024 04:02:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>In the <a href="https://webup.org/blog/the-high-risk-refactoring/" title="The High-Risk Refactoring - Miroslav Nikolov">The High-Risk Refactoring</a> article there is this concise <em>Addressing Risk</em> checklist to keep in mind when refactoring.<br>During past refactorings (also low-risk ones) I often used almost the same guidelines to help me and can only recommend you to do the same:</p>
<blockquote cite="https://webup.org/blog/the-high-risk-refactoring/">
<p>✅ Define constraints. <em>How far should I go</em>. <br>
✅ Isolate improvements from features. <em>Do not apply them simultaneously</em>. <br>
✅ Write extensive tests. <em>Higher level (integration) with fewer implementation details. They should run alongside changes</em>. <br>
✅ Have a visual confirmation. <em>Open the browser</em>.</p>
<p>❌ Do not skip tests. <em>Don't be lazy</em>.<br>
❌ Do not rely too much on code reviews and QA. <em>Humans make mistakes</em>.<br>
❌ Do not mix expensive cleanups with other changes. <em>But do that for small improvements</em>.</p>
</blockquote>
<p>(<a href="https://labnotes.org/weekend-reading-places-where-ive-lost-my-glasses/" title="Weekend Reading - Places where I've lost my glasses - Labnotes (by Assaf Arkin)">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p>In the <a href="https://webup.org/blog/the-high-risk-refactoring/" title="The High-Risk Refactoring - Miroslav Nikolov">The High-Risk Refactoring</a> article there is this concise <em>Addressing Risk</em> checklist to keep in mind when refactoring.<br>During past refactorings (also low-risk ones) I often used almost the same guidelines to help me and can only recommend you to do the same:</p>
<blockquote cite="https://webup.org/blog/the-high-risk-refactoring/">
<p>✅ Define constraints. <em>How far should I go</em>. <br>
✅ Isolate improvements from features. <em>Do not apply them simultaneously</em>. <br>
✅ Write extensive tests. <em>Higher level (integration) with fewer implementation details. They should run alongside changes</em>. <br>
✅ Have a visual confirmation. <em>Open the browser</em>.</p>
<p>❌ Do not skip tests. <em>Don't be lazy</em>.<br>
❌ Do not rely too much on code reviews and QA. <em>Humans make mistakes</em>.<br>
❌ Do not mix expensive cleanups with other changes. <em>But do that for small improvements</em>.</p>
</blockquote>
<p>(<a href="https://labnotes.org/weekend-reading-places-where-ive-lost-my-glasses/" title="Weekend Reading - Places where I've lost my glasses - Labnotes (by Assaf Arkin)">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Please Blog</title>
<link>https://blog.x-way.org/Misc/2024/02/25/Please-Blog.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324335</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 25 Feb 2024 03:17:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://ultreia.me/blog/please-blog/" title="ultreia.me - PLEASE Blog">Please Blog</a> — <em>a plea for less Big Web and more Small Web</em> and an encouraging article to write your own blog. It also touches on the part about writing on your own domain (so to keep your content yours and not be at risk of a third-party commercial 'social' service going away).</p>
<blockquote cite="https://ultreia.me/blog/please-blog/"><p>Don’t wait for the Pulitzer piece. Tell me about your ride to work, about your food, what flavor ice cream you like. Let me be part of happiness and sadness. Show me, that there is a human being out there that, agree or not, I can relate to. Because without it, we are just actors in a sea of actors, marketing, proselytizing, advocating, and threatening towards each other in an always vicious circle of striving for a relevance that only buys us more marketing, more proselytizing, more advocating, and more threats.</p></blockquote>
<p>(discovered via <a href="https://gigold.me/blog/links-links-links" title="Links, Links, Links | Thomas Gigold - Blog">Thomas Gigold</a>)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://ultreia.me/blog/please-blog/" title="ultreia.me - PLEASE Blog">Please Blog</a> — <em>a plea for less Big Web and more Small Web</em> and an encouraging article to write your own blog. It also touches on the part about writing on your own domain (so to keep your content yours and not be at risk of a third-party commercial 'social' service going away).</p>
<blockquote cite="https://ultreia.me/blog/please-blog/"><p>Don’t wait for the Pulitzer piece. Tell me about your ride to work, about your food, what flavor ice cream you like. Let me be part of happiness and sadness. Show me, that there is a human being out there that, agree or not, I can relate to. Because without it, we are just actors in a sea of actors, marketing, proselytizing, advocating, and threatening towards each other in an always vicious circle of striving for a relevance that only buys us more marketing, more proselytizing, more advocating, and more threats.</p></blockquote>
<p>(discovered via <a href="https://gigold.me/blog/links-links-links" title="Links, Links, Links | Thomas Gigold - Blog">Thomas Gigold</a>)</p>
]]></content:encoded>
</item>
<item>
<title>ads.txt</title>
<link>https://blog.x-way.org/Webdesign/2024/02/18/ads-txt.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324334</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 18 Feb 2024 17:38:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Added and <a href="https://iabtechlab.com/ads.txt/" title="IAB Tech Lab - Ads.txt - Authorized Digital Sellers">ads.txt</a> file to the blog. The idea is to avoid that someone can sell fake advertisment space for this blog.</p>
<p>As I don't use any advertisment here the content of the file is pretty basic:</p>
<pre>contact=https://blog.x-way.org/about.html</pre>
]]></description>
<content:encoded><![CDATA[<p>Added and <a href="https://iabtechlab.com/ads.txt/" title="IAB Tech Lab - Ads.txt - Authorized Digital Sellers">ads.txt</a> file to the blog. The idea is to avoid that someone can sell fake advertisment space for this blog.</p>
<p>As I don't use any advertisment here the content of the file is pretty basic:</p>
<pre>contact=https://blog.x-way.org/about.html</pre>
]]></content:encoded>
</item>
<item>
<title>ldapauth</title>
<link>https://blog.x-way.org/Linux/2024/02/18/ldapauth.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324333</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 18 Feb 2024 15:37:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p><a href="https://github.com/x-way/ldapauth" title="x-way/ldapauth">ldapauth</a> is a <a href="https://nodejs.org" title="Node.js">Node.js</a> script which I have been using for the last 12+ years mostly unchanged.</p>
<p>It started its life in a <a href="https://en.wikipedia.org/wiki/LXC" title="Linux Containers (LXC)">LXC</a> container, eventually was moved to a Docker container and recently ended up in its own repository on GitHub.</p>
<p>The functionality it provides is not extraordinary, but helped to bridge a gap where no other product was available.<br>
It talks <a href="https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol" title="Lightweight Directory Access Protocol - Wikipedia">LDAP</a> one one side (although limited to handle user lookup requests) and on the other side connects to a <a href="https://www.mongodb.com/" title="MongoDB - Document Oriented Database">MongoDB</a> database where the information is stored.</p>
<p>It emerged out of the desire to have an easy way to manage individual user accounts for my home WiFi. I already had MongoDB running for some other personal project and simply added the list of users there (including the UI for managing them).<br>
Thus the missing part was to get the WiFi accesspoint to lookup user accounts in MongoDB.</p>
<p>Of course WiFi accesspoints do not directly talk MongoDB, but rather some other protocol like <a href="https://en.wikipedia.org/wiki/RADIUS" title="Remote Authentication Dial-In User Service">RADIUS</a>.<br>
A <a href="https://freeradius.org/" title="FreeRADIUS">freeradius</a> server was quickly setup, but still couldn't talk to MongoDB at the time. Thus comes in <a href="https://github.com/x-way/ldapauth" title="x-way/ldapauth">ldapauth</a>, which takes LDAP queries from freeradius and turns them into MongoDB lookups so that in the end the WiFi accesspoint receives the user accounts :-)</p>
<p>Not sure if this is particularly useful for anyone else, but at least here it did provide good services (and continues to do so).<br>
Current score is that it has survived three different WiFi accesspoints and has been running on 5 different servers over the time.</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://github.com/x-way/ldapauth" title="x-way/ldapauth">ldapauth</a> is a <a href="https://nodejs.org" title="Node.js">Node.js</a> script which I have been using for the last 12+ years mostly unchanged.</p>
<p>It started its life in a <a href="https://en.wikipedia.org/wiki/LXC" title="Linux Containers (LXC)">LXC</a> container, eventually was moved to a Docker container and recently ended up in its own repository on GitHub.</p>
<p>The functionality it provides is not extraordinary, but helped to bridge a gap where no other product was available.<br>
It talks <a href="https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol" title="Lightweight Directory Access Protocol - Wikipedia">LDAP</a> one one side (although limited to handle user lookup requests) and on the other side connects to a <a href="https://www.mongodb.com/" title="MongoDB - Document Oriented Database">MongoDB</a> database where the information is stored.</p>
<p>It emerged out of the desire to have an easy way to manage individual user accounts for my home WiFi. I already had MongoDB running for some other personal project and simply added the list of users there (including the UI for managing them).<br>
Thus the missing part was to get the WiFi accesspoint to lookup user accounts in MongoDB.</p>
<p>Of course WiFi accesspoints do not directly talk MongoDB, but rather some other protocol like <a href="https://en.wikipedia.org/wiki/RADIUS" title="Remote Authentication Dial-In User Service">RADIUS</a>.<br>
A <a href="https://freeradius.org/" title="FreeRADIUS">freeradius</a> server was quickly setup, but still couldn't talk to MongoDB at the time. Thus comes in <a href="https://github.com/x-way/ldapauth" title="x-way/ldapauth">ldapauth</a>, which takes LDAP queries from freeradius and turns them into MongoDB lookups so that in the end the WiFi accesspoint receives the user accounts :-)</p>
<p>Not sure if this is particularly useful for anyone else, but at least here it did provide good services (and continues to do so).<br>
Current score is that it has survived three different WiFi accesspoints and has been running on 5 different servers over the time.</p>
]]></content:encoded>
</item>
<item>
<title>Hilltop Hoods - Laced Up</title>
<link>https://blog.x-way.org/Music/2024/02/18/Hilltop-Hoods-Laced-Up.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324332</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 18 Feb 2024 08:31:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p><a href="https://youtu.be/Nn-kfXCQt6A" title="Hilltop Hoods - Laced Up - YouTube">Hilltop Hoods - Laced Up</a></p>
<p>Some vibes from Australia ❤</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://youtu.be/Nn-kfXCQt6A" title="Hilltop Hoods - Laced Up - YouTube">Hilltop Hoods - Laced Up</a></p>
<p>Some vibes from Australia ❤</p>
]]></content:encoded>
</item>
<item>
<title>qr-bag</title>
<link>https://blog.x-way.org/Coding/2024/02/03/qr-bag.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324331</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 03 Feb 2024 19:55:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>Some time ago I used an online tool to generate some QR codes with a contact URL so I can put them on my luggage.<br>Now I got a new bag and need a new QR code for it. As I don't remember the online tool I used years ago, I decided to write my own tool.</p>
<p>Thus say hello to <a href="https://github.com/x-way/qr-bag" title="x-way/qr-bag: Generate a QR code with a lost bag logo in the middle pointing to a URL with information about the owner ">qr-bag</a>. It's a commandline tool written in Go to generate QR codes for URLs with a little logo in the middle.<br>The code for it is mostly a wrapper around the <a href="https://github.com/yeqown/go-qrcode" title="yeqown/go-qrcode">go-qrcode</a> library which does all the heavy lifting.</p>
<img src="https://blog.x-way.org/images/qr-bag123.png" width="173" height="173" alt="Example QR code">
]]></description>
<content:encoded><![CDATA[<p>Some time ago I used an online tool to generate some QR codes with a contact URL so I can put them on my luggage.<br>Now I got a new bag and need a new QR code for it. As I don't remember the online tool I used years ago, I decided to write my own tool.</p>
<p>Thus say hello to <a href="https://github.com/x-way/qr-bag" title="x-way/qr-bag: Generate a QR code with a lost bag logo in the middle pointing to a URL with information about the owner ">qr-bag</a>. It's a commandline tool written in Go to generate QR codes for URLs with a little logo in the middle.<br>The code for it is mostly a wrapper around the <a href="https://github.com/yeqown/go-qrcode" title="yeqown/go-qrcode">go-qrcode</a> library which does all the heavy lifting.</p>
<img src="https://blog.x-way.org/images/qr-bag123.png" width="173" height="173" alt="Example QR code">
]]></content:encoded>
</item>
<item>
<title>text-decoration-color</title>
<link>https://blog.x-way.org/Webdesign/2024/02/03/text-decoration-color.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324330</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 03 Feb 2024 16:27:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Just discovered the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration-color" title="text-decoration-color - CSS: Cascading Style Sheets | MDN"><code>text-decoration-color</code></a> CSS property and added it to the style on the blog:</p>
<pre>a:hover {color: #454545; text-decoration: underline; text-decoration-color: #26C4FF;}</pre>
<p>This causes that when you hover over a link in a post, the underline is not in the same boring gray as the text but lights up in a nice color :-)</p>
<p>(not to be confused with the hacky colored underlines in the righthand navigation bar, where I use a colored <code>border-bottom</code> to achieve a similar effect since 2002)</p>
]]></description>
<content:encoded><![CDATA[<p>Just discovered the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-decoration-color" title="text-decoration-color - CSS: Cascading Style Sheets | MDN"><code>text-decoration-color</code></a> CSS property and added it to the style on the blog:</p>
<pre>a:hover {color: #454545; text-decoration: underline; text-decoration-color: #26C4FF;}</pre>
<p>This causes that when you hover over a link in a post, the underline is not in the same boring gray as the text but lights up in a nice color :-)</p>
<p>(not to be confused with the hacky colored underlines in the righthand navigation bar, where I use a colored <code>border-bottom</code> to achieve a similar effect since 2002)</p>
]]></content:encoded>
</item>
<item>
<title>Blogroll cleanup 2024</title>
<link>https://blog.x-way.org/Misc/2024/01/31/Blogroll-cleanup-2024.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324329</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 31 Jan 2024 22:50:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>It's time again to do some cleanup of my blogroll before the links start to turn into 404 errors :-)</p>
<p>Removed:</p>
<ul>
<li><a href="https://web.archive.org/web/20200301211123/http://strcat.de/blog/" title="Veni, Vidi, VISA">Veni, Vidi, VISA</a></li>
<li><a href="https://web.archive.org/web/20230724205656/https://gru.gq/" title="grugq's domain - Cyber is Deception">gru.gq</a></li>
<li><a href="https://web.archive.org/web/20240119172554/http://www.brewdog.com/blog" title="BrewDog Craft Beer Blog">BrewDog</a></li>
<li><a href="https://mdlayher.com/blog/" title="Matt Layher">mdlayher.com</a></li>
<li><a href="https://blog.inliniac.net/" title="Inliniac | Everything inline.">Inliniac</a></li>
<li><a href="https://home.regit.org/" title="To Linux and beyond!">To Linux and beyond!</a></li>
<li><a href="http://lonesysadmin.net/" title="The Lone Sysadmin">The Lone Sysadmin</a></li>
<li><a href="https://eklitzke.org/" title="Evan Klitzke">eklitzke.org</a></li>
</ul>
]]></description>
<content:encoded><![CDATA[<p>It's time again to do some cleanup of my blogroll before the links start to turn into 404 errors :-)</p>
<p>Removed:</p>
<ul>
<li><a href="https://web.archive.org/web/20200301211123/http://strcat.de/blog/" title="Veni, Vidi, VISA">Veni, Vidi, VISA</a></li>
<li><a href="https://web.archive.org/web/20230724205656/https://gru.gq/" title="grugq's domain - Cyber is Deception">gru.gq</a></li>
<li><a href="https://web.archive.org/web/20240119172554/http://www.brewdog.com/blog" title="BrewDog Craft Beer Blog">BrewDog</a></li>
<li><a href="https://mdlayher.com/blog/" title="Matt Layher">mdlayher.com</a></li>
<li><a href="https://blog.inliniac.net/" title="Inliniac | Everything inline.">Inliniac</a></li>
<li><a href="https://home.regit.org/" title="To Linux and beyond!">To Linux and beyond!</a></li>
<li><a href="http://lonesysadmin.net/" title="The Lone Sysadmin">The Lone Sysadmin</a></li>
<li><a href="https://eklitzke.org/" title="Evan Klitzke">eklitzke.org</a></li>
</ul>
]]></content:encoded>
</item>
<item>
<title>Statistics revived</title>
<link>https://blog.x-way.org/Misc/2024/01/30/Statistics-revived.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324328</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 30 Jan 2024 06:46:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>Following in the trend of replacing tables, I've revived the old <a href="https://blog.x-way.org/statistics.html" title="x-log - Statistics">statistics page</a>.<br>Now using less markup as it is built with <code><div></code> and CSS only (the <code>display: inline-block;</code> property was particularly helpful).</p>
<p>(the Jekyll/Liquid templating to generate the data for it looks quite horrific though…)</p>
]]></description>
<content:encoded><![CDATA[<p>Following in the trend of replacing tables, I've revived the old <a href="https://blog.x-way.org/statistics.html" title="x-log - Statistics">statistics page</a>.<br>Now using less markup as it is built with <code><div></code> and CSS only (the <code>display: inline-block;</code> property was particularly helpful).</p>
<p>(the Jekyll/Liquid templating to generate the data for it looks quite horrific though…)</p>
]]></content:encoded>
</item>
<item>
<title>Tables are gone</title>
<link>https://blog.x-way.org/Webdesign/2024/01/28/Tables-are-gone.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324327</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 28 Jan 2024 16:47:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Over the last couple weeks I slowly replaced the various <table>-based layout elements of the blog with more modern HTML elements.<br>
And finally this afternoon the work was completed with the last <table> element gone.</p>
<p>Visually there should be almost no differences, but in case something looks strange just let <a href="https://blog.x-way.org/about.html" title="x-log - About">me</a> know :-)<br>
(and yes, style-wise everything is still using the pixel-based layout from 2002, one day this might change as well…)</p>
]]></description>
<content:encoded><![CDATA[<p>Over the last couple weeks I slowly replaced the various <table>-based layout elements of the blog with more modern HTML elements.<br>
And finally this afternoon the work was completed with the last <table> element gone.</p>
<p>Visually there should be almost no differences, but in case something looks strange just let <a href="https://blog.x-way.org/about.html" title="x-log - About">me</a> know :-)<br>
(and yes, style-wise everything is still using the pixel-based layout from 2002, one day this might change as well…)</p>
]]></content:encoded>
</item>
<item>
<title>Quick and dirty dark mode</title>
<link>https://blog.x-way.org/Webdesign/2024/01/27/Quick-and-dirty-dark-mode.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324326</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 27 Jan 2024 15:59:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>To provide basic dark mode support for the blog, I added the following lines of CSS:</p>
<pre>
@media (prefers-color-scheme: dark) {
html { filter: invert(1) hue-rotate(180deg); }
img, video, iframe { filter: invert(1) hue-rotate(180deg); }
}
</pre>
<p>If the browser/OS has dark mode enabled it will invert the colors and rotate the hue to achieve the dark mode effect.<br>The whole operation is applied a second time on images, videos and frames to avoid that they have their colors distorted.</p>
<p>You can get a preview by using the developer tools of your browser to enable dark mode :-)</p>
<p>The code is inspired by the post <a href="https://dev.to/akhilarjun/one-line-dark-mode-using-css-24li" title="One line - Dark Mode using CSS - DEV Community">here</a>, and then extended to provide a CSS-only solution by leveraging the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme" title="color-scheme - CSS: Cascading Style Sheets | MDN">color-scheme CSS property</a>.</p>
]]></description>
<content:encoded><![CDATA[<p>To provide basic dark mode support for the blog, I added the following lines of CSS:</p>
<pre>
@media (prefers-color-scheme: dark) {
html { filter: invert(1) hue-rotate(180deg); }
img, video, iframe { filter: invert(1) hue-rotate(180deg); }
}
</pre>
<p>If the browser/OS has dark mode enabled it will invert the colors and rotate the hue to achieve the dark mode effect.<br>The whole operation is applied a second time on images, videos and frames to avoid that they have their colors distorted.</p>
<p>You can get a preview by using the developer tools of your browser to enable dark mode :-)</p>
<p>The code is inspired by the post <a href="https://dev.to/akhilarjun/one-line-dark-mode-using-css-24li" title="One line - Dark Mode using CSS - DEV Community">here</a>, and then extended to provide a CSS-only solution by leveraging the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme" title="color-scheme - CSS: Cascading Style Sheets | MDN">color-scheme CSS property</a>.</p>
]]></content:encoded>
</item>
<item>
<title>Sub Focus, Dimension, Culture Shock & 1991</title>
<link>https://blog.x-way.org/Music/2024/01/21/Sub-Focus-Dimension-Culture-Shock-1991.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324325</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 21 Jan 2024 22:16:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p><a href="https://youtu.be/OZMWKqbcwzo" title="Sub Focus, Dimension, Culture Shock & 1991 - YouTube">Sub Focus, Dimension, Culture Shock & 1991</a></p>
<p>Some very fine Drum and bass. Recently got to experience two of them live (Sub Focus & 1991), and have plans to see Dimension next :-)</p>
<p>Especially like the little <a href="https://theprodigy.com" title="The Prodigy">The Prodigy</a> mixin starting at 1:04:30 🥳</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://youtu.be/OZMWKqbcwzo" title="Sub Focus, Dimension, Culture Shock & 1991 - YouTube">Sub Focus, Dimension, Culture Shock & 1991</a></p>
<p>Some very fine Drum and bass. Recently got to experience two of them live (Sub Focus & 1991), and have plans to see Dimension next :-)</p>
<p>Especially like the little <a href="https://theprodigy.com" title="The Prodigy">The Prodigy</a> mixin starting at 1:04:30 🥳</p>
]]></content:encoded>
</item>
<item>
<title>Keeping old URLs alive</title>
<link>https://blog.x-way.org/Misc/2024/01/21/Keeping-old-URLs-alive.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324324</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 21 Jan 2024 21:41:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>As mentioned before, I'm a supporter of the <a href="https://www.w3.org/Provider/Style/URI" title="Hypertext Style: Cool URIs don't change">Cool URIs don't change</a> approach.<br>Thus I try to keep all the URLs of this blog working (or at least make them redirect to the new place where the content is located).<br>Not always an easy task with old domains and multiple blogging engines accumulated over the years.</p>
<p>To help me with that (and ensure I don't break anything when updating a 10+ year old mod_rewrite config) I created a short Bash script to test the redirect behavior.<br>It contains a list of URLs and their expected redirect target, goes through them with <a href="https://curl.se" title="curl">curl</a> and checks that the correct <code>Location:</code> header is returned.</p>
<p>As it might be useful for others in similar situations, the script can be found <a href="https://blog.x-way.org/stuff/test.sh" title="test.sh">here</a>.</p>
]]></description>
<content:encoded><![CDATA[<p>As mentioned before, I'm a supporter of the <a href="https://www.w3.org/Provider/Style/URI" title="Hypertext Style: Cool URIs don't change">Cool URIs don't change</a> approach.<br>Thus I try to keep all the URLs of this blog working (or at least make them redirect to the new place where the content is located).<br>Not always an easy task with old domains and multiple blogging engines accumulated over the years.</p>
<p>To help me with that (and ensure I don't break anything when updating a 10+ year old mod_rewrite config) I created a short Bash script to test the redirect behavior.<br>It contains a list of URLs and their expected redirect target, goes through them with <a href="https://curl.se" title="curl">curl</a> and checks that the correct <code>Location:</code> header is returned.</p>
<p>As it might be useful for others in similar situations, the script can be found <a href="https://blog.x-way.org/stuff/test.sh" title="test.sh">here</a>.</p>
]]></content:encoded>
</item>
<item>
<title>I miss human curation</title>
<link>https://blog.x-way.org/Misc/2024/01/21/I-miss-human-curation.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324323</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 21 Jan 2024 07:14:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://blog.cassidoo.co/post/human-curation/" title="I miss human curation - Cassidy's blog">I miss human curation</a> — Where are my internet friends? And where are their weird blogs? (<a href="https://bookmark.kniebes.io/bookmark/a97dd47db2b511eebfd9408d5c84b5d9" title="Markus Kniebes Journal">via</a>)<p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://blog.cassidoo.co/post/human-curation/" title="I miss human curation - Cassidy's blog">I miss human curation</a> — Where are my internet friends? And where are their weird blogs? (<a href="https://bookmark.kniebes.io/bookmark/a97dd47db2b511eebfd9408d5c84b5d9" title="Markus Kniebes Journal">via</a>)<p>
]]></content:encoded>
</item>
<item>
<title>Postfix clear verification cache</title>
<link>https://blog.x-way.org/Linux/2024/01/07/Postfix-clear-verification-cache.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324322</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 07 Jan 2024 22:38:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>While adding some new alias functionality to my setup, it repeatedly failed with an error similar to this, despite my configuration changes:</p>
<pre>Recipient address rejected: unverified address: host XXX[XXX] said: 550 5.1.1
<foo@bar.com> User doesn't exist: foo@bar.com (in reply to RCPT TO command);</pre>
<p>Turns out that the negative verification result is cached and the cache is not reset during a reload/restart of postfix.<br>
Thus it must be cleared manually like this:</p>
<pre>/etc/init.d/postfix stop
rm /var/lib/postfix/verify_cache.db
/etc/init.d/postfix start</pre>
]]></description>
<content:encoded><![CDATA[<p>While adding some new alias functionality to my setup, it repeatedly failed with an error similar to this, despite my configuration changes:</p>
<pre>Recipient address rejected: unverified address: host XXX[XXX] said: 550 5.1.1
<foo@bar.com> User doesn't exist: foo@bar.com (in reply to RCPT TO command);</pre>
<p>Turns out that the negative verification result is cached and the cache is not reset during a reload/restart of postfix.<br>
Thus it must be cleared manually like this:</p>
<pre>/etc/init.d/postfix stop
rm /var/lib/postfix/verify_cache.db
/etc/init.d/postfix start</pre>
]]></content:encoded>
</item>
<item>
<title>Valid HTML5</title>
<link>https://blog.x-way.org/Webdesign/2024/01/03/Valid-HTML5.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324321</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 03 Jan 2024 20:59:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>After <a href="https://blog.x-way.org/Webdesign/2024/01/01/Winter-plain-2.html" title="Winter - plain 2">switching the colors</a> of the design, I kept the momentum and continued working on the HTML of the blog.</p>
<p>It took couple iterations of multiple hours, but now it's done: the HTML source of this blog is <a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fblog.x-way.org%2F" title="Nu HTML Checker">valid HTML5</a>!</p>
<p>Getting rid of the obsoleteness hidden in old blogentries dating back over 20 years also led to some interesting observations.<br>
Back when moving from HTML 4.01 to <a href="https://blog.x-way.org/Coding/2004/04/08/x-log_v202c.html" title="x-log v2.02c">XHTML 1.1</a>, I remember spending some time to transform old <code><br></code> tags to <code><br /></code>. And now for HTML5 I did the inverse and moved all <code><br /></code> tags back to <code><br></code> :-)</p>
<p>Also once more I'm very thankful for the work of the <a href="https://archive.org/" title="Internet Archive">Internet Archive</a>, which helped to recover images hosted on servers long gone (like URLs which already at the end of 2002 were no longer valid!).</p>
<p>Overall a lot of replacing no longer existing HTML tags and attributes with CSS definitions.<br>And there is virtually no change to the visual representation of the blog (which was the goal), so we still have the table-based layout with pixel-sized fonts as originally drafted in 2002.<br>Moving this to actually leverage modern HTML5 mechanisms and making it also more mobile friendly are tasks left for some future cold winter evenings :-)</p>
<p><a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fblog.x-way.org%2F" title="Valid W3C HTML5"><img src="https://blog.x-way.org/images/html5-validator-badge.png" width="352" height="124" alt="W3C HTML5"></a></p>
]]></description>
<content:encoded><![CDATA[<p>After <a href="https://blog.x-way.org/Webdesign/2024/01/01/Winter-plain-2.html" title="Winter - plain 2">switching the colors</a> of the design, I kept the momentum and continued working on the HTML of the blog.</p>
<p>It took couple iterations of multiple hours, but now it's done: the HTML source of this blog is <a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fblog.x-way.org%2F" title="Nu HTML Checker">valid HTML5</a>!</p>
<p>Getting rid of the obsoleteness hidden in old blogentries dating back over 20 years also led to some interesting observations.<br>
Back when moving from HTML 4.01 to <a href="https://blog.x-way.org/Coding/2004/04/08/x-log_v202c.html" title="x-log v2.02c">XHTML 1.1</a>, I remember spending some time to transform old <code><br></code> tags to <code><br /></code>. And now for HTML5 I did the inverse and moved all <code><br /></code> tags back to <code><br></code> :-)</p>
<p>Also once more I'm very thankful for the work of the <a href="https://archive.org/" title="Internet Archive">Internet Archive</a>, which helped to recover images hosted on servers long gone (like URLs which already at the end of 2002 were no longer valid!).</p>
<p>Overall a lot of replacing no longer existing HTML tags and attributes with CSS definitions.<br>And there is virtually no change to the visual representation of the blog (which was the goal), so we still have the table-based layout with pixel-sized fonts as originally drafted in 2002.<br>Moving this to actually leverage modern HTML5 mechanisms and making it also more mobile friendly are tasks left for some future cold winter evenings :-)</p>
<p><a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fblog.x-way.org%2F" title="Valid W3C HTML5"><img src="https://blog.x-way.org/images/html5-validator-badge.png" width="352" height="124" alt="W3C HTML5"></a></p>
]]></content:encoded>
</item>
<item>
<title>Winter - plain 2</title>
<link>https://blog.x-way.org/Webdesign/2024/01/01/Winter-plain-2.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324320</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 01 Jan 2024 12:41:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Happy New Year! — Happy New Colors!</p>
<p>Winter is here (for a while already), time to change the colors of the blog.<br>
To keep it in the nostalgic theme (the previous design was a <a href="https://blog.x-way.org/Webdesign/2022/06/04/Blogging-like-2002.html" title="x-log - Blogging like 2002">repurpose of the inital design from 2002</a>), I'm using the colors from the <a href="https://blog.x-way.org/Webdesign/2002/12/15/Winter.html" title="x-log - Winter">'plain 2' winter layout</a> (also from 2002).</p>
<p>Enjoy!</p>
]]></description>
<content:encoded><![CDATA[<p>Happy New Year! — Happy New Colors!</p>
<p>Winter is here (for a while already), time to change the colors of the blog.<br>
To keep it in the nostalgic theme (the previous design was a <a href="https://blog.x-way.org/Webdesign/2022/06/04/Blogging-like-2002.html" title="x-log - Blogging like 2002">repurpose of the inital design from 2002</a>), I'm using the colors from the <a href="https://blog.x-way.org/Webdesign/2002/12/15/Winter.html" title="x-log - Winter">'plain 2' winter layout</a> (also from 2002).</p>
<p>Enjoy!</p>
]]></content:encoded>
</item>
<item>
<title>MECSA</title>
<link>https://blog.x-way.org/Networking/2023/12/30/MECSA.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324319</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 30 Dec 2023 09:16:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>A <a href="https://news.ycombinator.com/item?id=38792358" title="True, MECSA is also interesting: https://mecsa.jrc.ec.europa.eu/en/ | Hacker News">comment on Hacker News</a> pointed me to the <a href="https://mecsa.jrc.ec.europa.eu/en/" title="My Email Communications Security Assessment (MECSA)">MECSA tool</a> provided by the European Union.</p>
<p>MECSA stands for My Email Communications Security Assessment, and is a tool to assess the security of email communication between providers.</p>
<p>As I run my own email server, I was curious to find out how my setup is scoring. Here are the results, seems like I'm doing a good job :-)</p>
<p><a href="https://blog.x-way.org/images/mecsa_scores_full.png" title="MECSA score for jaggi.info, showing 5/5 stars in Confidential Delivery, Phishing and Identity Theft, and Intergrity of Messages."><img src="https://blog.x-way.org/images/mecsa_scores.png" alt="MECSA score for jaggi.info, showing 5/5 stars in Confidential Delivery, Phishing and Identity Theft, and Intergrity of Messages." height="61" width="650"></a></p>
<p><a href="https://blog.x-way.org/images/mecsa_details_full.png" title="MECSA details for jaggi.info, showing 100 points in StartTLS, X509, SPF, DKIM, DMARC, DANE, DNSSEC and MTA-STS."><img src="https://blog.x-way.org/images/mecsa_details.png" alt="MECSA details for jaggi.info, showing 100 points in StartTLS, X509, SPF, DKIM, DMARC, DANE, DNSSEC and MTA-STS." height="75" width="650"></a></p>
<p>Link to the full report for jaggi.info: <a href="https://mecsa.jrc.ec.europa.eu/en/finderRequest/f856486ecaf94dce5e8022c0a97c63b3" title="Report id f856486ecaf94dce5e8022c0a97c63b3 for domain jaggi.info (28/12/2023)">https://mecsa.jrc.ec.europa.eu/en/finderRequest/f856486ecaf94dce5e8022c0a97c63b3</a></p>
]]></description>
<content:encoded><![CDATA[<p>A <a href="https://news.ycombinator.com/item?id=38792358" title="True, MECSA is also interesting: https://mecsa.jrc.ec.europa.eu/en/ | Hacker News">comment on Hacker News</a> pointed me to the <a href="https://mecsa.jrc.ec.europa.eu/en/" title="My Email Communications Security Assessment (MECSA)">MECSA tool</a> provided by the European Union.</p>
<p>MECSA stands for My Email Communications Security Assessment, and is a tool to assess the security of email communication between providers.</p>
<p>As I run my own email server, I was curious to find out how my setup is scoring. Here are the results, seems like I'm doing a good job :-)</p>
<p><a href="https://blog.x-way.org/images/mecsa_scores_full.png" title="MECSA score for jaggi.info, showing 5/5 stars in Confidential Delivery, Phishing and Identity Theft, and Intergrity of Messages."><img src="https://blog.x-way.org/images/mecsa_scores.png" alt="MECSA score for jaggi.info, showing 5/5 stars in Confidential Delivery, Phishing and Identity Theft, and Intergrity of Messages." height="61" width="650"></a></p>
<p><a href="https://blog.x-way.org/images/mecsa_details_full.png" title="MECSA details for jaggi.info, showing 100 points in StartTLS, X509, SPF, DKIM, DMARC, DANE, DNSSEC and MTA-STS."><img src="https://blog.x-way.org/images/mecsa_details.png" alt="MECSA details for jaggi.info, showing 100 points in StartTLS, X509, SPF, DKIM, DMARC, DANE, DNSSEC and MTA-STS." height="75" width="650"></a></p>
<p>Link to the full report for jaggi.info: <a href="https://mecsa.jrc.ec.europa.eu/en/finderRequest/f856486ecaf94dce5e8022c0a97c63b3" title="Report id f856486ecaf94dce5e8022c0a97c63b3 for domain jaggi.info (28/12/2023)">https://mecsa.jrc.ec.europa.eu/en/finderRequest/f856486ecaf94dce5e8022c0a97c63b3</a></p>
]]></content:encoded>
</item>
<item>
<title>Fix named checkhints extra record in hints</title>
<link>https://blog.x-way.org/Linux/2023/12/27/Fix-named-checkhints-extra-record-in-hints.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324318</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 27 Dec 2023 20:53:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>Recently named on my Debian server started to emit the following messages:</p>
<pre>Dec 23 18:30:05 server named[1168203]: checkhints: view external_network: b.root-servers.net/A (170.247.170.2) missing from hints
Dec 23 18:30:05 server named[1168203]: checkhints: view external_network: b.root-servers.net/A (199.9.14.201) extra record in hints
Dec 23 18:30:05 server named[1168203]: checkhints: view external_network: b.root-servers.net/AAAA (2801:1b8:10::b) missing from hints
Dec 23 18:30:05 server named[1168203]: checkhints: view external_network: b.root-servers.net/AAAA (2001:500:200::b) extra record in hints</pre>
<p>The reason for these warnings, is a <a href="https://b.root-servers.org/news/2023/05/16/new-addresses.html" title="New addresses for b.root-servers.net">IP change of the B root-server</a>.</p>
<p>Debian is <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1054393" title="Debian bug report #1054393">not ready yet</a> with updating their dns-root-data package.<br>To fix the mismatching IP definitions on a Debian system, the current root zone definitions can also be updated manually from Internic:</p>
<pre>curl https://www.internic.net/domain/named.root -s > /usr/share/dns/root.hints
curl https://www.internic.net/domain/named.root.sig -s > /usr/share/dns/root.hints.sig</pre>
]]></description>
<content:encoded><![CDATA[<p>Recently named on my Debian server started to emit the following messages:</p>
<pre>Dec 23 18:30:05 server named[1168203]: checkhints: view external_network: b.root-servers.net/A (170.247.170.2) missing from hints
Dec 23 18:30:05 server named[1168203]: checkhints: view external_network: b.root-servers.net/A (199.9.14.201) extra record in hints
Dec 23 18:30:05 server named[1168203]: checkhints: view external_network: b.root-servers.net/AAAA (2801:1b8:10::b) missing from hints
Dec 23 18:30:05 server named[1168203]: checkhints: view external_network: b.root-servers.net/AAAA (2001:500:200::b) extra record in hints</pre>
<p>The reason for these warnings, is a <a href="https://b.root-servers.org/news/2023/05/16/new-addresses.html" title="New addresses for b.root-servers.net">IP change of the B root-server</a>.</p>
<p>Debian is <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1054393" title="Debian bug report #1054393">not ready yet</a> with updating their dns-root-data package.<br>To fix the mismatching IP definitions on a Debian system, the current root zone definitions can also be updated manually from Internic:</p>
<pre>curl https://www.internic.net/domain/named.root -s > /usr/share/dns/root.hints
curl https://www.internic.net/domain/named.root.sig -s > /usr/share/dns/root.hints.sig</pre>
]]></content:encoded>
</item>
<item>
<title>Wikipedia Donation</title>
<link>https://blog.x-way.org/Misc/2023/12/10/Wikipedia-Donation.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324317</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 10 Dec 2023 22:24:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>Seems that after donating to Wikipedia there is a redirect to <a href="https://thankyou.wikipedia.org/wiki/Thank_You/en" rel="noreferrer" title="Thank You - Wikimedia Foundation">this page</a>, which sets a cookie to no longer show the donation banners.</p>
]]></description>
<content:encoded><![CDATA[<p>Seems that after donating to Wikipedia there is a redirect to <a href="https://thankyou.wikipedia.org/wiki/Thank_You/en" rel="noreferrer" title="Thank You - Wikimedia Foundation">this page</a>, which sets a cookie to no longer show the donation banners.</p>
]]></content:encoded>
</item>
<item>
<title>Why Personal Blogging Still Rules</title>
<link>https://blog.x-way.org/Misc/2023/04/30/Why-Personal-Blogging-Still-Rules.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324316</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 30 Apr 2023 14:42:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>Resonating article from <a href="https://mikegrindle.com/" title="Mike Grindle - Homepage">Mike Grindle</a> about personal blogging and how it fits into todays Internet: <a href="https://mikegrindle.com/posts/personal-blogging" title="Why Personal Blogging Still Rules - mikegrindle.com">Why Personal Blogging Still Rules</a></p>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>Before the social media craze or publishing platforms, and long before ‘content creator’ was a job title, blogs served as one of the primary forms of online expression and communication.</p>
</blockquote>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>Everything on your blog was made to look and feel the way you wanted. If it didn’t, you rolled your sleeves up and coded that stuff in like the webmaster you were. And if the masses didn’t like it, who cared? They had no obligations to you, and you had none to them.</p>
</blockquote>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>Hiding beneath the drivel that is Google’s search results, and all the trackers, cookies, ads and curated feeds that come with them, personal blogs and sites of all shapes and sizes are still there. They’re thriving even in a kind of interconnected web beneath the web.</p>
</blockquote>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>The blogs on this small or “indie” web come in many shapes and sizes. […] But at their core, they all have one characteristic in common: they’re there because their owners wanted to carve out their space on the internet.</p>
</blockquote>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>Your blog doesn’t have to be big and fancy. It doesn’t have to outrank everyone on Google, make money or “convert leads” to be important. It can be something that exists for its own sake, as your place to express yourself in whatever manner you please.</p>
</blockquote>
<p>(<a href="https://uninformation.org/webnotizen/23/why-personal-blogging-still-rules/" title="der Uninformat – »Why Personal Blogging Still Rules«">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p>Resonating article from <a href="https://mikegrindle.com/" title="Mike Grindle - Homepage">Mike Grindle</a> about personal blogging and how it fits into todays Internet: <a href="https://mikegrindle.com/posts/personal-blogging" title="Why Personal Blogging Still Rules - mikegrindle.com">Why Personal Blogging Still Rules</a></p>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>Before the social media craze or publishing platforms, and long before ‘content creator’ was a job title, blogs served as one of the primary forms of online expression and communication.</p>
</blockquote>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>Everything on your blog was made to look and feel the way you wanted. If it didn’t, you rolled your sleeves up and coded that stuff in like the webmaster you were. And if the masses didn’t like it, who cared? They had no obligations to you, and you had none to them.</p>
</blockquote>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>Hiding beneath the drivel that is Google’s search results, and all the trackers, cookies, ads and curated feeds that come with them, personal blogs and sites of all shapes and sizes are still there. They’re thriving even in a kind of interconnected web beneath the web.</p>
</blockquote>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>The blogs on this small or “indie” web come in many shapes and sizes. […] But at their core, they all have one characteristic in common: they’re there because their owners wanted to carve out their space on the internet.</p>
</blockquote>
<blockquote cite="https://mikegrindle.com/posts/personal-blogging">
<p>Your blog doesn’t have to be big and fancy. It doesn’t have to outrank everyone on Google, make money or “convert leads” to be important. It can be something that exists for its own sake, as your place to express yourself in whatever manner you please.</p>
</blockquote>
<p>(<a href="https://uninformation.org/webnotizen/23/why-personal-blogging-still-rules/" title="der Uninformat – »Why Personal Blogging Still Rules«">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>exec-hookd</title>
<link>https://blog.x-way.org/Linux/2023/04/23/exec-hookd.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324315</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 23 Apr 2023 22:32:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>To automate some of the deployment steps on my personal server, I needed a tool which can be triggered by a webhook and does execute some pre-defined commands.</p>
<p>A classic solution for this would be to have a simple PHP script with a call to <code>system(...)</code>. But I don't have PHP installed on the server itself and wanted this to be more lightweight than a full Apache+PHP installation.</p>
<p>Thus <a href="https://github.com/x-way/exec-hookd" title="x-way/exec-hookd: execute commands from webhooks">exec-hookd</a> was born. It is a small Go daemon which listens to HTTP POST requests and runs pre-defined commands when a matching path is requested.</p>
<p>Its configuration lives in a small JSON file, which lists the port to listen on and the paths together with their commands to execute:</p>
<pre>{
"Port": 8059,
"HookList": [
{
"Path": "/myhook",
"Exec": [
{
"Cmd": "/usr/bin/somecmd",
"Args": [
"--some",
"arguments"
],
"Timeout": "5s"
}
]
}
]
}</pre>
<p>The commands are called with a timeout after which they are stopped to avoid that things hang around forever.</p>
]]></description>
<content:encoded><![CDATA[<p>To automate some of the deployment steps on my personal server, I needed a tool which can be triggered by a webhook and does execute some pre-defined commands.</p>
<p>A classic solution for this would be to have a simple PHP script with a call to <code>system(...)</code>. But I don't have PHP installed on the server itself and wanted this to be more lightweight than a full Apache+PHP installation.</p>
<p>Thus <a href="https://github.com/x-way/exec-hookd" title="x-way/exec-hookd: execute commands from webhooks">exec-hookd</a> was born. It is a small Go daemon which listens to HTTP POST requests and runs pre-defined commands when a matching path is requested.</p>
<p>Its configuration lives in a small JSON file, which lists the port to listen on and the paths together with their commands to execute:</p>
<pre>{
"Port": 8059,
"HookList": [
{
"Path": "/myhook",
"Exec": [
{
"Cmd": "/usr/bin/somecmd",
"Args": [
"--some",
"arguments"
],
"Timeout": "5s"
}
]
}
]
}</pre>
<p>The commands are called with a timeout after which they are stopped to avoid that things hang around forever.</p>
]]></content:encoded>
</item>
<item>
<title>Nice git log alias</title>
<link>https://blog.x-way.org/Coding/2023/04/16/Nice-git-log-alias.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324314</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 16 Apr 2023 13:55:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p><a href="https://uninformation.org/" title="Wald- und Wiesen-Weblog - uninformation.org">Ralf</a> <a href="https://web.archive.org/web/20231128231558/https://masto.futbol/@oldschooldev/109839690235274960" title="ralf g.: killer-alias für das schönste gitlog in der shell">tooted</a> a nice and tidy git log output alias for the console:</p>
<code>
alias glg="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
</code>
]]></description>
<content:encoded><![CDATA[<p><a href="https://uninformation.org/" title="Wald- und Wiesen-Weblog - uninformation.org">Ralf</a> <a href="https://web.archive.org/web/20231128231558/https://masto.futbol/@oldschooldev/109839690235274960" title="ralf g.: killer-alias für das schönste gitlog in der shell">tooted</a> a nice and tidy git log output alias for the console:</p>
<code>
alias glg="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
</code>
]]></content:encoded>
</item>
<item>
<title>Docker registry facade with nginx</title>
<link>https://blog.x-way.org/Linux/2023/03/18/Docker-registry-facade-with-nginx.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324313</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 18 Mar 2023 10:36:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>Found <a href="https://httptoolkit.com/blog/docker-image-registry-facade/" title="Dodge the next Dockerpocalypse: how to own your own Docker Registry address">this inspiring blog post</a> about how to use your own domain for Docker images. (via <a href="https://news.ycombinator.com/item?id=35205838" title="How to own your own Docker Registry address | Hacker News">HN</a>)</p>
<p>It explains how to use your own domain with redirects such that the Docker registry hosting the images can be changed easily. Your domain is only used for issueing HTTP redirects, so that the actual data storage and transfer happens directly with the Docker registry.</p>
<p>The blog post comes with <a href="https://github.com/httptoolkit/docker-registry-facade/blob/main/Caddyfile" title="Caddyfile">a sample implementation for Caddy</a>. As my server is running <a href="https://nginx.org/" title="nginx">nginx</a>, I used the following config snippet to achieve the same result:</p>
<pre>
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name docker.x-way.org;
access_log /var/log/nginx/docker.x-way.org.access.log;
error_log /var/log/nginx/docker.x-way.org.error.log;
ssl_certificate /etc/letsencrypt/live/docker.x-way.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/docker.x-way.org/privkey.pem;
location / {
return 403;
}
location = /v2 {
add_header Cache-Control 'max-age=300, must-revalidate';
return 307 https://registry.hub.docker.com$request_uri;
}
location = /v2/ {
add_header Cache-Control 'max-age=300, must-revalidate';
return 307 https://registry.hub.docker.com$request_uri;
}
location = /v2/xway {
add_header Cache-Control 'max-age=300, must-revalidate';
return 307 https://registry.hub.docker.com$request_uri;
}
location /v2/xway/ {
add_header Cache-Control 'max-age=300, must-revalidate';
return 307 https://registry.hub.docker.com$request_uri;
}
}
</pre>
<p>Quickly tested it with some docker pull commands and already integrated it into the <a href="https://github.com/x-way/dnsupd/pull/72" title="Use custom registry by x-way - Pull Request #72 - x-way/dnsupd">build process of dnsupd</a>.</p>
]]></description>
<content:encoded><![CDATA[<p>Found <a href="https://httptoolkit.com/blog/docker-image-registry-facade/" title="Dodge the next Dockerpocalypse: how to own your own Docker Registry address">this inspiring blog post</a> about how to use your own domain for Docker images. (via <a href="https://news.ycombinator.com/item?id=35205838" title="How to own your own Docker Registry address | Hacker News">HN</a>)</p>
<p>It explains how to use your own domain with redirects such that the Docker registry hosting the images can be changed easily. Your domain is only used for issueing HTTP redirects, so that the actual data storage and transfer happens directly with the Docker registry.</p>
<p>The blog post comes with <a href="https://github.com/httptoolkit/docker-registry-facade/blob/main/Caddyfile" title="Caddyfile">a sample implementation for Caddy</a>. As my server is running <a href="https://nginx.org/" title="nginx">nginx</a>, I used the following config snippet to achieve the same result:</p>
<pre>
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name docker.x-way.org;
access_log /var/log/nginx/docker.x-way.org.access.log;
error_log /var/log/nginx/docker.x-way.org.error.log;
ssl_certificate /etc/letsencrypt/live/docker.x-way.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/docker.x-way.org/privkey.pem;
location / {
return 403;
}
location = /v2 {
add_header Cache-Control 'max-age=300, must-revalidate';
return 307 https://registry.hub.docker.com$request_uri;
}
location = /v2/ {
add_header Cache-Control 'max-age=300, must-revalidate';
return 307 https://registry.hub.docker.com$request_uri;
}
location = /v2/xway {
add_header Cache-Control 'max-age=300, must-revalidate';
return 307 https://registry.hub.docker.com$request_uri;
}
location /v2/xway/ {
add_header Cache-Control 'max-age=300, must-revalidate';
return 307 https://registry.hub.docker.com$request_uri;
}
}
</pre>
<p>Quickly tested it with some docker pull commands and already integrated it into the <a href="https://github.com/x-way/dnsupd/pull/72" title="Use custom registry by x-way - Pull Request #72 - x-way/dnsupd">build process of dnsupd</a>.</p>
]]></content:encoded>
</item>
<item>
<title>STRAYA 🇦🇺</title>
<link>https://blog.x-way.org/Music/2023/01/26/STRAYA.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324312</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 26 Jan 2023 05:43:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p>Here's a bit older mashup. Happy <a href="https://www.australiaday.com.au/" title="Australia Day 2023 - Australia Day in NSW">Australia Day</a>!</p>
<p><a href="https://youtu.be/rMdbVHPmCW0" title="National Anthem of STRAYA - YouTube">National Anthem of STRAYA</a></p>
]]></description>
<content:encoded><![CDATA[<p>Here's a bit older mashup. Happy <a href="https://www.australiaday.com.au/" title="Australia Day 2023 - Australia Day in NSW">Australia Day</a>!</p>
<p><a href="https://youtu.be/rMdbVHPmCW0" title="National Anthem of STRAYA - YouTube">National Anthem of STRAYA</a></p>
]]></content:encoded>
</item>
<item>
<title>ACME-CAA</title>
<link>https://blog.x-way.org/Networking/2023/01/18/ACME-CAA.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324311</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 18 Jan 2023 23:06:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>Let's Encrypt recently <a href="https://community.letsencrypt.org/t/enabling-acme-caa-account-and-method-binding/189588" title="Enabling ACME CAA Account and Method Binding">introduced support</a> for <a href="https://www.rfc-editor.org/rfc/rfc8657" title="RFC8657">ACME-CAA</a>.</p>
<p>I've now extended my existing CAA DNS entries with the ACME-CAA properties:</p>
<pre>% dig +short -t CAA x-way.org
0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/68891730; validationmethods=http-01"
0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/605777876; validationmethods=http-01"</pre>
<p>The effect of this is that Let's Encrypt will only grant a signed TLS certificate if the request comes from one of my two accounts (authenticated with the corresponding private key).<br>If the certificate request comes from a different account, no TLS certificate will be granted.<br>This protects against man-in-the-middle attacks, specifically against attacks where someone between Let's Encrypt and my server would be trying to impersonate my server to obtain a signed TLS certificate.</p>
<p>Addendum:<br>In case you're wondering where to get the accounturi value from, it can be found in your account file:</p>
<pre>% cat /etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory/*/regr.json
{"body": {}, "uri": "https://acme-v02.api.letsencrypt.org/acme/acct/605777876"}</pre>
]]></description>
<content:encoded><![CDATA[<p>Let's Encrypt recently <a href="https://community.letsencrypt.org/t/enabling-acme-caa-account-and-method-binding/189588" title="Enabling ACME CAA Account and Method Binding">introduced support</a> for <a href="https://www.rfc-editor.org/rfc/rfc8657" title="RFC8657">ACME-CAA</a>.</p>
<p>I've now extended my existing CAA DNS entries with the ACME-CAA properties:</p>
<pre>% dig +short -t CAA x-way.org
0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/68891730; validationmethods=http-01"
0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/605777876; validationmethods=http-01"</pre>
<p>The effect of this is that Let's Encrypt will only grant a signed TLS certificate if the request comes from one of my two accounts (authenticated with the corresponding private key).<br>If the certificate request comes from a different account, no TLS certificate will be granted.<br>This protects against man-in-the-middle attacks, specifically against attacks where someone between Let's Encrypt and my server would be trying to impersonate my server to obtain a signed TLS certificate.</p>
<p>Addendum:<br>In case you're wondering where to get the accounturi value from, it can be found in your account file:</p>
<pre>% cat /etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory/*/regr.json
{"body": {}, "uri": "https://acme-v02.api.letsencrypt.org/acme/acct/605777876"}</pre>
]]></content:encoded>
</item>
<item>
<title>JSON Feed</title>
<link>https://blog.x-way.org/Webdesign/2023/01/10/JSON-Feed.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324310</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 10 Jan 2023 21:51:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>Added a <a href="https://en.wikipedia.org/wiki/JSON_Feed" title="JSON Feed - Wikipedia">JSON Feed</a> to this blog (in additon to the existing <a href="https://blog.x-way.org/rss.xml" title="x-log - RSS feed">RSS</a> and <a href="https://blog.x-way.org/atom.xml" title="x-log - Atom feed">Atom</a> feeds): <a href="https://blog.x-way.org/feed.json" title="x-log - JSON feed">https://blog.x-way.org/feed.json</a></p>
<p>To build the proper JSON file, I used <a href="https://github.com/vallieres/jekyll-json-feed/tree/master" title="JSON Feed for Jekyll">this Jekyll template</a> and the <a href="https://validator.jsonfeed.org/" title="JSON Feed Validator">JSON Feed validator</a>.</p>
]]></description>
<content:encoded><![CDATA[<p>Added a <a href="https://en.wikipedia.org/wiki/JSON_Feed" title="JSON Feed - Wikipedia">JSON Feed</a> to this blog (in additon to the existing <a href="https://blog.x-way.org/rss.xml" title="x-log - RSS feed">RSS</a> and <a href="https://blog.x-way.org/atom.xml" title="x-log - Atom feed">Atom</a> feeds): <a href="https://blog.x-way.org/feed.json" title="x-log - JSON feed">https://blog.x-way.org/feed.json</a></p>
<p>To build the proper JSON file, I used <a href="https://github.com/vallieres/jekyll-json-feed/tree/master" title="JSON Feed for Jekyll">this Jekyll template</a> and the <a href="https://validator.jsonfeed.org/" title="JSON Feed Validator">JSON Feed validator</a>.</p>
]]></content:encoded>
</item>
<item>
<title>Get last 24h of logs with AWK</title>
<link>https://blog.x-way.org/Linux/2023/01/03/Get-last-24h-of-logs-with-AWK.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324309</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 03 Jan 2023 14:40:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>For a temporary log analysis task, I wanted to get the last 24h of logs from a <a href="http://www.postfix.org/" title="The Postfix Home Page">Postfix</a> logfile.<br>To achieve this I came up with the following AWK oneliner (which fails in spectacular ways around new years):</p>
<code>
awk -F '[ :]+' 'BEGIN{m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|"); for(o=1;o<=m;o++){months[d[o]]=sprintf("%02d",o)}} mktime(strftime("%Y")" "months[$1]" "sprintf("%02d",$2+1)" "$3" "$4" "$5) > systime()'
</code>
<p>This is then used in a cronjob to get a <a href="http://jimsun.linxnet.com/postfix_contrib.html" title="JIMSUN - Postfix Contribs">pflogsumm</a> summary of the last 24h:</p>
<code>
cat /var/log/mail.log | awk -F '[ :]+' 'BEGIN{m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|"); for(o=1;o<=m;o++){months[d[o]]=sprintf("%02d",o)}} mktime(strftime("%Y")" "months[$1]" "sprintf("%02d",$2+1)" "$3" "$4" "$5) > systime()' | pflogsumm
</code>
]]></description>
<content:encoded><![CDATA[<p>For a temporary log analysis task, I wanted to get the last 24h of logs from a <a href="http://www.postfix.org/" title="The Postfix Home Page">Postfix</a> logfile.<br>To achieve this I came up with the following AWK oneliner (which fails in spectacular ways around new years):</p>
<code>
awk -F '[ :]+' 'BEGIN{m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|"); for(o=1;o<=m;o++){months[d[o]]=sprintf("%02d",o)}} mktime(strftime("%Y")" "months[$1]" "sprintf("%02d",$2+1)" "$3" "$4" "$5) > systime()'
</code>
<p>This is then used in a cronjob to get a <a href="http://jimsun.linxnet.com/postfix_contrib.html" title="JIMSUN - Postfix Contribs">pflogsumm</a> summary of the last 24h:</p>
<code>
cat /var/log/mail.log | awk -F '[ :]+' 'BEGIN{m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|"); for(o=1;o<=m;o++){months[d[o]]=sprintf("%02d",o)}} mktime(strftime("%Y")" "months[$1]" "sprintf("%02d",$2+1)" "$3" "$4" "$5) > systime()' | pflogsumm
</code>
]]></content:encoded>
</item>
<item>
<title>Happy New Year 2023</title>
<link>https://blog.x-way.org/Misc/2022/12/31/Happy-New-Year-2023.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324308</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 31 Dec 2022 13:59:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://youtu.be/ZKGgsQg17cw" title="Sydney New Year's Eve midgnight fireworks - YouTube">Sydney New Year's Eve midgnight fireworks</a></p>
<p>As usual, Sydney is a bit ahead of us. Great memories, long time ago :-)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://youtu.be/ZKGgsQg17cw" title="Sydney New Year's Eve midgnight fireworks - YouTube">Sydney New Year's Eve midgnight fireworks</a></p>
<p>As usual, Sydney is a bit ahead of us. Great memories, long time ago :-)</p>
]]></content:encoded>
</item>
<item>
<title>Alpha Bravo Charlie</title>
<link>https://blog.x-way.org/Misc/2022/12/25/Alpha-Bravo-Charlie.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324307</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 25 Dec 2022 22:11:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>While closing an old account I had to communicate using the infamous NATO/ICAO phonetic alphabet (US banks like to exchange the 20+ character long <a href="https://en.wikipedia.org/wiki/International_Bank_Account_Number" title="International Bank Account Number - Wikipedia">IBANs</a> via poor-quality call-center phonelines).</p>
<p>As it has been a while since I last used it, I created a handy table to quickly lookup the code words: <a href="http://nato.sigint.ch" title="NATO/ICAO phonetic alphabet">nato.sigint.ch</a></p>
<p>Special feature: when queried by curl (eg. without a text/html Accept header) it returns the table as plaintext :-)</p>
<pre># curl nato.sigint.ch
A Alpha S Sierra
B Bravo T Tango
C Charlie U Uniform
D Delta V Victor
E Echo W Whiskey
F Foxtrot X X-ray
G Golf Y Yankee
H Hotel Z Zulu
I India 0 Zero
J Juliett 1 One
K Kilo 2 Two
L Lima 3 Three
M Mike 4 Four
N November 5 Five
O Oscar 6 Six
P Papa 7 Seven
Q Quebec 8 Eight
R Romeo 9 Niner</pre>
]]></description>
<content:encoded><![CDATA[<p>While closing an old account I had to communicate using the infamous NATO/ICAO phonetic alphabet (US banks like to exchange the 20+ character long <a href="https://en.wikipedia.org/wiki/International_Bank_Account_Number" title="International Bank Account Number - Wikipedia">IBANs</a> via poor-quality call-center phonelines).</p>
<p>As it has been a while since I last used it, I created a handy table to quickly lookup the code words: <a href="http://nato.sigint.ch" title="NATO/ICAO phonetic alphabet">nato.sigint.ch</a></p>
<p>Special feature: when queried by curl (eg. without a text/html Accept header) it returns the table as plaintext :-)</p>
<pre># curl nato.sigint.ch
A Alpha S Sierra
B Bravo T Tango
C Charlie U Uniform
D Delta V Victor
E Echo W Whiskey
F Foxtrot X X-ray
G Golf Y Yankee
H Hotel Z Zulu
I India 0 Zero
J Juliett 1 One
K Kilo 2 Two
L Lima 3 Three
M Mike 4 Four
N November 5 Five
O Oscar 6 Six
P Papa 7 Seven
Q Quebec 8 Eight
R Romeo 9 Niner</pre>
]]></content:encoded>
</item>
<item>
<title>How to Exit Vim</title>
<link>https://blog.x-way.org/Linux/2022/08/07/How-to-Exit-Vim.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324306</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 07 Aug 2022 22:19:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p><img src="https://blog.x-way.org/images/how-to-exit-vim.jpg" alt="How to Exit Vim" height="459" width="680"></p>
<p>(<a href="https://twitter.com/sheeshee/status/1556000047539654657" title="Su-Shee (@sheeshee) / Twitter">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p><img src="https://blog.x-way.org/images/how-to-exit-vim.jpg" alt="How to Exit Vim" height="459" width="680"></p>
<p>(<a href="https://twitter.com/sheeshee/status/1556000047539654657" title="Su-Shee (@sheeshee) / Twitter">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Add node to MongoDB cluster</title>
<link>https://blog.x-way.org/Linux/2022/07/06/Add-node-to-MongoDB-cluster.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324305</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 06 Jul 2022 22:14:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>To add a new node to an existing <a href="https://www.mongodb.com/" title="MongoDB">MongoDB</a> cluster, login to the mongo shell on the primary node and run the following command:</p>
<pre>rs.add({host:"mongodb3.example.net:27017"})</pre>
<p>Similar to remove a node from the cluster, use:</p>
<pre>rs.remove("mongodb3.example.net:27017")</pre>
]]></description>
<content:encoded><![CDATA[<p>To add a new node to an existing <a href="https://www.mongodb.com/" title="MongoDB">MongoDB</a> cluster, login to the mongo shell on the primary node and run the following command:</p>
<pre>rs.add({host:"mongodb3.example.net:27017"})</pre>
<p>Similar to remove a node from the cluster, use:</p>
<pre>rs.remove("mongodb3.example.net:27017")</pre>
]]></content:encoded>
</item>
<item>
<title>Custom nginx error pages</title>
<link>https://blog.x-way.org/Webdesign/2022/06/19/Custom-nginx-error-pages.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324304</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 19 Jun 2022 09:48:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>For quite some time I've been using custom nginx error pages on this site.<br>
My approach so far was to generate a bunch of static HTML with the various error messages and then configure them for each corresponding HTTP status codes in nginx.<br>As there are quite a number of HTTP errors, I used a little shell script to generate the whole config and HTML, in the end I had a huge file with snippets like the one below.</p>
<pre>
error_page 429 @custom_error_429;
location @custom_error_429 {
internal;
more_set_headers 'Content-Type: text/html';
echo '<html>...</html>';
}
</pre>
<p>Now while implementing custom error pages for a different project, I tried to see if there is an easier way to do this.<br>
Some searching lead to the <a href="https://blog.adriaan.io/one-nginx-error-page-to-rule-them-all.html" title="One NGINX error page to rule them all - Adriaan's blog">One NGINX error page to rule them all</a> article which describes an alternative approach leveraging the nginx <abbr title="Server Side Includes">SSI</abbr> module to generate the error pages on the fly.</p>
<p>
Instead of generating and defining a specific error page for each error, a single error page is used for all errors.
</p>
<pre>
error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
415 416 417 418 421 422 423 424 425 426 428 429 431 451 500
501 502 503 504 505 506 507 508 510 511 /error.html;
location = /error.html {
ssi on;
internal;
root /var/www/default;
}
</pre>
<p>nginx provides the status code as variable to our error page, but we also need the error message to make it more userfriendly.<br>
For this we define a mapping of status codes to the error messages.</p>
<pre>
map $status $status_text {
400 'Bad Request';
401 'Unauthorized';
402 'Payment Required';
403 'Forbidden';
404 'Not Found';
405 'Method Not Allowed';
406 'Not Acceptable';
407 'Proxy Authentication Required';
408 'Request Timeout';
409 'Conflict';
410 'Gone';
411 'Length Required';
412 'Precondition Failed';
413 'Payload Too Large';
414 'URI Too Long';
415 'Unsupported Media Type';
416 'Range Not Satisfiable';
417 'Expectation Failed';
418 'I\'m a teapot';
421 'Misdirected Request';
422 'Unprocessable Entity';
423 'Locked';
424 'Failed Dependency';
425 'Too Early';
426 'Upgrade Required';
428 'Precondition Required';
429 'Too Many Requests';
431 'Request Header Fields Too Large';
451 'Unavailable For Legal Reasons';
500 'Internal Server Error';
501 'Not Implemented';
502 'Bad Gateway';
503 'Service Unavailable';
504 'Gateway Timeout';
505 'HTTP Version Not Supported';
506 'Variant Also Negotiates';
507 'Insufficient Storage';
508 'Loop Detected';
510 'Not Extended';
511 'Network Authentication Required';
default 'Something went wrong';
}
</pre>
<p>Now we have the <var>status</var> and the <var>status_text</var> variables available in our error.html page.</p>
<pre>
<html><body>
<h1><!--# echo var="status" default="" -->
<!--# echo var="status_text" default="Something went wrong" --></h1>
</body></html>
</pre>
]]></description>
<content:encoded><![CDATA[<p>For quite some time I've been using custom nginx error pages on this site.<br>
My approach so far was to generate a bunch of static HTML with the various error messages and then configure them for each corresponding HTTP status codes in nginx.<br>As there are quite a number of HTTP errors, I used a little shell script to generate the whole config and HTML, in the end I had a huge file with snippets like the one below.</p>
<pre>
error_page 429 @custom_error_429;
location @custom_error_429 {
internal;
more_set_headers 'Content-Type: text/html';
echo '<html>...</html>';
}
</pre>
<p>Now while implementing custom error pages for a different project, I tried to see if there is an easier way to do this.<br>
Some searching lead to the <a href="https://blog.adriaan.io/one-nginx-error-page-to-rule-them-all.html" title="One NGINX error page to rule them all - Adriaan's blog">One NGINX error page to rule them all</a> article which describes an alternative approach leveraging the nginx <abbr title="Server Side Includes">SSI</abbr> module to generate the error pages on the fly.</p>
<p>
Instead of generating and defining a specific error page for each error, a single error page is used for all errors.
</p>
<pre>
error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
415 416 417 418 421 422 423 424 425 426 428 429 431 451 500
501 502 503 504 505 506 507 508 510 511 /error.html;
location = /error.html {
ssi on;
internal;
root /var/www/default;
}
</pre>
<p>nginx provides the status code as variable to our error page, but we also need the error message to make it more userfriendly.<br>
For this we define a mapping of status codes to the error messages.</p>
<pre>
map $status $status_text {
400 'Bad Request';
401 'Unauthorized';
402 'Payment Required';
403 'Forbidden';
404 'Not Found';
405 'Method Not Allowed';
406 'Not Acceptable';
407 'Proxy Authentication Required';
408 'Request Timeout';
409 'Conflict';
410 'Gone';
411 'Length Required';
412 'Precondition Failed';
413 'Payload Too Large';
414 'URI Too Long';
415 'Unsupported Media Type';
416 'Range Not Satisfiable';
417 'Expectation Failed';
418 'I\'m a teapot';
421 'Misdirected Request';
422 'Unprocessable Entity';
423 'Locked';
424 'Failed Dependency';
425 'Too Early';
426 'Upgrade Required';
428 'Precondition Required';
429 'Too Many Requests';
431 'Request Header Fields Too Large';
451 'Unavailable For Legal Reasons';
500 'Internal Server Error';
501 'Not Implemented';
502 'Bad Gateway';
503 'Service Unavailable';
504 'Gateway Timeout';
505 'HTTP Version Not Supported';
506 'Variant Also Negotiates';
507 'Insufficient Storage';
508 'Loop Detected';
510 'Not Extended';
511 'Network Authentication Required';
default 'Something went wrong';
}
</pre>
<p>Now we have the <var>status</var> and the <var>status_text</var> variables available in our error.html page.</p>
<pre>
<html><body>
<h1><!--# echo var="status" default="" -->
<!--# echo var="status_text" default="Something went wrong" --></h1>
</body></html>
</pre>
]]></content:encoded>
</item>
<item>
<title>nitter</title>
<link>https://blog.x-way.org/Misc/2022/06/15/nitter.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324303</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 15 Jun 2022 21:08:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://en.wikipedia.org/wiki/Nitter" title="nitter">nitter</a> provides a free and open source alternative front-end to Twitter. It talks with the API and does not show any JavaScript or ads (thus no 'forced-login' overlay after reading 5 tweets or similar nastiness).<br>
The source code for it is available on <a href="https://github.com/zedeus/nitter" title="">GitHub</a>.</p>
<p>It does a direct mapping of the profile URLs, thus <code>https://twitter.com/sheeshee</code> becomes <code>https://<b>nitter.net</b>/sheeshee</code></p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://en.wikipedia.org/wiki/Nitter" title="nitter">nitter</a> provides a free and open source alternative front-end to Twitter. It talks with the API and does not show any JavaScript or ads (thus no 'forced-login' overlay after reading 5 tweets or similar nastiness).<br>
The source code for it is available on <a href="https://github.com/zedeus/nitter" title="">GitHub</a>.</p>
<p>It does a direct mapping of the profile URLs, thus <code>https://twitter.com/sheeshee</code> becomes <code>https://<b>nitter.net</b>/sheeshee</code></p>
]]></content:encoded>
</item>
<item>
<title>Blogging like 2002</title>
<link>https://blog.x-way.org/Webdesign/2022/06/04/Blogging-like-2002.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324302</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 04 Jun 2022 11:32:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>On the occasion of the <a href="https://blog.x-way.org/Misc/2022/06/02/Happy-20th-Birthday-x-log.html" title="Happy 20th Birthday x-log">20th anniversary of this blog</a>, I've used <a href="https://archive.org/" title="Internet Archive">archive.org</a> to reconstruct the original HTML layout from back in the time and applied it to the Jekyll templates.</p>
<p>Enjoy the blog in all the (<table> based) glory from 2002 :-)</p>
]]></description>
<content:encoded><![CDATA[<p>On the occasion of the <a href="https://blog.x-way.org/Misc/2022/06/02/Happy-20th-Birthday-x-log.html" title="Happy 20th Birthday x-log">20th anniversary of this blog</a>, I've used <a href="https://archive.org/" title="Internet Archive">archive.org</a> to reconstruct the original HTML layout from back in the time and applied it to the Jekyll templates.</p>
<p>Enjoy the blog in all the (<table> based) glory from 2002 :-)</p>
]]></content:encoded>
</item>
<item>
<title>Happy 20th Birthday x-log</title>
<link>https://blog.x-way.org/Misc/2022/06/02/Happy-20th-Birthday-x-log.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324301</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 02 Jun 2022 22:54:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>On June 2nd 2002 I published the first (test) entry in this weblog. The first entry has disappeared since (thus making <a href="https://blog.x-way.org/Webdesign/2002/06/03/Flash-Sites.html" title="Flash-Sites">the second entry</a> the first one in the <a href="https://blog.x-way.org/archive/archive-2002-06.html" title="x-log - Archive - 2002-06" >archive of June 2002</a>).</p>
<p><img src="https://blog.x-way.org/images/first_entry.png" alt="Screenshot of the first (test) entry" height="59" width="290"></p>
<p>Compared to <a href="https://web.archive.org/web/20020808101503/http://waterwave.ch/weblog/about.php" title="archive.org x-log about page from 2002">20 years ago</a>, the about page no longer needs to explain what a weblog is.<br>
Interesting though that the linked <a href="https://web.archive.org/web/20011204164555/http://www.jonet.org/data/beitraege.983619029.22602.html" title="archive.org: Peter Praschl: Was ist eigentlich ein Weblog?">definition of a weblog</a> from back then already did foresee the rise and fall in popularity of weblogs which happend during the last two decades.<br>To me it seems in the last 1-2 years there has been an increase again in activity around personal weblogs; curious to see if this revival trend continues.
</p>
<p>Also the weblog here has changed quite a bit. Initially its content was more on the pure web-logging side (commenting on interesting links I encountered during my daily Internet surfing) mixed with some kind of a journal/commentary of my day-to-day life. Later on it moved more towards a 'knowledge dump' on technical topics mixed with some music discoveries and random personal post from festivals and travels. And lately it has been rather sparse again with posts, still mostly on technical topics around coding, networking, security mixed with some personal posts commenting on the current world situation.<br>The frequency of posts also followed the changes in content where early on there sometimes were multiple posts per day, nowadays there can be multiple months without any post and there were even entire years where nothing new was posted; let's see how this goes in the future :-)</p>
<p>From the list of linked Blogs in 2002, only deep-resonance aka <a href="https://kniebes.com/" title="Markus Kniebes">mk</a> is still active, special shout-out to <a href="https://kniebes.com/now">Markus</a> for the continuous persistence.<br>To the next twenty years :-)</p>
]]></description>
<content:encoded><![CDATA[<p>On June 2nd 2002 I published the first (test) entry in this weblog. The first entry has disappeared since (thus making <a href="https://blog.x-way.org/Webdesign/2002/06/03/Flash-Sites.html" title="Flash-Sites">the second entry</a> the first one in the <a href="https://blog.x-way.org/archive/archive-2002-06.html" title="x-log - Archive - 2002-06" >archive of June 2002</a>).</p>
<p><img src="https://blog.x-way.org/images/first_entry.png" alt="Screenshot of the first (test) entry" height="59" width="290"></p>
<p>Compared to <a href="https://web.archive.org/web/20020808101503/http://waterwave.ch/weblog/about.php" title="archive.org x-log about page from 2002">20 years ago</a>, the about page no longer needs to explain what a weblog is.<br>
Interesting though that the linked <a href="https://web.archive.org/web/20011204164555/http://www.jonet.org/data/beitraege.983619029.22602.html" title="archive.org: Peter Praschl: Was ist eigentlich ein Weblog?">definition of a weblog</a> from back then already did foresee the rise and fall in popularity of weblogs which happend during the last two decades.<br>To me it seems in the last 1-2 years there has been an increase again in activity around personal weblogs; curious to see if this revival trend continues.
</p>
<p>Also the weblog here has changed quite a bit. Initially its content was more on the pure web-logging side (commenting on interesting links I encountered during my daily Internet surfing) mixed with some kind of a journal/commentary of my day-to-day life. Later on it moved more towards a 'knowledge dump' on technical topics mixed with some music discoveries and random personal post from festivals and travels. And lately it has been rather sparse again with posts, still mostly on technical topics around coding, networking, security mixed with some personal posts commenting on the current world situation.<br>The frequency of posts also followed the changes in content where early on there sometimes were multiple posts per day, nowadays there can be multiple months without any post and there were even entire years where nothing new was posted; let's see how this goes in the future :-)</p>
<p>From the list of linked Blogs in 2002, only deep-resonance aka <a href="https://kniebes.com/" title="Markus Kniebes">mk</a> is still active, special shout-out to <a href="https://kniebes.com/now">Markus</a> for the continuous persistence.<br>To the next twenty years :-)</p>
]]></content:encoded>
</item>
<item>
<title>mt-set-time</title>
<link>https://blog.x-way.org/Networking/2022/03/26/mt-set-time.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324300</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 26 Mar 2022 16:15:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>A while ago I wrote a little tool to set the time on <a href="https://mikrotik.com/" title="MikroTik Routers and Wireless">MikroTik</a> devices.
It takes the current time from the local machine and does set it on the device through the API (while respecting the timezone configured on it).<br>
I mostly use it to set the proper time when the device time was completely off (when setting up a new device or when it has been powered off for a long time).
Afterwards NTP should take care of keeping the time in sync.</p>
<p>The tool is now available on GitHub together with installation and usage instructions: <a href="https://github.com/x-way/mt-set-time" title="x-way/mt-set-time: Set time on MikroTik routers">mt-set-time</a></p>
]]></description>
<content:encoded><![CDATA[<p>A while ago I wrote a little tool to set the time on <a href="https://mikrotik.com/" title="MikroTik Routers and Wireless">MikroTik</a> devices.
It takes the current time from the local machine and does set it on the device through the API (while respecting the timezone configured on it).<br>
I mostly use it to set the proper time when the device time was completely off (when setting up a new device or when it has been powered off for a long time).
Afterwards NTP should take care of keeping the time in sync.</p>
<p>The tool is now available on GitHub together with installation and usage instructions: <a href="https://github.com/x-way/mt-set-time" title="x-way/mt-set-time: Set time on MikroTik routers">mt-set-time</a></p>
]]></content:encoded>
</item>
<item>
<title>Fight Putin - Ride a Bike</title>
<link>https://blog.x-way.org/Misc/2022/03/15/Fight-Putin-Ride-a-Bike.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324299</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 15 Mar 2022 12:55:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://blog.x-way.org/images/fight-putin-ride-a-bike.jpeg" title="Fight Putin - Ride a Bike"><img src="https://blog.x-way.org/images/fight-putin-ride-a-bike_small.jpeg" alt="Fight Putin - Ride a Bike" height="515" width="300"></a></p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://blog.x-way.org/images/fight-putin-ride-a-bike.jpeg" title="Fight Putin - Ride a Bike"><img src="https://blog.x-way.org/images/fight-putin-ride-a-bike_small.jpeg" alt="Fight Putin - Ride a Bike" height="515" width="300"></a></p>
]]></content:encoded>
</item>
<item>
<title>Dr Putin isch</title>
<link>https://blog.x-way.org/Music/2022/02/27/Dr-Putin-isch.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324298</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 27 Feb 2022 11:53:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p><a href="https://youtu.be/R-oqHUlptq8" title="Dr Putin isch e Hueresohn - YouTube">Dr Putin isch e Hueresohn</a></p>
<p>(<a href="https://www.reddit.com/r/BUENZLI/comments/t08crk/mis_neue_lieblingslied/" title="/r/BUENZLI on reddit.com">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://youtu.be/R-oqHUlptq8" title="Dr Putin isch e Hueresohn - YouTube">Dr Putin isch e Hueresohn</a></p>
<p>(<a href="https://www.reddit.com/r/BUENZLI/comments/t08crk/mis_neue_lieblingslied/" title="/r/BUENZLI on reddit.com">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Non à la guerre! Nein zum Krieg!</title>
<link>https://blog.x-way.org/Misc/2022/02/26/Non-a-la-guerre-Nein-zum-Krieg.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324297</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 26 Feb 2022 21:22:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>Today I went to Bern to the <a href="https://www.swissinfo.ch/eng/ukraine--up-to-20-000-people-march-in-bern-for-peace/47383836" title="Ukraine: up to 20'000 people march in Bern for peace">rally for peace</a>.<br>
My motivation was to show support for the people suffering in this war and to send a signal to our swiss government that the population wants clear participation in sanctions (while remaining neutral, the two in my view are not exclusive!).</p>
<p>Swiss media reported that this was the largest rally for peace in Switzerland since the <a href="https://blog.x-way.org/Misc/2003/03/22/Tous_ensemble_tous_ensemble_non_a_la_guerre.html" title="x-log - Tous ensemble, tous ensemble, non à la guerre!">rallies against the war in Iraq in 2003</a>. That I can link to my own blog entry regarding the rally for peace from 19 years ago, makes me sad.<br>
Clearly we as human species did not progress enough on this topic :-(</p>
<p>Besides showing up to the rally, I also did donate to the <a href="https://www.icrc.org/" title="International Committee of the Red Cross">ICRC</a> to provide humanitarian aid and I do encourage you to do the same.</p>
]]></description>
<content:encoded><![CDATA[<p>Today I went to Bern to the <a href="https://www.swissinfo.ch/eng/ukraine--up-to-20-000-people-march-in-bern-for-peace/47383836" title="Ukraine: up to 20'000 people march in Bern for peace">rally for peace</a>.<br>
My motivation was to show support for the people suffering in this war and to send a signal to our swiss government that the population wants clear participation in sanctions (while remaining neutral, the two in my view are not exclusive!).</p>
<p>Swiss media reported that this was the largest rally for peace in Switzerland since the <a href="https://blog.x-way.org/Misc/2003/03/22/Tous_ensemble_tous_ensemble_non_a_la_guerre.html" title="x-log - Tous ensemble, tous ensemble, non à la guerre!">rallies against the war in Iraq in 2003</a>. That I can link to my own blog entry regarding the rally for peace from 19 years ago, makes me sad.<br>
Clearly we as human species did not progress enough on this topic :-(</p>
<p>Besides showing up to the rally, I also did donate to the <a href="https://www.icrc.org/" title="International Committee of the Red Cross">ICRC</a> to provide humanitarian aid and I do encourage you to do the same.</p>
]]></content:encoded>
</item>
<item>
<title>EFF Member Badge 2022</title>
<link>https://blog.x-way.org/Badges/2022/02/20/EFF-Member-Badge-2022.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324296</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 20 Feb 2022 09:22:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Badges/">Badges</category>
<description><![CDATA[<p><a href="https://www.eff.org/" title="Electronic Frontier Foundation | Defending your rights in the digital world"><img src="https://blog.x-way.org/images/member-badge-2022b.jpg" alt="EFF Member Badge 2022" height="300" width="300"></a></p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://www.eff.org/" title="Electronic Frontier Foundation | Defending your rights in the digital world"><img src="https://blog.x-way.org/images/member-badge-2022b.jpg" alt="EFF Member Badge 2022" height="300" width="300"></a></p>
]]></content:encoded>
</item>
<item>
<title>vtysock</title>
<link>https://blog.x-way.org/Networking/2022/01/29/vtysock.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324295</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 29 Jan 2022 21:38:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>After switching my Debian hosts from <a href="https://en.wikipedia.org/wiki/Quagga_(software)" title="Quagga Software Routing Suite">Quagga</a> to <a href="https://frrouting.org/" title="FRRouting">FRRouting</a>, I noticed that running vtysh has become quite a bit slower especially when making multiple calls to it from my status/monitoring scripts.
<br>This has also been observed by other users of FRRouting (there's an open issue in their bugtracker: <a href="https://github.com/FRRouting/frr/issues/7799" title="vtysh is significantly slower in FRR than Quagga">#7799</a>).</p>
<p>The Prometheus <a href="https://github.com/tynany/frr_exporter" title="Prometheus exporter for Free Range Routing">frr_exporter</a> works around this by directly sending commands to the UNIX sockets of the FRR daemons (<a href="https://github.com/tynany/frr_exporter/pull/50" title="frr_exporter - refactor: send cmds to unix socket">PR</a>).</p>
<p>To use the same approach in my monitoring scripts, I wrote a small utility which acts as a drop-in replacement for vtysh and sends the commands directly to the UNIX sockets of the FRR daemons: <a href="https://github.com/x-way/vtysock" title="x-way/vtysock - a quick vtysh replacement">vtysock</a>
<br>By skipping the parsing and validation checks done in vtysh, vtysock can achieve a significant speed improvement when executing commands.</p>
]]></description>
<content:encoded><![CDATA[<p>After switching my Debian hosts from <a href="https://en.wikipedia.org/wiki/Quagga_(software)" title="Quagga Software Routing Suite">Quagga</a> to <a href="https://frrouting.org/" title="FRRouting">FRRouting</a>, I noticed that running vtysh has become quite a bit slower especially when making multiple calls to it from my status/monitoring scripts.
<br>This has also been observed by other users of FRRouting (there's an open issue in their bugtracker: <a href="https://github.com/FRRouting/frr/issues/7799" title="vtysh is significantly slower in FRR than Quagga">#7799</a>).</p>
<p>The Prometheus <a href="https://github.com/tynany/frr_exporter" title="Prometheus exporter for Free Range Routing">frr_exporter</a> works around this by directly sending commands to the UNIX sockets of the FRR daemons (<a href="https://github.com/tynany/frr_exporter/pull/50" title="frr_exporter - refactor: send cmds to unix socket">PR</a>).</p>
<p>To use the same approach in my monitoring scripts, I wrote a small utility which acts as a drop-in replacement for vtysh and sends the commands directly to the UNIX sockets of the FRR daemons: <a href="https://github.com/x-way/vtysock" title="x-way/vtysock - a quick vtysh replacement">vtysock</a>
<br>By skipping the parsing and validation checks done in vtysh, vtysock can achieve a significant speed improvement when executing commands.</p>
]]></content:encoded>
</item>
<item>
<title>Force SSH to use IPv6</title>
<link>https://blog.x-way.org/Networking/2022/01/23/Force-SSH-to-use-IPv6.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324294</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 23 Jan 2022 10:53:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>In situations where IPv6 connectivity performs better than IPv4, you might want to force SSH to use IPv6. In interactive mode this can be achieved with the <code>-6</code> commandline parameter.<br>But in situations where you can't modify the commandline parameters a different approach is needed (for example in rsync backup scripts which use SSH as underlying transport layer).</p>
<p>We can use the <a href="https://man.openbsd.org/ssh_config.5" title="ssh_config(5) - OpenBSD manual pages">ssh_config</a> file to encforce that IPv6 is used for a specific host:</p>
<pre>
Host myipv6host
AddressFamily inet6
</pre>
<p>This instructs all SSH commands to use IPv6 when connecting to myipv6host.</p>
<p>The same approach also works to force usage of <a href="https://blog.x-way.org/Networking/2013/07/05/Mandatory-requirement-for-all-non-IPv6-capable-products.html">Legacy IP</a> by specyfing <code>inet</code> as address family.</p>
]]></description>
<content:encoded><![CDATA[<p>In situations where IPv6 connectivity performs better than IPv4, you might want to force SSH to use IPv6. In interactive mode this can be achieved with the <code>-6</code> commandline parameter.<br>But in situations where you can't modify the commandline parameters a different approach is needed (for example in rsync backup scripts which use SSH as underlying transport layer).</p>
<p>We can use the <a href="https://man.openbsd.org/ssh_config.5" title="ssh_config(5) - OpenBSD manual pages">ssh_config</a> file to encforce that IPv6 is used for a specific host:</p>
<pre>
Host myipv6host
AddressFamily inet6
</pre>
<p>This instructs all SSH commands to use IPv6 when connecting to myipv6host.</p>
<p>The same approach also works to force usage of <a href="https://blog.x-way.org/Networking/2013/07/05/Mandatory-requirement-for-all-non-IPv6-capable-products.html">Legacy IP</a> by specyfing <code>inet</code> as address family.</p>
]]></content:encoded>
</item>
<item>
<title>Google Analytics removed</title>
<link>https://blog.x-way.org/Webdesign/2022/01/19/Google-Analytics-removed.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324293</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 19 Jan 2022 22:45:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>After running it for a bit more than a decade, I've now removed again the Google Analytics tracking from this site. It does not feel appropriate anymore on a personal website.<br>At the moment no alternative statistics solution is in place yet, but I could imagine setting up a self-hosted solution like <a href="https://matomo.org/" title="Matomo Analytics - The Google Analytics alternative that protects your data">Matomo</a> or <a href="https://plausible.io/" title="Plausible Analytics | Simple, privacy-friendly Google Analytics alternative">Plausible</a> in the future.</p>
]]></description>
<content:encoded><![CDATA[<p>After running it for a bit more than a decade, I've now removed again the Google Analytics tracking from this site. It does not feel appropriate anymore on a personal website.<br>At the moment no alternative statistics solution is in place yet, but I could imagine setting up a self-hosted solution like <a href="https://matomo.org/" title="Matomo Analytics - The Google Analytics alternative that protects your data">Matomo</a> or <a href="https://plausible.io/" title="Plausible Analytics | Simple, privacy-friendly Google Analytics alternative">Plausible</a> in the future.</p>
]]></content:encoded>
</item>
<item>
<title>Google Analytics declared illegal in the EU</title>
<link>https://blog.x-way.org/Webdesign/2022/01/19/Google-Analytics-declared-illegal-in-the-EU.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324292</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 19 Jan 2022 20:45:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p><a href="https://tuta.com/blog/posts/is-google-analytics-illegal/" title="Google Analytics declared illegal in the EU">Google Analytics declared illegal in the EU</a>.</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://tuta.com/blog/posts/is-google-analytics-illegal/" title="Google Analytics declared illegal in the EU">Google Analytics declared illegal in the EU</a>.</p>
]]></content:encoded>
</item>
<item>
<title>Wordle</title>
<link>https://blog.x-way.org/Misc/2022/01/05/Wordle.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324291</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Wed, 05 Jan 2022 07:09:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://www.nytimes.com/games/wordle/index.html" title="Wordle - A daily word game">Wordle</a> seems to be the trending topic these days.<br>It's a word game similar to the french <a href="https://fr.wikipedia.org/wiki/Motus_(jeu_t%C3%A9l%C3%A9vis%C3%A9)" title="Motus - Wikipedia">Motus</a> game show (resp. the american <a href="https://en.wikipedia.org/wiki/Lingo_(American_game_show)" title="Lingo - Wikipedia">Lingo</a> game show).</p>
<p>Wordle 200 4/6<br>
<br>
⬜⬜⬜🟩⬜<br>
⬜⬜🟨🟩⬜<br>
⬜⬜⬜🟩🟩<br>
🟩🟩🟩🟩🟩<br>
</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://www.nytimes.com/games/wordle/index.html" title="Wordle - A daily word game">Wordle</a> seems to be the trending topic these days.<br>It's a word game similar to the french <a href="https://fr.wikipedia.org/wiki/Motus_(jeu_t%C3%A9l%C3%A9vis%C3%A9)" title="Motus - Wikipedia">Motus</a> game show (resp. the american <a href="https://en.wikipedia.org/wiki/Lingo_(American_game_show)" title="Lingo - Wikipedia">Lingo</a> game show).</p>
<p>Wordle 200 4/6<br>
<br>
⬜⬜⬜🟩⬜<br>
⬜⬜🟨🟩⬜<br>
⬜⬜⬜🟩🟩<br>
🟩🟩🟩🟩🟩<br>
</p>
]]></content:encoded>
</item>
<item>
<title>Y2K22</title>
<link>https://blog.x-way.org/Coding/2022/01/01/Y2K22.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324290</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 01 Jan 2022 21:48:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>Turns out that signed 32-bit numbers can be exhausted long before <a href="https://en.wikipedia.org/wiki/Year_2038_problem" title="Year 2038 problem">Y2038</a>, when you use them to store time in YYMMDDHHMM format. (<a href="https://rachelbythebay.com/w/2022/01/01/baddate/" title="rachelbythebay - YYMMDDHHMM just overflowed a signed 32 bit int">via</a>)</p>
]]></description>
<content:encoded><![CDATA[<p>Turns out that signed 32-bit numbers can be exhausted long before <a href="https://en.wikipedia.org/wiki/Year_2038_problem" title="Year 2038 problem">Y2038</a>, when you use them to store time in YYMMDDHHMM format. (<a href="https://rachelbythebay.com/w/2022/01/01/baddate/" title="rachelbythebay - YYMMDDHHMM just overflowed a signed 32 bit int">via</a>)</p>
]]></content:encoded>
</item>
<item>
<title>Open Source on Mars</title>
<link>https://blog.x-way.org/Coding/2021/04/19/Open-Source-on-Mars.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324289</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Mon, 19 Apr 2021 16:21:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p>Received a badge from GitHub's <a href="https://github.com/readme/nasa-ingenuity-helicopter" title="Open Source on Mars: Community powers NASA’s Ingenuity Helicopter - The ReadMe Project">Open Source on Mars</a> <a href="https://github.blog/2021-04-19-open-source-goes-to-mars/" title="Open source goes to Mars - The GitHub Blog">initiative</a> :-)</p>
<p><a href="https://github.com/x-way"><img src="https://blog.x-way.org/images/github_mars_2020_helicopter_contributor.png" alt="Mars 2020 Helicopter Contributor - Andreas Jaggi contributed code to 1 repository used in the Mars 2020 Helicopter Mission: torvalds/linux" title="Mars 2020 Helicopter Contributor - Andreas Jaggi contributed code to 1 repository used in the Mars 2020 Helicopter Mission: torvalds/linux" width="333" height="117"></a></p>
]]></description>
<content:encoded><![CDATA[<p>Received a badge from GitHub's <a href="https://github.com/readme/nasa-ingenuity-helicopter" title="Open Source on Mars: Community powers NASA’s Ingenuity Helicopter - The ReadMe Project">Open Source on Mars</a> <a href="https://github.blog/2021-04-19-open-source-goes-to-mars/" title="Open source goes to Mars - The GitHub Blog">initiative</a> :-)</p>
<p><a href="https://github.com/x-way"><img src="https://blog.x-way.org/images/github_mars_2020_helicopter_contributor.png" alt="Mars 2020 Helicopter Contributor - Andreas Jaggi contributed code to 1 repository used in the Mars 2020 Helicopter Mission: torvalds/linux" title="Mars 2020 Helicopter Contributor - Andreas Jaggi contributed code to 1 repository used in the Mars 2020 Helicopter Mission: torvalds/linux" width="333" height="117"></a></p>
]]></content:encoded>
</item>
<item>
<title>Top 21 Security Experts to follow on Twitter in 2021</title>
<link>https://blog.x-way.org/Networking/2021/04/17/Top-21-Security-Experts-to-follow-on-Twitter-in-2021.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324288</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 17 Apr 2021 06:58:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>From the <a href="https://web.archive.org/web/20210412004031/https://securityboulevard.com/2021/04/top-21-cybersecurity-experts-you-must-follow-on-twitter-in-2021/" title="Top-21 Cybersecurity Experts You Must Follow on Twitter in 2021 - Security Boulevard (archive.org)">article on Security Boulevard</a>.</p>
<ol>
<li><a href="https://twitter.com/rafaybaloch" title="Rafay Baloch (@rafaybaloch) / Twitter">Rafay Baloch</a></li>
<li><a href="https://twitter.com/troyhunt" title="Troy Hunt (@troyhunt) / Twitter">Troy Hunt</a></li>
<li><a href="https://twitter.com/kevinmitnick" title="Kevin Mitnick (@kevinmitnick) / Twitter">Kevin Mitnick</a></li>
<li><a href="https://twitter.com/RachelTobac" title="Rachel Tobac (@RachelTobac) / Twitter">Rachel Tobac</a></li>
<li><a href="https://twitter.com/mikko" title="Mikko Hyppönen (@mikko) / Twitter">Mikko Hyppönen</a></li>
<li><a href="https://twitter.com/k8em0" title="Katie Moussouris (@k8em0) / Twitter">Katie Moussouris</a></li>
<li><a href="https://twitter.com/schneierblog" title="Bruce Schneier (@schneierblog) / Twitter">Bruce Schneier</a></li>
<li><a href="https://twitter.com/briankrebs" title="Brian Krebs (@briankrebs) / Twitter">Brian Krebs</a></li>
<li><a href="https://twitter.com/jeremiahg" title="Jeremiah Grossman (@jeremiahg) / Twitter">Jeremiah Grossman</a></li>
<li><a href="https://twitter.com/e_kaspersky" title="Eugene Kaspersky (@e_kaspersky) / Twitter">Eugene Kaspersky</a></li>
<li><a href="https://twitter.com/govcso" title="Dan Lohemann (@govcso) / Twitter">Dan Lohemann</a></li>
<li><a href="https://twitter.com/CybersecuritySF" title="Steve Morgan (@CybersecuritySF) / Twitter">Steve Morgan</a></li>
<li><a href="https://twitter.com/TylerCohenWood" title="Tyler Cohen Wood (@TylerCohenWood) / Twitter">Tyler Cohen Wood</a></li>
<li><a href="https://twitter.com/gcluley" title="Graham Cluley (@gcluley) / Twitter">Graham Cluley</a></li>
<li><a href="https://twitter.com/TrackerPayton" title="Theresa Payton (@TrackerPayton) / Twitter">Theresa Payton</a></li>
<li><a href="https://twitter.com/Shirastweet" title="Shira Rubinoff (@Shirastweet) / Twitter">Shira Rubinoff</a></li>
<li><a href="https://twitter.com/evacide" title="Eva Galperin (@evacide) / Twitter">Eva Galperin</a></li>
<li><a href="https://twitter.com/marcusjcarey" title="Marcus J. Carey (@marcusjcarey) / Twitter">Marcus J. Carey</a></li>
<li><a href="https://twitter.com/jaysonstreet" title="Jayson E Street (@jaysonstreet) / Twitter">Jayson E Street</a></li>
<li><a href="https://twitter.com/securityweekly" title="Paul Asadoorian (@securityweekly) / Twitter">Paul Asadoorian</a></li>
<li><a href="https://twitter.com/adam_k_levin" title="Adam K. Levin (@adam_k_levin) / Twitter">Adam K. Levin</a></li>
</ol>
]]></description>
<content:encoded><![CDATA[<p>From the <a href="https://web.archive.org/web/20210412004031/https://securityboulevard.com/2021/04/top-21-cybersecurity-experts-you-must-follow-on-twitter-in-2021/" title="Top-21 Cybersecurity Experts You Must Follow on Twitter in 2021 - Security Boulevard (archive.org)">article on Security Boulevard</a>.</p>
<ol>
<li><a href="https://twitter.com/rafaybaloch" title="Rafay Baloch (@rafaybaloch) / Twitter">Rafay Baloch</a></li>
<li><a href="https://twitter.com/troyhunt" title="Troy Hunt (@troyhunt) / Twitter">Troy Hunt</a></li>
<li><a href="https://twitter.com/kevinmitnick" title="Kevin Mitnick (@kevinmitnick) / Twitter">Kevin Mitnick</a></li>
<li><a href="https://twitter.com/RachelTobac" title="Rachel Tobac (@RachelTobac) / Twitter">Rachel Tobac</a></li>
<li><a href="https://twitter.com/mikko" title="Mikko Hyppönen (@mikko) / Twitter">Mikko Hyppönen</a></li>
<li><a href="https://twitter.com/k8em0" title="Katie Moussouris (@k8em0) / Twitter">Katie Moussouris</a></li>
<li><a href="https://twitter.com/schneierblog" title="Bruce Schneier (@schneierblog) / Twitter">Bruce Schneier</a></li>
<li><a href="https://twitter.com/briankrebs" title="Brian Krebs (@briankrebs) / Twitter">Brian Krebs</a></li>
<li><a href="https://twitter.com/jeremiahg" title="Jeremiah Grossman (@jeremiahg) / Twitter">Jeremiah Grossman</a></li>
<li><a href="https://twitter.com/e_kaspersky" title="Eugene Kaspersky (@e_kaspersky) / Twitter">Eugene Kaspersky</a></li>
<li><a href="https://twitter.com/govcso" title="Dan Lohemann (@govcso) / Twitter">Dan Lohemann</a></li>
<li><a href="https://twitter.com/CybersecuritySF" title="Steve Morgan (@CybersecuritySF) / Twitter">Steve Morgan</a></li>
<li><a href="https://twitter.com/TylerCohenWood" title="Tyler Cohen Wood (@TylerCohenWood) / Twitter">Tyler Cohen Wood</a></li>
<li><a href="https://twitter.com/gcluley" title="Graham Cluley (@gcluley) / Twitter">Graham Cluley</a></li>
<li><a href="https://twitter.com/TrackerPayton" title="Theresa Payton (@TrackerPayton) / Twitter">Theresa Payton</a></li>
<li><a href="https://twitter.com/Shirastweet" title="Shira Rubinoff (@Shirastweet) / Twitter">Shira Rubinoff</a></li>
<li><a href="https://twitter.com/evacide" title="Eva Galperin (@evacide) / Twitter">Eva Galperin</a></li>
<li><a href="https://twitter.com/marcusjcarey" title="Marcus J. Carey (@marcusjcarey) / Twitter">Marcus J. Carey</a></li>
<li><a href="https://twitter.com/jaysonstreet" title="Jayson E Street (@jaysonstreet) / Twitter">Jayson E Street</a></li>
<li><a href="https://twitter.com/securityweekly" title="Paul Asadoorian (@securityweekly) / Twitter">Paul Asadoorian</a></li>
<li><a href="https://twitter.com/adam_k_levin" title="Adam K. Levin (@adam_k_levin) / Twitter">Adam K. Levin</a></li>
</ol>
]]></content:encoded>
</item>
<item>
<title>security.txt</title>
<link>https://blog.x-way.org/Webdesign/2021/03/28/security-txt.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324287</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 28 Mar 2021 08:16:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p>This website now also serves a <a href="https://securitytxt.org/" title="security.txt: Proposed standard for defining security policies">security.txt</a> file which is a standardized way of making security contact information available. (<a href="https://en.wikipedia.org/wiki/Security.txt" title="security.txt - Wikipedia">Wikipedia</a>)</p>
<p>The file is available in two locations <a href="https://blog.x-way.org/security.txt">/security.txt</a> (the classic location) and <a href="https://blog.x-way.org/.well-known/security.txt">/.well-known/security.txt</a> (the standard location following RFC8615).</p>
<p>To easily add the file on all my domains, I'm using the following nginx config snippet.</p>
<pre>location /security.txt {
add_header Content-Type 'text/plain';
add_header Cache-Control 'no-cache, no-store, must-revalidate';
add_header Pragma 'no-cache';
add_header Expires '0';
add_header Vary '*';
return 200 "Contact: mailto:andreas+security.txt@jaggi.info\nExpires: Tue, 19 Jan 2038 03:14:07 +0000\nEncryption: http://andreas-jaggi.ch/A3A54203.asc\n";
}
location /.well-known/security.txt {
add_header Content-Type 'text/plain';
add_header Cache-Control 'no-cache, no-store, must-revalidate';
add_header Pragma 'no-cache';
add_header Expires '0';
add_header Vary '*';
return 200 "Contact: mailto:andreas+security.txt@jaggi.info\nExpires: Tue, 19 Jan 2038 03:14:07 +0000\nEncryption: http://andreas-jaggi.ch/A3A54203.asc\n";
}</pre>
<p>This snippet is stored in a dedicated file (/etc/nginx/conf_includes/securitytxt) and is included in the various server config blocks like this:</p>
<pre>server {
server_name example.com;
include /etc/nginx/conf_includes/securitytxt;
location / {
# rest of website
}
}</pre>
]]></description>
<content:encoded><![CDATA[<p>This website now also serves a <a href="https://securitytxt.org/" title="security.txt: Proposed standard for defining security policies">security.txt</a> file which is a standardized way of making security contact information available. (<a href="https://en.wikipedia.org/wiki/Security.txt" title="security.txt - Wikipedia">Wikipedia</a>)</p>
<p>The file is available in two locations <a href="https://blog.x-way.org/security.txt">/security.txt</a> (the classic location) and <a href="https://blog.x-way.org/.well-known/security.txt">/.well-known/security.txt</a> (the standard location following RFC8615).</p>
<p>To easily add the file on all my domains, I'm using the following nginx config snippet.</p>
<pre>location /security.txt {
add_header Content-Type 'text/plain';
add_header Cache-Control 'no-cache, no-store, must-revalidate';
add_header Pragma 'no-cache';
add_header Expires '0';
add_header Vary '*';
return 200 "Contact: mailto:andreas+security.txt@jaggi.info\nExpires: Tue, 19 Jan 2038 03:14:07 +0000\nEncryption: http://andreas-jaggi.ch/A3A54203.asc\n";
}
location /.well-known/security.txt {
add_header Content-Type 'text/plain';
add_header Cache-Control 'no-cache, no-store, must-revalidate';
add_header Pragma 'no-cache';
add_header Expires '0';
add_header Vary '*';
return 200 "Contact: mailto:andreas+security.txt@jaggi.info\nExpires: Tue, 19 Jan 2038 03:14:07 +0000\nEncryption: http://andreas-jaggi.ch/A3A54203.asc\n";
}</pre>
<p>This snippet is stored in a dedicated file (/etc/nginx/conf_includes/securitytxt) and is included in the various server config blocks like this:</p>
<pre>server {
server_name example.com;
include /etc/nginx/conf_includes/securitytxt;
location / {
# rest of website
}
}</pre>
]]></content:encoded>
</item>
<item>
<title>Fixing 'snmpd[19784]: error on subcontainer 'ia_addr' insert (-1)' messages</title>
<link>https://blog.x-way.org/Linux/2021/02/13/Fixing-snmpd-error-on-subcontainer-ia-addr-insert-messages.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324284</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 13 Feb 2021 08:57:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>The default configuration of snmpd on Debian has debug level logging enabled and thus we end up with a constant flood of these messages in /var/log/syslog</p>
<pre>snmpd[19784]: error on subcontainer 'ia_addr' insert (-1)</pre>
<p>The fix is to lower the logging level, which can be accomplished like this on systems with systemd:</p>
<pre>cp /lib/systemd/system/snmpd.service /etc/systemd/system/snmpd.service
sed -i 's/Lsd/LS6d/' /etc/systemd/system/snmpd.service
systemctl daemon-reload
systemctl restart snmpd</pre>
<p>On systems without systemd, the logging level is set by the init script (unless explicitly configured in /etc/default/snmpd), and can be changed like this:</p>
<pre>sed -i 's/Lsd/LS6d/g' /etc/default/snmpd
sed -i 's/Lsd/LS6d/g' /etc/init.d/snmpd
service snmpd restart</pre>
]]></description>
<content:encoded><![CDATA[<p>The default configuration of snmpd on Debian has debug level logging enabled and thus we end up with a constant flood of these messages in /var/log/syslog</p>
<pre>snmpd[19784]: error on subcontainer 'ia_addr' insert (-1)</pre>
<p>The fix is to lower the logging level, which can be accomplished like this on systems with systemd:</p>
<pre>cp /lib/systemd/system/snmpd.service /etc/systemd/system/snmpd.service
sed -i 's/Lsd/LS6d/' /etc/systemd/system/snmpd.service
systemctl daemon-reload
systemctl restart snmpd</pre>
<p>On systems without systemd, the logging level is set by the init script (unless explicitly configured in /etc/default/snmpd), and can be changed like this:</p>
<pre>sed -i 's/Lsd/LS6d/g' /etc/default/snmpd
sed -i 's/Lsd/LS6d/g' /etc/init.d/snmpd
service snmpd restart</pre>
]]></content:encoded>
</item>
<item>
<title>Embracing the future with SolNet</title>
<link>https://blog.x-way.org/Networking/2021/02/04/Embracing-the-future-with-SolNet.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324285</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 04 Feb 2021 10:01:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>This was the initial state of my new <a href="https://www.solnet.ch/" title="SolNet - Internet & Solution Provider">SolNet</a> fibre connection:</p>
<p><img src="https://blog.x-way.org/images/solnet-ipv6-only.png" alt="SolNet connection with native IPv6 but no IPv4" width="487" height="61"></p>
<p>As I am a proponent of IPv6 this made me very happy, but unfortunately about 20% of my daily websites only offer <a href="https://blog.x-way.org/Networking/2013/07/05/Mandatory-requirement-for-all-non-IPv6-capable-products.html">legacy Internet</a> (which later on I got working as well).</p>
]]></description>
<content:encoded><![CDATA[<p>This was the initial state of my new <a href="https://www.solnet.ch/" title="SolNet - Internet & Solution Provider">SolNet</a> fibre connection:</p>
<p><img src="https://blog.x-way.org/images/solnet-ipv6-only.png" alt="SolNet connection with native IPv6 but no IPv4" width="487" height="61"></p>
<p>As I am a proponent of IPv6 this made me very happy, but unfortunately about 20% of my daily websites only offer <a href="https://blog.x-way.org/Networking/2013/07/05/Mandatory-requirement-for-all-non-IPv6-capable-products.html">legacy Internet</a> (which later on I got working as well).</p>
]]></content:encoded>
</item>
<item>
<title>Prozentrechnen ist schwer</title>
<link>https://blog.x-way.org/Misc/2021/02/04/Prozentrechnen-ist-schwer.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324286</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 04 Feb 2021 08:20:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://www.truewealth.ch/" title="True Wealth - Swiss Online Wealth Management">TrueWealth</a> hat's nicht so mit Prozentrechnen:</p>
<p><img src="https://blog.x-way.org/images/truewealth-prozentrechnen.png" title="6 + 33 + 3 + 12 + 47 = ?" alt="6 + 33 + 3 + 12 + 47 = ?" width="335" height="196"></p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://www.truewealth.ch/" title="True Wealth - Swiss Online Wealth Management">TrueWealth</a> hat's nicht so mit Prozentrechnen:</p>
<p><img src="https://blog.x-way.org/images/truewealth-prozentrechnen.png" title="6 + 33 + 3 + 12 + 47 = ?" alt="6 + 33 + 3 + 12 + 47 = ?" width="335" height="196"></p>
]]></content:encoded>
</item>
<item>
<title>Using your own router on a Sunrise fiber line</title>
<link>https://blog.x-way.org/Networking/2020/12/05/Using-your-own-router-on-a-Sunrise-fiber-line.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324283</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 05 Dec 2020 22:26:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>Sunrise does not like when people run their own router on a fiber line. While they do not directly forbid it, they don't provide any of the required configuration parameters which makes it quite hard to use your own router.</p>
<p>Below you'll find the required configuration parameters to make your own router connect with IPv4 and IPv6 on a Sunrise fiber line.<br>Beware though that especially the VLAN configuration might be different depending on your city, the following worked for me in Zürich.</p>
<p>Also, please note that I do not recommend Sunrise as Internet provider (as a matter of fact I'm on the way out of their contract and switching to <a href="https://www.solnet.ch/" title="SolNet">SolNet</a>).<br>Besides not supporting to bring your own router, they also like to make up additional early-termination fees (the contract states 100CHF early termination fees, but once you call them to initiate the process they tell you that it's gonna cost 300CHF as they decided to change their pricing structure unilaterally).</p>
<p>Enough of the ranting, now to the interesting part :-)</p>
<p>The Sunrise line has multiple VLANs to differentiate between Internet, Phone and TV services.<br>To receive an IPv4 address it requires a special value for the Client Identifier DHCP option.<br>For IPv6 <a href="https://en.wikipedia.org/wiki/IPv6_rapid_deployment" title="IPv6 rapid deployment">6rd</a> is employed, for which we need to know the prefix and gateway address.</p>
<p>The following configuration was tested with a <a href="https://mikrotik.com/" title="MikroTik Routers and Wireless">MikroTik</a> CRS125 router starting from the default settings.<br>For simplicity I've named the network interfaces according to their intended usage (eg. <code>LAN</code>, <code>sunrise</code> and <code>6rd</code>).</p>
<p>The first step is to configure the VLAN on top of your fiber interface. In my case it was VLAN ID 131, others were also successful with VLAN ID 10.</p>
<pre>/interface vlan add interface=sfp1-gateway name=sunrise vlan-id=131</pre>
<p>Next let's put in place some basic firewall rules to make sure we're not exposing our LAN to the Internet once the connection comes up.</p>
<pre>/ip firewall filter
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward in-interface=LAN out-interface=sunrise
add action=drop chain=forward
add action=accept chain=input connection-state=established,related
add action=accept chain=input protocol=icmp
add action=drop chain=input in-interface=!LAN</pre>
<pre>/ip firewall nat
add action=masquerade chain=srcnat out-interface=sunrise</pre>
<p>Now we can configure the special value for the Client Identifier DHCP option and configure the DHCP client on the VLAN interface.</p>
<pre>/ip dhcp-client option add code=61 name=clientid-sunrise value="'dslforum.org,Fast5360-sunrise'"</pre>
<pre>/ip dhcp-client add dhcp-options=clientid-sunrise disabled=no interface=sunrise</pre>
<p>This should now give us IPv4 Internet connectivity. We can test this by checking that we received an IPv4 address, have an IPv4 default route and that we can ping a host in the Internet.</p>
<pre>/ip dhcp-client print
Flags: X - disabled, I - invalid, D - dynamic
# INTERFACE USE-PEER-DNS ADD-DEFAULT-ROUTE STATUS ADDRESS
0 sunrise yes yes bound 198.51.100.123/25</pre>
<pre>/ip route check 1.1
status: ok
interface: sunrise
nexthop: 198.51.100.1</pre>
<pre>/ping count=1 1.1
SEQ HOST SIZE TTL TIME STATUS
0 1.0.0.1 56 59 1ms
sent=1 received=1 packet-loss=0% min-rtt=1ms avg-rtt=1ms max-rtt=1ms</pre>
<p>Sunrise doesn't offer native IPv6 connectivity but employs 6rd (which defines how to create a 6to4 tunnel based on the public IPv4 address, an IPv6 prefix and the tunnel gateway).</p>
<p>Before we setup the 6rd tunnel, it's important to put in place firewall rules for IPv6 as afterwards all devices on the local network will receive a public IPv6 address.</p>
<pre>/ipv6 firewall filter
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward in-interface=LAN
add action=drop chain=forward
add action=accept chain=input connection-state=established,related
add action=accept chain=input protocol=icmpv6
add action=drop chain=input</pre>
<p>To setup the 6rd tunnel, I've modified an existing script with the specific parameters for Sunrise (namely the <kbd>2001:1710::/28</kbd> prefix and the <kbd>212.161.209.1</kbd> tunnel gateway address).<br>The script creates the tunnel interface, configures an IPv6 address on the external interface, configures an IPv6 address on the internal interface (which also enables SLAAC to provide IPv6 addresses to the clients on the local network) and configures an IPv6 default route over the 6rd tunnel.</p>
<p>The script itself will be run via the scheduler, thus let's save it under the name <kbd>6rd-script</kbd>.</p>
<pre>
:global ipv6localinterface "LAN"
:global uplinkinterface "sunrise"
:global IPv4addr [/ip address get [find interface=$uplinkinterface] address];
:global IPv4addr [:pick $IPv4addr 0 [:find $IPv4addr "/"]]
:global IPv4addr2 [:pick $IPv4addr 0 30]
:global IPv6temp [:toip6 ("1::" . $IPv4addr2)]
:global IPv4hex1 [:pick $IPv6temp 3 4]
:global IPv4hex2 [:pick $IPv6temp 4 7]
:global IPv4hex3 [:pick $IPv6temp 8 9]
:global IPv4hex4 [:pick $IPv6temp 9 12]
:global IPv6addr [("2001:171" . $IPv4hex1 . ":". $IPv4hex2 .$IPv4hex3 . ":" . $IPv4hex4 . "0::1/64")]
:global IPv6addrLoc [("2001:171" . $IPv4hex1 . ":". $IPv4hex2 . $IPv4hex3 . ":" . $IPv4hex4 . "1::1/64")]
#6to4 interface
:global 6to4id [/interface 6to4 find where name="6rd"]
:if ($6to4id!="") do={
:global 6to4addr [/interface 6to4 get $6to4id local-address]
if ($6to4addr != $IPv4addr) do={ :log warning "Updating local-address for 6to4 tunnel '6rd' from '$6to4addr' to '$IPv4addr'."; /interface 6to4 set [find name="6rd"] local-address=$IPv4addr }
} else { :log warning "Creating 6to4 interface '6rd'. "; /interface 6to4 add !keepalive local-address=$IPv4addr mtu=1480 name="6rd" remote-address=212.161.209.1 }
#ipv6 for uplink
:global IPv6addrnumber [/ipv6 address find where comment="6rd" and interface="6rd"]
:if ($IPv6addrnumber!="") do={
:global oldip ([/ipv6 address get $IPv6addrnumber address])
if ($oldip != $IPv6addr) do={ :log warning "Updating 6rd IPv6 from '$oldip' to '$IPv6addr'."; /ipv6 address set number=$IPv6addrnumber address=$IPv6addr disabled=no }
} else {:log warning "Setting up 6rd IPv6 '$IPv6addr' to '6rd'. "; /ipv6 address add address=$IPv6addr interface="6rd" comment="6rd" advertise=no }
#ipv6 for local
:global IPv6addrnumberLocal [/ipv6 address find where comment=("6rd_local") and interface=$ipv6localinterface]
:if ($IPv6addrnumberLocal!="") do={
:global oldip ([/ipv6 address get $IPv6addrnumberLocal address])
if ($oldip != $IPv6addrLoc) do={ :log warning "Updating 6rd LOCAL IPv6 from '$oldip' to '$IPv6addrLoc'."; /ipv6 address set number=$IPv6addrnumberLocal address=$IPv6addrLoc disabled=no }
} else {:log warning "Setting up 6rd LOCAL IPv6 '$IPv6addrLoc' na '$ipv6localinterface'. "; /ipv6 address add address=$IPv6addrLoc interface=$ipv6localinterface comment="6rd_local" advertise=yes }
#ipv6 route
:global routa [/ipv6 route find where dst-address="2000::/3" and gateway="6rd"]
if ($routa="") do={ :log warning "Setting IPv6 route '2000::/3' pres '6rd'. "; /ipv6 route add distance=1 dst-address="2000::/3" gateway="6rd" }
</pre>
<p>Once we've added the script we also need to create the scheduler entry to run it periodically (as it needs to re-configure the tunnel and addresses whenever the public IPv4 address changes).</p>
<pre>/system scheduler add interval=1m name=schedule1 on-event=6rd-script</pre>
<p>After the first run of the script we should now have IPv6 connectivity. Let's test this again by checking that we have a public IPv6 address, an IPv6 default route and can ping an IPv6 host in the Internet.</p>
<pre>/ipv6 address print where interface=6rd and global
Flags: X - disabled, I - invalid, D - dynamic, G - global, L - link-local
# ADDRESS FROM-POOL INTERFACE ADVERTISE
0 G ;;; 6rd
2001:171c:6336:47b0::1/64 6rd no</pre>
<pre>/ipv6 route check 2600::
status: ok
interface: 6rd
nexthop: 2600::</pre>
<pre>/ping count=1 2600::
SEQ HOST SIZE TTL TIME STATUS
0 2600:: 56 50 118ms echo reply
sent=1 received=1 packet-loss=0% min-rtt=118ms avg-rtt=118ms max-rtt=118ms</pre>
<p>And that's how you can configure and validate IPv4 and IPv6 connectivity with your own router on a Sunrise fiber line despite them not liking it very much ;-)</p>
]]></description>
<content:encoded><![CDATA[<p>Sunrise does not like when people run their own router on a fiber line. While they do not directly forbid it, they don't provide any of the required configuration parameters which makes it quite hard to use your own router.</p>
<p>Below you'll find the required configuration parameters to make your own router connect with IPv4 and IPv6 on a Sunrise fiber line.<br>Beware though that especially the VLAN configuration might be different depending on your city, the following worked for me in Zürich.</p>
<p>Also, please note that I do not recommend Sunrise as Internet provider (as a matter of fact I'm on the way out of their contract and switching to <a href="https://www.solnet.ch/" title="SolNet">SolNet</a>).<br>Besides not supporting to bring your own router, they also like to make up additional early-termination fees (the contract states 100CHF early termination fees, but once you call them to initiate the process they tell you that it's gonna cost 300CHF as they decided to change their pricing structure unilaterally).</p>
<p>Enough of the ranting, now to the interesting part :-)</p>
<p>The Sunrise line has multiple VLANs to differentiate between Internet, Phone and TV services.<br>To receive an IPv4 address it requires a special value for the Client Identifier DHCP option.<br>For IPv6 <a href="https://en.wikipedia.org/wiki/IPv6_rapid_deployment" title="IPv6 rapid deployment">6rd</a> is employed, for which we need to know the prefix and gateway address.</p>
<p>The following configuration was tested with a <a href="https://mikrotik.com/" title="MikroTik Routers and Wireless">MikroTik</a> CRS125 router starting from the default settings.<br>For simplicity I've named the network interfaces according to their intended usage (eg. <code>LAN</code>, <code>sunrise</code> and <code>6rd</code>).</p>
<p>The first step is to configure the VLAN on top of your fiber interface. In my case it was VLAN ID 131, others were also successful with VLAN ID 10.</p>
<pre>/interface vlan add interface=sfp1-gateway name=sunrise vlan-id=131</pre>
<p>Next let's put in place some basic firewall rules to make sure we're not exposing our LAN to the Internet once the connection comes up.</p>
<pre>/ip firewall filter
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward in-interface=LAN out-interface=sunrise
add action=drop chain=forward
add action=accept chain=input connection-state=established,related
add action=accept chain=input protocol=icmp
add action=drop chain=input in-interface=!LAN</pre>
<pre>/ip firewall nat
add action=masquerade chain=srcnat out-interface=sunrise</pre>
<p>Now we can configure the special value for the Client Identifier DHCP option and configure the DHCP client on the VLAN interface.</p>
<pre>/ip dhcp-client option add code=61 name=clientid-sunrise value="'dslforum.org,Fast5360-sunrise'"</pre>
<pre>/ip dhcp-client add dhcp-options=clientid-sunrise disabled=no interface=sunrise</pre>
<p>This should now give us IPv4 Internet connectivity. We can test this by checking that we received an IPv4 address, have an IPv4 default route and that we can ping a host in the Internet.</p>
<pre>/ip dhcp-client print
Flags: X - disabled, I - invalid, D - dynamic
# INTERFACE USE-PEER-DNS ADD-DEFAULT-ROUTE STATUS ADDRESS
0 sunrise yes yes bound 198.51.100.123/25</pre>
<pre>/ip route check 1.1
status: ok
interface: sunrise
nexthop: 198.51.100.1</pre>
<pre>/ping count=1 1.1
SEQ HOST SIZE TTL TIME STATUS
0 1.0.0.1 56 59 1ms
sent=1 received=1 packet-loss=0% min-rtt=1ms avg-rtt=1ms max-rtt=1ms</pre>
<p>Sunrise doesn't offer native IPv6 connectivity but employs 6rd (which defines how to create a 6to4 tunnel based on the public IPv4 address, an IPv6 prefix and the tunnel gateway).</p>
<p>Before we setup the 6rd tunnel, it's important to put in place firewall rules for IPv6 as afterwards all devices on the local network will receive a public IPv6 address.</p>
<pre>/ipv6 firewall filter
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward in-interface=LAN
add action=drop chain=forward
add action=accept chain=input connection-state=established,related
add action=accept chain=input protocol=icmpv6
add action=drop chain=input</pre>
<p>To setup the 6rd tunnel, I've modified an existing script with the specific parameters for Sunrise (namely the <kbd>2001:1710::/28</kbd> prefix and the <kbd>212.161.209.1</kbd> tunnel gateway address).<br>The script creates the tunnel interface, configures an IPv6 address on the external interface, configures an IPv6 address on the internal interface (which also enables SLAAC to provide IPv6 addresses to the clients on the local network) and configures an IPv6 default route over the 6rd tunnel.</p>
<p>The script itself will be run via the scheduler, thus let's save it under the name <kbd>6rd-script</kbd>.</p>
<pre>
:global ipv6localinterface "LAN"
:global uplinkinterface "sunrise"
:global IPv4addr [/ip address get [find interface=$uplinkinterface] address];
:global IPv4addr [:pick $IPv4addr 0 [:find $IPv4addr "/"]]
:global IPv4addr2 [:pick $IPv4addr 0 30]
:global IPv6temp [:toip6 ("1::" . $IPv4addr2)]
:global IPv4hex1 [:pick $IPv6temp 3 4]
:global IPv4hex2 [:pick $IPv6temp 4 7]
:global IPv4hex3 [:pick $IPv6temp 8 9]
:global IPv4hex4 [:pick $IPv6temp 9 12]
:global IPv6addr [("2001:171" . $IPv4hex1 . ":". $IPv4hex2 .$IPv4hex3 . ":" . $IPv4hex4 . "0::1/64")]
:global IPv6addrLoc [("2001:171" . $IPv4hex1 . ":". $IPv4hex2 . $IPv4hex3 . ":" . $IPv4hex4 . "1::1/64")]
#6to4 interface
:global 6to4id [/interface 6to4 find where name="6rd"]
:if ($6to4id!="") do={
:global 6to4addr [/interface 6to4 get $6to4id local-address]
if ($6to4addr != $IPv4addr) do={ :log warning "Updating local-address for 6to4 tunnel '6rd' from '$6to4addr' to '$IPv4addr'."; /interface 6to4 set [find name="6rd"] local-address=$IPv4addr }
} else { :log warning "Creating 6to4 interface '6rd'. "; /interface 6to4 add !keepalive local-address=$IPv4addr mtu=1480 name="6rd" remote-address=212.161.209.1 }
#ipv6 for uplink
:global IPv6addrnumber [/ipv6 address find where comment="6rd" and interface="6rd"]
:if ($IPv6addrnumber!="") do={
:global oldip ([/ipv6 address get $IPv6addrnumber address])
if ($oldip != $IPv6addr) do={ :log warning "Updating 6rd IPv6 from '$oldip' to '$IPv6addr'."; /ipv6 address set number=$IPv6addrnumber address=$IPv6addr disabled=no }
} else {:log warning "Setting up 6rd IPv6 '$IPv6addr' to '6rd'. "; /ipv6 address add address=$IPv6addr interface="6rd" comment="6rd" advertise=no }
#ipv6 for local
:global IPv6addrnumberLocal [/ipv6 address find where comment=("6rd_local") and interface=$ipv6localinterface]
:if ($IPv6addrnumberLocal!="") do={
:global oldip ([/ipv6 address get $IPv6addrnumberLocal address])
if ($oldip != $IPv6addrLoc) do={ :log warning "Updating 6rd LOCAL IPv6 from '$oldip' to '$IPv6addrLoc'."; /ipv6 address set number=$IPv6addrnumberLocal address=$IPv6addrLoc disabled=no }
} else {:log warning "Setting up 6rd LOCAL IPv6 '$IPv6addrLoc' na '$ipv6localinterface'. "; /ipv6 address add address=$IPv6addrLoc interface=$ipv6localinterface comment="6rd_local" advertise=yes }
#ipv6 route
:global routa [/ipv6 route find where dst-address="2000::/3" and gateway="6rd"]
if ($routa="") do={ :log warning "Setting IPv6 route '2000::/3' pres '6rd'. "; /ipv6 route add distance=1 dst-address="2000::/3" gateway="6rd" }
</pre>
<p>Once we've added the script we also need to create the scheduler entry to run it periodically (as it needs to re-configure the tunnel and addresses whenever the public IPv4 address changes).</p>
<pre>/system scheduler add interval=1m name=schedule1 on-event=6rd-script</pre>
<p>After the first run of the script we should now have IPv6 connectivity. Let's test this again by checking that we have a public IPv6 address, an IPv6 default route and can ping an IPv6 host in the Internet.</p>
<pre>/ipv6 address print where interface=6rd and global
Flags: X - disabled, I - invalid, D - dynamic, G - global, L - link-local
# ADDRESS FROM-POOL INTERFACE ADVERTISE
0 G ;;; 6rd
2001:171c:6336:47b0::1/64 6rd no</pre>
<pre>/ipv6 route check 2600::
status: ok
interface: 6rd
nexthop: 2600::</pre>
<pre>/ping count=1 2600::
SEQ HOST SIZE TTL TIME STATUS
0 2600:: 56 50 118ms echo reply
sent=1 received=1 packet-loss=0% min-rtt=118ms avg-rtt=118ms max-rtt=118ms</pre>
<p>And that's how you can configure and validate IPv4 and IPv6 connectivity with your own router on a Sunrise fiber line despite them not liking it very much ;-)</p>
]]></content:encoded>
</item>
<item>
<title>MTA-STS</title>
<link>https://blog.x-way.org/Networking/2020/11/21/MTA-STS.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324282</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 21 Nov 2020 09:47:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>Recently I added <a href="https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol#SMTP_MTA_Strict_Transport_Security" title="SMTP MTA Strict-Transport-Security">MTA-STS</a> support to one of my domains, and it turns out that this was easier than expected.</p>
<p>MTA-STS is used to tell mail senders that your server supports TLS. And then you can define the policy for your server and tell them that they should only use TLS (resp. STARTTLS) when connecting to you and not fall back to unencrypted SMTP.</p>
<p>The way this works is with two components:</p>
<ul>
<li>a special <code>_mta-sts.<your-site.com></code> TXT DNS entry indicating that your domain supports MTA-STS and the version number of your MTA-STS policy</li>
<li>a mta-sts.txt file served under a specific well-known URL <code>https://mta-sts.<your-site.com>/.well-known/mta-sts.txt</code> containing your MTA-STS policy (which mx hosts it is valid for, should it be run in enforcing or testing mode, max-age etc.)</li>
</ul>
<p>The idea is that a mail sender checks your MTA-STS policy through protected channels (DNSSEC, HTTPS) and then never sends mails to you in plaintext (similar approach as <a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security" title="HTTP Strict Transport Security">HSTS</a> for HTTP but this time between mail servers).</p>
<p>To setup the MTA-STS configuration, I followed this <a href="https://www.naut.ca/blog/2020/04/07/mta-sts-in-5-minutes/" title="Enable MTA-STS in 5 Minutes with NGINX">Enable MTA-STS in 5 Minutes with NGINX</a> guide from <a href="https://www.naut.ca/" title="Home - Yoonsik Park">Yoonsik Park</a>.</p>
<p>Then to check my configuration I used this <a href="https://aykevl.nl/apps/mta-sts/" title="MTA-STS validator">MTA-STS validator</a> (which is an opensource project available on <a href="https://github.com/aykevl/mta-sts" title="GitHub - aykevl/mta-sts: Online tool for MTA-STS checking: https://aykevl.nl/apps/mta-sts/">GitHub</a>), the classic <a href="https://www.checktls.com/TestReceiver" title="//email/testTo:">checktls.com //email/testTo: tool</a> (MTA-STS checking needs to be explicitly enabled under 'More Options') and the free testing service provided by <a href="https://www.hardenize.com/" title="Harenize: Comprehensive web site configuration test">Hardenize</a>.</p>
]]></description>
<content:encoded><![CDATA[<p>Recently I added <a href="https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol#SMTP_MTA_Strict_Transport_Security" title="SMTP MTA Strict-Transport-Security">MTA-STS</a> support to one of my domains, and it turns out that this was easier than expected.</p>
<p>MTA-STS is used to tell mail senders that your server supports TLS. And then you can define the policy for your server and tell them that they should only use TLS (resp. STARTTLS) when connecting to you and not fall back to unencrypted SMTP.</p>
<p>The way this works is with two components:</p>
<ul>
<li>a special <code>_mta-sts.<your-site.com></code> TXT DNS entry indicating that your domain supports MTA-STS and the version number of your MTA-STS policy</li>
<li>a mta-sts.txt file served under a specific well-known URL <code>https://mta-sts.<your-site.com>/.well-known/mta-sts.txt</code> containing your MTA-STS policy (which mx hosts it is valid for, should it be run in enforcing or testing mode, max-age etc.)</li>
</ul>
<p>The idea is that a mail sender checks your MTA-STS policy through protected channels (DNSSEC, HTTPS) and then never sends mails to you in plaintext (similar approach as <a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security" title="HTTP Strict Transport Security">HSTS</a> for HTTP but this time between mail servers).</p>
<p>To setup the MTA-STS configuration, I followed this <a href="https://www.naut.ca/blog/2020/04/07/mta-sts-in-5-minutes/" title="Enable MTA-STS in 5 Minutes with NGINX">Enable MTA-STS in 5 Minutes with NGINX</a> guide from <a href="https://www.naut.ca/" title="Home - Yoonsik Park">Yoonsik Park</a>.</p>
<p>Then to check my configuration I used this <a href="https://aykevl.nl/apps/mta-sts/" title="MTA-STS validator">MTA-STS validator</a> (which is an opensource project available on <a href="https://github.com/aykevl/mta-sts" title="GitHub - aykevl/mta-sts: Online tool for MTA-STS checking: https://aykevl.nl/apps/mta-sts/">GitHub</a>), the classic <a href="https://www.checktls.com/TestReceiver" title="//email/testTo:">checktls.com //email/testTo: tool</a> (MTA-STS checking needs to be explicitly enabled under 'More Options') and the free testing service provided by <a href="https://www.hardenize.com/" title="Harenize: Comprehensive web site configuration test">Hardenize</a>.</p>
]]></content:encoded>
</item>
<item>
<title>15 years of o5</title>
<link>https://blog.x-way.org/Webdesign/2020/11/01/15-years-of-o5.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324281</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 01 Nov 2020 19:03:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Webdesign/">Webdesign</category>
<description><![CDATA[<p><a href="https://blog.x-way.org/Webdesign/2005/11/01/CSS-Reboot-Fall-2005.html" title="x-log - CSS Reboot Fall 2005">15 years ago</a> this weblog received the current o5 design (or theme as it would be called nowadays).<br>
During this time the design has aged quite well and also survived <a href="https://blog.x-way.org/Misc/2011/11/26/Online-Again.html" title="x-log - Online Again">the move</a> of the backend from a self-written PHP blog-engine to Jekyll.</p>
<p>Although it still works surprisingly well and presents the content nicely every day, there are some parts where better usage of contemporary technologies would be desirable.<br>It has no mobile version nor a responsive layout as the design was created before the now omnipresent smartphones were invented. Similar is the font-size hardcoded and not very adequate for todays retina displays. And yes, it uses the XHTML 1.0 strict standard with all its quirks and CSS tricks from 2002 (which luckily are still supported in current browsers).</p>
<p>Overall I'm quite happy that the o5 design has turned out to be so timeless and that I did not have to come up with a new one every other year (btw: I don't remember where the o5 name came from, likely the 5 is a reference to 2005 when it was created).</p>
<p>With the current Corona situation forcing me to spend more time at home again, I have the feeling that some things might change around the weblog (not quite sure what or when exactly, first I need to re-learn how websites are built in 2020 :-).</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://blog.x-way.org/Webdesign/2005/11/01/CSS-Reboot-Fall-2005.html" title="x-log - CSS Reboot Fall 2005">15 years ago</a> this weblog received the current o5 design (or theme as it would be called nowadays).<br>
During this time the design has aged quite well and also survived <a href="https://blog.x-way.org/Misc/2011/11/26/Online-Again.html" title="x-log - Online Again">the move</a> of the backend from a self-written PHP blog-engine to Jekyll.</p>
<p>Although it still works surprisingly well and presents the content nicely every day, there are some parts where better usage of contemporary technologies would be desirable.<br>It has no mobile version nor a responsive layout as the design was created before the now omnipresent smartphones were invented. Similar is the font-size hardcoded and not very adequate for todays retina displays. And yes, it uses the XHTML 1.0 strict standard with all its quirks and CSS tricks from 2002 (which luckily are still supported in current browsers).</p>
<p>Overall I'm quite happy that the o5 design has turned out to be so timeless and that I did not have to come up with a new one every other year (btw: I don't remember where the o5 name came from, likely the 5 is a reference to 2005 when it was created).</p>
<p>With the current Corona situation forcing me to spend more time at home again, I have the feeling that some things might change around the weblog (not quite sure what or when exactly, first I need to re-learn how websites are built in 2020 :-).</p>
]]></content:encoded>
</item>
<item>
<title>NAT Slipstreaming (NAT traversal part 2)</title>
<link>https://blog.x-way.org/Networking/2020/10/31/NAT-Slipstreaming.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324280</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 31 Oct 2020 22:55:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>Compared to the <a href="https://blog.x-way.org/Networking/2020/08/23/How-NAT-traversal-works.html" title="x-log - How NAT traversal works">previous post</a> where intentional NAT traversal was discussed, here now comes an article about 'unintentional' (malicious) NAT traversal.</p>
<p><a href="https://samy.pl/" title="Samy Kamar">Samy Kamar</a> describes in his <a href="https://samy.pl/slipstream/" title="Samy Kamar - NAT Slipstreaming">NAT Slipstreaming article</a> how a combination of TCP packet segmentation and smuggling SIP requests in HTTP, can be used to trick the NAT <abbr title="Application Layer Gateway">ALG</abbr> of your router into opening arbitrary ports for inbound connections from the Internet to your computer.</p>
<p>The article analyses in detail the SIP ALG of the Linux netfilter stack in it's default configuration, but likely similar attacks could also be possible with ALGs of other protocols and vendors.</p>
<p>Important to note: the Linux SIP ALG module has two parameters (sip_direct_media and sip_direct_signalling), which restrict the IP address for which additional ports are opened to the one sending the original SIP packet. By default they are set to 1, but if any of these is set to 0 in a router's configuration, the described NAT Slipstreaming attack will not only allow to make inbound connections to your computer, but also to any other device in the local network!</p>
]]></description>
<content:encoded><![CDATA[<p>Compared to the <a href="https://blog.x-way.org/Networking/2020/08/23/How-NAT-traversal-works.html" title="x-log - How NAT traversal works">previous post</a> where intentional NAT traversal was discussed, here now comes an article about 'unintentional' (malicious) NAT traversal.</p>
<p><a href="https://samy.pl/" title="Samy Kamar">Samy Kamar</a> describes in his <a href="https://samy.pl/slipstream/" title="Samy Kamar - NAT Slipstreaming">NAT Slipstreaming article</a> how a combination of TCP packet segmentation and smuggling SIP requests in HTTP, can be used to trick the NAT <abbr title="Application Layer Gateway">ALG</abbr> of your router into opening arbitrary ports for inbound connections from the Internet to your computer.</p>
<p>The article analyses in detail the SIP ALG of the Linux netfilter stack in it's default configuration, but likely similar attacks could also be possible with ALGs of other protocols and vendors.</p>
<p>Important to note: the Linux SIP ALG module has two parameters (sip_direct_media and sip_direct_signalling), which restrict the IP address for which additional ports are opened to the one sending the original SIP packet. By default they are set to 1, but if any of these is set to 0 in a router's configuration, the described NAT Slipstreaming attack will not only allow to make inbound connections to your computer, but also to any other device in the local network!</p>
]]></content:encoded>
</item>
<item>
<title>How NAT traversal works</title>
<link>https://blog.x-way.org/Networking/2020/08/23/How-NAT-traversal-works.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324279</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 23 Aug 2020 21:08:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p><a href="https://tailscale.com/blog/how-nat-traversal-works/" title="How NAT traversal works - Tailscale Blog">How NAT traversal works</a> – is a very well written and detailed article from <a href="https://www.dave.tf/" title="Dave.tf">Dave Anderson</a> explaining the different NAT scenarios and the tricks that can be used to establish a peer-to-peer UDP connection between machines sitting behind them.</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://tailscale.com/blog/how-nat-traversal-works/" title="How NAT traversal works - Tailscale Blog">How NAT traversal works</a> – is a very well written and detailed article from <a href="https://www.dave.tf/" title="Dave.tf">Dave Anderson</a> explaining the different NAT scenarios and the tricks that can be used to establish a peer-to-peer UDP connection between machines sitting behind them.</p>
]]></content:encoded>
</item>
<item>
<title>Replace the root disk</title>
<link>https://blog.x-way.org/Linux/2020/06/07/Replace-the-root-disk.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324278</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 07 Jun 2020 10:58:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>Recently the disk holding the root (<kbd>/</kbd>) filesystem on one of my linux systems started to report increased <a href="https://en.wikipedia.org/wiki/S.M.A.R.T." title="S.M.A.R.T - Wikipedia">SMART</a> raw read error rates, seek error rates and ECC recovered hardware errors.</p>
<p>As these are early indications of a failing disk, it became time to replace the disk.</p>
<p>Normally replacing a disk comes down to plugging in the new one, coyping over the data, umount the old disk, mount the new one in place, unplug the old disk.<br>But when it is the disk with the root filesystem a couple extra steps are needed.</p>
<p>The steps below worked for my Debian system without problems (even used the opportunity to upgrade to an SSD :-)</p>
<p>(source is <a href="https://unix.stackexchange.com/questions/338387/how-do-i-replace-root-drive-on-debian" title="How do I replace Root Drive on Debian?">this thread</a> on StackExchange)</p>
<blockquote>
<p>The following makes some assumptions:</p>
<ul>
<li>All commands ran as root when possible</li>
<li>You are on a physical console to the host (need to type in grub commands to boot up the new disk!)</li>
<li>You want an ext4 files system</li>
<li>You are loosely familiar on a basic level with all commands run</li>
<li>You are NOT booting from a RAID device</li>
</ul>
<p>So here we go.</p>
<ol>
<li>Physically install new disk into computer and connect to available port leaving old disk in existing position.</li>
<li>Boot computer into old OS.</li>
<li>Prepare and mount new disk; first identify new disk<br>
<kbd>fdisk -l</kbd>
</li>
<li>Partition new disk<br>
<kbd>fdisk /dev/(newdisk)</kbd><br>
Make partition primary partition with type "83" file system type.
</li>
<li>Create filesystem<br>
<kbd>mkfs.ext4 /dev/(newpartition)</kbd>
</li>
<li>Mount new filesystem<br>
<kbd>mkdir /mnt/(newpartitionmountpoint)</kbd><br>
<kbd>mount /dev/(newpartition) /mnt/(newpartitionmountpoint)</kbd>
</li>
<li>Copy disk:<br>
<kbd>/sbin/init 1</kbd> (drop to single user mode)<br>
<kbd>rsync -avxHAX / /mnt/(newpartitionmountpoint)</kbd>
</li>
<li>Update FSTAB on newdisk<br>
<kbd>blkid</kbd> (note UUID of new partition)<br>
<kbd>vi /mnt/(newpartitionmountpoint)/etc/fstab</kbd><br>
Replace existing UUID of / in FSTAB to new disk UUID
</li>
<li>Configure grub and install to new disk boot loader:<br>
<kbd>grub-mkconfig</kbd><br>
<kbd>update-grub</kbd><br>
<kbd>grub-install /dev/(newdisk)</kbd>
</li>
<li>Copy grub.cfg from old disk to new<br>
<kbd>cp -ax /boot/grub/grub.cfg /mnt/(newpartitionmountpoint)/boot/grub/grub.cfg</kbd>
</li>
<li>Open grub.cfg on new disk and replace all UUIDs with new disk<br>
<kbd>vi /mnt/(newpartitionmountpoint)/boot/grub/grub.cfg</kbd><br>
Replace all old UUIDs with the UUID of the new disk
</li>
<li>Shut down computer<br>
<kbd>shutdown</kbd>
</li>
<li>Physically move the new drive to the 1st drive location and remove old drive</li>
<li>Start computer and grub should present:<br>
<pre>error: no such device: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
GRUB rescue></pre>
</li>
<li>Manually boot new OS from grub; first identify the drive and partition of the boot files<br>
<kbd>ls</kbd> [to identify your drive and partition options]<br>
<kbd>ls (hdx,p)/</kbd> [to identify which partition has the /boot folder]
</li>
<li>Then, you can load the boot menu manually from the drive and partition you found above. Typically this would be (hd0,msdos1).<br>
<kbd>set prefix="(hdx,p)/boot/grub"</kbd><br>
<kbd>set root="(hdx,p)"</kbd><br>
<kbd>insmod normal</kbd><br>
<kbd>normal</kbd>
</li>
<li>Login to OS on new drive</li>
<li>Configure grub again<br>
<kbd>fdisk -l</kbd> (note dev of newdisk)<br>
<kbd>grub-mkconfig</kbd><br>
<kbd>update-grub</kbd><br>
<kbd>grub-install /dev/newdisk</kbd>
</li>
</ol>
<p>And that should be it!</p>
</blockquote>
]]></description>
<content:encoded><![CDATA[<p>Recently the disk holding the root (<kbd>/</kbd>) filesystem on one of my linux systems started to report increased <a href="https://en.wikipedia.org/wiki/S.M.A.R.T." title="S.M.A.R.T - Wikipedia">SMART</a> raw read error rates, seek error rates and ECC recovered hardware errors.</p>
<p>As these are early indications of a failing disk, it became time to replace the disk.</p>
<p>Normally replacing a disk comes down to plugging in the new one, coyping over the data, umount the old disk, mount the new one in place, unplug the old disk.<br>But when it is the disk with the root filesystem a couple extra steps are needed.</p>
<p>The steps below worked for my Debian system without problems (even used the opportunity to upgrade to an SSD :-)</p>
<p>(source is <a href="https://unix.stackexchange.com/questions/338387/how-do-i-replace-root-drive-on-debian" title="How do I replace Root Drive on Debian?">this thread</a> on StackExchange)</p>
<blockquote>
<p>The following makes some assumptions:</p>
<ul>
<li>All commands ran as root when possible</li>
<li>You are on a physical console to the host (need to type in grub commands to boot up the new disk!)</li>
<li>You want an ext4 files system</li>
<li>You are loosely familiar on a basic level with all commands run</li>
<li>You are NOT booting from a RAID device</li>
</ul>
<p>So here we go.</p>
<ol>
<li>Physically install new disk into computer and connect to available port leaving old disk in existing position.</li>
<li>Boot computer into old OS.</li>
<li>Prepare and mount new disk; first identify new disk<br>
<kbd>fdisk -l</kbd>
</li>
<li>Partition new disk<br>
<kbd>fdisk /dev/(newdisk)</kbd><br>
Make partition primary partition with type "83" file system type.
</li>
<li>Create filesystem<br>
<kbd>mkfs.ext4 /dev/(newpartition)</kbd>
</li>
<li>Mount new filesystem<br>
<kbd>mkdir /mnt/(newpartitionmountpoint)</kbd><br>
<kbd>mount /dev/(newpartition) /mnt/(newpartitionmountpoint)</kbd>
</li>
<li>Copy disk:<br>
<kbd>/sbin/init 1</kbd> (drop to single user mode)<br>
<kbd>rsync -avxHAX / /mnt/(newpartitionmountpoint)</kbd>
</li>
<li>Update FSTAB on newdisk<br>
<kbd>blkid</kbd> (note UUID of new partition)<br>
<kbd>vi /mnt/(newpartitionmountpoint)/etc/fstab</kbd><br>
Replace existing UUID of / in FSTAB to new disk UUID
</li>
<li>Configure grub and install to new disk boot loader:<br>
<kbd>grub-mkconfig</kbd><br>
<kbd>update-grub</kbd><br>
<kbd>grub-install /dev/(newdisk)</kbd>
</li>
<li>Copy grub.cfg from old disk to new<br>
<kbd>cp -ax /boot/grub/grub.cfg /mnt/(newpartitionmountpoint)/boot/grub/grub.cfg</kbd>
</li>
<li>Open grub.cfg on new disk and replace all UUIDs with new disk<br>
<kbd>vi /mnt/(newpartitionmountpoint)/boot/grub/grub.cfg</kbd><br>
Replace all old UUIDs with the UUID of the new disk
</li>
<li>Shut down computer<br>
<kbd>shutdown</kbd>
</li>
<li>Physically move the new drive to the 1st drive location and remove old drive</li>
<li>Start computer and grub should present:<br>
<pre>error: no such device: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
GRUB rescue></pre>
</li>
<li>Manually boot new OS from grub; first identify the drive and partition of the boot files<br>
<kbd>ls</kbd> [to identify your drive and partition options]<br>
<kbd>ls (hdx,p)/</kbd> [to identify which partition has the /boot folder]
</li>
<li>Then, you can load the boot menu manually from the drive and partition you found above. Typically this would be (hd0,msdos1).<br>
<kbd>set prefix="(hdx,p)/boot/grub"</kbd><br>
<kbd>set root="(hdx,p)"</kbd><br>
<kbd>insmod normal</kbd><br>
<kbd>normal</kbd>
</li>
<li>Login to OS on new drive</li>
<li>Configure grub again<br>
<kbd>fdisk -l</kbd> (note dev of newdisk)<br>
<kbd>grub-mkconfig</kbd><br>
<kbd>update-grub</kbd><br>
<kbd>grub-install /dev/newdisk</kbd>
</li>
</ol>
<p>And that should be it!</p>
</blockquote>
]]></content:encoded>
</item>
<item>
<title>rkhunter CRLF confusion</title>
<link>https://blog.x-way.org/Linux/2020/05/24/rkhunter-CRLF-confusion.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324277</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 24 May 2020 11:22:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>On my Linux hosts I'm running <a href="http://rkhunter.sourceforge.net/" title="The Rootkit Hunter project">rkhunter</a>. On a newly configured host it lately reported the following warning:</p>
<pre>Warning: The SSH and rkhunter configuration options should be the same:
SSH configuration option 'PermitRootLogin': no
Rkhunter configuration option 'ALLOW_SSH_ROOT_USER': no</pre>
<p>On first sight the warning does not seem to make much sense, as both configuration options seem to be set to the same value (<code>no</code>).<br>
But digging further reveals that they are stored slightly different:</p>
<pre># file /etc/rkhunter.conf
/etc/rkhunter.conf: ASCII text
# file /etc/ssh/sshd_config
/etc/ssh/sshd_config: ASCII text, with CRLF line terminators</pre>
<p>Turns out that rkhunter is also checking the line terminators as part of the configuration values, and warns because they are different.</p>
<p>Knowing this, the fix is simple: run <a href="http://dos2unix.sourceforge.net/" title="dos2unix">dos2unix</a> on the CRLF file</p>
]]></description>
<content:encoded><![CDATA[<p>On my Linux hosts I'm running <a href="http://rkhunter.sourceforge.net/" title="The Rootkit Hunter project">rkhunter</a>. On a newly configured host it lately reported the following warning:</p>
<pre>Warning: The SSH and rkhunter configuration options should be the same:
SSH configuration option 'PermitRootLogin': no
Rkhunter configuration option 'ALLOW_SSH_ROOT_USER': no</pre>
<p>On first sight the warning does not seem to make much sense, as both configuration options seem to be set to the same value (<code>no</code>).<br>
But digging further reveals that they are stored slightly different:</p>
<pre># file /etc/rkhunter.conf
/etc/rkhunter.conf: ASCII text
# file /etc/ssh/sshd_config
/etc/ssh/sshd_config: ASCII text, with CRLF line terminators</pre>
<p>Turns out that rkhunter is also checking the line terminators as part of the configuration values, and warns because they are different.</p>
<p>Knowing this, the fix is simple: run <a href="http://dos2unix.sourceforge.net/" title="dos2unix">dos2unix</a> on the CRLF file</p>
]]></content:encoded>
</item>
<item>
<title>ipaddr CLI tool</title>
<link>https://blog.x-way.org/Networking/2020/05/21/ipaddr-CLI-tool.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324276</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Thu, 21 May 2020 19:38:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>While doing some maintenance on my server, I got tired of searching through the output of <code>ip addr show</code> to find the IP addresses configured on the interfaces.<br>
Thus I wrote a simple CLI tool to display the information I needed in a concise and human friendly form: <a href="https://github.com/x-way/ipaddr" title="ipaddr - human friendly list of IP addresses and network interfaces">ipaddr</a></p>
<pre>$ ipaddr
lo 127.0.0.1/8
ens5 198.51.100.160/24
tun24008 10.123.199.78/32
tun71991639 10.200.123.5/32
tun26724 10.100.100.235/32
tun3883710 10.123.111.7/32</pre>
<p>A nice side-effect of writing this in <a href="https://golang.org/" title="The Go Programming Language">Go</a> is that it works out-of-the-box also on non-Linux systems :-)</p>
]]></description>
<content:encoded><![CDATA[<p>While doing some maintenance on my server, I got tired of searching through the output of <code>ip addr show</code> to find the IP addresses configured on the interfaces.<br>
Thus I wrote a simple CLI tool to display the information I needed in a concise and human friendly form: <a href="https://github.com/x-way/ipaddr" title="ipaddr - human friendly list of IP addresses and network interfaces">ipaddr</a></p>
<pre>$ ipaddr
lo 127.0.0.1/8
ens5 198.51.100.160/24
tun24008 10.123.199.78/32
tun71991639 10.200.123.5/32
tun26724 10.100.100.235/32
tun3883710 10.123.111.7/32</pre>
<p>A nice side-effect of writing this in <a href="https://golang.org/" title="The Go Programming Language">Go</a> is that it works out-of-the-box also on non-Linux systems :-)</p>
]]></content:encoded>
</item>
<item>
<title>Poor man's reboot notification</title>
<link>https://blog.x-way.org/Linux/2020/04/18/Poor-mans-reboot-notification.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324275</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 18 Apr 2020 15:03:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Linux/">Linux</category>
<description><![CDATA[<p>Sometimes you need to be notified about reboots of a machine without having the luxury of a proper monitoring system.</p>
<p>The following crontab entry triggers an e-mail when the host has been rebooted in the last 5 minutes.</p>
<pre>*/5 * * * * [ $(sed -e 's/\..*//' /proc/uptime) -lt 540 ] && echo "Host has been rebooted! Uptime: $(uptime)"</pre>
]]></description>
<content:encoded><![CDATA[<p>Sometimes you need to be notified about reboots of a machine without having the luxury of a proper monitoring system.</p>
<p>The following crontab entry triggers an e-mail when the host has been rebooted in the last 5 minutes.</p>
<pre>*/5 * * * * [ $(sed -e 's/\..*//' /proc/uptime) -lt 540 ] && echo "Host has been rebooted! Uptime: $(uptime)"</pre>
]]></content:encoded>
</item>
<item>
<title>Cottage cheese Avocado Crostini</title>
<link>https://blog.x-way.org/Food/2020/04/12/Cottage-cheese-Avocado-Crostini.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324274</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 12 Apr 2020 19:16:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Food/">Food</category>
<description><![CDATA[<p>Inspired by <a href="https://fooby.ch/de/rezepte/17073/avocado-ricotta-crostini" title="Avocado-Ricotta-Crostini - Rezepte | fooby.ch">this recipe</a>, I made some yummy Crostini using Cottage cheese (instead of Ricotta cheese) and Avocado with some drops of Aceto balsamico.</p>
<p><img src="https://blog.x-way.org/images/cottage_cheese_avocado_crostini.jpeg" alt="Cottage cheese Avocado Crostini" width="439" height="329"></p>
]]></description>
<content:encoded><![CDATA[<p>Inspired by <a href="https://fooby.ch/de/rezepte/17073/avocado-ricotta-crostini" title="Avocado-Ricotta-Crostini - Rezepte | fooby.ch">this recipe</a>, I made some yummy Crostini using Cottage cheese (instead of Ricotta cheese) and Avocado with some drops of Aceto balsamico.</p>
<p><img src="https://blog.x-way.org/images/cottage_cheese_avocado_crostini.jpeg" alt="Cottage cheese Avocado Crostini" width="439" height="329"></p>
]]></content:encoded>
</item>
<item>
<title>Ein Lied für Jetzt</title>
<link>https://blog.x-way.org/Music/2020/03/28/Ein-Lied-fur-Jetzt.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324273</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 28 Mar 2020 08:53:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p><a href="https://youtu.be/t_s6waEUTbI" title="die ärzte - Ein Lied für Jetzt - YouTube">die ärzte - Ein Lied für Jetzt</a></p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://youtu.be/t_s6waEUTbI" title="die ärzte - Ein Lied für Jetzt - YouTube">die ärzte - Ein Lied für Jetzt</a></p>
]]></content:encoded>
</item>
<item>
<title>ip_compact and ip_diff</title>
<link>https://blog.x-way.org/Networking/2020/03/21/ip_compact-and-ip_diff.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324272</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 21 Mar 2020 15:18:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Networking/">Networking</category>
<description><![CDATA[<p>Somehow I always end up working with lists of IP networks and needing to minimize and compare them.</p>
<p>Some of my Perl scripts for this might still be hidden in a corporate source repository, and somewhere in the backups of my old Linux laptop should be even earlier attempts in Bash.</p>
<p>Both of them are not very useful to me where they are, thus I've written yet another version.<br>This time in Go using the <a href="https://github.com/mikioh/ipaddr" title="package ipaddr">ipaddr</a> package.</p>
<p>Say hello to <a href="https://github.com/x-way/ip_compact" title="ip_compact - Compact a list of IP prefixes">ip_compact</a> and <a href="https://github.com/x-way/ip_diff" title="ip_diff - Compare two lists of IP prefixes">ip_diff</a> :-)</p>
]]></description>
<content:encoded><![CDATA[<p>Somehow I always end up working with lists of IP networks and needing to minimize and compare them.</p>
<p>Some of my Perl scripts for this might still be hidden in a corporate source repository, and somewhere in the backups of my old Linux laptop should be even earlier attempts in Bash.</p>
<p>Both of them are not very useful to me where they are, thus I've written yet another version.<br>This time in Go using the <a href="https://github.com/mikioh/ipaddr" title="package ipaddr">ipaddr</a> package.</p>
<p>Say hello to <a href="https://github.com/x-way/ip_compact" title="ip_compact - Compact a list of IP prefixes">ip_compact</a> and <a href="https://github.com/x-way/ip_diff" title="ip_diff - Compare two lists of IP prefixes">ip_diff</a> :-)</p>
]]></content:encoded>
</item>
<item>
<title>#StayTheFuckHome</title>
<link>https://blog.x-way.org/Music/2020/03/17/StayTheFuckHome.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324271</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 17 Mar 2020 19:33:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p><a href="https://youtu.be/CP70fI3BUs8" title="Bitch Queens - #StayTheFuckHome - YouTube">Bitch Queens - #StayTheFuckHome</a></p>
<p><a href="https://staythefuckhome.com/" title="Stay The Fuck Home!">Stay The Fuck Home!</a></p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://youtu.be/CP70fI3BUs8" title="Bitch Queens - #StayTheFuckHome - YouTube">Bitch Queens - #StayTheFuckHome</a></p>
<p><a href="https://staythefuckhome.com/" title="Stay The Fuck Home!">Stay The Fuck Home!</a></p>
]]></content:encoded>
</item>
<item>
<title>This Page is Designed to Last</title>
<link>https://blog.x-way.org/Misc/2019/12/20/This-Page-is-Designed-to-Last.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324270</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Fri, 20 Dec 2019 09:56:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p><a href="https://jeffhuang.com/designed_to_last/" title="This Page is Designed to Last: A Manifesto for Preserving Content on the Web">This Page is Designed to Last</a> — a manifesto from Jeff Huang for preserving content on the web, where he advocates to keep content on the web available and pledges to keep his site available for the next 10 years.</p>
<p>Having my content in this weblog online since 2002, I can very much relate to this initiative and additionally would like to point to the efforts of <a href="https://archive.org/">archive.org</a> (aka. The Internet Archive).<br>The wayback machine of archive.org allows to see old versions of websites, even when the website itself is no longer available.</p>
<p>For me personally this became critically useful when the database of my weblog vanished with no current backup and I then used the archived versions from archive.org to <a href="https://blog.x-way.org/Misc/2011/11/26/Online-Again.html" title="Online Again">restore the missing content</a>.</p>
<p>Thus I would like to encourage everyone to support the efforts of archive.org with a <a href="https://archive.org/donate/" title="Donate to the Internet Archive!">donation</a>.</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://jeffhuang.com/designed_to_last/" title="This Page is Designed to Last: A Manifesto for Preserving Content on the Web">This Page is Designed to Last</a> — a manifesto from Jeff Huang for preserving content on the web, where he advocates to keep content on the web available and pledges to keep his site available for the next 10 years.</p>
<p>Having my content in this weblog online since 2002, I can very much relate to this initiative and additionally would like to point to the efforts of <a href="https://archive.org/">archive.org</a> (aka. The Internet Archive).<br>The wayback machine of archive.org allows to see old versions of websites, even when the website itself is no longer available.</p>
<p>For me personally this became critically useful when the database of my weblog vanished with no current backup and I then used the archived versions from archive.org to <a href="https://blog.x-way.org/Misc/2011/11/26/Online-Again.html" title="Online Again">restore the missing content</a>.</p>
<p>Thus I would like to encourage everyone to support the efforts of archive.org with a <a href="https://archive.org/donate/" title="Donate to the Internet Archive!">donation</a>.</p>
]]></content:encoded>
</item>
<item>
<title>The Comet Is Coming</title>
<link>https://blog.x-way.org/Music/2019/11/02/The-Comet-Is-Coming.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324269</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 02 Nov 2019 11:04:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Music/">Music</category>
<description><![CDATA[<p><a href="https://youtu.be/G55GspnNkBo" title="The Comet Is Coming - Summon The Fire - YouTube">The Comet Is Coming - Summon The Fire</a></p>
<p><a href="https://www.thecometiscoming.co.uk/" title="The Comet Is Coming">The Comet Is Coming</a> is a 21st century style Jazz band.<br>
Discovered at the <a href="https://jazznojazz.ch/" title="Zurich Jazznojazz Festival 2019">Jazznojazz</a> festival :-)</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://youtu.be/G55GspnNkBo" title="The Comet Is Coming - Summon The Fire - YouTube">The Comet Is Coming - Summon The Fire</a></p>
<p><a href="https://www.thecometiscoming.co.uk/" title="The Comet Is Coming">The Comet Is Coming</a> is a 21st century style Jazz band.<br>
Discovered at the <a href="https://jazznojazz.ch/" title="Zurich Jazznojazz Festival 2019">Jazznojazz</a> festival :-)</p>
]]></content:encoded>
</item>
<item>
<title>More productive Git</title>
<link>https://blog.x-way.org/Coding/2019/05/25/More-productive-Git.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324268</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sat, 25 May 2019 07:47:00 +0200</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p><a href="https://increment.com/open-source/more-productive-git/" title="More productive Git">More productive Git</a> — a short article from <a href="https://www.kartar.net/" title="Kartar.Net">James Turnbull</a> with 'Tips for acquiring Git super powers'.</p>
<p>TL;DR:</p>
<ul>
<li><code>git reset <filename></code></li>
<li><code>git cherry-pick <commitid></code></li>
<li><code>git commit --amend</code></li>
<li><code>git stash</code></li>
<li><code>git log --stat</code></li>
<li><code>git bisect</code></li>
</ul>
]]></description>
<content:encoded><![CDATA[<p><a href="https://increment.com/open-source/more-productive-git/" title="More productive Git">More productive Git</a> — a short article from <a href="https://www.kartar.net/" title="Kartar.Net">James Turnbull</a> with 'Tips for acquiring Git super powers'.</p>
<p>TL;DR:</p>
<ul>
<li><code>git reset <filename></code></li>
<li><code>git cherry-pick <commitid></code></li>
<li><code>git commit --amend</code></li>
<li><code>git stash</code></li>
<li><code>git log --stat</code></li>
<li><code>git bisect</code></li>
</ul>
]]></content:encoded>
</item>
<item>
<title>Engineering Management</title>
<link>https://blog.x-way.org/Coding/2019/01/06/Engineering-Management.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324267</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 06 Jan 2019 13:21:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<description><![CDATA[<p><a href="https://charity.wtf/2019/01/04/engineering-management-the-pendulum-or-the-ladder/" title="Engineering Management: The Pendulum Or The Ladder">Engineering Management: The Pendulum Or The Ladder</a> — a well written article from <a href="https://charity.wtf/" title="Charity Majors">Charity Majors</a> about the non-trivial entanglement between engineering and management, explaining how doing everything at the same time does lead to unhappy/un-fulfilled people. Also worth reading in this context is the prequel article <a href="https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/" title="The Engineer/Manager Pendulum">The Engineer/Manager Pendulum</a>.</p>
]]></description>
<content:encoded><![CDATA[<p><a href="https://charity.wtf/2019/01/04/engineering-management-the-pendulum-or-the-ladder/" title="Engineering Management: The Pendulum Or The Ladder">Engineering Management: The Pendulum Or The Ladder</a> — a well written article from <a href="https://charity.wtf/" title="Charity Majors">Charity Majors</a> about the non-trivial entanglement between engineering and management, explaining how doing everything at the same time does lead to unhappy/un-fulfilled people. Also worth reading in this context is the prequel article <a href="https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/" title="The Engineer/Manager Pendulum">The Engineer/Manager Pendulum</a>.</p>
]]></content:encoded>
</item>
<item>
<title>Blogroll cleanup</title>
<link>https://blog.x-way.org/Misc/2019/01/06/Blogroll-cleanup.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324266</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Sun, 06 Jan 2019 12:55:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Misc/">Misc</category>
<description><![CDATA[<p>As some links on my blogroll start to turn into 404 errors it's time to do some cleanup and also to bring in some fresh blood :-)</p>
<p>Removed:</p>
<ul>
<li><a href="https://web.archive.org/web/20200221101248/http://www.mezzoblue.com/" title="mezzoblue">mezzoblue</a></li>
<li><a href="http://daveshea.com/blog/" title="Dave Shea">Dave Shea</a></li>
<li><a href="http://www.pepilog.de/" title="Pepilog">Pepilog</a></li>
<li><a href="https://www.elfengleich.de/" title="Elfengleich">e.loge</a></li>
<li><a href="https://web.archive.org/web/20180313151513/http://www.ende-der-vernunft.org/" title="EDV">EDV</a></li>
<li><a href="https://web.archive.org/web/20170221215450/http://sid.rstack.org/blog/" title="sid.rstack.org/blog">sid.rstack.org/blog</a></li>
<li><a href="https://web.archive.org/web/20161223004544/https://couchblog.de/codecandies/" title="Code Candies">Code Candies</a></li>
<li><a href="https://thepacketgeek.com/" title="thePacketGeek">thePacketGeek</a></li>
<li><a href="http://lovfoood.blogspot.com/" title="lovfoood">lovfoood</a></li>
</ul>
<p>Added:</p>
<ul>
<li><a href="https://charity.wtf/" title="charity.wtf">charity.wtf</a></li>
</ul>
]]></description>
<content:encoded><![CDATA[<p>As some links on my blogroll start to turn into 404 errors it's time to do some cleanup and also to bring in some fresh blood :-)</p>
<p>Removed:</p>
<ul>
<li><a href="https://web.archive.org/web/20200221101248/http://www.mezzoblue.com/" title="mezzoblue">mezzoblue</a></li>
<li><a href="http://daveshea.com/blog/" title="Dave Shea">Dave Shea</a></li>
<li><a href="http://www.pepilog.de/" title="Pepilog">Pepilog</a></li>
<li><a href="https://www.elfengleich.de/" title="Elfengleich">e.loge</a></li>
<li><a href="https://web.archive.org/web/20180313151513/http://www.ende-der-vernunft.org/" title="EDV">EDV</a></li>
<li><a href="https://web.archive.org/web/20170221215450/http://sid.rstack.org/blog/" title="sid.rstack.org/blog">sid.rstack.org/blog</a></li>
<li><a href="https://web.archive.org/web/20161223004544/https://couchblog.de/codecandies/" title="Code Candies">Code Candies</a></li>
<li><a href="https://thepacketgeek.com/" title="thePacketGeek">thePacketGeek</a></li>
<li><a href="http://lovfoood.blogspot.com/" title="lovfoood">lovfoood</a></li>
</ul>
<p>Added:</p>
<ul>
<li><a href="https://charity.wtf/" title="charity.wtf">charity.wtf</a></li>
</ul>
]]></content:encoded>
</item>
<item>
<title>New Year - New Vim Trick</title>
<link>https://blog.x-way.org/Coding/2019/01/01/New-Year-New-Vim-Trick.html</link>
<guid isPermaLink="true">http://waterwave.ch/weblog/detail.php?id=324265</guid>
<dc:creator>Andreas Jaggi</dc:creator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nd-nc/1.0/</creativeCommons:license>
<pubDate>Tue, 01 Jan 2019 22:24:00 +0100</pubDate>
<category domain="https://blog.x-way.org/Coding/">Coding</category>
<des