summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2022-09-04 11:18:04 +0300
committerPaul Buetow <paul@buetow.org>2022-09-04 11:18:04 +0300
commit15ebfecc8b79f09ad965a14612400aa79c918850 (patch)
tree30af4a7f2f4c05586e37197f29f2bcda5f5480f8
parentcad6faf1704824bed16bb18ee46db2b6c74c1a2c (diff)
parentd86d8efaa8e0a4cac70547d5529ed44881dd3e81 (diff)
Merge branch 'content-gemtext' of codeberg.org:snonux/foo.zone into content-gemtext
-rw-r--r--contact-information.gmi37
-rw-r--r--gemfeed/2008-06-26-perl-poetry.gmi6
-rw-r--r--gemfeed/2008-12-29-using-my-nokia-n95-for-fixing-my-mta.gmi6
-rw-r--r--gemfeed/2010-04-09-standard-ml-and-haskell.gmi2
-rw-r--r--gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.gmi6
-rw-r--r--gemfeed/2010-05-09-the-fype-programming-language.gmi6
-rw-r--r--gemfeed/2011-05-07-perl-daemon-service-framework.gmi6
-rw-r--r--gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.gmi2
-rw-r--r--gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.gmi6
-rw-r--r--gemfeed/2016-04-03-offsite-backup-with-zfs.gmi6
-rw-r--r--gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.gmi6
-rw-r--r--gemfeed/2016-04-16-offsite-backup-with-zfs-part2.gmi6
-rw-r--r--gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.gmi2
-rw-r--r--gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi6
-rw-r--r--gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.gmi6
-rw-r--r--gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.gmi2
-rw-r--r--gemfeed/2021-04-24-welcome-to-the-geminispace.gmi2
-rw-r--r--gemfeed/2021-05-16-personal-bash-coding-style-guide.gmi6
-rw-r--r--gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.gmi6
-rw-r--r--gemfeed/2021-07-04-the-well-grounded-rubyist.gmi2
-rw-r--r--gemfeed/2021-08-01-on-being-pedantic-about-open-source.gmi10
-rw-r--r--gemfeed/2021-09-12-keep-it-simple-and-stupid.gmi8
-rw-r--r--gemfeed/2021-10-22-defensive-devops.gmi6
-rw-r--r--gemfeed/2021-11-29-bash-golf-part-1.gmi8
-rw-r--r--gemfeed/2021-12-26-how-to-stay-sane-as-a-devops-person.gmi6
-rw-r--r--gemfeed/2022-01-01-bash-golf-part-2.gmi6
-rw-r--r--gemfeed/2022-01-23-welcome-to-the-foo.zone.gmi6
-rw-r--r--gemfeed/2022-02-04-computer-operating-systems-i-use.gmi6
-rw-r--r--gemfeed/2022-03-06-the-release-of-dtail-4.0.0.gmi6
-rw-r--r--gemfeed/2022-04-10-creative-universe.gmi6
-rw-r--r--gemfeed/2022-05-27-perl-is-still-a-great-choice.gmi6
-rw-r--r--gemfeed/2022-06-15-sweating-the-small-stuff.gmi6
-rw-r--r--gemfeed/2022-07-30-lets-encrypt-with-openbsd-and-rex.gmi662
-rw-r--r--gemfeed/2022-08-27-gemtexter-1.1.0-lets-gemtext-again.gmi91
-rw-r--r--gemfeed/atom.xml844
-rw-r--r--gemfeed/index.gmi2
-rw-r--r--index.gmi5
-rw-r--r--other-resources.gmi1
38 files changed, 1613 insertions, 199 deletions
diff --git a/contact-information.gmi b/contact-information.gmi
deleted file mode 100644
index 49d4f907..00000000
--- a/contact-information.gmi
+++ /dev/null
@@ -1,37 +0,0 @@
-# Contact information
-
-## Personal information
-
-* Name: Paul Buetow
-* E-Mail: paul at buetow period org
-
-=> ./paul.jpg Paul Buetow
-
-## My sites
-
-=> https://foo.zone foo.zone - My personal website and blog
-=> gemini://foo.zone foo.zone - My personal website and blog (Gemini)
-=> https://codeberg.org/snonux codeberg.org/snonux - My personal Codeberg page
-=> https://dtail.dev dtail.dev - DTail at Mimecast
-=> https://github.com/mimecast/ioriot github.com/mimecast/ioriot - I/O Riot at Mimecast (currently unmaintained)
-=> https://irregular.ninja irregular.ninja - My street photography site (warn: multiple MBs, it's photos after all)
-
-## Social Media
-
-I am sharing articles that I found interesting regularly these social media channels:
-
-=> https://www.linkedin.com/in/paul-buetow-b4857270/ My LinkedIn profile
-=> https://twitter.com/snonux twitter.com/snonux - My Twitter profile
-=> https://t.me/snonux t.me/snonux - My Telegram channel
-
-## Internet Relay Chat
-
-I am on irc.german-elite.net in #talk, #coding, #linux (and maybe in others) as "rantanplan" or sometimes as "snonux".
-
-## Site mirrors
-
-=> ./site-mirrors.gmi Check out all mirrors of this site (Gemini as well as HTTP+HTML)
-
-That's all for now...
-
-=> ./ Go back to the main site
diff --git a/gemfeed/2008-06-26-perl-poetry.gmi b/gemfeed/2008-06-26-perl-poetry.gmi
index f79fa803..64fce4a7 100644
--- a/gemfeed/2008-06-26-perl-poetry.gmi
+++ b/gemfeed/2008-06-26-perl-poetry.gmi
@@ -1,5 +1,7 @@
# Perl Poetry
+> Published by Paul at 2008-06-26, last updated at 2021-05-04
+
```
'\|/' *
-- * -----
@@ -23,8 +25,6 @@ _~~|~/_|_|__/|~~~~~~~ | / ~~~~~ | | ~~~~~~~~
(__) (____)
```
-> Published by Paul at 2008-06-26, last updated at 2021-05-04
-
Here are some Perl Poems I wrote. They don't do anything useful when you run them, but they don't produce a compiler error either. They only exist for fun and demonstrate what you can do with Perl syntax.
Wikipedia: "Perl poetry is the practice of writing poems that can be compiled as legal Perl code, for example the piece known as Black Perl. Perl poetry is made possible by the large number of English words that are used in the Perl language. New poems are regularly submitted to the community at PerlMonks."
@@ -161,6 +161,6 @@ Did you like what you saw? Have a look at Codeberg to see my other poems too:
=> https://codeberg.org/snonux/perl-poetry
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2008-12-29-using-my-nokia-n95-for-fixing-my-mta.gmi b/gemfeed/2008-12-29-using-my-nokia-n95-for-fixing-my-mta.gmi
index 635a1290..940b1f52 100644
--- a/gemfeed/2008-12-29-using-my-nokia-n95-for-fixing-my-mta.gmi
+++ b/gemfeed/2008-12-29-using-my-nokia-n95-for-fixing-my-mta.gmi
@@ -1,5 +1,7 @@
# Using my Nokia N95 for fixing my MTA
+> Published by Paul at 2008-12-29, last updated at 2021-12-01
+
```
_
@@ -17,8 +19,6 @@ _jgs_\|//_\\|///_\V/_\|//__
Art by Joan Stark
```
-> Published by Paul at 2008-12-29, last updated at 2021-12-01
-
The last week I was in Vidin, Bulgaria with no internet access and I had to fix my MTA (Postfix) at host.0.buetow.org which serves E-Mail for all my customers at P. B. Labs. Good, that I do not guarantee high availability on my web services (I've to do a full time job somewhere else too).
My first attempt to find an internet café, which was working during Christmastime, failed. However, I found with my N95 phone lots of free WLAN hotspots. The hotspots refused me logging into my server using SSH as I have configured a non-standard port for SSH for security reasons. Without knowing the costs, I used the GPRS internet access of my German phone provider (yes, I had to pay roaming fees).
@@ -36,6 +36,6 @@ It was a pain in the ass. My next mobile phone MUST have a full QWERTY keyboard.
At the moment I am in Sofia, Bulgaria. Here I can use at least an unprotected WLAN hotspot which belongs to one of the neighbours which I don’t know in person, and it is not blocking any port at all :)
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2010-04-09-standard-ml-and-haskell.gmi b/gemfeed/2010-04-09-standard-ml-and-haskell.gmi
index 5adda706..6b6b9db6 100644
--- a/gemfeed/2010-04-09-standard-ml-and-haskell.gmi
+++ b/gemfeed/2010-04-09-standard-ml-and-haskell.gmi
@@ -169,6 +169,6 @@ fun my_filter f l = foldr (make_filter_fn f) [] l
my_filter f l = foldr (make_filter_fn f) [] l
```
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.gmi b/gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.gmi
index 7bdfc8a0..d529b68e 100644
--- a/gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.gmi
+++ b/gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.gmi
@@ -1,5 +1,7 @@
# Lazy Evaluation with Standard ML
+> Published by Paul at 2010-05-07
+
```
_____|~~\_____ _____________
@@ -13,8 +15,6 @@
`||||
```
-> Published by Paul at 2010-05-07
-
In contrast to Haskell, Standard SML does not use lazy evaluation by default but an eager evaluation.
=> https://en.wikipedia.org/wiki/Eager_evaluation
@@ -97,6 +97,6 @@ first 10 nat_pairs_not_null
=> http://www.haskell.org/
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2010-05-09-the-fype-programming-language.gmi b/gemfeed/2010-05-09-the-fype-programming-language.gmi
index 09cb266a..89967831 100644
--- a/gemfeed/2010-05-09-the-fype-programming-language.gmi
+++ b/gemfeed/2010-05-09-the-fype-programming-language.gmi
@@ -1,5 +1,7 @@
# The Fype Programming Language
+> Published by Paul at 2010-05-09, last updated at 2021-05-05
+
```
____ _ __
/ / _|_ _ _ __ ___ _ _ ___ __ _| |__ / _|_ _
@@ -9,8 +11,6 @@
|___/|_| |___/ |___/
```
-> Published by Paul at 2010-05-09, last updated at 2021-05-05
-
Fype is an interpreted programming language created by me for learning and fun. The interpreter is written in C. It has been tested on FreeBSD and NetBSD and may also work on other Unix like operating systems such as Linux based ones. Besides learning and fun, there is no other use case of why Fype exists as many other programming languages are much faster and more powerful.
The Fype syntax is straightforward and uses a maximum look ahead of 1 and an effortless top-down parsing mechanism. Fype is parsing and interpreting its code simultaneously. This means that syntax errors are only detected during program runtime.
@@ -505,6 +505,6 @@ You can find all of this on the GitHub page. There is also an "examples" folders
=> https://codeberg.org/snonux/fype
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2011-05-07-perl-daemon-service-framework.gmi b/gemfeed/2011-05-07-perl-daemon-service-framework.gmi
index 92feacbf..67f8e305 100644
--- a/gemfeed/2011-05-07-perl-daemon-service-framework.gmi
+++ b/gemfeed/2011-05-07-perl-daemon-service-framework.gmi
@@ -1,5 +1,7 @@
# Perl Daemon (Service Framework)
+> Published by Paul at 2011-05-07, last updated at 2021-05-07
+
```
a'! _,,_ a'! _,,_ a'! _,,_
\\_/ \ \\_/ \ \\_/ \.-,
@@ -7,8 +9,6 @@
//\ //\\ //\ //\\ //\ //\\jrei
```
-> Published by Paul at 2011-05-07, last updated at 2021-05-07
-
PerlDaemon is a minimal daemon for Linux and other Unix like operating systems programmed in Perl. It is a minimal but pretty functional and fairly generic service framework. This means that it does not do anything useful other than providing a framework for starting, stopping, configuring and logging. To do something useful, a module (written in Perl) must be provided.
## Features
@@ -158,6 +158,6 @@ You can find PerlDaemon (including the examples) at:
=> https://codeberg.org/snonux/perldaemon
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.gmi b/gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.gmi
index 3fe85a38..66a6351d 100644
--- a/gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.gmi
+++ b/gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.gmi
@@ -138,6 +138,6 @@ fib(10) = 55
It's entertaining to play with :-).
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.gmi b/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.gmi
index 97fa612f..e82a79e6 100644
--- a/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.gmi
+++ b/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.gmi
@@ -1,5 +1,7 @@
# Run Debian on your phone with Debroid
+> Published by Paul at 2015-12-05, last updated at 2021-05-16
+
```
____ _ _ _
| _ \ ___| |__ _ __ ___ (_) __| |
@@ -9,8 +11,6 @@
```
-> Published by Paul at 2015-12-05, last updated at 2021-05-16
-
You can use the following tutorial to install a full-blown Debian GNU/Linux Chroot on an LG G3 D855 CyanogenMod 13 (Android 6). First of all, you need to have root permissions on your phone, and you also need to have the developer mode activated. The following steps have been tested on Linux (Fedora 23).
=> ./2015-12-05-run-debian-on-your-phone-with-debroid/Deboroid.png
@@ -175,6 +175,6 @@ exit
Reboot & test! Enjoy!
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2016-04-03-offsite-backup-with-zfs.gmi b/gemfeed/2016-04-03-offsite-backup-with-zfs.gmi
index f631c54b..7958c4a8 100644
--- a/gemfeed/2016-04-03-offsite-backup-with-zfs.gmi
+++ b/gemfeed/2016-04-03-offsite-backup-with-zfs.gmi
@@ -1,5 +1,7 @@
# Offsite backup with ZFS
+> Published by Paul at 2016-04-03
+
```
________________
|# : : #|
@@ -13,8 +15,6 @@
\____||__|_____|__|
```
-> Published by Paul at 2016-04-03
-
=> ./2016-04-03-offsite-backup-with-zfs.gmi Offsite backup with ZFS Part 1 (you are reading this atm.)
=> ./2016-04-16-offsite-backup-with-zfs-part2.gmi Offsite backup with ZFS Part 2
@@ -40,6 +40,6 @@ The solution is adding another USB drive (2TB) with an encryption container (GEL
I am thinking of buying a second 2TB USB drive and setting it up the same way as the first one. So I could alternate the backups. One drive would be at the secret location, and the other drive would be at home. And these drives would swap place after each cycle. This would give some security about the failure of that drive, and I would have to go to the secret location only once (swapping the drives) instead of twice (picking that drive up to update the data + bringing it back to the remote location).
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.gmi b/gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.gmi
index 5ccfc3a6..ce5e737b 100644
--- a/gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.gmi
+++ b/gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.gmi
@@ -1,5 +1,7 @@
# Jails and ZFS with Puppet on FreeBSD
+> Published by Paul at 2016-04-09
+
```
__ __
(( \---/ ))
@@ -20,8 +22,6 @@
\ `.
```
-> Published by Paul at 2016-04-09
-
Over the last couple of years I wrote quite a few Puppet modules in order to manage my personal server infrastructure. One of them manages FreeBSD Jails and another one ZFS file systems. I thought I would give a brief overview in how it looks and feels.
## ZFS
@@ -385,6 +385,6 @@ Of course I am operating multiple Jails on the same host this way with Puppet:
All done in a pretty automated manor.
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.gmi b/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.gmi
index 8c5c2126..42798b99 100644
--- a/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.gmi
+++ b/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.gmi
@@ -1,5 +1,7 @@
# Offsite backup with ZFS (Part 2)
+> Published by Paul at 2016-04-16
+
```
________________
|# : : #|
@@ -15,8 +17,6 @@
\____||__|_____|__|
```
-> Published by Paul at 2016-04-16
-
=> ./2016-04-03-offsite-backup-with-zfs.gmi Offsite backup with ZFS Part 1
=> ./2016-04-16-offsite-backup-with-zfs-part2.gmi Offsite backup with ZFS Part 2 (you are reading this atm.)
@@ -26,6 +26,6 @@ Whenever I update the offsite backup, I am doing it to the drive, which is kept
Furthermore, I added scrubbing ("zpool scrub...") to the script. It ensures that the file system is consistent and that there are no bad blocks on the disk and the file system. To increase the reliability, I also run a "zfs set copies=2 zroot". That setting is also synchronized to the offsite ZFS pool. ZFS stores every data block to disk twice now. Yes, it consumes twice as much disk space, making it better fault-tolerant against hardware errors (e.g. only individual disk sectors going bad).
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.gmi b/gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.gmi
index d0ee14bd..eb96edf6 100644
--- a/gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.gmi
+++ b/gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.gmi
@@ -234,6 +234,6 @@ Whenever I have to change a DNS entry, all I have to do is:
That's much more comfortable now than manually clicking at some web UIs at Schlund Technologies.
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi b/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi
index b320e4ca..74bfbfca 100644
--- a/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi
+++ b/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi
@@ -1,5 +1,7 @@
# Object oriented programming with ANSI C
+> Published by Paul at 2016-11-20, updated 2022-01-29
+
```
___ ___ ____ ____
/ _ \ / _ \| _ \ / ___|
@@ -9,8 +11,6 @@
```
-> Published by Paul at 2016-11-20, updated 2022-01-29
-
You can do a little of object-oriented programming in the C Programming Language. However, that is, in my humble opinion, limited. It's easier to use a different programming language than C for OOP. But still it's an interesting exercise to try using C for this.
## Function pointers
@@ -98,6 +98,6 @@ Big C software projects, like Linux, also follow some OOP techniques:
C is a very old programming language with it's quirks. This might be one of the reasons why Linux will also let Rust code in.
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.gmi b/gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.gmi
index 7cf16c9b..39ccd971 100644
--- a/gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.gmi
+++ b/gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.gmi
@@ -1,5 +1,7 @@
# Realistic load testing with I/O Riot for Linux
+> Published by Paul at 2018-06-01, last updated at 2021-05-08
+
```
.---.
/ \
@@ -11,8 +13,6 @@
jgs\__/'---'\__/
```
-> Published by Paul at 2018-06-01, last updated at 2021-05-08
-
## Foreword
This text first was published in the german IT-Administrator computer Magazine. 3 years have passed since and I decided to publish it on my blog too.
@@ -186,6 +186,6 @@ For example, the open syscall opens a file and returns the responsible file desc
=> https://graphiteapp.org Graphite
=> https://en.wikipedia.org/wiki/Memory-mapped_I/O Memory mapped I/O
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.gmi b/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.gmi
index 243a3dcc..800a43ec 100644
--- a/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.gmi
+++ b/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.gmi
@@ -103,6 +103,6 @@ Mimecast highly encourages you to have a look at DTail and submit an issue for a
=> https://dtail.dev
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2021-04-24-welcome-to-the-geminispace.gmi b/gemfeed/2021-04-24-welcome-to-the-geminispace.gmi
index e13e296c..855f0efb 100644
--- a/gemfeed/2021-04-24-welcome-to-the-geminispace.gmi
+++ b/gemfeed/2021-04-24-welcome-to-the-geminispace.gmi
@@ -76,6 +76,6 @@ Check out one of the following links for more information about Gemini. For exam
=> gemini://gemini.circumlunar.space
=> https://gemini.circumlunar.space
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2021-05-16-personal-bash-coding-style-guide.gmi b/gemfeed/2021-05-16-personal-bash-coding-style-guide.gmi
index 6e3e26be..a2b127fc 100644
--- a/gemfeed/2021-05-16-personal-bash-coding-style-guide.gmi
+++ b/gemfeed/2021-05-16-personal-bash-coding-style-guide.gmi
@@ -1,5 +1,7 @@
# Personal Bash coding style guide
+> Published by Paul at 2021-05-16
+
```
.---------------------------.
/,--..---..---..---..---..--. `.
@@ -13,8 +15,6 @@
"\__/"---------------"\__/"-+---+'
```
-> Published by Paul at 2021-05-16
-
Lately, I have been polishing and writing a lot of Bash code. Not that I never wrote a lot of Bash, but now as I also looked through the Google Shell Style Guide, I thought it is time also to write my thoughts on that. I agree with that guide in most, but not in all points.
=> https://google.github.io/styleguide/shellguide.html Google Shell Style Guide
@@ -380,6 +380,6 @@ I also highly recommend having a read through the "Advanced Bash-Scripting Guide
=> https://tldp.org/LDP/abs/html/ Advanced Bash-Scripting Guide
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.gmi b/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.gmi
index f44e7337..28b023b3 100644
--- a/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.gmi
+++ b/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.gmi
@@ -1,5 +1,7 @@
# Gemtexter - One Bash script to rule it all
+> Published by Paul at 2021-06-05
+
```
o .,<>., o
|\/\/\/\/|
@@ -41,8 +43,6 @@
`+a:f:......jrei'''
```
-> Published by Paul at 2021-06-05
-
You might have read my previous blog post about entering the Geminispace, where I pointed out the benefits of having and maintaining an internet presence there. This whole site (the blog and all other pages) is composed in the Gemtext markup language.
=> ./2021-04-24-welcome-to-the-geminispace.gmi Welcome to the Geminispace
@@ -166,6 +166,6 @@ It was quite a lot of fun writing Gemtexter. It's a relatively small project, bu
I finally revamped my personal internet site and started to blog again. I wanted the result to be exactly how it is now: A slightly retro-inspired internet site built for fun with unconventional tools.
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi b/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi
index 8a568e5c..a5aa750c 100644
--- a/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi
+++ b/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi
@@ -102,6 +102,6 @@ I liked this book so much so that I even bought myself a (used) paper copy of it
Will I abandon my beloved Perl? Probably not. There are also some Perl scripts I use at work. But unfortunately I only have a limited amount of time and I have to use it wisely. I might look into Raku (formerly known as Perl 6) next year and use it for a personal pet project, who knows. :-). I also highly recommend reading the two Perl books "Modern Perl" and "Higher-Order Perl".
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2021-08-01-on-being-pedantic-about-open-source.gmi b/gemfeed/2021-08-01-on-being-pedantic-about-open-source.gmi
index 96583f64..a9a82df8 100644
--- a/gemfeed/2021-08-01-on-being-pedantic-about-open-source.gmi
+++ b/gemfeed/2021-08-01-on-being-pedantic-about-open-source.gmi
@@ -1,5 +1,7 @@
# On being Pedantic about Open-Source
+> Published by Paul at 2021-08-01
+
```
__
_____....--' .'
@@ -12,8 +14,6 @@
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^' LGB - Art by lgbearrd
```
-> Published by Paul at 2021-08-01
-
I believe that it is essential to always have free and open-source alternatives to any kind of closed-source proprietary software available to choose from. But there are a couple of points you need to take into consideration.
## The costs of open-source
@@ -56,7 +56,9 @@ Security bugs in open-source projects are exposed to the public and fixed quickl
## Always watch out for open-source alternatives
-Do you need Microsoft Word? Why don't you just use the Vim text editor or GNU Emacs to write your letters? If that's too nerdy, you can still use open-source alternatives such as AbiWord or LibreOffice. Larger organizations have the tendency to standardize the software their employees have to use. Unfortunately, as Microsoft Word is the de-facto standard text processing program, most companies prefer Word over LibreOffice. Same with Microsoft Excel vs LibreOffice Calc or other spreadsheet alternatives like Gnumeric. I don't know why that is; please E-Mail me, and I will update this blog article. I guess the devil lies in the detail here.
+Do you need Microsoft Word? Why don't you just use the Vim text editor or GNU Emacs to write your letters? If that's too nerdy, you can still use open-source alternatives such as AbiWord or LibreOffice. Larger organizations have the tendency to standardize the software their employees have to use. Unfortunately, as Microsoft Word is the de-facto standard text processing program, most companies prefer Word over LibreOffice. Same with Microsoft Excel vs LibreOffice Calc or other spreadsheet alternatives like Gnumeric. I don't know why that is; please....
+
+E-Mail me your comments to paul at buetow dot org! :-)
I only use free and open-source operating systems on my personal Laptops, Desktop PCs and servers (FreeBSD and Linux based ones). Most of the programs and apps I use on them are free and open-source as well, and I am comfortable with it for over twenty years. Exceptions are the BIOSes and some firmwares of my devices. I also use Skype as most of my friends and family are using it. They are, unfortunately, proprietary software still. But I will be looking into Matrix as a Skype alternative when I have time. There are also open BIOS alternatives, but they usually don't work on my devices.
@@ -108,6 +110,6 @@ Should you be pedantic about open-source software? It depends. It depends on you
You have better chances when you know how to manage your own server and install and manage alternatives to the big cloud providers by yourself. I have the advantage that I have work experience as a Linux Systems Administrator here. I mentioned NextCloud already. I use NextCloud for online photo and file storage, contact and calendar sync and as an RSS news feed server. You could do the same with your own E-Mail server, you can also host your own website and blog. I also mentioned Matrix as a Skype alternative (which could also be an alternative to WhatsApp, Skype, Telegram, Viber, ...). I don't know a lot about Matrix yet, but it seems to be a very neat alternative. I am ready to invest time in it as one of my future personal pet projects. Not only because I think it's better, but also because for fun and as a hobby. But this doesn't mean that I invest *all* of my personal free time in it.
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2021-09-12-keep-it-simple-and-stupid.gmi b/gemfeed/2021-09-12-keep-it-simple-and-stupid.gmi
index ce17b016..0b91f2c1 100644
--- a/gemfeed/2021-09-12-keep-it-simple-and-stupid.gmi
+++ b/gemfeed/2021-09-12-keep-it-simple-and-stupid.gmi
@@ -1,5 +1,7 @@
# Keep it simple and stupid
+> Published by Paul at 2021-09-12, last updated at 2022-04-21
+
```
_______________ |*\_/*|_______
| ___________ | .-. .-. ||_/-\_|______ |
@@ -15,8 +17,6 @@
-------------------- --------------------
```
-> Published by Paul at 2021-09-12, last updated at 2022-04-21
-
A robust computer system must be kept simple and stupid (KISS). The fancier the system is, the more can break. Unfortunately, most systems tend to become complex and challenging to maintain in today's world. In the early days, so I was told, engineers understood every part of the system, but nowadays, we see more of the "lasagna" stack. One layer or framework is built on top of another layer, and in the end, nobody has got a clue what's going on.
# Need faster hardware
@@ -91,7 +91,9 @@ There is, however, a trap. The more you spend time with things, the more these t
=> https://unixsheikh.com/articles/is-the-madness-ever-going-to-end.html Is the madness ever going to end?
-Enough ranted for now :-). E-Mail me your comments to paul at buetow dot org!
+Enough ranted for now!
+
+E-Mail me your comments to paul at buetow dot org! :-)
> Controversially, a lack of features is a feature. Enjoy your peace an quiet. - Michael W Lucas
diff --git a/gemfeed/2021-10-22-defensive-devops.gmi b/gemfeed/2021-10-22-defensive-devops.gmi
index 7dfeba41..8cfb2f38 100644
--- a/gemfeed/2021-10-22-defensive-devops.gmi
+++ b/gemfeed/2021-10-22-defensive-devops.gmi
@@ -1,5 +1,7 @@
# Defensive DevOps
+> Published by Paul at 2021-10-22
+
```
c=====e
H
@@ -10,8 +12,6 @@
ASCII Art by Clyde Watson
```
-> Published by Paul at 2021-10-22
-
I have seen many different setups and infrastructures during my carreer. My roles always included front-line ad-hoc fire fighting production issues. This often involves identifying and fixing these under time pressure, without the comfort of 2-week-long SCRUM sprints and without an exhaustive QA process. I also wrote a lot of code (Bash, Ruby, Perl, Go, and a little Java), and I followed the typical software development process, but that did not always apply to critical production issues.
Unfortunately, no system is 100% reliable, and you can never be prepared for a subset of the possible problem-space. IT infrastructures can be complex. Not even mentioning Kubernetes yet, a Microservice-based infrastructure can complicate things even further. You can take care of 99% of all potential problems by following all DevOps best practices. Those best practices are not the subject of this blog post; this post is about the sub 1% of the issues arising from nowhere you can't be prepared for.
@@ -99,6 +99,6 @@ For every major incident, you need to follow up with an incident retrospective.
This usually means creating one or more tickets, which will be dealt with soon. Once the permanent fix is deployed, you can remove your ad-hoc automation and monitoring around it and focus on your regular work again.
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2021-11-29-bash-golf-part-1.gmi b/gemfeed/2021-11-29-bash-golf-part-1.gmi
index a22b2597..3f162804 100644
--- a/gemfeed/2021-11-29-bash-golf-part-1.gmi
+++ b/gemfeed/2021-11-29-bash-golf-part-1.gmi
@@ -1,5 +1,7 @@
# Bash Golf Part 1
+> Published by Paul at 2021-11-29, last updated at 2022-01-05
+
```
'\ . . |>18>>
@@ -12,8 +14,6 @@ jgs^^^^^^^`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Art by Joan Stark
```
-> Published by Paul at 2021-11-29, last updated at 2022-01-05
-
This is the first blog post about my Bash Golf series. This series is about random Bash tips, tricks and weirdnesses I came across. It's a collection of smaller articles I wrote in an older (in German language) blog, which I translated and refreshed with some new content.
=> ./2021-11-29-bash-golf-part-1.gmi Bash Golf Part 1 (you are reading this atm.)
@@ -461,6 +461,8 @@ In the Bash you will have to fall back to an external command like "bc" (the arb
.10
```
-See you later for the next post of this series. E-Mail me your comments to paul at buetow dot org!
+See you later for the next post of this series.
+
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2021-12-26-how-to-stay-sane-as-a-devops-person.gmi b/gemfeed/2021-12-26-how-to-stay-sane-as-a-devops-person.gmi
index 0fc5d755..0d66372d 100644
--- a/gemfeed/2021-12-26-how-to-stay-sane-as-a-devops-person.gmi
+++ b/gemfeed/2021-12-26-how-to-stay-sane-as-a-devops-person.gmi
@@ -1,5 +1,7 @@
# How to stay sane as a DevOps person
+> Published by Paul at 2021-12-26, last updated at 2022-01-12
+
```
)
) (( (
@@ -22,8 +24,6 @@
~~~~~'
```
-> Published by Paul at 2021-12-26, last updated at 2022-01-12
-
Log4shell (CVE-2021-44228) made it clear, once again, that working in information technology is not an easy job (especially when you are a DevOps person). I thought it would be interesting to summarize a few techniques to help you to relax.
(PS: When I mean DevOps, I also mean Site Reliability Engineers and Sysadmins. I believe SRE, DevOps Engineer and Sysadmin are just synonym titles for the same job).
@@ -123,6 +123,6 @@ Another blog post worth reading:
=> https://unixsheikh.com/articles/how-to-stay-sane-in-todays-world-of-tech.html
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2022-01-01-bash-golf-part-2.gmi b/gemfeed/2022-01-01-bash-golf-part-2.gmi
index ff4f595d..3885f92e 100644
--- a/gemfeed/2022-01-01-bash-golf-part-2.gmi
+++ b/gemfeed/2022-01-01-bash-golf-part-2.gmi
@@ -1,5 +1,7 @@
# Bash Golf Part 2
+> Published by Paul at 2022-01-01, last updated at 2022-01-05
+
```
'\ '\ . . |>18>>
@@ -12,8 +14,6 @@ jgs^^^^^^^`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Art by Joan Stark, mod. by Paul Buetow
```
-> Published by Paul at 2022-01-01, last updated at 2022-01-05
-
This is the second blog post about my Bash Golf series. This series is random Bash tips, tricks and weirdnesses I came across. It's a collection of smaller articles I wrote in an older (in German language) blog, which I translated and refreshed with some new content.
=> ./2021-11-29-bash-golf-part-1.gmi Bash Golf Part 1
@@ -480,6 +480,6 @@ To change this behaviour, pipefile can be used. Now, the pipes exit status is 1
1
```
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2022-01-23-welcome-to-the-foo.zone.gmi b/gemfeed/2022-01-23-welcome-to-the-foo.zone.gmi
index be5727a4..1c27c4e0 100644
--- a/gemfeed/2022-01-23-welcome-to-the-foo.zone.gmi
+++ b/gemfeed/2022-01-23-welcome-to-the-foo.zone.gmi
@@ -1,5 +1,7 @@
# Welcome to the foo.zone
+> Published by Paul at 2022-01-23
+
```
__
/ _| ___ ___ _______ _ __ ___
@@ -9,8 +11,6 @@
```
-> Published by Paul at 2022-01-23
-
I don't count this as a real blog post, but more of an announcement (I aim to write one real post once monthly). From now on, "foo.zone" is the new address of this site. All other addresses will still forward to it and eventually (based on the traffic still going through) will be deactivated.
As you can read on Wikipedia, "foo" is, alongside to "bar" and "baz", a metasyntactic variable (you know what I mean if you are a programmer or IT person):
@@ -44,6 +44,6 @@ As a funny bit, I almost chose "foo.surf" over "foo.zone" as in "surfing this si
The host buetow.org will stay. However, not as the primary address for this site. I will keep using it for my personal internet infrastructure as well as for most of my E-Mail addresses. I used buetow.org for that over the past 10 years already anyway and that won't change any time soon. I don't know what I am going to do with snonux.de in the long run. A .de SLD (for Germany) is pretty cheap, so I might just keep it for now.
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2022-02-04-computer-operating-systems-i-use.gmi b/gemfeed/2022-02-04-computer-operating-systems-i-use.gmi
index c254edc6..85a476ea 100644
--- a/gemfeed/2022-02-04-computer-operating-systems-i-use.gmi
+++ b/gemfeed/2022-02-04-computer-operating-systems-i-use.gmi
@@ -1,5 +1,7 @@
# Computer operating systems I use(d)
+> Published by Paul at 2022-02-04, updated 2022-02-18
+
```
/( )`
\ \___ / |
@@ -21,8 +23,6 @@
`--{__________) \/ "Berkeley Unix Daemon"
```
-> Published by Paul at 2022-02-04, updated 2022-02-18
-
This is a list of Operating Systems I currently use. This list is in no particular order and also will be updated over time. The very first operating system I used was MS-DOS (mainly for games) and the very first Unix like operating system I used was SuSE Linux 5.3. My first smartphone OS was Symbian on a clunky Sony Ericsson device.
## Fedora Linux
@@ -225,6 +225,6 @@ I have been using NetBSD on an old Sun Sparcstation 10 as a student. I also have
=> https://www.dragonflybsd.org/ DragonFly BSD - Fork of FreeBSD 4
=> http://wiki.postmarketos.org/wiki/Phosh Phosh (on postmarketOS) - A true Linux shell for the smartphone
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2022-03-06-the-release-of-dtail-4.0.0.gmi b/gemfeed/2022-03-06-the-release-of-dtail-4.0.0.gmi
index 75fe6ccd..b466ed28 100644
--- a/gemfeed/2022-03-06-the-release-of-dtail-4.0.0.gmi
+++ b/gemfeed/2022-03-06-the-release-of-dtail-4.0.0.gmi
@@ -1,5 +1,7 @@
# The release of DTail 4.0.0
+> Published by Paul at 2022-03-06
+
```
,_---~~~~~----._
_,,_,*^____ _____``*g*\"*,
@@ -14,8 +16,6 @@
| |
```
-> Published by Paul at 2022-03-06
-
I have recently released DTail 4.0.0 and this blog post goes through all the new goodies. You can also read my previous post about DTail in case you wonder what DTail is:
=> ./2021-04-22-dtail-the-distributed-log-tail-program.gmi DTail - The distributed log tail program
@@ -294,6 +294,6 @@ Thanks!
Paul
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2022-04-10-creative-universe.gmi b/gemfeed/2022-04-10-creative-universe.gmi
index 7839daf6..017b0f13 100644
--- a/gemfeed/2022-04-10-creative-universe.gmi
+++ b/gemfeed/2022-04-10-creative-universe.gmi
@@ -1,5 +1,7 @@
# Creative universe
+> Published by Paul at 2022-04-10, last updated at 2022-04-18
+
```
. + . . . . . .
. . . *
@@ -21,8 +23,6 @@
- the universe
```
-> Published by Paul at 2022-04-10, last updated at 2022-04-18
-
## Prelude
I have been participating in an annual work-internal project contest (we call it Pet Project contest) since I moved to London and switched jobs to my current employer. I am very happy to say that I won a "silver" prize last week here 🎆. Over the last couple of years I have been a finalist in this contest six times and won some kind of prize five times. Some of my projects were also released as open source software. One had a magazine article published, and for another one I wrote an article on my employer's engineering blog. If you have followed all my posts on this blog (the one you are currently reading), then you have probably figured out what these projects were:
@@ -137,6 +137,6 @@ Relevant books I can recommend are:
* The Off Switch; Mark Cropley; Virgin Books
* Ultralearning; Scott Young; Thorsons
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2022-05-27-perl-is-still-a-great-choice.gmi b/gemfeed/2022-05-27-perl-is-still-a-great-choice.gmi
index 58485064..3081ccf2 100644
--- a/gemfeed/2022-05-27-perl-is-still-a-great-choice.gmi
+++ b/gemfeed/2022-05-27-perl-is-still-a-great-choice.gmi
@@ -1,9 +1,9 @@
# Perl is still a great choice
-=> ./2022-05-27-perl-is-still-a-great-choice/regular_expressions.png
-
> Published by Paul at 2022-05-27, Comic source: XKCD
+=> ./2022-05-27-perl-is-still-a-great-choice/regular_expressions.png
+
Perl (the Practical Extraction and Report Language) is a battle-tested, mature, multi-paradigm dynamic programming language. Note that it's not called PERL, neither P.E.R.L. nor Pearl. "Perl" is the name of the language and "perl" the name of the interpreter or the interpreter command.
Unfortunately (it makes me sad), Perl's popularity has been declining over the last years as Google trends shows:
@@ -118,7 +118,7 @@ Btw.: Did you know that the first version of PHP was a set of Perl snippets? Onl
=> https://www.perl.org
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2022-06-15-sweating-the-small-stuff.gmi b/gemfeed/2022-06-15-sweating-the-small-stuff.gmi
index 982f316d..1ba32c49 100644
--- a/gemfeed/2022-06-15-sweating-the-small-stuff.gmi
+++ b/gemfeed/2022-06-15-sweating-the-small-stuff.gmi
@@ -1,5 +1,7 @@
# Sweating the small stuff - Tiny projects of mine
+> Published by Paul at 2022-06-15, last updated at 2022-06-18
+
```
_
/_/_ .'''.
@@ -8,8 +10,6 @@
`..'
```
-> Published by Paul at 2022-06-15, last updated at 2022-06-18
-
This blog post is a bit different from the others. It consists of multiple but smaller projects worth mentioning. I got inspired by Julia Evan's "Tiny programs" blog post and the side projects of The Sephist, so I thought I would also write a blog posts listing a couple of small projects of mine:
=> https://jvns.ca/blog/2022/03/08/tiny-programs/ Tiny programs
@@ -323,6 +323,6 @@ If you wonder what Gemini is:
=> ./2021-04-24-welcome-to-the-geminispace.gmi Welcome to the Geminispae
-E-Mail me your comments to paul at buetow dot org!
+E-Mail me your comments to paul at buetow dot org! :-)
=> ../ Go back to the main site
diff --git a/gemfeed/2022-07-30-lets-encrypt-with-openbsd-and-rex.gmi b/gemfeed/2022-07-30-lets-encrypt-with-openbsd-and-rex.gmi
new file mode 100644
index 00000000..d7af2e45
--- /dev/null
+++ b/gemfeed/2022-07-30-lets-encrypt-with-openbsd-and-rex.gmi
@@ -0,0 +1,662 @@
+# Let's Encrypt with OpenBSD and Rex
+
+> Published by Paul at 2022-07-30
+
+```
+ / _ \
+ The Hebern Machine \ ." ". /
+ ___ / \
+ .."" "".. | O |
+ / \ | |
+ / \ | |
+ ---------------------------------
+ _/ o (O) o _ |
+ _/ ." ". |
+ I/ _________________/ \ |
+ _/I ." | |
+ ===== / I / / |
+ ===== | | | \ | _________________." |
+===== | | | | | / \ / _|_|__|_|_ __ |
+ | | | | | | | \ "._." / o o \ ." ". |
+ | --| --| -| / \ _/ / \ |
+ \____\____\__| \ ______ | / | | |
+ -------- --- / | | |
+ ( ) (O) / \ / |
+ ----------------------- ".__." |
+ _|__________________________________________|_
+ / \
+ /________________________________________________\
+ ASCII Art by John Savard
+```
+
+I was amazed how easy it is to automatically generate and update Let's Encrypt certificates with OpenBSD.
+
+## What's Let's Encrypt?
+
+> Let's Encrypt is a non-profit certificate authority run by Internet Security Research Group that provides X.509 certificates for Transport Layer Security (TLS) encryption at no charge. It is the world's largest certificate authority, used by more than 265 million websites, with the goal of all websites being secure and using HTTPS.
+
+=> https://en.wikipedia.org/wiki/Let's_Encrypt Source: Wikipedia
+
+In short, it gives away TLS certificates for your website - for free! The catch is, that the certificates are only valid for three months. So it is better to automate certificate generation and renevals.
+
+## Meet `acme-client`
+
+`acme-client` is the default Automatic Certifcate Management Environment (ACME) client on OpenBSD and part of the OpenBSD base system.
+
+When invoked, the client first checks whether certificates actually require to be generated.
+
+* It first checks whether a certificate already exists, if not, it will attempt to generate a new one.
+* If the certificate already exists but expires within the next 30 days, it will renew it.
+* Otherwise, `acme-client` won't do anything.
+
+Oversimplified, the following steps are undertaken by `acme-client` for generating a new certificate:
+
+* Reading its config file `/etc/acme-client.conf` for a list of hosts (and their alternative names) to generate certificates for. So it means you can also have certificates for abritary subdomains!
+* Automatic generation of the private certificate part (the certificate key) and the certificate signing request (CSR) to `/etc/ssl/...`.
+* Requesting Let's Encrypt to sign the certificate. This also includes providing a set of temporary files which will be requested by Let's Encrypt in the next step for verification.
+* Let's Encrypt then will contact the hostname for the certificate through a special URL (e.g. `http://foo.zone/.well-known/acme-challenge/...`) to verify that the requester is the valid owner of the host.
+* Let's Encrypt generates a certificate, which then is downloaded to `/etc/ssl/...`.
+
+## Configuration
+
+There is some (but easy) configuration required to make that all work on OpenBSD.
+
+### acme-client.conf
+
+This is how my `/etc/acme-client.conf` looks like (I copied a template from `/etc/examples/acme-client.conf` to `/etc/acme-client.conf` and added my domains to the bottom:
+
+```
+#
+# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
+#
+authority letsencrypt {
+ api url "https://acme-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-privkey.pem"
+}
+
+authority letsencrypt-staging {
+ api url "https://acme-staging-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-staging-privkey.pem"
+}
+
+authority buypass {
+ api url "https://api.buypass.com/acme/directory"
+ account key "/etc/acme/buypass-privkey.pem"
+ contact "mailto:me@example.com"
+}
+
+authority buypass-test {
+ api url "https://api.test4.buypass.no/acme/directory"
+ account key "/etc/acme/buypass-test-privkey.pem"
+ contact "mailto:me@example.com"
+}
+
+domain buetow.org {
+ alternative names { www.buetow.org paul.buetow.org }
+ domain key "/etc/ssl/private/buetow.org.key"
+ domain full chain certificate "/etc/ssl/buetow.org.fullchain.pem"
+ sign with letsencrypt
+}
+
+domain dtail.dev {
+ alternative names { www.dtail.dev }
+ domain key "/etc/ssl/private/dtail.dev.key"
+ domain full chain certificate "/etc/ssl/dtail.dev.fullchain.pem"
+ sign with letsencrypt
+}
+
+domain foo.zone {
+ alternative names { www.foo.zone }
+ domain key "/etc/ssl/private/foo.zone.key"
+ domain full chain certificate "/etc/ssl/foo.zone.fullchain.pem"
+ sign with letsencrypt
+}
+
+domain irregular.ninja {
+ alternative names { www.irregular.ninja }
+ domain key "/etc/ssl/private/irregular.ninja.key"
+ domain full chain certificate "/etc/ssl/irregular.ninja.fullchain.pem"
+ sign with letsencrypt
+}
+
+domain snonux.land {
+ alternative names { www.snonux.land }
+ domain key "/etc/ssl/private/snonux.land.key"
+ domain full chain certificate "/etc/ssl/snonux.land.fullchain.pem"
+ sign with letsencrypt
+}
+```
+
+### httpd.conf
+
+For ACME to work you will also need to configure the HTTP daemon so that the "special" ACME requests made from Let's Encrypt are served correctly. I am using the standard OpenBSD `httpd` here. These are the snippets I use for the `foo.zone` host in `/etc/httpd.conf` (of course, you need similar setup for all other hosts as well):
+
+```
+server "foo.zone" {
+ listen on * port 80
+ location "/.well-known/acme-challenge/*" {
+ root "/acme"
+ request strip 2
+ }
+ location * {
+ block return 302 "https://$HTTP_HOST$REQUEST_URI"
+ }
+}
+
+server "foo.zone" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/foo.zone.fullchain.pem"
+ key "/etc/ssl/private/foo.zone.key"
+ }
+ location * {
+ root "/htdocs/gemtexter/foo.zone"
+ directory auto index
+ }
+}
+```
+
+As you see, plain HTTP only serves the ACME challenge path. Otherwise, it is redirecting the requests to TLS. The TLS section then attempts to use the Let's Encrypt certificates.
+
+It is worth noticing that `httpd` will start without the certificates actually being present. This will cause a certificate error when you try to reach the HTTPS endpoint but it helps to bootstrap Let's Encrypt. As you saw in the config snippet above, Let's Encrypt only requests the plain HTTP endpoint for the verification process so that HTTPS doesn't need to be operational yet at this stage. But once the certificates are generated, you will have to reload or restart `httpd` in order to use any new certificate.
+
+### CRON job
+
+You could now run `doas acme-client foo.zone` to generate the certificate or to renew it. Or you could automate it with CRON.
+
+I have created a script `/usr/local/bin/acme.sh` for that for all of my domains:
+
+```
+#!/bin/sh
+
+function handle_cert {
+ host=$1
+ # Create symlink, so that relayd also can read it.
+ crt_path=/etc/ssl/$host
+ if [ -e $crt_path.crt ]; then
+ rm $crt_path.crt
+ fi
+ ln -s $crt_path.fullchain.pem $crt_path.crt
+ # Requesting and renewing certificate.
+ /usr/sbin/acme-client -v $host
+}
+
+has_update=no
+handle_cert www.buetow.org
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.paul.buetow.org
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.tmp.buetow.org
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.dtail.dev
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.foo.zone
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.irregular.ninja
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.snonux.land
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+
+# Pick up the new certs.
+if [ $has_update = yes ]; then
+ /usr/sbin/rcctl reload httpd
+ /usr/sbin/rcctl reload relayd
+ /usr/sbin/rcctl restart smtpd
+fi
+```
+
+And added the following line to `/etc/daily.local` to run the script once daily so that certificates will be renewed fully automatically:
+
+```
+/usr/local/bin/acme.sh
+```
+
+I am receiving a daily output via E-Mail like this now:
+
+```
+Running daily.local:
+acme-client: /etc/ssl/buetow.org.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/paul.buetow.org.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/tmp.buetow.org.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/dtail.dev.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/foo.zone.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/irregular.ninja.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/snonux.land.fullchain.pem: certificate valid: 79 days left
+```
+
+## relayd.conf and smtpd.conf
+
+Besides of `httpd`, `relayd` (mainly for Gemini) and `smtpd` (for mail, of course) also use TLS certificates. And as you can see in `acme.sh`, the services are also reloaded or restarted (`smtpd` doesn't support reload) whenever a certificate was generated or updated.
+
+## Rexification
+
+I didn't write all these configuration files by hand. As a matter of fact, everything is automated with the Rex configuration management system.
+
+=> https://www.rexify.org
+
+At the top of the `Rexfile` I define all my hosts:
+
+```
+our @acme_hosts = qw/buetow.org paul.buetow.org tmp.buetow.org dtail.dev foo.zone irregular.ninja snonux.land/;
+```
+
+### General ACME client configuration
+
+ACME will be installed into the frontend group of hosts. Here, blowfish is the primary, and twofish the secondary OpenBSD box.
+
+```
+group frontends => 'blowfish.buetow.org', 'twofish.buetow.org';
+```
+
+This is my Rex task for the general ACME configuration:
+
+```
+desc 'Configure ACME client';
+task 'acme', group => 'frontends',
+ sub {
+ file '/etc/acme-client.conf',
+ content => template('./etc/acme-client.conf.tpl',
+ acme_hosts => \@acme_hosts,
+ is_primary => $is_primary),
+ owner => 'root',
+ group => 'wheel',
+ mode => '644';
+
+ file '/usr/local/bin/acme.sh',
+ content => template('./scripts/acme.sh.tpl',
+ acme_hosts => \@acme_hosts,
+ is_primary => $is_primary),
+ owner => 'root',
+ group => 'wheel',
+ mode => '744';
+
+ file '/etc/daily.local',
+ ensure => 'present',
+ owner => 'root',
+ group => 'wheel',
+ mode => '644';
+
+ append_if_no_such_line '/etc/daily.local', '/usr/local/bin/acme.sh';
+ };
+```
+
+And there is also a Rex task just to run the ACME script remotely:
+
+```
+desc 'Invoke ACME client';
+task 'acme_invoke', group => 'frontends',
+ sub {
+ say run '/usr/local/bin/acme.sh';
+ };
+
+```
+
+Furthermore, this snippet (also at the top of the Rexfile) helps to determine whether the current server is the primary server (all hosts will be without the `www.` prefix) or the secondary server (all hosts will be with the `www.` prefix):
+
+```
+# Bootstrapping the FQDN based on the server IP as the hostname and domain
+# facts aren't set yet due to the myname file in the first place.
+our $fqdns = sub {
+ my $ipv4 = shift;
+ return 'blowfish.buetow.org' if $ipv4 eq '23.88.35.144';
+ return 'twofish.buetow.org' if $ipv4 eq '108.160.134.135';
+ Rex::Logger::info("Unable to determine hostname for $ipv4", 'error');
+ return 'HOSTNAME-UNKNOWN.buetow.org';
+};
+
+# To determine whether the server is the primary or the secondary.
+our $is_primary = sub {
+ my $ipv4 = shift;
+ $fqdns->($ipv4) eq 'blowfish.buetow.org';
+};
+```
+
+The following is the `acme-client.conf.tpl` Rex template file used for the automation. You see here that the `www.` prefix isn't sent for the primary server. E.g. `foo.zone` will be served by the primary server (in my case a server located in Germany) and `www.foo.zone` by the secondary server (in my case a server located in Japan):
+
+```
+#
+# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
+#
+authority letsencrypt {
+ api url "https://acme-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-privkey.pem"
+}
+
+authority letsencrypt-staging {
+ api url "https://acme-staging-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-staging-privkey.pem"
+}
+
+authority buypass {
+ api url "https://api.buypass.com/acme/directory"
+ account key "/etc/acme/buypass-privkey.pem"
+ contact "mailto:me@example.com"
+}
+
+authority buypass-test {
+ api url "https://api.test4.buypass.no/acme/directory"
+ account key "/etc/acme/buypass-test-privkey.pem"
+ contact "mailto:me@example.com"
+}
+
+<%
+ our $primary = $is_primary->($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+%>
+
+<% for my $host (@$acme_hosts) { %>
+domain <%= $prefix.$host %> {
+ domain key "/etc/ssl/private/<%= $prefix.$host %>.key"
+ domain full chain certificate "/etc/ssl/<%= $prefix.$host %>.fullchain.pem"
+ sign with letsencrypt
+}
+<% } %>
+
+```
+
+And this is the `acme.sh.tpl`:
+
+```
+#!/bin/sh
+
+<%
+ our $primary = $is_primary->($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+-%>
+
+function handle_cert {
+ host=$1
+ # Create symlink, so that relayd also can read it.
+ crt_path=/etc/ssl/$host
+ if [ -e $crt_path.crt ]; then
+ rm $crt_path.crt
+ fi
+ ln -s $crt_path.fullchain.pem $crt_path.crt
+ # Requesting and renewing certificate.
+ /usr/sbin/acme-client -v $host
+}
+
+has_update=no
+<% for my $host (@$acme_hosts) { -%>
+handle_cert <%= $prefix.$host %>
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+<% } -%>
+
+# Pick up the new certs.
+if [ $has_update = yes ]; then
+ /usr/sbin/rcctl reload httpd
+ /usr/sbin/rcctl reload relayd
+ /usr/sbin/rcctl restart smtpd
+fi
+```
+
+### Service rexification
+
+These are the Rex tasks setting up `httpd`, `relayd` and `smtpd` services:
+
+```
+desc 'Setup httpd';
+task 'httpd', group => 'frontends',
+ sub {
+ append_if_no_such_line '/etc/rc.conf.local', 'httpd_flags=';
+
+ file '/etc/httpd.conf',
+ content => template('./etc/httpd.conf.tpl',
+ acme_hosts => \@acme_hosts,
+ is_primary => $is_primary),
+ owner => 'root',
+ group => 'wheel',
+ mode => '644',
+ on_change => sub { service 'httpd' => 'restart' };
+
+ service 'httpd', ensure => 'started';
+ };
+
+desc 'Setup relayd';
+task 'relayd', group => 'frontends',
+ sub {
+ append_if_no_such_line '/etc/rc.conf.local', 'relayd_flags=';
+
+ file '/etc/relayd.conf',
+ content => template('./etc/relayd.conf.tpl',
+ ipv6address => $ipv6address,
+ is_primary => $is_primary),
+ owner => 'root',
+ group => 'wheel',
+ mode => '600',
+ on_change => sub { service 'relayd' => 'restart' };
+
+ service 'relayd', ensure => 'started';
+ };
+
+desc 'Setup OpenSMTPD';
+task 'smtpd', group => 'frontends',
+ sub {
+ Rex::Logger::info('Dealing with mail aliases');
+ file '/etc/mail/aliases',
+ source => './etc/mail/aliases',
+ owner => 'root',
+ group => 'wheel',
+ mode => '644',
+ on_change => sub { say run 'newaliases' };
+
+ Rex::Logger::info('Dealing with mail virtual domains');
+ file '/etc/mail/virtualdomains',
+ source => './etc/mail/virtualdomains',
+ owner => 'root',
+ group => 'wheel',
+ mode => '644',
+ on_change => sub { service 'smtpd' => 'restart' };
+
+ Rex::Logger::info('Dealing with mail virtual users');
+ file '/etc/mail/virtualusers',
+ source => './etc/mail/virtualusers',
+ owner => 'root',
+ group => 'wheel',
+ mode => '644',
+ on_change => sub { service 'smtpd' => 'restart' };
+
+ Rex::Logger::info('Dealing with smtpd.conf');
+ file '/etc/mail/smtpd.conf',
+ content => template('./etc/mail/smtpd.conf.tpl',
+ is_primary => $is_primary),
+ owner => 'root',
+ group => 'wheel',
+ mode => '644',
+ on_change => sub { service 'smtpd' => 'restart' };
+
+ service 'smtpd', ensure => 'started';
+ };
+
+```
+
+This is `httpd.conf.tpl`:
+
+```
+<%
+ our $primary = $is_primary->($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+%>
+
+# Plain HTTP for ACME and HTTPS redirect
+<% for my $host (@$acme_hosts) { %>
+server "<%= $prefix.$host %>" {
+ listen on * port 80
+ location "/.well-known/acme-challenge/*" {
+ root "/acme"
+ request strip 2
+ }
+ location * {
+ block return 302 "https://$HTTP_HOST$REQUEST_URI"
+ }
+}
+<% } %>
+
+# Gemtexter hosts
+<% for my $host (qw/foo.zone snonux.land/) { %>
+server "<%= $prefix.$host %>" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/<%= $prefix.$host %>.fullchain.pem"
+ key "/etc/ssl/private/<%= $prefix.$host %>.key"
+ }
+ location * {
+ root "/htdocs/gemtexter/<%= $host %>"
+ directory auto index
+ }
+}
+<% } %>
+
+# DTail special host
+server "<%= $prefix %>dtail.dev" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/<%= $prefix %>dtail.dev.fullchain.pem"
+ key "/etc/ssl/private/<%= $prefix %>dtail.dev.key"
+ }
+ location * {
+ block return 302 "https://github.dtail.dev$REQUEST_URI"
+ }
+}
+
+# Irregular Ninja special host
+server "<%= $prefix %>irregular.ninja" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/<%= $prefix %>irregular.ninja.fullchain.pem"
+ key "/etc/ssl/private/<%= $prefix %>irregular.ninja.key"
+ }
+ location * {
+ root "/htdocs/irregular.ninja"
+ directory auto index
+ }
+}
+
+# buetow.org special host.
+server "<%= $prefix %>buetow.org" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/<%= $prefix %>buetow.org.fullchain.pem"
+ key "/etc/ssl/private/<%= $prefix %>buetow.org.key"
+ }
+ block return 302 "https://paul.buetow.org"
+}
+
+server "<%= $prefix %>paul.buetow.org" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/<%= $prefix %>paul.buetow.org.fullchain.pem"
+ key "/etc/ssl/private/<%= $prefix %>paul.buetow.org.key"
+ }
+ block return 302 "https://foo.zone/contact-information.html"
+}
+
+server "<%= $prefix %>tmp.buetow.org" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/<%= $prefix %>tmp.buetow.org.fullchain.pem"
+ key "/etc/ssl/private/<%= $prefix %>tmp.buetow.org.key"
+ }
+ root "/htdocs/buetow.org/tmp"
+ directory auto index
+}
+```
+
+and this the `relayd.conf.tpl`:
+
+
+```
+<%
+ our $primary = $is_primary->($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+%>
+
+log connection
+
+tcp protocol "gemini" {
+ tls keypair <%= $prefix %>foo.zone
+ tls keypair <%= $prefix %>buetow.org
+}
+
+relay "gemini4" {
+ listen on <%= $vio0_ip %> port 1965 tls
+ protocol "gemini"
+ forward to 127.0.0.1 port 11965
+}
+
+relay "gemini6" {
+ listen on <%= $ipv6address->($hostname) %> port 1965 tls
+ protocol "gemini"
+ forward to 127.0.0.1 port 11965
+}
+```
+
+And last but not least, this is the `smtpd.conf.tpl`:
+
+```
+<%
+ our $primary = $is_primary->($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+%>
+
+pki "buetow_org_tls" cert "/etc/ssl/<%= $prefix %>buetow.org.fullchain.pem"
+pki "buetow_org_tls" key "/etc/ssl/private/<%= $prefix %>buetow.org.key"
+
+table aliases file:/etc/mail/aliases
+table virtualdomains file:/etc/mail/virtualdomains
+table virtualusers file:/etc/mail/virtualusers
+
+listen on socket
+listen on all tls pki "buetow_org_tls" hostname "<%= $prefix %>buetow.org"
+#listen on all
+
+action localmail mbox alias <aliases>
+action receive mbox virtual <virtualusers>
+action outbound relay
+
+match from any for domain <virtualdomains> action receive
+match from local for local action localmail
+match from local for any action outbound
+```
+
+## All pieces together
+
+For the full `Rexfile` example and all the templates, please look at the Git repository:
+
+=> https://codeberg.org/snonux/rexfiles
+
+Besides of ACME, also other things, such as DNS server, are rexified too. The following command will run all the Rex tasks and configure everything on my frontend machines automatically:
+
+```
+rex commons
+```
+
+The `commons` is a group of task I specified which combines a set of common tasks I always want to execute on all frontend machines. This also includes the ACME tasks mentioned in this article!
+
+## Conclusion
+
+ACME and Let's Encrypt greatly help reducing recurring manual maintenance work (creating and renewing certificates). Furthermore, all the certificates are free of costs! I love to use OpenBSD and Rex to automate all of this.
+
+OpenBSD suits perfectly here as all the tools are already part of the base installation. Rex is not as powerful and popular as other configuration management systems (e.g. Puppet, Chef, SALT or even Ansible). It is more of an underdog and the community is small. But I like underdogs.
+
+I love the fact that a `Rexfile` is just a Perl DSL. Why re-inventing the wheel? Also, OpenBSD comes with Perl in the base system. So no new programming language had to be added to my mix for the configuration management system. Also, the `acme.sh` shell script is not a Bash but a standard Bourne shell script so that I didn't have to install yet another shell as OpenBSD does not come with the Bash pre-installed.
+
+E-Mail me your comments to paul at buetow dot org! :-)
+
+=> ../ Go back to the main site
diff --git a/gemfeed/2022-08-27-gemtexter-1.1.0-lets-gemtext-again.gmi b/gemfeed/2022-08-27-gemtexter-1.1.0-lets-gemtext-again.gmi
new file mode 100644
index 00000000..30121d57
--- /dev/null
+++ b/gemfeed/2022-08-27-gemtexter-1.1.0-lets-gemtext-again.gmi
@@ -0,0 +1,91 @@
+# Gemtexter 1.1.0 - Let's Gemtext again
+
+> Published by Paul at 2022-08-27
+
+```
+-=[ typewriter ]=- 1/98
+
+ .-------.
+ _|~~ ~~ |_
+ =(_|_______|_)=
+ |:::::::::|
+ |:::::::[]|
+ |o=======.|
+ jgs `"""""""""`
+```
+
+I am proud to announce that I've released Gemtexter version `1.1.0`. What is Gemtexter? It's my static site generator written in GNU Bash:
+
+=> ./2021-06-05-gemtexter-one-bash-script-to-rule-it-all.gmi Gemtexter - One Bash script to rule it all
+=> https://codeberg.org/snonux/gemtexter
+
+It has been around a year since I released the first version `1.0.0`. Although, there aren't any groundbreaking changes, there have been a couple of smaller commits and adjustments. I was quite surprised that I received a bunch of feedback and requests about Gemtexter so it means that I am not the only person in the universe actually using it.
+
+## What's new?
+
+### Automatic check for GNU version requirements
+
+Gemtexter relies on the GNU versions of the tools `grep`, `sed` and `date` and it also requires the Bash shell in version 5 at least. That's now done in the `check_dependencies()` function:
+
+```
+check_dependencies () {
+ # At least, Bash 5 is required
+ local -i required_version=5
+ IFS=. read -ra version <<< "$BASH_VERSION"
+ if [ "${version[0]}" -lt $required_version ]; then
+ log ERROR "ERROR, \"bash\" must be at least at major version $required_version!"
+ exit 2
+ fi
+
+ # These must be the GNU versions of the commands
+ for tool in $DATE $SED $GREP; do
+ if ! $tool --version | grep -q GNU; then
+ log ERROR "ERROR, \"$tool\" command is not the GNU version, please install!"
+ exit 2
+ fi
+ done
+}
+```
+
+Especially macOS users didn't read the `README` carefully enough to install GNU Grep, GNU Sed and GNU Date before using Gemtexter.
+
+### Backticks now produce `inline code blocks` in the HTML output
+
+The Gemtext format doesn't support inline code blocks, but Gemtexter now produces `inline code blocks` (means, small code fragments can be placed in the middle of a paragraph) in the HTML output when the code block is enclosed with Backticks. There were no adjustments required for the Markdown output format, because Markdown supports it already out of the box.
+
+### Cache for Atom feed generation
+
+The Bash is not the most performant language. Gemtexter already takes a couple of seconds only to generate the Atom feed for around two hand full of articles on my slightly underpowered Surface Go 2 Linux tablet. Therefore, I introduced a cache, so that subsequent Atom feed generation runs finish much quicker. The cache uses a checksum of the Gemtext `.gmi` file to decide whether anything of the content has changed or not.
+
+### Input filter support
+
+Once your capsule reaches a certain size, it can become annoying to re-generate everything if you only want to preview the HTML or Markdown output of one single content file. The following will add a filter to only generate the files matching a regular expression:
+
+```
+./gemtexter --generate '.*hello.*'
+```
+
+### Revamped `git` support
+
+The Git support has been completely rewritten. It's now more reliable and faster too. Have a look at the `README` for more information.
+
+### Addition of `htmlextras` and web font support
+
+The `htmlextras` folder now contains all extra files required for the HTML output format such as cascading style sheet (CSS) files and web fonts.
+
+### Sub-section support
+
+It's now possible to define sub-sections within a Gemtexter capsule. For the HTML output, each sub-section can use its own CSS and web font definitions. E.g.:
+
+=> https://foo.zone The foo.zone main site
+=> https://foo.zone/notes The notes sub-section (with different fonts)
+
+### More
+
+Additionally, there were a couple of bug fixes, refactorings and overall improvements in the documentation made.
+
+Overall, it's a pretty solid `1.1.0` release without anything groundbreaking (therefore no major version jump). But I am happy about it.
+
+E-Mail me your comments to paul at buetow dot org! :-)
+
+=> ../ Go back to the main site
diff --git a/gemfeed/atom.xml b/gemfeed/atom.xml
index ca42dddf..b3427605 100644
--- a/gemfeed/atom.xml
+++ b/gemfeed/atom.xml
@@ -1,12 +1,695 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
- <updated>2022-07-07T22:06:15+03:00</updated>
+ <updated>2022-08-28T10:16:27+01:00</updated>
<title>foo.zone feed</title>
<subtitle>To be in the .zone!</subtitle>
<link href="gemini://foo.zone/gemfeed/atom.xml" rel="self" />
<link href="gemini://foo.zone/" />
<id>gemini://foo.zone/</id>
<entry>
+ <title>Gemtexter 1.1.0 - Let's Gemtext again</title>
+ <link href="gemini://foo.zone/gemfeed/2022-08-27-gemtexter-1.1.0-lets-gemtext-again.gmi" />
+ <id>gemini://foo.zone/gemfeed/2022-08-27-gemtexter-1.1.0-lets-gemtext-again.gmi</id>
+ <updated>2022-08-27T18:25:57+01:00</updated>
+ <author>
+ <name>Paul C. Buetow</name>
+ <email>comments@mx.buetow.org</email>
+ </author>
+ <summary>I am proud to announce that I've released Gemtexter version . What is Gemtexter? It's my static site generator written in GNU Bash:. .....to read on please visit my site.</summary>
+ <content type="xhtml">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ <h1>Gemtexter 1.1.0 - Let's Gemtext again</h1>
+<p class="quote"><i>Published by Paul at 2022-08-27</i></p>
+<pre>
+-=[ typewriter ]=- 1/98
+
+ .-------.
+ _|~~ ~~ |_
+ =(_|_______|_)=
+ |:::::::::|
+ |:::::::[]|
+ |o=======.|
+ jgs <span class="inlinecode">"""""""""</span>
+</pre><br />
+<p>I am proud to announce that I've released Gemtexter version <span class="inlinecode">1.1.0</span>. What is Gemtexter? It's my static site generator written in GNU Bash:</p>
+<a class="textlink" href="https://foo.zone/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html">Gemtexter - One Bash script to rule it all</a><br />
+<a class="textlink" href="https://codeberg.org/snonux/gemtexter">https://codeberg.org/snonux/gemtexter</a><br />
+<p>It has been around a year since I released the first version <span class="inlinecode">1.0.0</span>. Although, there aren't any groundbreaking changes, there have been a couple of smaller commits and adjustments. I was quite surprised that I received a bunch of feedback and requests about Gemtexter so it means that I am not the only person in the universe actually using it.</p>
+<h2>What's new?</h2>
+<h3>Automatic check for GNU version requirements</h3>
+<p>Gemtexter relies on the GNU versions of the tools <span class="inlinecode">grep</span>, <span class="inlinecode">sed</span> and <span class="inlinecode">date</span> and it also requires the Bash shell in version 5 at least. That's now done in the <span class="inlinecode">check_dependencies()</span> function:</p>
+<pre>
+check_dependencies () {
+ # At least, Bash 5 is required
+ local -i required_version=5
+ IFS=. read -ra version &lt;&lt;&lt; "$BASH_VERSION"
+ if [ "${version[0]}" -lt $required_version ]; then
+ log ERROR "ERROR, \"bash\" must be at least at major version $required_version!"
+ exit 2
+ fi
+
+ # These must be the GNU versions of the commands
+ for tool in $DATE $SED $GREP; do
+ if ! $tool --version | grep -q GNU; then
+ log ERROR "ERROR, \"$tool\" command is not the GNU version, please install!"
+ exit 2
+ fi
+ done
+}
+</pre><br />
+<p>Especially macOS users didn't read the <span class="inlinecode">README</span> carefully enough to install GNU Grep, GNU Sed and GNU Date before using Gemtexter.</p>
+<h3>Backticks now produce <span class="inlinecode">inline code blocks</span> in the HTML output</h3>
+<p>The Gemtext format doesn't support inline code blocks, but Gemtexter now produces <span class="inlinecode">inline code blocks</span> (means, small code fragments can be placed in the middle of a paragraph) in the HTML output when the code block is enclosed with Backticks. There were no adjustments required for the Markdown output format, because Markdown supports it already out of the box.</p>
+<h3>Cache for Atom feed generation</h3>
+<p>The Bash is not the most performant language. Gemtexter already takes a couple of seconds only to generate the Atom feed for around two hand full of articles on my slightly underpowered Surface Go 2 Linux tablet. Therefore, I introduced a cache, so that subsequent Atom feed generation runs finish much quicker. The cache uses a checksum of the Gemtext <span class="inlinecode">.gmi</span> file to decide whether anything of the content has changed or not.</p>
+<h3>Input filter support</h3>
+<p>Once your capsule reaches a certain size, it can become annoying to re-generate everything if you only want to preview the HTML or Markdown output of one single content file. The following will add a filter to only generate the files matching a regular expression:</p>
+<pre>
+./gemtexter --generate '.*hello.*'
+</pre><br />
+<h3>Revamped <span class="inlinecode">git</span> support</h3>
+<p>The Git support has been completely rewritten. It's now more reliable and faster too. Have a look at the <span class="inlinecode">README</span> for more information.</p>
+<h3>Addition of <span class="inlinecode">htmlextras</span> and web font support</h3>
+<p>The <span class="inlinecode">htmlextras</span> folder now contains all extra files required for the HTML output format such as cascading style sheet (CSS) files and web fonts.</p>
+<h3>Sub-section support</h3>
+<p>It's now possible to define sub-sections within a Gemtexter capsule. For the HTML output, each sub-section can use its own CSS and web font definitions. E.g.:</p>
+<a class="textlink" href="https://foo.zone">The foo.zone main site</a><br />
+<a class="textlink" href="https://foo.zone/notes">The notes sub-section (with different fonts)</a><br />
+<h3>More</h3>
+<p>Additionally, there were a couple of bug fixes, refactorings and overall improvements in the documentation made. </p>
+<p>Overall, it's a pretty solid <span class="inlinecode">1.1.0</span> release without anything groundbreaking (therefore no major version jump). But I am happy about it.</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
+ </div>
+ </content>
+ </entry>
+ <entry>
+ <title>Let's Encrypt with OpenBSD and Rex</title>
+ <link href="gemini://foo.zone/gemfeed/2022-07-30-lets-encrypt-with-openbsd-and-rex.gmi" />
+ <id>gemini://foo.zone/gemfeed/2022-07-30-lets-encrypt-with-openbsd-and-rex.gmi</id>
+ <updated>2022-07-30T12:14:31+01:00</updated>
+ <author>
+ <name>Paul C. Buetow</name>
+ <email>comments@mx.buetow.org</email>
+ </author>
+ <summary>I was amazed how easy it is to automatically generate and update Let's Encrypt certificates with OpenBSD.. .....to read on please visit my site.</summary>
+ <content type="xhtml">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ <h1>Let's Encrypt with OpenBSD and Rex</h1>
+<p class="quote"><i>Published by Paul at 2022-07-30</i></p>
+<pre>
+ / _ \
+ The Hebern Machine \ ." ". /
+ ___ / \
+ .."" "".. | O |
+ / \ | |
+ / \ | |
+ ---------------------------------
+ _/ o (O) o _ |
+ _/ ." ". |
+ I/ _________________/ \ |
+ _/I ." | |
+ ===== / I / / |
+ ===== | | | \ | _________________." |
+===== | | | | | / \ / _|_|__|_|_ __ |
+ | | | | | | | \ "._." / o o \ ." ". |
+ | --| --| -| / \ _/ / \ |
+ \____\____\__| \ ______ | / | | |
+ -------- --- / | | |
+ ( ) (O) / \ / |
+ ----------------------- ".__." |
+ _|__________________________________________|_
+ / \
+ /________________________________________________\
+ ASCII Art by John Savard
+</pre><br />
+<p>I was amazed how easy it is to automatically generate and update Let's Encrypt certificates with OpenBSD.</p>
+<h2>What's Let's Encrypt?</h2>
+<p class="quote"><i>Let's Encrypt is a non-profit certificate authority run by Internet Security Research Group that provides X.509 certificates for Transport Layer Security (TLS) encryption at no charge. It is the world's largest certificate authority, used by more than 265 million websites, with the goal of all websites being secure and using HTTPS.</i></p>
+<a class="textlink" href="https://en.wikipedia.org/wiki/Let's_Encrypt">Source: Wikipedia</a><br />
+<p>In short, it gives away TLS certificates for your website - for free! The catch is, that the certificates are only valid for three months. So it is better to automate certificate generation and renevals.</p>
+<h2>Meet <span class="inlinecode">acme-client</span></h2>
+<p><span class="inlinecode">acme-client</span> is the default Automatic Certifcate Management Environment (ACME) client on OpenBSD and part of the OpenBSD base system. </p>
+<p>When invoked, the client first checks whether certificates actually require to be generated.</p>
+<ul>
+<li>It first checks whether a certificate already exists, if not, it will attempt to generate a new one.</li>
+<li>If the certificate already exists but expires within the next 30 days, it will renew it.</li>
+<li>Otherwise, <span class="inlinecode">acme-client</span> won't do anything.</li>
+</ul>
+<p>Oversimplified, the following steps are undertaken by <span class="inlinecode">acme-client</span> for generating a new certificate:</p>
+<ul>
+<li>Reading its config file <span class="inlinecode">/etc/acme-client.conf</span> for a list of hosts (and their alternative names) to generate certificates for. So it means you can also have certificates for abritary subdomains!</li>
+<li>Automatic generation of the private certificate part (the certificate key) and the certificate signing request (CSR) to <span class="inlinecode">/etc/ssl/...</span>.</li>
+<li>Requesting Let's Encrypt to sign the certificate. This also includes providing a set of temporary files which will be requested by Let's Encrypt in the next step for verification.</li>
+<li>Let's Encrypt then will contact the hostname for the certificate through a special URL (e.g. <span class="inlinecode">http://foo.zone/.well-known/acme-challenge/...</span>) to verify that the requester is the valid owner of the host.</li>
+<li>Let's Encrypt generates a certificate, which then is downloaded to <span class="inlinecode">/etc/ssl/...</span>.</li>
+</ul>
+<h2>Configuration</h2>
+<p>There is some (but easy) configuration required to make that all work on OpenBSD.</p>
+<h3>acme-client.conf</h3>
+<p>This is how my <span class="inlinecode">/etc/acme-client.conf</span> looks like (I copied a template from <span class="inlinecode">/etc/examples/acme-client.conf</span> to <span class="inlinecode">/etc/acme-client.conf</span> and added my domains to the bottom:</p>
+<pre>
+#
+# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
+#
+authority letsencrypt {
+ api url "https://acme-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-privkey.pem"
+}
+
+authority letsencrypt-staging {
+ api url "https://acme-staging-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-staging-privkey.pem"
+}
+
+authority buypass {
+ api url "https://api.buypass.com/acme/directory"
+ account key "/etc/acme/buypass-privkey.pem"
+ contact "mailto:me@example.com"
+}
+
+authority buypass-test {
+ api url "https://api.test4.buypass.no/acme/directory"
+ account key "/etc/acme/buypass-test-privkey.pem"
+ contact "mailto:me@example.com"
+}
+
+domain buetow.org {
+ alternative names { www.buetow.org paul.buetow.org }
+ domain key "/etc/ssl/private/buetow.org.key"
+ domain full chain certificate "/etc/ssl/buetow.org.fullchain.pem"
+ sign with letsencrypt
+}
+
+domain dtail.dev {
+ alternative names { www.dtail.dev }
+ domain key "/etc/ssl/private/dtail.dev.key"
+ domain full chain certificate "/etc/ssl/dtail.dev.fullchain.pem"
+ sign with letsencrypt
+}
+
+domain foo.zone {
+ alternative names { www.foo.zone }
+ domain key "/etc/ssl/private/foo.zone.key"
+ domain full chain certificate "/etc/ssl/foo.zone.fullchain.pem"
+ sign with letsencrypt
+}
+
+domain irregular.ninja {
+ alternative names { www.irregular.ninja }
+ domain key "/etc/ssl/private/irregular.ninja.key"
+ domain full chain certificate "/etc/ssl/irregular.ninja.fullchain.pem"
+ sign with letsencrypt
+}
+
+domain snonux.land {
+ alternative names { www.snonux.land }
+ domain key "/etc/ssl/private/snonux.land.key"
+ domain full chain certificate "/etc/ssl/snonux.land.fullchain.pem"
+ sign with letsencrypt
+}
+</pre><br />
+<h3>httpd.conf</h3>
+<p>For ACME to work you will also need to configure the HTTP daemon so that the "special" ACME requests made from Let's Encrypt are served correctly. I am using the standard OpenBSD <span class="inlinecode">httpd</span> here. These are the snippets I use for the <span class="inlinecode">foo.zone</span> host in <span class="inlinecode">/etc/httpd.conf</span> (of course, you need similar setup for all other hosts as well):</p>
+<pre>
+server "foo.zone" {
+ listen on * port 80
+ location "/.well-known/acme-challenge/*" {
+ root "/acme"
+ request strip 2
+ }
+ location * {
+ block return 302 "https://$HTTP_HOST$REQUEST_URI"
+ }
+}
+
+server "foo.zone" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/foo.zone.fullchain.pem"
+ key "/etc/ssl/private/foo.zone.key"
+ }
+ location * {
+ root "/htdocs/gemtexter/foo.zone"
+ directory auto index
+ }
+}
+</pre><br />
+<p>As you see, plain HTTP only serves the ACME challenge path. Otherwise, it is redirecting the requests to TLS. The TLS section then attempts to use the Let's Encrypt certificates.</p>
+<p>It is worth noticing that <span class="inlinecode">httpd</span> will start without the certificates actually being present. This will cause a certificate error when you try to reach the HTTPS endpoint but it helps to bootstrap Let's Encrypt. As you saw in the config snippet above, Let's Encrypt only requests the plain HTTP endpoint for the verification process so that HTTPS doesn't need to be operational yet at this stage. But once the certificates are generated, you will have to reload or restart <span class="inlinecode">httpd</span> in order to use any new certificate.</p>
+<h3>CRON job</h3>
+<p>You could now run <span class="inlinecode">doas acme-client foo.zone</span> to generate the certificate or to renew it. Or you could automate it with CRON.</p>
+<p>I have created a script <span class="inlinecode">/usr/local/bin/acme.sh</span> for that for all of my domains:</p>
+<pre>
+#!/bin/sh
+
+function handle_cert {
+ host=$1
+ # Create symlink, so that relayd also can read it.
+ crt_path=/etc/ssl/$host
+ if [ -e $crt_path.crt ]; then
+ rm $crt_path.crt
+ fi
+ ln -s $crt_path.fullchain.pem $crt_path.crt
+ # Requesting and renewing certificate.
+ /usr/sbin/acme-client -v $host
+}
+
+has_update=no
+handle_cert www.buetow.org
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.paul.buetow.org
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.tmp.buetow.org
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.dtail.dev
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.foo.zone
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.irregular.ninja
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+handle_cert www.snonux.land
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+
+# Pick up the new certs.
+if [ $has_update = yes ]; then
+ /usr/sbin/rcctl reload httpd
+ /usr/sbin/rcctl reload relayd
+ /usr/sbin/rcctl restart smtpd
+fi
+</pre><br />
+<p>And added the following line to <span class="inlinecode">/etc/daily.local</span> to run the script once daily so that certificates will be renewed fully automatically:</p>
+<pre>
+/usr/local/bin/acme.sh
+</pre><br />
+<p>I am receiving a daily output via E-Mail like this now:</p>
+<pre>
+Running daily.local:
+acme-client: /etc/ssl/buetow.org.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/paul.buetow.org.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/tmp.buetow.org.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/dtail.dev.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/foo.zone.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/irregular.ninja.fullchain.pem: certificate valid: 80 days left
+acme-client: /etc/ssl/snonux.land.fullchain.pem: certificate valid: 79 days left
+</pre><br />
+<h2>relayd.conf and smtpd.conf</h2>
+<p>Besides of <span class="inlinecode">httpd</span>, <span class="inlinecode">relayd</span> (mainly for Gemini) and <span class="inlinecode">smtpd</span> (for mail, of course) also use TLS certificates. And as you can see in <span class="inlinecode">acme.sh</span>, the services are also reloaded or restarted (<span class="inlinecode">smtpd</span> doesn't support reload) whenever a certificate was generated or updated.</p>
+<h2>Rexification</h2>
+<p>I didn't write all these configuration files by hand. As a matter of fact, everything is automated with the Rex configuration management system.</p>
+<a class="textlink" href="https://www.rexify.org">https://www.rexify.org</a><br />
+<p>At the top of the <span class="inlinecode">Rexfile</span> I define all my hosts:</p>
+<pre>
+our @acme_hosts = qw/buetow.org paul.buetow.org tmp.buetow.org dtail.dev foo.zone irregular.ninja snonux.land/;
+</pre><br />
+<h3>General ACME client configuration</h3>
+<p>ACME will be installed into the frontend group of hosts. Here, blowfish is the primary, and twofish the secondary OpenBSD box.</p>
+<pre>
+group frontends =&gt; 'blowfish.buetow.org', 'twofish.buetow.org';
+</pre><br />
+<p>This is my Rex task for the general ACME configuration:</p>
+<pre>
+desc 'Configure ACME client';
+task 'acme', group =&gt; 'frontends',
+ sub {
+ file '/etc/acme-client.conf',
+ content =&gt; template('./etc/acme-client.conf.tpl',
+ acme_hosts =&gt; \@acme_hosts,
+ is_primary =&gt; $is_primary),
+ owner =&gt; 'root',
+ group =&gt; 'wheel',
+ mode =&gt; '644';
+
+ file '/usr/local/bin/acme.sh',
+ content =&gt; template('./scripts/acme.sh.tpl',
+ acme_hosts =&gt; \@acme_hosts,
+ is_primary =&gt; $is_primary),
+ owner =&gt; 'root',
+ group =&gt; 'wheel',
+ mode =&gt; '744';
+
+ file '/etc/daily.local',
+ ensure =&gt; 'present',
+ owner =&gt; 'root',
+ group =&gt; 'wheel',
+ mode =&gt; '644';
+
+ append_if_no_such_line '/etc/daily.local', '/usr/local/bin/acme.sh';
+ };
+</pre><br />
+<p>And there is also a Rex task just to run the ACME script remotely:</p>
+<pre>
+desc 'Invoke ACME client';
+task 'acme_invoke', group =&gt; 'frontends',
+ sub {
+ say run '/usr/local/bin/acme.sh';
+ };
+
+</pre><br />
+<p>Furthermore, this snippet (also at the top of the Rexfile) helps to determine whether the current server is the primary server (all hosts will be without the <span class="inlinecode">www.</span> prefix) or the secondary server (all hosts will be with the <span class="inlinecode">www.</span> prefix):</p>
+<pre>
+# Bootstrapping the FQDN based on the server IP as the hostname and domain
+# facts aren't set yet due to the myname file in the first place.
+our $fqdns = sub {
+ my $ipv4 = shift;
+ return 'blowfish.buetow.org' if $ipv4 eq '23.88.35.144';
+ return 'twofish.buetow.org' if $ipv4 eq '108.160.134.135';
+ Rex::Logger::info("Unable to determine hostname for $ipv4", 'error');
+ return 'HOSTNAME-UNKNOWN.buetow.org';
+};
+
+# To determine whether the server is the primary or the secondary.
+our $is_primary = sub {
+ my $ipv4 = shift;
+ $fqdns-&gt;($ipv4) eq 'blowfish.buetow.org';
+};
+</pre><br />
+<p>The following is the <span class="inlinecode">acme-client.conf.tpl</span> Rex template file used for the automation. You see here that the <span class="inlinecode">www.</span> prefix isn't sent for the primary server. E.g. <span class="inlinecode">foo.zone</span> will be served by the primary server (in my case a server located in Germany) and <span class="inlinecode">www.foo.zone</span> by the secondary server (in my case a server located in Japan):</p>
+<pre>
+#
+# $OpenBSD: acme-client.conf,v 1.4 2020/09/17 09:13:06 florian Exp $
+#
+authority letsencrypt {
+ api url "https://acme-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-privkey.pem"
+}
+
+authority letsencrypt-staging {
+ api url "https://acme-staging-v02.api.letsencrypt.org/directory"
+ account key "/etc/acme/letsencrypt-staging-privkey.pem"
+}
+
+authority buypass {
+ api url "https://api.buypass.com/acme/directory"
+ account key "/etc/acme/buypass-privkey.pem"
+ contact "mailto:me@example.com"
+}
+
+authority buypass-test {
+ api url "https://api.test4.buypass.no/acme/directory"
+ account key "/etc/acme/buypass-test-privkey.pem"
+ contact "mailto:me@example.com"
+}
+
+&lt;%
+ our $primary = $is_primary-&gt;($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+%&gt;
+
+&lt;% for my $host (@$acme_hosts) { %&gt;
+domain &lt;%= $prefix.$host %&gt; {
+ domain key "/etc/ssl/private/&lt;%= $prefix.$host %&gt;.key"
+ domain full chain certificate "/etc/ssl/&lt;%= $prefix.$host %&gt;.fullchain.pem"
+ sign with letsencrypt
+}
+&lt;% } %&gt;
+
+</pre><br />
+<p>And this is the <span class="inlinecode">acme.sh.tpl</span>:</p>
+<pre>
+#!/bin/sh
+
+&lt;%
+ our $primary = $is_primary-&gt;($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+-%&gt;
+
+function handle_cert {
+ host=$1
+ # Create symlink, so that relayd also can read it.
+ crt_path=/etc/ssl/$host
+ if [ -e $crt_path.crt ]; then
+ rm $crt_path.crt
+ fi
+ ln -s $crt_path.fullchain.pem $crt_path.crt
+ # Requesting and renewing certificate.
+ /usr/sbin/acme-client -v $host
+}
+
+has_update=no
+&lt;% for my $host (@$acme_hosts) { -%&gt;
+handle_cert &lt;%= $prefix.$host %&gt;
+if [ $? -eq 0 ]; then
+ has_update=yes
+fi
+&lt;% } -%&gt;
+
+# Pick up the new certs.
+if [ $has_update = yes ]; then
+ /usr/sbin/rcctl reload httpd
+ /usr/sbin/rcctl reload relayd
+ /usr/sbin/rcctl restart smtpd
+fi
+</pre><br />
+<h3>Service rexification </h3>
+<p>These are the Rex tasks setting up <span class="inlinecode">httpd</span>, <span class="inlinecode">relayd</span> and <span class="inlinecode">smtpd</span> services:</p>
+<pre>
+desc 'Setup httpd';
+task 'httpd', group =&gt; 'frontends',
+ sub {
+ append_if_no_such_line '/etc/rc.conf.local', 'httpd_flags=';
+
+ file '/etc/httpd.conf',
+ content =&gt; template('./etc/httpd.conf.tpl',
+ acme_hosts =&gt; \@acme_hosts,
+ is_primary =&gt; $is_primary),
+ owner =&gt; 'root',
+ group =&gt; 'wheel',
+ mode =&gt; '644',
+ on_change =&gt; sub { service 'httpd' =&gt; 'restart' };
+
+ service 'httpd', ensure =&gt; 'started';
+ };
+
+desc 'Setup relayd';
+task 'relayd', group =&gt; 'frontends',
+ sub {
+ append_if_no_such_line '/etc/rc.conf.local', 'relayd_flags=';
+
+ file '/etc/relayd.conf',
+ content =&gt; template('./etc/relayd.conf.tpl',
+ ipv6address =&gt; $ipv6address,
+ is_primary =&gt; $is_primary),
+ owner =&gt; 'root',
+ group =&gt; 'wheel',
+ mode =&gt; '600',
+ on_change =&gt; sub { service 'relayd' =&gt; 'restart' };
+
+ service 'relayd', ensure =&gt; 'started';
+ };
+
+desc 'Setup OpenSMTPD';
+task 'smtpd', group =&gt; 'frontends',
+ sub {
+ Rex::Logger::info('Dealing with mail aliases');
+ file '/etc/mail/aliases',
+ source =&gt; './etc/mail/aliases',
+ owner =&gt; 'root',
+ group =&gt; 'wheel',
+ mode =&gt; '644',
+ on_change =&gt; sub { say run 'newaliases' };
+
+ Rex::Logger::info('Dealing with mail virtual domains');
+ file '/etc/mail/virtualdomains',
+ source =&gt; './etc/mail/virtualdomains',
+ owner =&gt; 'root',
+ group =&gt; 'wheel',
+ mode =&gt; '644',
+ on_change =&gt; sub { service 'smtpd' =&gt; 'restart' };
+
+ Rex::Logger::info('Dealing with mail virtual users');
+ file '/etc/mail/virtualusers',
+ source =&gt; './etc/mail/virtualusers',
+ owner =&gt; 'root',
+ group =&gt; 'wheel',
+ mode =&gt; '644',
+ on_change =&gt; sub { service 'smtpd' =&gt; 'restart' };
+
+ Rex::Logger::info('Dealing with smtpd.conf');
+ file '/etc/mail/smtpd.conf',
+ content =&gt; template('./etc/mail/smtpd.conf.tpl',
+ is_primary =&gt; $is_primary),
+ owner =&gt; 'root',
+ group =&gt; 'wheel',
+ mode =&gt; '644',
+ on_change =&gt; sub { service 'smtpd' =&gt; 'restart' };
+
+ service 'smtpd', ensure =&gt; 'started';
+ };
+
+</pre><br />
+<p>This is <span class="inlinecode">httpd.conf.tpl</span>:</p>
+<pre>
+&lt;%
+ our $primary = $is_primary-&gt;($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+%&gt;
+
+# Plain HTTP for ACME and HTTPS redirect
+&lt;% for my $host (@$acme_hosts) { %&gt;
+server "&lt;%= $prefix.$host %&gt;" {
+ listen on * port 80
+ location "/.well-known/acme-challenge/*" {
+ root "/acme"
+ request strip 2
+ }
+ location * {
+ block return 302 "https://$HTTP_HOST$REQUEST_URI"
+ }
+}
+&lt;% } %&gt;
+
+# Gemtexter hosts
+&lt;% for my $host (qw/foo.zone snonux.land/) { %&gt;
+server "&lt;%= $prefix.$host %&gt;" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/&lt;%= $prefix.$host %&gt;.fullchain.pem"
+ key "/etc/ssl/private/&lt;%= $prefix.$host %&gt;.key"
+ }
+ location * {
+ root "/htdocs/gemtexter/&lt;%= $host %&gt;"
+ directory auto index
+ }
+}
+&lt;% } %&gt;
+
+# DTail special host
+server "&lt;%= $prefix %&gt;dtail.dev" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/&lt;%= $prefix %&gt;dtail.dev.fullchain.pem"
+ key "/etc/ssl/private/&lt;%= $prefix %&gt;dtail.dev.key"
+ }
+ location * {
+ block return 302 "https://github.dtail.dev$REQUEST_URI"
+ }
+}
+
+# Irregular Ninja special host
+server "&lt;%= $prefix %&gt;irregular.ninja" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/&lt;%= $prefix %&gt;irregular.ninja.fullchain.pem"
+ key "/etc/ssl/private/&lt;%= $prefix %&gt;irregular.ninja.key"
+ }
+ location * {
+ root "/htdocs/irregular.ninja"
+ directory auto index
+ }
+}
+
+# buetow.org special host.
+server "&lt;%= $prefix %&gt;buetow.org" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/&lt;%= $prefix %&gt;buetow.org.fullchain.pem"
+ key "/etc/ssl/private/&lt;%= $prefix %&gt;buetow.org.key"
+ }
+ block return 302 "https://paul.buetow.org"
+}
+
+server "&lt;%= $prefix %&gt;paul.buetow.org" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/&lt;%= $prefix %&gt;paul.buetow.org.fullchain.pem"
+ key "/etc/ssl/private/&lt;%= $prefix %&gt;paul.buetow.org.key"
+ }
+ block return 302 "https://foo.zone/contact-information.html"
+}
+
+server "&lt;%= $prefix %&gt;tmp.buetow.org" {
+ listen on * tls port 443
+ tls {
+ certificate "/etc/ssl/&lt;%= $prefix %&gt;tmp.buetow.org.fullchain.pem"
+ key "/etc/ssl/private/&lt;%= $prefix %&gt;tmp.buetow.org.key"
+ }
+ root "/htdocs/buetow.org/tmp"
+ directory auto index
+}
+</pre><br />
+<p>and this the <span class="inlinecode">relayd.conf.tpl</span>:</p>
+<pre>
+&lt;%
+ our $primary = $is_primary-&gt;($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+%&gt;
+
+log connection
+
+tcp protocol "gemini" {
+ tls keypair &lt;%= $prefix %&gt;foo.zone
+ tls keypair &lt;%= $prefix %&gt;buetow.org
+}
+
+relay "gemini4" {
+ listen on &lt;%= $vio0_ip %&gt; port 1965 tls
+ protocol "gemini"
+ forward to 127.0.0.1 port 11965
+}
+
+relay "gemini6" {
+ listen on &lt;%= $ipv6address-&gt;($hostname) %&gt; port 1965 tls
+ protocol "gemini"
+ forward to 127.0.0.1 port 11965
+}
+</pre><br />
+<p>And last but not least, this is the <span class="inlinecode">smtpd.conf.tpl</span>:</p>
+<pre>
+&lt;%
+ our $primary = $is_primary-&gt;($vio0_ip);
+ our $prefix = $primary ? '' : 'www.';
+%&gt;
+
+pki "buetow_org_tls" cert "/etc/ssl/&lt;%= $prefix %&gt;buetow.org.fullchain.pem"
+pki "buetow_org_tls" key "/etc/ssl/private/&lt;%= $prefix %&gt;buetow.org.key"
+
+table aliases file:/etc/mail/aliases
+table virtualdomains file:/etc/mail/virtualdomains
+table virtualusers file:/etc/mail/virtualusers
+
+listen on socket
+listen on all tls pki "buetow_org_tls" hostname "&lt;%= $prefix %&gt;buetow.org"
+#listen on all
+
+action localmail mbox alias &lt;aliases&gt;
+action receive mbox virtual &lt;virtualusers&gt;
+action outbound relay
+
+match from any for domain &lt;virtualdomains&gt; action receive
+match from local for local action localmail
+match from local for any action outbound
+</pre><br />
+<h2>All pieces together</h2>
+<p>For the full <span class="inlinecode">Rexfile</span> example and all the templates, please look at the Git repository:</p>
+<a class="textlink" href="https://codeberg.org/snonux/rexfiles">https://codeberg.org/snonux/rexfiles</a><br />
+<p>Besides of ACME, also other things, such as DNS server, are rexified too. The following command will run all the Rex tasks and configure everything on my frontend machines automatically:</p>
+<pre>
+rex commons
+</pre><br />
+<p>The <span class="inlinecode">commons</span> is a group of task I specified which combines a set of common tasks I always want to execute on all frontend machines. This also includes the ACME tasks mentioned in this article!</p>
+<h2>Conclusion</h2>
+<p>ACME and Let's Encrypt greatly help reducing recurring manual maintenance work (creating and renewing certificates). Furthermore, all the certificates are free of costs! I love to use OpenBSD and Rex to automate all of this.</p>
+<p>OpenBSD suits perfectly here as all the tools are already part of the base installation. Rex is not as powerful and popular as other configuration management systems (e.g. Puppet, Chef, SALT or even Ansible). It is more of an underdog and the community is small. But I like underdogs.</p>
+<p>I love the fact that a <span class="inlinecode">Rexfile</span> is just a Perl DSL. Why re-inventing the wheel? Also, OpenBSD comes with Perl in the base system. So no new programming language had to be added to my mix for the configuration management system. Also, the <span class="inlinecode">acme.sh</span> shell script is not a Bash but a standard Bourne shell script so that I didn't have to install yet another shell as OpenBSD does not come with the Bash pre-installed.</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
+ </div>
+ </content>
+ </entry>
+ <entry>
<title>Sweating the small stuff - Tiny projects of mine</title>
<link href="gemini://foo.zone/gemfeed/2022-06-15-sweating-the-small-stuff.gmi" />
<id>gemini://foo.zone/gemfeed/2022-06-15-sweating-the-small-stuff.gmi</id>
@@ -19,6 +702,7 @@
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Sweating the small stuff - Tiny projects of mine</h1>
+<p class="quote"><i>Published by Paul at 2022-06-15, last updated at 2022-06-18</i></p>
<pre>
_
/_/_ .'''.
@@ -26,7 +710,6 @@
jgs \_\ `. .'''
`..'
</pre><br />
-<p class="quote"><i>Published by Paul at 2022-06-15, last updated at 2022-06-18</i></p>
<p>This blog post is a bit different from the others. It consists of multiple but smaller projects worth mentioning. I got inspired by Julia Evan's "Tiny programs" blog post and the side projects of The Sephist, so I thought I would also write a blog posts listing a couple of small projects of mine:</p>
<a class="textlink" href="https://jvns.ca/blog/2022/03/08/tiny-programs/">Tiny programs</a><br />
<a class="textlink" href="https://thesephist.com/projects/">The Sephist's project list</a><br />
@@ -243,7 +926,7 @@ v = 008 [v = p*c*(s != c ? 2 : 1)] Total logical CPUs
<a class="textlink" href="gemini://konpeito.media">gemini://konpeito.media</a><br />
<p>If you wonder what Gemini is:</p>
<a class="textlink" href="https://foo.zone/gemfeed/2021-04-24-welcome-to-the-geminispace.html">Welcome to the Geminispae</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -260,8 +943,8 @@ v = 008 [v = p*c*(s != c ? 2 : 1)] Total logical CPUs
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Perl is still a great choice</h1>
-<a href="https://foo.zone/gemfeed/2022-05-27-perl-is-still-a-great-choice/regular_expressions.png"><img src="https://foo.zone/gemfeed/2022-05-27-perl-is-still-a-great-choice/regular_expressions.png" /></a><br />
<p class="quote"><i>Published by Paul at 2022-05-27, Comic source: XKCD</i></p>
+<a href="https://foo.zone/gemfeed/2022-05-27-perl-is-still-a-great-choice/regular_expressions.png"><img src="https://foo.zone/gemfeed/2022-05-27-perl-is-still-a-great-choice/regular_expressions.png" /></a><br />
<p>Perl (the Practical Extraction and Report Language) is a battle-tested, mature, multi-paradigm dynamic programming language. Note that it's not called PERL, neither P.E.R.L. nor Pearl. "Perl" is the name of the language and "perl" the name of the interpreter or the interpreter command.</p>
<p>Unfortunately (it makes me sad), Perl's popularity has been declining over the last years as Google trends shows:</p>
<a href="https://foo.zone/gemfeed/2022-05-27-perl-is-still-a-great-choice/googletrendsperl.jpg"><img src="https://foo.zone/gemfeed/2022-05-27-perl-is-still-a-great-choice/googletrendsperl.jpg" /></a><br />
@@ -344,7 +1027,7 @@ v = 008 [v = p*c*(s != c ? 2 : 1)] Total logical CPUs
</ul>
<p>Btw.: Did you know that the first version of PHP was a set of Perl snippets? Only later, PHP became an independent programming language.</p>
<a class="textlink" href="https://www.perl.org">https://www.perl.org</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -361,6 +1044,7 @@ v = 008 [v = p*c*(s != c ? 2 : 1)] Total logical CPUs
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Creative universe</h1>
+<p class="quote"><i>Published by Paul at 2022-04-10, last updated at 2022-04-18</i></p>
<pre>
. + . . . . . .
. . . *
@@ -381,7 +1065,6 @@ v = 008 [v = p*c*(s != c ? 2 : 1)] Total logical CPUs
. . . . . . . . + . . +
- the universe
</pre><br />
-<p class="quote"><i>Published by Paul at 2022-04-10, last updated at 2022-04-18</i></p>
<h2>Prelude</h2>
<p>I have been participating in an annual work-internal project contest (we call it Pet Project contest) since I moved to London and switched jobs to my current employer. I am very happy to say that I won a "silver" prize last week here 🎆. Over the last couple of years I have been a finalist in this contest six times and won some kind of prize five times. Some of my projects were also released as open source software. One had a magazine article published, and for another one I wrote an article on my employer's engineering blog. If you have followed all my posts on this blog (the one you are currently reading), then you have probably figured out what these projects were:</p>
<a class="textlink" href="https://foo.zone/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.html">DTail - The distributed log tail program</a><br />
@@ -451,7 +1134,7 @@ learn () {
<li>The Off Switch; Mark Cropley; Virgin Books</li>
<li>Ultralearning; Scott Young; Thorsons</li>
</ul>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -468,12 +1151,13 @@ learn () {
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>The release of DTail 4.0.0</h1>
+<p class="quote"><i>Published by Paul at 2022-03-06</i></p>
<pre>
,_---~~~~~----._
_,,_,*^____ _____``*g*\"*,
____ _____ _ _ / __/ /' ^. / \ ^@q f
| _ \_ _|_ _(_) | @f | @)) | | @)) l 0 _/
- | | | || |/ _` | | | \`/ \~____ / __ \_____/ \
+ | | | || |/ _<span class="inlinecode"> | | | \</span>/ \~____ / __ \_____/ \
| |_| || | (_| | | | | _l__l_ I
|____/ |_|\__,_|_|_| } [______] I
] | | | |
@@ -481,7 +1165,6 @@ learn () {
| |
| |
</pre><br />
-<p class="quote"><i>Published by Paul at 2022-03-06</i></p>
<p>I have recently released DTail 4.0.0 and this blog post goes through all the new goodies. You can also read my previous post about DTail in case you wonder what DTail is:</p>
<a class="textlink" href="https://foo.zone/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.html">DTail - The distributed log tail program</a><br />
<p>If you want to jump directly to DTail, do it here (there are nice animated gifs which demonstrates the usage pretty well):</p>
@@ -703,7 +1386,7 @@ exec /usr/local/bin/dtailhealth --server localhost:2222
<p>I am a bit busy at the moment with two other pet projects of mine (one internal work-project, and one personal one, the latter you will read about in the next couple of months). If you have ideas (or even a patch), then please don't hesitate to contact me (either via E-Mail or a request at GitHub).</p>
<p>Thanks!</p>
<p>Paul</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -720,6 +1403,7 @@ exec /usr/local/bin/dtailhealth --server localhost:2222
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Computer operating systems I use(d)</h1>
+<p class="quote"><i>Published by Paul at 2022-02-04, updated 2022-02-18</i></p>
<pre>
/( )`
\ \___ / |
@@ -727,20 +1411,19 @@ exec /usr/local/bin/dtailhealth --server localhost:2222
(/\/ \ \ /\
/ / | ` \
O O ) / |
- `-^--'`&lt; '
+ <span class="inlinecode">-^--'</span>&lt; '
(_.) _ ) /
- `.___/` /
+ <span class="inlinecode">.___/</span> /
`-----' /
&lt;----. __ / __ \
&lt;----|====O)))==) \) /====
- &lt;----' `--' `.__,' \
+ &lt;----' <span class="inlinecode">--' </span>.__,' \
| |
\ /
______( (_ / \______
(FL) ,' ,-----' | \
`--{__________) \/ "Berkeley Unix Daemon"
</pre><br />
-<p class="quote"><i>Published by Paul at 2022-02-04, updated 2022-02-18</i></p>
<p>This is a list of Operating Systems I currently use. This list is in no particular order and also will be updated over time. The very first operating system I used was MS-DOS (mainly for games) and the very first Unix like operating system I used was SuSE Linux 5.3. My first smartphone OS was Symbian on a clunky Sony Ericsson device.</p>
<h2>Fedora Linux</h2>
<p>Fedora Linux is the operating system I use on my primary (personal) laptop. It's a ThinkPad X1 Carbon Gen. 9. Lenovo which comes along with official Lenovo Linux support. I already noticed hardware firmware updates being installed directly through Fedora from Lenovo. Fedora is a real powerhouse, cutting-edge and reasonably stable at the same time. It's baked by Red Hat.</p>
@@ -869,7 +1552,7 @@ GNU/kFreeBSD rhea.buetow.org 8.0-RELEASE-p5 FreeBSD 8.0-RELEASE-p5 #2: Sat Nov 2
<a class="textlink" href="https://asteroidos.org/">Asteroids OS - Open source smartphone OS</a><br />
<a class="textlink" href="https://www.dragonflybsd.org/">DragonFly BSD - Fork of FreeBSD 4</a><br />
<a class="textlink" href="http://wiki.postmarketos.org/wiki/Phosh">Phosh (on postmarketOS) - A true Linux shell for the smartphone</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -886,6 +1569,7 @@ GNU/kFreeBSD rhea.buetow.org 8.0-RELEASE-p5 FreeBSD 8.0-RELEASE-p5 #2: Sat Nov 2
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Welcome to the foo.zone</h1>
+<p class="quote"><i>Published by Paul at 2022-01-23</i></p>
<pre>
__
/ _| ___ ___ _______ _ __ ___
@@ -894,7 +1578,6 @@ GNU/kFreeBSD rhea.buetow.org 8.0-RELEASE-p5 FreeBSD 8.0-RELEASE-p5 #2: Sat Nov 2
|_| \___/ \___(_)___\___/|_| |_|\___|
</pre><br />
-<p class="quote"><i>Published by Paul at 2022-01-23</i></p>
<p>I don't count this as a real blog post, but more of an announcement (I aim to write one real post once monthly). From now on, "foo.zone" is the new address of this site. All other addresses will still forward to it and eventually (based on the traffic still going through) will be deactivated.</p>
<p>As you can read on Wikipedia, "foo" is, alongside to "bar" and "baz", a metasyntactic variable (you know what I mean if you are a programmer or IT person):</p>
<a class="textlink" href="https://en.wikipedia.org/wiki/Metasyntactic_variable">https://en.wikipedia.org/wiki/Metasyntactic_variable</a><br />
@@ -916,7 +1599,7 @@ GNU/kFreeBSD rhea.buetow.org 8.0-RELEASE-p5 FreeBSD 8.0-RELEASE-p5 #2: Sat Nov 2
<p>As a funny bit, I almost chose "foo.surf" over "foo.zone" as in "surfing this site", but then decided against it as I would have to tell everyone that I am not into water sports so much. Well, on the other hand, I now may have to explain to non-programmers that I am not a fan of the rock band "Foo Fighters". But that will be acceptable, as I don't expect "normal" people visiting the foo zone as much anyway. If you reached as far, I have to congratulate you. You are not a normal person.</p>
<h2>What about my old hosts</h2>
<p>The host buetow.org will stay. However, not as the primary address for this site. I will keep using it for my personal internet infrastructure as well as for most of my E-Mail addresses. I used buetow.org for that over the past 10 years already anyway and that won't change any time soon. I don't know what I am going to do with snonux.de in the long run. A .de SLD (for Germany) is pretty cheap, so I might just keep it for now. </p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -933,6 +1616,7 @@ GNU/kFreeBSD rhea.buetow.org 8.0-RELEASE-p5 FreeBSD 8.0-RELEASE-p5 #2: Sat Nov 2
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Bash Golf Part 2</h1>
+<p class="quote"><i>Published by Paul at 2022-01-01, last updated at 2022-01-05</i></p>
<pre>
'\ '\ . . |&gt;18&gt;&gt;
@@ -944,7 +1628,6 @@ GNU/kFreeBSD rhea.buetow.org 8.0-RELEASE-p5 FreeBSD 8.0-RELEASE-p5 #2: Sat Nov 2
jgs^^^^^^^`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Art by Joan Stark, mod. by Paul Buetow
</pre><br />
-<p class="quote"><i>Published by Paul at 2022-01-01, last updated at 2022-01-05</i></p>
<p>This is the second blog post about my Bash Golf series. This series is random Bash tips, tricks and weirdnesses I came across. It's a collection of smaller articles I wrote in an older (in German language) blog, which I translated and refreshed with some new content.</p>
<a class="textlink" href="https://foo.zone/gemfeed/2021-11-29-bash-golf-part-1.html">Bash Golf Part 1</a><br />
<a class="textlink" href="https://foo.zone/gemfeed/2022-01-01-bash-golf-part-2.html">Bash Golf Part 2 (you are reading this atm.)</a><br />
@@ -1328,7 +2011,7 @@ PAUL:X:1000:1000:PAUL BUETOW:/HOME/PAUL:/BIN/BASH
❯ echo $?
1
</pre><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -1345,6 +2028,7 @@ PAUL:X:1000:1000:PAUL BUETOW:/HOME/PAUL:/BIN/BASH
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>How to stay sane as a DevOps person </h1>
+<p class="quote"><i>Published by Paul at 2021-12-26, last updated at 2022-01-12</i></p>
<pre>
)
) (( (
@@ -1355,7 +2039,7 @@ PAUL:X:1000:1000:PAUL BUETOW:/HOME/PAUL:/BIN/BASH
| // : | -__ ~__ o)____)),__ - '&gt; &gt;- &gt;
| // : |- \_ \ -\_\ -\ \ \ ~\_ \ -&gt;&gt; - , &gt;&gt;
| // : |_~_\ -\__\ \~'\ \ \, \__ . -&lt;- &gt;&gt;
- `-----._| ` -__`-- - ~~ -- ` --~&gt; &gt;
+ <span class="inlinecode">-----._| </span> -__<span class="inlinecode">-- - ~~ -- </span> --~&gt; &gt;
_/___\_ //)_`// | ||]
_____[_______]_[~~-_ (.L_/ ||
[____________________]' `\_,/'/
@@ -1366,7 +2050,6 @@ PAUL:X:1000:1000:PAUL BUETOW:/HOME/PAUL:/BIN/BASH
-----||-/------`-._/||-o--o---o---
~~~~~'
</pre><br />
-<p class="quote"><i>Published by Paul at 2021-12-26, last updated at 2022-01-12</i></p>
<p>Log4shell (CVE-2021-44228) made it clear, once again, that working in information technology is not an easy job (especially when you are a DevOps person). I thought it would be interesting to summarize a few techniques to help you to relax.</p>
<p>(PS: When I mean DevOps, I also mean Site Reliability Engineers and Sysadmins. I believe SRE, DevOps Engineer and Sysadmin are just synonym titles for the same job).</p>
<a class="textlink" href="https://en.wikipedia.org/wiki/Log4Shell">https://en.wikipedia.org/wiki/Log4Shell</a><br />
@@ -1420,7 +2103,7 @@ PAUL:X:1000:1000:PAUL BUETOW:/HOME/PAUL:/BIN/BASH
<h2>More</h2>
<p>Another blog post worth reading:</p>
<a class="textlink" href="https://unixsheikh.com/articles/how-to-stay-sane-in-todays-world-of-tech.html">https://unixsheikh.com/articles/how-to-stay-sane-in-todays-world-of-tech.html</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -1437,6 +2120,7 @@ PAUL:X:1000:1000:PAUL BUETOW:/HOME/PAUL:/BIN/BASH
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Bash Golf Part 1</h1>
+<p class="quote"><i>Published by Paul at 2021-11-29, last updated at 2022-01-05</i></p>
<pre>
'\ . . |&gt;18&gt;&gt;
@@ -1448,7 +2132,6 @@ PAUL:X:1000:1000:PAUL BUETOW:/HOME/PAUL:/BIN/BASH
jgs^^^^^^^`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Art by Joan Stark
</pre><br />
-<p class="quote"><i>Published by Paul at 2021-11-29, last updated at 2022-01-05</i></p>
<p>This is the first blog post about my Bash Golf series. This series is about random Bash tips, tricks and weirdnesses I came across. It's a collection of smaller articles I wrote in an older (in German language) blog, which I translated and refreshed with some new content.</p>
<a class="textlink" href="https://foo.zone/gemfeed/2021-11-29-bash-golf-part-1.html">Bash Golf Part 1 (you are reading this atm.)</a><br />
<a class="textlink" href="https://foo.zone/gemfeed/2022-01-01-bash-golf-part-2.html">Bash Golf Part 2</a><br />
@@ -1803,7 +2486,8 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
❯ bc &lt;&lt;&lt; 'scale=2; 1/10'
.10
</pre><br />
-<p>See you later for the next post of this series. E-Mail me your comments to paul at buetow dot org!</p>
+<p>See you later for the next post of this series.</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -1820,6 +2504,7 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Defensive DevOps</h1>
+<p class="quote"><i>Published by Paul at 2021-10-22</i></p>
<pre>
c=====e
H
@@ -1829,7 +2514,6 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
(__((__((___()()()------------------------------------' |_____|
ASCII Art by Clyde Watson
</pre><br />
-<p class="quote"><i>Published by Paul at 2021-10-22</i></p>
<p>I have seen many different setups and infrastructures during my carreer. My roles always included front-line ad-hoc fire fighting production issues. This often involves identifying and fixing these under time pressure, without the comfort of 2-week-long SCRUM sprints and without an exhaustive QA process. I also wrote a lot of code (Bash, Ruby, Perl, Go, and a little Java), and I followed the typical software development process, but that did not always apply to critical production issues.</p>
<p>Unfortunately, no system is 100% reliable, and you can never be prepared for a subset of the possible problem-space. IT infrastructures can be complex. Not even mentioning Kubernetes yet, a Microservice-based infrastructure can complicate things even further. You can take care of 99% of all potential problems by following all DevOps best practices. Those best practices are not the subject of this blog post; this post is about the sub 1% of the issues arising from nowhere you can't be prepared for. </p>
<p>Is there a software bug in a production, even though the software passed QA (after all, it is challenging to reproduce production behaviour in an artificial testing environment) and the software didn't show any issues running in production until a special case came up just now after it got deployed to production a week ago? Are there multiple hardware failure happening which causes loss of service redundancy or data inaccessibility? Is the automation of external customers connected to our infrastructure putting unexpectedly extra pressure on your grid, driving higher latencies and putting the SLAs at risk? You bet the solution is: Sysadmins, SREs and DevOps Engineers to the rescue. </p>
@@ -1882,7 +2566,7 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
<h2>Retrospective</h2>
<p>For every major incident, you need to follow up with an incident retrospective. A blame-free, detailed description of exactly what went wrong to cause the incident, along with a list of steps to take to prevent a similar incident from occurring again in the future.</p>
<p>This usually means creating one or more tickets, which will be dealt with soon. Once the permanent fix is deployed, you can remove your ad-hoc automation and monitoring around it and focus on your regular work again.</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -1899,6 +2583,7 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Keep it simple and stupid</h1>
+<p class="quote"><i>Published by Paul at 2021-09-12, last updated at 2022-04-21</i></p>
<pre>
_______________ |*\_/*|_______
| ___________ | .-. .-. ||_/-\_|______ |
@@ -1913,7 +2598,6 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
/ ************ \ / ************ \
-------------------- --------------------
</pre><br />
-<p class="quote"><i>Published by Paul at 2021-09-12, last updated at 2022-04-21</i></p>
<p>A robust computer system must be kept simple and stupid (KISS). The fancier the system is, the more can break. Unfortunately, most systems tend to become complex and challenging to maintain in today's world. In the early days, so I was told, engineers understood every part of the system, but nowadays, we see more of the "lasagna" stack. One layer or framework is built on top of another layer, and in the end, nobody has got a clue what's going on.</p>
<h1>Need faster hardware</h1>
<p>This not just makes the system much more complex, difficult to maintain and challenging to troubleshoot, but also slow. So more experts are needed to support it. Also, newer and faster hardware is required to make it run smoothly. Often, it's so much easier to buy speedier hardware than rewrite a whole system from scratch from the bottom-up. The latter would require much more resources in the short run, but in the long run, it should pay off. Unfortunately, many project owners scare away from it as they only want to get their project done and then move on.</p>
@@ -1951,7 +2635,8 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
<p>There is, however, a trap. The more you spend time with things, the more these things feel natural to you and you become an expert. The more you become an expert, the more you introduce more abstractions and other clever ways of doing things. For you, things seem to be KISS still, but another person may not be an expert and might not understand what you do. One of the fundamental challenges is to keep things really KISS. You might add abstraction upon abstraction to a system and don't even notice it until it is too late.</p>
<h2>Other relevant readings</h2>
<a class="textlink" href="https://unixsheikh.com/articles/is-the-madness-ever-going-to-end.html">Is the madness ever going to end?</a><br />
-<p>Enough ranted for now :-). E-Mail me your comments to paul at buetow dot org!</p>
+<p>Enough ranted for now!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
<p class="quote"><i>Controversially, a lack of features is a feature. Enjoy your peace an quiet. - Michael W Lucas </i></p>
</div>
</content>
@@ -1969,6 +2654,7 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>On being Pedantic about Open-Source</h1>
+<p class="quote"><i>Published by Paul at 2021-08-01</i></p>
<pre>
__
_____....--' .'
@@ -1980,7 +2666,6 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
| | `---'
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^' LGB - Art by lgbearrd
</pre><br />
-<p class="quote"><i>Published by Paul at 2021-08-01</i></p>
<p>I believe that it is essential to always have free and open-source alternatives to any kind of closed-source proprietary software available to choose from. But there are a couple of points you need to take into consideration. </p>
<h2>The costs of open-source</h2>
<p>One benefit of using open-source software is that it doesn't cost anything, right? That's correct in many cases. However, in some cases you still need to spend a significant amount of time configuring the software to work for you. It will be more expensive to use open-source software than proprietary commercial one if you aren't careful. </p>
@@ -2002,7 +2687,8 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
<p>One of the main conceptions about open-source software is that it is more secure than closed-source software because everybody can read and fix the code. Is that actually true? You can only be sure when you audit the code by yourself. If you are like me, you won't have time to audit all the open-source software you use. It's impossible to audit more than 100 million lines of Linux kernel code. Static code analysis tools come in handy here, but they still require humans to look at the results.</p>
<p>Security bugs in open-source projects are exposed to the public and fixed quickly, while we don't know exactly what happens to security bugs in closed-source ones. Still, hackers and security specialists can find them through reverse engineering and penetration testing. Overall, thinking of security, In my opinion it is still better to prefer open-source software because the more significant the project, the higher the probability that security bugs are found and fixed as more parties are looking into it. Furthermore, provided you have the necessary resources, you could still deduct an audit by yourself. The latter especially happens when companies with its own security and penetration testing departments are evaluating the use of open-source. This is something not every company can afford though.</p>
<h2>Always watch out for open-source alternatives</h2>
-<p>Do you need Microsoft Word? Why don't you just use the Vim text editor or GNU Emacs to write your letters? If that's too nerdy, you can still use open-source alternatives such as AbiWord or LibreOffice. Larger organizations have the tendency to standardize the software their employees have to use. Unfortunately, as Microsoft Word is the de-facto standard text processing program, most companies prefer Word over LibreOffice. Same with Microsoft Excel vs LibreOffice Calc or other spreadsheet alternatives like Gnumeric. I don't know why that is; please E-Mail me, and I will update this blog article. I guess the devil lies in the detail here.</p>
+<p>Do you need Microsoft Word? Why don't you just use the Vim text editor or GNU Emacs to write your letters? If that's too nerdy, you can still use open-source alternatives such as AbiWord or LibreOffice. Larger organizations have the tendency to standardize the software their employees have to use. Unfortunately, as Microsoft Word is the de-facto standard text processing program, most companies prefer Word over LibreOffice. Same with Microsoft Excel vs LibreOffice Calc or other spreadsheet alternatives like Gnumeric. I don't know why that is; please....</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
<p>I only use free and open-source operating systems on my personal Laptops, Desktop PCs and servers (FreeBSD and Linux based ones). Most of the programs and apps I use on them are free and open-source as well, and I am comfortable with it for over twenty years. Exceptions are the BIOSes and some firmwares of my devices. I also use Skype as most of my friends and family are using it. They are, unfortunately, proprietary software still. But I will be looking into Matrix as a Skype alternative when I have time. There are also open BIOS alternatives, but they usually don't work on my devices.</p>
<h2>What about mobile?</h2>
<p>I struggle to go 100% open-source on my Smartphone. I use a Samsung phone with the stock Android as provided by Samsung. I love the device as it is large enough to use as a portable reading and note-taking device, and it can also take decent pictures. As a cloud backup solution, I have my own NextCloud server (open-source). Android is mainly open-source software, but many closed parts are still included. I replaced most of the standard apps with free and open-source variants from the F-Droid store though.</p>
@@ -2031,7 +2717,7 @@ bash: line 1: 1/10.0 : syntax error: invalid arithmetic operator (error token is
<h2>Conclusion</h2>
<p>Should you be pedantic about open-source software? It depends. It depends on your fundamental values and how much time you are ready to invest. Open-source software is not just free as in money, but also free as in freedom. You will gain back complete control of your personal data. Unfortunately, installing ready proprietary apps from the Play Store is much more convenient than building up a trustworthy open-source-based infrastructure by yourself. As a guideline, use proprietary software and services with caution. Be mindful about your choices and where you leave your digital fingerprints. In doubt, think less is more. Do you really need this new shiny app? What benefit does it provide to you? Probably you don't really need that shiny new app.</p>
<p>You have better chances when you know how to manage your own server and install and manage alternatives to the big cloud providers by yourself. I have the advantage that I have work experience as a Linux Systems Administrator here. I mentioned NextCloud already. I use NextCloud for online photo and file storage, contact and calendar sync and as an RSS news feed server. You could do the same with your own E-Mail server, you can also host your own website and blog. I also mentioned Matrix as a Skype alternative (which could also be an alternative to WhatsApp, Skype, Telegram, Viber, ...). I don't know a lot about Matrix yet, but it seems to be a very neat alternative. I am ready to invest time in it as one of my future personal pet projects. Not only because I think it's better, but also because for fun and as a hobby. But this doesn't mean that I invest *all* of my personal free time in it.</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -2112,7 +2798,7 @@ Hello World
<p>I liked this book so much so that I even bought myself a (used) paper copy of it. To my delight, there was also a free eBook version in ePub format included, which I now have on my Kobo Forma eBook reader. :-)</p>
<h2>Perl</h2>
<p>Will I abandon my beloved Perl? Probably not. There are also some Perl scripts I use at work. But unfortunately I only have a limited amount of time and I have to use it wisely. I might look into Raku (formerly known as Perl 6) next year and use it for a personal pet project, who knows. :-). I also highly recommend reading the two Perl books "Modern Perl" and "Higher-Order Perl".</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -2129,6 +2815,7 @@ Hello World
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Gemtexter - One Bash script to rule it all</h1>
+<p class="quote"><i>Published by Paul at 2021-06-05</i></p>
<pre>
o .,&lt;&gt;., o
|\/\/\/\/|
@@ -2150,26 +2837,25 @@ Hello World
_-' |\ . |
_..--.. . /"---\ | ` | . |
-=====================,' _ \=(*#(7.#####() | `/_.. , (
- _.-''``';'-''-) ,. \ ' '+/// | .'/ \ ``-.) \
- ,' _.- (( `-' `._\ `` \_/_.' ) /`-._ ) |
+ _.-''`<span class="inlinecode">';'-''-) ,. \ ' '+/// | .'/ \ </span>`-.) \
+ ,' _.- (( <span class="inlinecode">-' </span>._\ `<span class="inlinecode"> \_/_.' ) /</span>-._ ) |
,'\ ,' _.'.`:-. \.-' / &lt;_L )" |
- _/ `._,' ,')`; `-'`' | L / /
+ _/ <span class="inlinecode">._,' ,')</span>; <span class="inlinecode">-'</span>' | L / /
/ `. ,' ,|_/ / \ ( &lt;_-' \
- \ / `./ ' / /,' \ /|` `. |
- )\ /`._ ,'`._.-\ |) \'
- / `.' )-'.-,' )__) |\ `|
- : /`. `.._(--.`':`':/ \ ) \ \
+ \ / <span class="inlinecode">./ ' / /,' \ /|</span> `. |
+ )\ /<span class="inlinecode">._ ,'</span>._.-\ |) \'
+ / <span class="inlinecode">.' )-'.-,' )__) |\ </span>|
+ : /<span class="inlinecode">. </span>.._(--.<span class="inlinecode">':</span>':/ \ ) \ \
|::::\ ,'/::;-)) / ( )`. |
||::::: . .::': :`-( |/ . |
||::::| . :| |==[]=: . - \
|||:::| : || : | | /\ ` |
___ ___ '|;:::| | |' \=[]=| / \ \
-| /_ ||``|||::::: | ; | | | \_.'\_ `-.
-: \_``[]--[]|::::'\_;' )-'..`._ .-'\``:: ` . \
- \___.&gt;`''-.||:.__,' SSt |_______`&gt; &lt;_____:::. . . \ _/
+| /_ ||`<span class="inlinecode">|||::::: | ; | | | \_.'\_ </span>-.
+: \_`<span class="inlinecode">[]--[]|::::'\_;' )-'..</span>._ .-'\`<span class="inlinecode">:: </span> . \
+ \___.&gt;<span class="inlinecode">''-.||:.__,' SSt |_______</span>&gt; &lt;_____:::. . . \ _/
`+a:f:......jrei'''
</pre><br />
-<p class="quote"><i>Published by Paul at 2021-06-05</i></p>
<p>You might have read my previous blog post about entering the Geminispace, where I pointed out the benefits of having and maintaining an internet presence there. This whole site (the blog and all other pages) is composed in the Gemtext markup language. </p>
<a class="textlink" href="https://foo.zone/gemfeed/2021-04-24-welcome-to-the-geminispace.html">Welcome to the Geminispace</a><br />
<p>This comes with the benefit that I can write content in my favourite text editor (Vim). </p>
@@ -2251,7 +2937,7 @@ assert::equals "$(generate::make_link md "$gemtext")" \
<h2>Conclusion</h2>
<p>It was quite a lot of fun writing Gemtexter. It's a relatively small project, but given that I worked on that in my spare time once in a while, it kept me busy for several weeks. </p>
<p>I finally revamped my personal internet site and started to blog again. I wanted the result to be exactly how it is now: A slightly retro-inspired internet site built for fun with unconventional tools. </p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -2268,6 +2954,7 @@ assert::equals "$(generate::make_link md "$gemtext")" \
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Personal Bash coding style guide</h1>
+<p class="quote"><i>Published by Paul at 2021-05-16</i></p>
<pre>
.---------------------------.
/,--..---..---..---..---..--. `.
@@ -2280,7 +2967,6 @@ assert::equals "$(generate::make_link md "$gemtext")" \
// \\ // \\ |===|| hjw
"\__/"---------------"\__/"-+---+'
</pre><br />
-<p class="quote"><i>Published by Paul at 2021-05-16</i></p>
<p>Lately, I have been polishing and writing a lot of Bash code. Not that I never wrote a lot of Bash, but now as I also looked through the Google Shell Style Guide, I thought it is time also to write my thoughts on that. I agree with that guide in most, but not in all points. </p>
<a class="textlink" href="https://google.github.io/styleguide/shellguide.html">Google Shell Style Guide</a><br />
<h2>My modifications</h2>
@@ -2559,7 +3245,7 @@ fi
<h2>Advanced Bash learning pro tip</h2>
<p>I also highly recommend having a read through the "Advanced Bash-Scripting Guide" (not from Google). I use it as the universal Bash reference and learn something new every time I look at it.</p>
<a class="textlink" href="https://tldp.org/LDP/abs/html/">Advanced Bash-Scripting Guide</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -2593,7 +3279,7 @@ fi
|Gemini|
| |
|______|
- '-`'-` .
+ '-<span class="inlinecode">'-</span> .
/ . \'\ . .'
''( .'\.' ' .;'
'.;.;' ;'.;' ..;;' AsH
@@ -2629,7 +3315,7 @@ fi
<p>Check out one of the following links for more information about Gemini. For example, you will find a FAQ that explains why the protocol is named Gemini. Many Gemini capsules are dual-hosted via Gemini and HTTP(S) so that people new to Gemini can sneak peek at the content with a regular web browser. Some people go as far as tri-hosting all their content via HTTP(S), Gemini and Gopher.</p>
<a class="textlink" href="gemini://gemini.circumlunar.space">gemini://gemini.circumlunar.space</a><br />
<a class="textlink" href="https://gemini.circumlunar.space">https://gemini.circumlunar.space</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -2710,7 +3396,7 @@ dtail –servers serverlist.txt –files ‘/var/log/*.log’ –regex ‘(?i:er
<h2>Open Source</h2>
<p>Mimecast highly encourages you to have a look at DTail and submit an issue for any features you would like to see. Have you found a bug? Maybe you just have a question or comment? If you want to go a step further: We would also love to see pull requests for any features or improvements. Either way, if in doubt just contact us via the DTail GitHub page.</p>
<a class="textlink" href="https://dtail.dev">https://dtail.dev</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -2727,17 +3413,17 @@ dtail –servers serverlist.txt –files ‘/var/log/*.log’ –regex ‘(?i:er
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Realistic load testing with I/O Riot for Linux</h1>
+<p class="quote"><i>Published by Paul at 2018-06-01, last updated at 2021-05-08</i></p>
<pre>
.---.
/ \
\.@-@./
- /`\_/`\
+ /<span class="inlinecode">\_/</span>\
// _ \\
| \ )|_
- /`\_`&gt; &lt;_/ \
+ /<span class="inlinecode">\_</span>&gt; &lt;_/ \
jgs\__/'---'\__/
</pre><br />
-<p class="quote"><i>Published by Paul at 2018-06-01, last updated at 2021-05-08</i></p>
<h2>Foreword</h2>
<p>This text first was published in the german IT-Administrator computer Magazine. 3 years have passed since and I decided to publish it on my blog too. </p>
<a class="textlink" href="https://www.admin-magazin.de/Das-Heft/2018/06/Realistische-Lasttests-mit-I-O-Riot">https://www.admin-magazin.de/Das-Heft/2018/06/Realistische-Lasttests-mit-I-O-Riot</a><br />
@@ -2849,7 +3535,7 @@ Total time: 1213.00s
<a class="textlink" href="https://www.coker.com.au/bonnie++/">Bonnie++</a><br />
<a class="textlink" href="https://graphiteapp.org">Graphite</a><br />
<a class="textlink" href="https://en.wikipedia.org/wiki/Memory-mapped_I/O">Memory mapped I/O</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -2866,6 +3552,7 @@ Total time: 1213.00s
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Object oriented programming with ANSI C</h1>
+<p class="quote"><i>Published by Paul at 2016-11-20, updated 2022-01-29</i></p>
<pre>
___ ___ ____ ____
/ _ \ / _ \| _ \ / ___|
@@ -2874,7 +3561,6 @@ Total time: 1213.00s
\___/ \___/|_| \____|
</pre><br />
-<p class="quote"><i>Published by Paul at 2016-11-20, updated 2022-01-29</i></p>
<p>You can do a little of object-oriented programming in the C Programming Language. However, that is, in my humble opinion, limited. It's easier to use a different programming language than C for OOP. But still it's an interesting exercise to try using C for this.</p>
<h2>Function pointers</h2>
<p>Let's have a look at the following sample program. All you have to do is to add a function pointer such as "calculate" to the definition of struct "something_s". Later, during the struct initialization, assign a function address to that function pointer:</p>
@@ -2941,7 +3627,7 @@ mult.calculate(mult,a,b));
<p>Big C software projects, like Linux, also follow some OOP techniques:</p>
<a class="textlink" href="https://lwn.net/Articles/444910/">https://lwn.net/Articles/444910/</a><br />
<p>C is a very old programming language with it's quirks. This might be one of the reasons why Linux will also let Rust code in.</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -3166,7 +3852,7 @@ apply Service "dig6" {
<li>The BIND server will notify all slave DNS servers (at the moment, only one). And it will transfer the new version of the zone.</li>
</ul>
<p>That's much more comfortable now than manually clicking at some web UIs at Schlund Technologies.</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -3183,6 +3869,7 @@ apply Service "dig6" {
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Offsite backup with ZFS (Part 2)</h1>
+<p class="quote"><i>Published by Paul at 2016-04-16</i></p>
<pre>
________________
|# : : #|
@@ -3197,13 +3884,12 @@ apply Service "dig6" {
| || | | |
\____||__|_____|__|
</pre><br />
-<p class="quote"><i>Published by Paul at 2016-04-16</i></p>
<a class="textlink" href="https://foo.zone/gemfeed/2016-04-03-offsite-backup-with-zfs.html">Offsite backup with ZFS Part 1</a><br />
<a class="textlink" href="https://foo.zone/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.html">Offsite backup with ZFS Part 2 (you are reading this atm.)</a><br />
<p>I enhanced the procedure a bit. From now on, I have two external 2TB USB hard drives. Both are set up precisely the same way. To decrease the probability that both drives will not fail simultaneously, they are of different brands. One drive is kept at a secret location. The other one is held at home, right next to my HP MicroServer.</p>
<p>Whenever I update the offsite backup, I am doing it to the drive, which is kept locally. Afterwards, I bring it to the secret location, swap the drives, and bring the other back home. This ensures that I will always have an offsite backup available at a different location than my home - even while updating one copy of it.</p>
<p>Furthermore, I added scrubbing ("zpool scrub...") to the script. It ensures that the file system is consistent and that there are no bad blocks on the disk and the file system. To increase the reliability, I also run a "zfs set copies=2 zroot". That setting is also synchronized to the offsite ZFS pool. ZFS stores every data block to disk twice now. Yes, it consumes twice as much disk space, making it better fault-tolerant against hardware errors (e.g. only individual disk sectors going bad). </p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -3220,6 +3906,7 @@ apply Service "dig6" {
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Jails and ZFS with Puppet on FreeBSD</h1>
+<p class="quote"><i>Published by Paul at 2016-04-09</i></p>
<pre>
__ __
(( \---/ ))
@@ -3239,7 +3926,6 @@ apply Service "dig6" {
\ `. hjw
\ `.
</pre><br />
-<p class="quote"><i>Published by Paul at 2016-04-09</i></p>
<p>Over the last couple of years I wrote quite a few Puppet modules in order to manage my personal server infrastructure. One of them manages FreeBSD Jails and another one ZFS file systems. I thought I would give a brief overview in how it looks and feels.</p>
<h2>ZFS</h2>
<p>The ZFS module is a pretty basic one. It does not manage ZFS pools yet as I am not creating them often enough which would justify implementing an automation. But let's see how we can create a ZFS file system (on an already given ZFS pool named ztank):</p>
@@ -3582,7 +4268,7 @@ Notice: Finished catalog run in 206.09 seconds
<li>...etc</li>
</ul>
<p>All done in a pretty automated manor. </p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -3599,6 +4285,7 @@ Notice: Finished catalog run in 206.09 seconds
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Offsite backup with ZFS</h1>
+<p class="quote"><i>Published by Paul at 2016-04-03</i></p>
<pre>
________________
|# : : #|
@@ -3611,7 +4298,6 @@ Notice: Finished catalog run in 206.09 seconds
| || | | |
\____||__|_____|__|
</pre><br />
-<p class="quote"><i>Published by Paul at 2016-04-03</i></p>
<a class="textlink" href="https://foo.zone/gemfeed/2016-04-03-offsite-backup-with-zfs.html">Offsite backup with ZFS Part 1 (you are reading this atm.)</a><br />
<a class="textlink" href="https://foo.zone/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.html">Offsite backup with ZFS Part 2</a><br />
<h2>Please don't lose all my pictures again!</h2>
@@ -3625,7 +4311,7 @@ Notice: Finished catalog run in 206.09 seconds
<p>The solution is adding another USB drive (2TB) with an encryption container (GELI) and a ZFS pool. The GELI encryption requires a secret key and a secret passphrase. I am updating the data to that drive once every three months (my calendar is reminding me about it), and afterwards, I keep that drive at a secret location outside of my apartment. All the information needed to decrypt (mounting the GELI container) is stored at another (secure) place. Key and passphrase are kept at different sites, though. Even if someone knew of it, he would not be able to decrypt it as some additional insider knowledge would be required as well.</p>
<h2>Walking one round less</h2>
<p>I am thinking of buying a second 2TB USB drive and setting it up the same way as the first one. So I could alternate the backups. One drive would be at the secret location, and the other drive would be at home. And these drives would swap place after each cycle. This would give some security about the failure of that drive, and I would have to go to the secret location only once (swapping the drives) instead of twice (picking that drive up to update the data + bringing it back to the remote location).</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -3642,6 +4328,7 @@ Notice: Finished catalog run in 206.09 seconds
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Run Debian on your phone with Debroid</h1>
+<p class="quote"><i>Published by Paul at 2015-12-05, last updated at 2021-05-16</i></p>
<pre>
____ _ _ _
| _ \ ___| |__ _ __ ___ (_) __| |
@@ -3650,7 +4337,6 @@ Notice: Finished catalog run in 206.09 seconds
|____/ \___|_.__/|_| \___/|_|\__,_|
</pre><br />
-<p class="quote"><i>Published by Paul at 2015-12-05, last updated at 2021-05-16</i></p>
<p>You can use the following tutorial to install a full-blown Debian GNU/Linux Chroot on an LG G3 D855 CyanogenMod 13 (Android 6). First of all, you need to have root permissions on your phone, and you also need to have the developer mode activated. The following steps have been tested on Linux (Fedora 23).</p>
<a href="https://foo.zone/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid/Deboroid.png"><img src="https://foo.zone/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid/Deboroid.png" /></a><br />
<h2>Foreword</h2>
@@ -3789,7 +4475,7 @@ chmod +x /data/local/userinit.sh
exit
</pre><br />
<p>Reboot &amp; test! Enjoy!</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -3931,7 +4617,7 @@ fib(9) = 34
fib(10) = 55
</pre><br />
<p>It's entertaining to play with :-).</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -3948,13 +4634,13 @@ fib(10) = 55
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Perl Daemon (Service Framework)</h1>
+<p class="quote"><i>Published by Paul at 2011-05-07, last updated at 2021-05-07</i></p>
<pre>
a'! _,,_ a'! _,,_ a'! _,,_
\\_/ \ \\_/ \ \\_/ \.-,
\, /-( /'-,\, /-( /'-, \, /-( /
//\ //\\ //\ //\\ //\ //\\jrei
</pre><br />
-<p class="quote"><i>Published by Paul at 2011-05-07, last updated at 2021-05-07</i></p>
<p>PerlDaemon is a minimal daemon for Linux and other Unix like operating systems programmed in Perl. It is a minimal but pretty functional and fairly generic service framework. This means that it does not do anything useful other than providing a framework for starting, stopping, configuring and logging. To do something useful, a module (written in Perl) must be provided.</p>
<h2>Features</h2>
<p>PerlDaemon supports:</p>
@@ -4077,7 +4763,7 @@ sub do ($) {
<h2>May the source be with you</h2>
<p>You can find PerlDaemon (including the examples) at:</p>
<a class="textlink" href="https://codeberg.org/snonux/perldaemon">https://codeberg.org/snonux/perldaemon</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -4094,6 +4780,7 @@ sub do ($) {
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>The Fype Programming Language</h1>
+<p class="quote"><i>Published by Paul at 2010-05-09, last updated at 2021-05-05</i></p>
<pre>
____ _ __
/ / _|_ _ _ __ ___ _ _ ___ __ _| |__ / _|_ _
@@ -4102,7 +4789,6 @@ sub do ($) {
(_)_/ |_| \__, | .__/ \___| \__, |\___|\__,_|_| |_(_)_| \__, |
|___/|_| |___/ |___/
</pre><br />
-<p class="quote"><i>Published by Paul at 2010-05-09, last updated at 2021-05-05</i></p>
<p>Fype is an interpreted programming language created by me for learning and fun. The interpreter is written in C. It has been tested on FreeBSD and NetBSD and may also work on other Unix like operating systems such as Linux based ones. Besides learning and fun, there is no other use case of why Fype exists as many other programming languages are much faster and more powerful.</p>
<p>The Fype syntax is straightforward and uses a maximum look ahead of 1 and an effortless top-down parsing mechanism. Fype is parsing and interpreting its code simultaneously. This means that syntax errors are only detected during program runtime. </p>
<p>Fype is a recursive acronym and means "Fype is For Your Program Execution" or "Fype is Free Yak Programmed for ELF". You could also say, "It's not a hype - it's Fype!".</p>
@@ -4492,7 +5178,7 @@ BB
<h2>May the source be with you</h2>
<p>You can find all of this on the GitHub page. There is also an "examples" folders containing some Fype scripts!</p>
<a class="textlink" href="https://codeberg.org/snonux/fype">https://codeberg.org/snonux/fype</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -4509,6 +5195,7 @@ BB
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Lazy Evaluation with Standard ML</h1>
+<p class="quote"><i>Published by Paul at 2010-05-07</i></p>
<pre>
_____|~~\_____ _____________
@@ -4518,10 +5205,9 @@ BB
_- | ) / |--| | |
__-_______________ /__/_______| |_________
( |---- | |
- `---------------'--\\\\ .`--' -Glyde-
+ <span class="inlinecode">---------------'--\\\\ .</span>--' -Glyde-
`||||
</pre><br />
-<p class="quote"><i>Published by Paul at 2010-05-07</i></p>
<p>In contrast to Haskell, Standard SML does not use lazy evaluation by default but an eager evaluation. </p>
<a class="textlink" href="https://en.wikipedia.org/wiki/Eager_evaluation">https://en.wikipedia.org/wiki/Eager_evaluation</a><br />
<a class="textlink" href="https://en.wikipedia.org/wiki/Lazy_evaluation">https://en.wikipedia.org/wiki/Lazy_evaluation</a><br />
@@ -4592,7 +5278,7 @@ first 10 nat_pairs_not_null
-}
</pre><br />
<a class="textlink" href="http://www.haskell.org/">http://www.haskell.org/</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -4746,7 +5432,7 @@ my_map f l = foldr (make_map_fn f) [] l
fun my_filter f l = foldr (make_filter_fn f) [] l
my_filter f l = foldr (make_filter_fn f) [] l
</pre><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -4763,6 +5449,7 @@ my_filter f l = foldr (make_filter_fn f) [] l
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Using my Nokia N95 for fixing my MTA</h1>
+<p class="quote"><i>Published by Paul at 2008-12-29, last updated at 2021-12-01</i></p>
<pre>
_
@@ -4779,7 +5466,6 @@ my_filter f l = foldr (make_filter_fn f) [] l
_jgs_\|//_\\|///_\V/_\|//__
Art by Joan Stark
</pre><br />
-<p class="quote"><i>Published by Paul at 2008-12-29, last updated at 2021-12-01</i></p>
<p>The last week I was in Vidin, Bulgaria with no internet access and I had to fix my MTA (Postfix) at host.0.buetow.org which serves E-Mail for all my customers at P. B. Labs. Good, that I do not guarantee high availability on my web services (I've to do a full time job somewhere else too). </p>
<p>My first attempt to find an internet café, which was working during Christmastime, failed. However, I found with my N95 phone lots of free WLAN hotspots. The hotspots refused me logging into my server using SSH as I have configured a non-standard port for SSH for security reasons. Without knowing the costs, I used the GPRS internet access of my German phone provider (yes, I had to pay roaming fees). </p>
<a href="https://foo.zone/gemfeed/2008-12-29-using-my-nokia-n95-for-fixing-my-mta/nokia-n95.jpg"><img alt="Picture of a Nokia N95" title="Picture of a Nokia N95" src="https://foo.zone/gemfeed/2008-12-29-using-my-nokia-n95-for-fixing-my-mta/nokia-n95.jpg" /></a><br />
@@ -4792,7 +5478,7 @@ _jgs_\|//_\\|///_\V/_\|//__
</ul>
<p>It was a pain in the ass. My next mobile phone MUST have a full QWERTY keyboard. This would have made my life lots easier. :)</p>
<p>At the moment I am in Sofia, Bulgaria. Here I can use at least an unprotected WLAN hotspot which belongs to one of the neighbours which I don’t know in person, and it is not blocking any port at all :)</p>
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
@@ -4809,6 +5495,7 @@ _jgs_\|//_\\|///_\V/_\|//__
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<h1>Perl Poetry</h1>
+<p class="quote"><i>Published by Paul at 2008-06-26, last updated at 2021-05-04</i></p>
<pre>
'\|/' *
-- * -----
@@ -4818,11 +5505,11 @@ _jgs_\|//_\\|///_\V/_\|//__
: ( ( .-''`'.
. \ \ / \
. \ \ / \
- \ `-' `'.
+ \ <span class="inlinecode">-' </span>'.
\ . ' / `.
\ ( \ ) ( .')
,, t '. | / | (
- '|``_/^\___ '| |`'-..-'| ( ()
+ '|`<span class="inlinecode">_/^\___ '| |</span>'-..-'| ( ()
_~~|~/_|_|__/|~~~~~~~ | / ~~~~~ | | ~~~~~~~~
-_ |L[|]L|/ | |\ MJP ) )
( |( / /|
@@ -4831,7 +5518,6 @@ _~~|~/_|_|__/|~~~~~~~ | / ~~~~~ | | ~~~~~~~~
~ ~ ~~~ _|| (_/ (___)_| |Nov291999
(__) (____)
</pre><br />
-<p class="quote"><i>Published by Paul at 2008-06-26, last updated at 2021-05-04</i></p>
<p>Here are some Perl Poems I wrote. They don't do anything useful when you run them, but they don't produce a compiler error either. They only exist for fun and demonstrate what you can do with Perl syntax.</p>
<p>Wikipedia: "Perl poetry is the practice of writing poems that can be compiled as legal Perl code, for example the piece known as Black Perl. Perl poetry is made possible by the large number of English words that are used in the Perl language. New poems are regularly submitted to the community at PerlMonks."</p>
<a class="textlink" href="https://en.wikipedia.org/wiki/Perl">https://en.wikipedia.org/wiki/Perl</a><br />
@@ -4956,7 +5642,7 @@ This is perl, v5.8.8 built for i386-freebsd-64int
<h2>More...</h2>
<p>Did you like what you saw? Have a look at Codeberg to see my other poems too:</p>
<a class="textlink" href="https://codeberg.org/snonux/perl-poetry">https://codeberg.org/snonux/perl-poetry</a><br />
-<p>E-Mail me your comments to paul at buetow dot org!</p>
+<p>E-Mail me your comments to paul at buetow dot org! :-)</p>
</div>
</content>
</entry>
diff --git a/gemfeed/index.gmi b/gemfeed/index.gmi
index d73b35ad..468e451b 100644
--- a/gemfeed/index.gmi
+++ b/gemfeed/index.gmi
@@ -2,6 +2,8 @@
## To be in the .zone!
+=> ./2022-08-27-gemtexter-1.1.0-lets-gemtext-again.gmi 2022-08-27 - Gemtexter 1.1.0 - Let's Gemtext again
+=> ./2022-07-30-lets-encrypt-with-openbsd-and-rex.gmi 2022-07-30 - Let's Encrypt with OpenBSD and Rex
=> ./2022-06-15-sweating-the-small-stuff.gmi 2022-06-15 - Sweating the small stuff - Tiny projects of mine
=> ./2022-05-27-perl-is-still-a-great-choice.gmi 2022-05-27 - Perl is still a great choice
=> ./2022-04-10-creative-universe.gmi 2022-04-10 - Creative universe
diff --git a/index.gmi b/index.gmi
index efd5d721..1b4c9118 100644
--- a/index.gmi
+++ b/index.gmi
@@ -13,7 +13,8 @@
Welcome to the foo.zone. It's my personal internet site and blog. Everything you read on this site is my personal opinion and experience. You can call me a Linux/*BSD enthusiast and hobbyist. I also have many other interests. However, you will encounter mostly (if not only) technical content on this site.
-=> ./contact-information.gmi My contact information
+=> https://paul.buetow.org My contact information (via HTTP)
+=> gemini://paul.buetow.org My contact information (via Gemini)
=> ./resources.gmi My list of resources
If you reach this site via the modern web, please read this:
@@ -29,6 +30,8 @@ If you reach this site via the modern web, please read this:
### Posts
+=> ./gemfeed/2022-08-27-gemtexter-1.1.0-lets-gemtext-again.gmi 2022-08-27 - Gemtexter 1.1.0 - Let's Gemtext again
+=> ./gemfeed/2022-07-30-lets-encrypt-with-openbsd-and-rex.gmi 2022-07-30 - Let's Encrypt with OpenBSD and Rex
=> ./gemfeed/2022-06-15-sweating-the-small-stuff.gmi 2022-06-15 - Sweating the small stuff - Tiny projects of mine
=> ./gemfeed/2022-05-27-perl-is-still-a-great-choice.gmi 2022-05-27 - Perl is still a great choice
=> ./gemfeed/2022-04-10-creative-universe.gmi 2022-04-10 - Creative universe
diff --git a/other-resources.gmi b/other-resources.gmi
index 77b04f5c..85b6a7be 100644
--- a/other-resources.gmi
+++ b/other-resources.gmi
@@ -60,6 +60,7 @@ _-" . ' + . . ,//////0\ | /00HHHHHHHMMMMM
* 2016 - Omni (de)
* 2017 - Das Arkonadia-Rätsel (de)
* 2017 - Das Erwachen (de) - Maschinenintelligenz-Trilogie
+* 2019 - Das Netz der Sterne (de), Audio book
* 2020 - Die Eskalation (de) - Maschinenintelligenz-Trilogie
* 2021 - Mars Discovery (de) - Maschinenintelligenz-Trilogie
* 2022 - Netz der Sterne (de) - Audio book