Recent changes to this wiki:

Add instructions for systemd-resolved
diff --git a/posts/setting-up-your-own-dnssec-aware.mdwn b/posts/setting-up-your-own-dnssec-aware.mdwn
index 807277c..86d07ba 100644
--- a/posts/setting-up-your-own-dnssec-aware.mdwn
+++ b/posts/setting-up-your-own-dnssec-aware.mdwn
@@ -77,6 +77,23 @@ If you're not using DHCP, then you simply need to put this in your `/etc/resolv.
 
     nameserver 127.0.0.1
 
+or on more recent distros, the following in `/etc/systemd/resolved.conf`:
+
+    [Resolve]
+    DNS=127.0.0.1
+    DNSSEC=no
+
+Yes, you need `DNSSEC=no` because otherwise it will break insecure
+delegations and you'll see messages like this one in your logs:
+
+    systemd-resolved[1161]: DNSSEC validation failed for question dyn.fmarier.org IN SOA: no-signature
+
+You can test that
+[systemd-resolved](https://www.freedesktop.org/wiki/Software/systemd/resolved/)
+is configured properly using:
+
+    systemd-resolve --status
+
 ## Testing DNSSEC resolution
 
 Once everything is configured properly, the best way I found to test that this setup was actually working is to use a web browser to visit these sites:

Remove obsolete and unnecessary options
diff --git a/posts/hardening-ssh-servers.mdwn b/posts/hardening-ssh-servers.mdwn
index 75b715a..1d5de08 100644
--- a/posts/hardening-ssh-servers.mdwn
+++ b/posts/hardening-ssh-servers.mdwn
@@ -14,11 +14,9 @@ you forget):
 
 This is what `/etc/ssh/sshd_config` should contain:
 
-    Protocol 2
     HostKey /etc/ssh/ssh_host_ed25519_key
     HostKey /etc/ssh/ssh_host_rsa_key
     HostKey /etc/ssh/ssh_host_ecdsa_key
-    UsePrivilegeSeparation sandbox
     AuthenticationMethods publickey
     PasswordAuthentication no
     PermitRootLogin no

Put the fully-qualified hostname in the ServerName field
This is needed because we won't be able to get a TLS cert for the short name
and so using the full name will avoid warnings that the server name can't be
found in any of the TLS certs names.
diff --git a/posts/usual-server-setup.mdwn b/posts/usual-server-setup.mdwn
index 0b1e3c4..45f17cf 100644
--- a/posts/usual-server-setup.mdwn
+++ b/posts/usual-server-setup.mdwn
@@ -280,7 +280,7 @@ I enable these in `/etc/apache2/conf-enabled/security.conf`:
 
 I also create a new `/etc/apache2/conf-available/servername.conf` which contains:
 
-    ServerName machine_hostname
+    ServerName machine_hostname.example.com
 
 and then run:
 

Use stronger OpenVPN 2.4+ crypto
diff --git a/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn b/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
index 2913757..853ef79 100644
--- a/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
+++ b/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
@@ -93,9 +93,10 @@ and set the following in `/etc/openvpn/server.conf` (which includes recommendati
     push "dhcp-option DNS 74.207.241.5"
     push "dhcp-option DNS 74.207.242.5"
     tls-auth ta.key 0
-    tls-cipher DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:DHE-RS
-    cipher AES-256-CBC
-    auth SHA384
+    tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-GCM-SHA384
+    tls-version-min 1.2
+    cipher AES-256-GCM
+    ncp-disable
     user nobody
     group nogroup
 
@@ -159,8 +160,7 @@ then click the "Avanced" button and set the following:
 * General
    * Use LZO data compression: `YES`
 * Security
-   * Cipher: `AES-256-CBC`
-   * HMAC Authentication: `SHA-384`
+   * Cipher: `AES-256-GCM`
 * TLS Authentication
    * Server Certificate Check: `Verify name exactly`
    * Subject Match: `server`
diff --git a/posts/using-openvpn-on-android-lollipop.mdwn b/posts/using-openvpn-on-android-lollipop.mdwn
index 74d3e6e..4a08a0f 100644
--- a/posts/using-openvpn-on-android-lollipop.mdwn
+++ b/posts/using-openvpn-on-android-lollipop.mdwn
@@ -57,8 +57,7 @@ Authentication/Encryption:
 - Use TLS Authentication: `YES`
 - TLS Auth File: `ta.key`
 - TLS Direction: `1`
-- Encryption cipher: `AES-256-CBC`
-- Packet authentication: `SHA384` (**not** `SHA-384`)
+- Encryption cipher: `AES-256-GCM`
 
 Advanced:
 
diff --git a/posts/using-openvpn-on-ios-and-osx.mdwn b/posts/using-openvpn-on-ios-and-osx.mdwn
index d104815..41eb522 100644
--- a/posts/using-openvpn-on-ios-and-osx.mdwn
+++ b/posts/using-openvpn-on-ios-and-osx.mdwn
@@ -58,8 +58,7 @@ Here is the config I successfully used to connect to my server:
     ca ca.crt
     cert iphone.crt
     key iphone.key
-    cipher AES-256-CBC
-    auth SHA384
+    cipher AES-256-GCM
     comp-lzo yes
     proto udp
     tls-remote server
@@ -92,7 +91,6 @@ connection:
 - **Advanced**
    - add the following extra OpenVPN configuration commands:
 
-         cipher AES-256-CBC
-         auth SHA384
+         cipher AES-256-GCM
 
 [[!tag openvpn]] [[!tag ios]] [[!tag osx]]

Add a new option in latest network-manager-openvpn version
diff --git a/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn b/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
index 6fa82a3..2913757 100644
--- a/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
+++ b/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
@@ -168,7 +168,8 @@ then click the "Avanced" button and set the following:
      * Remote peer certificate TLS type: `Server`
    * Verify peer (server) certificate nsCertType designation: `YES`
      * Remove peer certificate nsCert designation: `Server`
-   * Use additional TLS authentication: `YES`
+   * Additional TLS authentication or encryption:
+     * Mode: `TLS-Auth`
      * Key File: `/etc/openvpn/ta.key`
      * Key Direction: `1`
 

Format option correctly
diff --git a/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn b/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
index c9aacdc..6fa82a3 100644
--- a/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
+++ b/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
@@ -162,7 +162,7 @@ then click the "Avanced" button and set the following:
    * Cipher: `AES-256-CBC`
    * HMAC Authentication: `SHA-384`
 * TLS Authentication
-   * Server Certificate Check: Verify name exactly
+   * Server Certificate Check: `Verify name exactly`
    * Subject Match: `server`
    * Verify peer (server) certificate usage signature: `YES`
      * Remote peer certificate TLS type: `Server`

Link to a tweet without a missing word.
diff --git a/posts/server-migration-plan.mdwn b/posts/server-migration-plan.mdwn
index 56962d7..8d67302 100644
--- a/posts/server-migration-plan.mdwn
+++ b/posts/server-migration-plan.mdwn
@@ -92,7 +92,7 @@ go through a similar process.
 
 # Migrating servers
 
-* [Tweet](https://twitter.com/libravatar/status/364659172983308288) and [dent](https://identi.ca/libravatar/note/UFBI9ne8SsOftkYlSKPHQQ) about the upcoming migration.
+* [Tweet](https://twitter.com/libravatar/status/1028767128227205120) and [dent](https://identi.ca/libravatar/note/UFBI9ne8SsOftkYlSKPHQQ) about the upcoming migration.
 
 * Enable the static file config on the old server (disabling the Django app):
 

Note that the authorized_keys file should be moved, not just deleted
diff --git a/posts/server-migration-plan.mdwn b/posts/server-migration-plan.mdwn
index a695a55..56962d7 100644
--- a/posts/server-migration-plan.mdwn
+++ b/posts/server-migration-plan.mdwn
@@ -135,8 +135,8 @@ go through a similar process.
 
 # Disable mirror sync
 
-* Log into each mirror and comment out the sync cron jobs in `/etc/cron.d/libravatar-slave`.
-* Make sure mirrors are no longer able to connect to the old server by deleting `/var/lib/libravatar/master/.ssh/authorized_keys` on the old server.
+* Log into each mirror and comment out the update cron jobs in `/etc/cron.d/libravatar-slave`.
+* Make sure mirrors are no longer able to connect to the old server by moving `/var/lib/libravatar/master/.ssh/authorized_keys` to the new server and removing it from the old server.
 
 # Testing the main site
 

Fix file ownership after the rsync
diff --git a/posts/server-migration-plan.mdwn b/posts/server-migration-plan.mdwn
index 9ee4ccb..a695a55 100644
--- a/posts/server-migration-plan.mdwn
+++ b/posts/server-migration-plan.mdwn
@@ -131,6 +131,7 @@ go through a similar process.
 
         chmod go-w /var/lib/libravatar/avatar
         chmod go-w /var/lib/libravatar/user
+        chown -R root:root /var/lib/libravatar/avatar/* /var/lib/libravatar/user/*
 
 # Disable mirror sync
 

Fix path and use fake server names to avoid copy/paste errors
diff --git a/posts/server-migration-plan.mdwn b/posts/server-migration-plan.mdwn
index 5eb525d..9ee4ccb 100644
--- a/posts/server-migration-plan.mdwn
+++ b/posts/server-migration-plan.mdwn
@@ -122,10 +122,10 @@ go through a similar process.
 
   * From laptop:
 
-        rsync -a -H -v husavik.libravatar.org:/var/lib/libravatar/avatar .
-        rsync -a -H -v husavik.libravatar.org:/var/lib/libravatar/user .
-        rsync -a -H -v avatar/* selfoss.libravatar.org:/var/lib/libravatar/avatar/
-        rsync -a -H -v user/* selfoss.libravatar.org:/var/lib/libravatar/avatar/
+        rsync -a -H -v old.libravatar.org:/var/lib/libravatar/avatar .
+        rsync -a -H -v old.libravatar.org:/var/lib/libravatar/user .
+        rsync -a -H -v avatar/* new.libravatar.org:/var/lib/libravatar/avatar/
+        rsync -a -H -v user/* new.libravatar.org:/var/lib/libravatar/user/
 
   * On the new server:
 

Delete any leftovers from a previous test run
diff --git a/posts/server-migration-plan.mdwn b/posts/server-migration-plan.mdwn
index 0b1bc01..5eb525d 100644
--- a/posts/server-migration-plan.mdwn
+++ b/posts/server-migration-plan.mdwn
@@ -116,7 +116,9 @@ go through a similar process.
   * On the new server:
 
         chmod a+w /var/lib/libravatar/avatar
+        rm -rf /var/lib/libravatar/avatar/*
         chmod a+w /var/lib/libravatar/user
+        rm -rf /var/lib/libravatar/user/*
 
   * From laptop:
 

Expand the instructions to include actual commands
diff --git a/posts/server-migration-plan.mdwn b/posts/server-migration-plan.mdwn
index 9918bba..0b1bc01 100644
--- a/posts/server-migration-plan.mdwn
+++ b/posts/server-migration-plan.mdwn
@@ -94,9 +94,24 @@ go through a similar process.
 
 * [Tweet](https://twitter.com/libravatar/status/364659172983308288) and [dent](https://identi.ca/libravatar/note/UFBI9ne8SsOftkYlSKPHQQ) about the upcoming migration.
 
-* Enable the static file config on the old server (disabling the Django app).
-* Disable pgbouncer to ensure that Django cannot access postgres anymore.
-* Copy the database from the old server and restore it on the new server **making sure it's in the UTF8 encoding**.
+* Enable the static file config on the old server (disabling the Django app):
+
+      cd /etc/apache2/
+      mv sites-enabled sites-enabled.django
+      mv sites-enabled.static sites-enabled
+      apache2ctl configtest
+      systemctl restart apache2.service
+
+* Disable pgbouncer to ensure that Django cannot access postgres anymore:
+
+      systemctl stop pgbouncer.service
+
+* Copy the database from the old server and restore it on the new server **making sure it's in the UTF8 encoding**:
+
+      dropdb libravatar
+      createdb -O djangouser -E utf8 libravatar
+      pg_restore -d libravatar libravatar20180812.pg
+
 * Copy `/var/lib/libravatar` from the old server to the new one.
   * On the new server:
 
@@ -131,6 +146,13 @@ go through a similar process.
 * If testing is successful, update DNS A and AAAA records to point to the new server with a short TTL (in case we need to revert).
 
 * Enable the proxy config on the old server.
+
+      cd /etc/apache2/
+      mv sites-enabled sites-enabled.static
+      mv sites-enabled.proxy/ sites-enabled
+      apache2ctl configtest
+      systemctl restart apache2.service
+
 * Hack my local `/etc/hosts` file to point to the old server's IP address.
 * Test basic functionality going through the proxy.
 * Remove local `/etc/hosts` hacks.

Fix typo
diff --git a/posts/server-migration-plan.mdwn b/posts/server-migration-plan.mdwn
index 4be060c..9918bba 100644
--- a/posts/server-migration-plan.mdwn
+++ b/posts/server-migration-plan.mdwn
@@ -133,7 +133,7 @@ go through a similar process.
 * Enable the proxy config on the old server.
 * Hack my local `/etc/hosts` file to point to the old server's IP address.
 * Test basic functionality going through the proxy.
-* Remove local `/etc/hosts/` hacks.
+* Remove local `/etc/hosts` hacks.
 
 # Re-enable mirror sync
 

Add a note about setting the server time to UTC
diff --git a/posts/usual-server-setup.mdwn b/posts/usual-server-setup.mdwn
index f70beca..0b1e3c4 100644
--- a/posts/usual-server-setup.mdwn
+++ b/posts/usual-server-setup.mdwn
@@ -222,6 +222,8 @@ To keep the system clock accurate and increase the amount of entropy
 available to the server, I install the above packages and add the `tpm_rng`
 module to `/etc/modules`.
 
+I also set the server timezone to **UTC** using `dpkg-reconfigure tzdata`.
+
 # Preventing mistakes
 
     apt install molly-guard safe-rm sl

Mention the need to test both IPv4 and IPv6
diff --git a/posts/server-migration-plan.mdwn b/posts/server-migration-plan.mdwn
index f184c73..4be060c 100644
--- a/posts/server-migration-plan.mdwn
+++ b/posts/server-migration-plan.mdwn
@@ -122,12 +122,13 @@ go through a similar process.
 
 # Testing the main site
 
-* Hack my local `/etc/hosts` file to point to the new server's IP address:
+* Hack my local `/etc/hosts` file to point to the new server's IPv4 address:
 
-      xxx.xxx.xxx.xxx www.libravatar.org stats.libravatar.org cdn.libravatar.org
+      xxx.xxx.xxx.xxx www.libravatar.org stats.libravatar.org cdn.libravatar.org seccdn.libravatar.org
 
 * Test all functionality on the new site.
-* If testing is successful, update DNS to point to the new server with a short TTL (in case we need to revert).
+* Do a basic version of the previous test using IPv6.
+* If testing is successful, update DNS A and AAAA records to point to the new server with a short TTL (in case we need to revert).
 
 * Enable the proxy config on the old server.
 * Hack my local `/etc/hosts` file to point to the old server's IP address.

Clarify the DNS entries to modify
diff --git a/posts/server-migration-plan.mdwn b/posts/server-migration-plan.mdwn
index cb2358e..f184c73 100644
--- a/posts/server-migration-plan.mdwn
+++ b/posts/server-migration-plan.mdwn
@@ -12,7 +12,7 @@ go through a similar process.
 
 # Prepare DNS
 
-* Change the TTL on the DNS entry for `libravatar.org` to 3600 seconds.
+* Change the TTL on the DNS entry for `libravatar.org` (i.e. bare `A` and `AAAA` records) to **3600** seconds.
 * Remove the mirrors I don't control from the DNS load balancer (`cdn` **and** `seccdn`).
 * Remove the main server from `cdn` and `seccdn` in DNS.
 

Reduce verbosity of sshd
The INFO level now provides the pubkey fingerprints of logged in users.
diff --git a/posts/usual-server-setup.mdwn b/posts/usual-server-setup.mdwn
index e461a3e..f70beca 100644
--- a/posts/usual-server-setup.mdwn
+++ b/posts/usual-server-setup.mdwn
@@ -86,7 +86,6 @@ and end up with the following settings in `/etc/ssh/sshd_config` (jessie):
     PermitRootLogin no
 
     AcceptEnv LANG LC_* TZ
-    LogLevel VERBOSE
     AllowGroups sshuser
 
 On those servers where I need [duplicity/paramiko to

Create missing log files to make logcheck happy
diff --git a/posts/usual-server-setup.mdwn b/posts/usual-server-setup.mdwn
index 62b01f0..e461a3e 100644
--- a/posts/usual-server-setup.mdwn
+++ b/posts/usual-server-setup.mdwn
@@ -140,6 +140,11 @@ and fixing the log rotation configuration by adding the following to
 
     create 644 root adm
 
+I usually create these empty files to silence logcheck errors:
+
+    touch /var/log/mail.{err,warn}
+    chown root:adm /var/log/mail.{err,warn}
+
 I also modify the main logcheck configuration file
 (`/etc/logcheck/logcheck.conf`):
 

Comment moderation
diff --git a/posts/mercurial-commit-series-phabricator-using-arcanist/comment_1_d14f851bb83a648edec489e7a777af2b._comment b/posts/mercurial-commit-series-phabricator-using-arcanist/comment_1_d14f851bb83a648edec489e7a777af2b._comment
new file mode 100644
index 0000000..848e6a0
--- /dev/null
+++ b/posts/mercurial-commit-series-phabricator-using-arcanist/comment_1_d14f851bb83a648edec489e7a777af2b._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ ip="195.166.157.111"
+ claimedauthor="Standard8"
+ subject="Missing a useful part"
+ date="2018-08-02T13:31:35Z"
+ content="""
+I think you're missing one useful part to commit series updates.
+
+It is unclear if you let it prompt you for the commit messages & data when you upload, but if you do, then you can follow this slightly easier process.
+
+* upload first patch with `arc diff`, set the reviewer and bug number.
+* Note the \"Dnnnn\" number.
+* upload the second patch, again with `arc diff`. Also set the reviewer and bug number, but this time add to the summary \"Depends on Dnnnn\" (where Dnnnn is the id of the previous patch).
+
+Then you can avoid linking the commits in the phabricator UI.
+
+Also when you then need to update a diff, you can simply do `arc diff` to generate the new version as it already knows what it depends on.
+"""]]

Link to Libravatar revival blogpost
diff --git a/posts/looking-back-on-starting-libravatar.mdwn b/posts/looking-back-on-starting-libravatar.mdwn
index 8b5bcab..cb10af1 100644
--- a/posts/looking-back-on-starting-libravatar.mdwn
+++ b/posts/looking-back-on-starting-libravatar.mdwn
@@ -2,6 +2,8 @@
 [[!meta date="2018-04-02T18:00:00.000-07:00"]]
 [[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
 
+**Update (2018-07-31): [Libravatar is not going away](https://blog.libravatar.org/posts/Libravatar.org_is_not_going_away/)**
+
 As noted on the [official Libravatar
 blog](https://blog.libravatar.org/posts/Libravatar.org_is_shutting_down_on_2018-09-01/),
 I will be shutting the service down on 2018-09-01.

Add a section on amending commits after the fact
diff --git a/posts/mercurial-commit-series-phabricator-using-arcanist.mdwn b/posts/mercurial-commit-series-phabricator-using-arcanist.mdwn
index c485eb3..746fe80 100644
--- a/posts/mercurial-commit-series-phabricator-using-arcanist.mdwn
+++ b/posts/mercurial-commit-series-phabricator-using-arcanist.mdwn
@@ -95,7 +95,7 @@ earliest to latest):
 
 # Link all revisions together
 
-In order to ensure that these commits depend on one another, lick on that
+In order to ensure that these commits depend on one another, click on that
 last [`phabricator.services.mozilla.com`
 link](https://phabricator.services.mozilla.com/D2486), then click "Related
 Revisions" then "Edit Parent Revisions" in the right-hand side bar and then
@@ -107,4 +107,57 @@ revision](https://phabricator.services.mozilla.com/D2485) and repeat the
 same steps to set [D2484](https://phabricator.services.mozilla.com/D2484) as
 its parent.
 
+# Amend one of the commits
+
+As it turns out my first patch wasn't perfect and I needed to amend the
+middle commit to fix some test failures that came up after [pushing to
+Try](https://treeherder.mozilla.org/#/jobs?repo=try&revision=5ec6dd24172c11d5fc498dfcc9e5a0287ade312e).
+I ended up with the following commits (as viewed in `hg histedit`):
+
+    pick ee4d9e9fcbad 477986 Bug 1461515 - Split tracking annotations from tracki...
+    pick c24f4d9e75b9 477992 Bug 1461515 - Fix and expand tracking annotation tes...
+    pick 1840f68978a7 477993 Bug 1461515 - Make TP test fail if it uses the wrong...
+
+which highlights that the last two commits changed and that I would have two
+revisions ([D2485](https://phabricator.services.mozilla.com/D2485) and
+[D2486](https://phabricator.services.mozilla.com/D2486)) to update in
+Phabricator.
+
+However, since the only reason why the third patch has a different commit
+hash is because its parent changed, theres's no need to upload it again to
+Phabricator. [Lando](https://lando.services.mozilla.com/) doesn't care about
+the parent **hash** and relies instead on the parent **revision ID**. It
+essentially applies diffs one at a time.
+
+The trick was to pass the `--update DXXXX` argument to `arc diff`:
+
+    ~/devel/mozilla-unified (annotation-list-1461515)$ hg up c24f4d9e75b9
+    2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+    (leaving bookmark annotation-list-1461515)
+
+    ~/devel/mozilla-unified (c24f4d9)$ arc diff --no-amend --update D2485
+    Linting...
+    No lint engine configured for this project.
+    Running unit tests...
+    No unit test engine is configured for this project.
+     SKIP STAGING  Phabricator does not support staging areas for this repository.
+    Updated an existing Differential revision:
+            Revision URI: https://phabricator.services.mozilla.com/D2485
+
+    Included changes:
+      M       browser/base/content/test/general/trackingPage.html
+      M       netwerk/test/unit/test_trackingProtection_annotateChannels.js
+      M       toolkit/components/antitracking/test/browser/browser_imageCache.js
+      M       toolkit/components/antitracking/test/browser/browser_subResources.js
+      M       toolkit/components/antitracking/test/browser/head.js
+      M       toolkit/components/antitracking/test/browser/popup.html
+      M       toolkit/components/antitracking/test/browser/tracker.js
+      M       toolkit/components/url-classifier/tests/UrlClassifierTestUtils.jsm
+      M       toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_bug1312515.html
+      M       toolkit/components/url-classifier/tests/mochitest/trackingRequest.html
+
+Note that changing the commit message will not automatically update the
+revision details in Phabricator. This has to be done manually in the Web UI
+if required.
+
 [[!tag mozilla]] [[!tag mercurial]]

Add Phabricator commit series blogpost
diff --git a/posts/mercurial-commit-series-phabricator-using-arcanist.mdwn b/posts/mercurial-commit-series-phabricator-using-arcanist.mdwn
new file mode 100644
index 0000000..c485eb3
--- /dev/null
+++ b/posts/mercurial-commit-series-phabricator-using-arcanist.mdwn
@@ -0,0 +1,110 @@
+[[!meta title="Mercurial commit series in Phabricator using Arcanist"]]
+[[!meta date="2018-08-01T09:00:00:00.000-07:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+[Phabricator](https://www.phacility.com/phabricator/) supports multi-commit
+patch series, but it's not yet obvious how to do it using Mercurial. So this
+the "hg" equivalent of [this blog post for git
+users](https://smacleod.ca/posts/commit-series-with-phabricator/ ).
+
+Note that other people have written [tools and
+plugins](https://groups.google.com/d/topic/mozilla.dev.platform/o9f2S0vO47k/discussion)
+to do the same thing and that [an official client is coming
+soon](https://groups.google.com/d/msg/mozilla.dev.platform/LhUq1EUvcfg/yLuTpAhvCAAJ).
+
+# Initial setup
+
+I'm going to assume that you've setup arcanist and gotten an account on the
+[Mozilla Phabricator instance](https://phabricator.services.mozilla.com/).
+If you haven't, follow this [video
+introduction](https://www.youtube.com/watch?reload=9&v=3e-eaeeIDXk) or the
+[excellent
+documentation](https://moz-conduit.readthedocs.io/en/latest/phabricator-user.html)
+for it (Bryce also wrote additionnal [instructions for Windows
+users](https://www.brycevandyk.com/setting-up-arcanist-for-mozilla-development-on-windows/)).
+
+# Make a list of commits to submit
+
+First of all, use `hg histedit` to make a list of the commits that are needed:
+
+    pick ee4d9e9fcbad 477986 Bug 1461515 - Split tracking annotations from tracki...
+    pick 5509b5db01a4 477987 Bug 1461515 - Fix and expand tracking annotation tes...
+    pick e40312debf76 477988 Bug 1461515 - Make TP test fail if it uses the wrong...
+
+# Create Phabricator revisions
+
+Now, create a Phabricator *revision* for each commit (in order, from
+earliest to latest):
+
+    ~/devel/mozilla-unified (annotation-list-1461515)$ hg up ee4d9e9fcbad
+    5 files updated, 0 files merged, 0 files removed, 0 files unresolved
+    (leaving bookmark annotation-list-1461515)
+
+    ~/devel/mozilla-unified (ee4d9e9)$ arc diff --no-amend
+    Linting...
+    No lint engine configured for this project.
+    Running unit tests...
+    No unit test engine is configured for this project.
+     SKIP STAGING  Phabricator does not support staging areas for this repository.
+    Created a new Differential revision:
+            Revision URI: https://phabricator.services.mozilla.com/D2484
+
+    Included changes:
+      M       modules/libpref/init/all.js
+      M       netwerk/base/nsChannelClassifier.cpp
+      M       netwerk/base/nsChannelClassifier.h
+      M       toolkit/components/url-classifier/Classifier.cpp
+      M       toolkit/components/url-classifier/SafeBrowsing.jsm
+      M       toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+      M       toolkit/components/url-classifier/tests/UrlClassifierTestUtils.jsm
+      M       toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_bug1312515.html
+      M       xpcom/base/ErrorList.py
+
+    ~/devel/mozilla-unified (ee4d9e9)$ hg up 5509b5db01a4
+    3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+    ~/devel/mozilla-unified (5509b5d)$ arc diff --no-amend
+    Linting...
+    No lint engine configured for this project.
+    Running unit tests...
+    No unit test engine is configured for this project.
+     SKIP STAGING  Phabricator does not support staging areas for this repository.
+    Created a new Differential revision:
+            Revision URI: https://phabricator.services.mozilla.com/D2485
+
+    Included changes:
+      M       toolkit/components/url-classifier/tests/UrlClassifierTestUtils.jsm
+      M       toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_bug1312515.html
+      M       toolkit/components/url-classifier/tests/mochitest/trackingRequest.html
+
+    ~/devel/mozilla-unified (5509b5d)$ hg up e40312debf76
+    2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+    ~/devel/mozilla-unified (e40312d)$ arc diff --no-amend
+    Linting...
+    No lint engine configured for this project.
+    Running unit tests...
+    No unit test engine is configured for this project.
+     SKIP STAGING  Phabricator does not support staging areas for this repository.
+    Created a new Differential revision:
+            Revision URI: https://phabricator.services.mozilla.com/D2486
+
+    Included changes:
+      M       toolkit/components/url-classifier/tests/mochitest/classifiedAnnotatedPBFrame.html
+      M       toolkit/components/url-classifier/tests/mochitest/test_privatebrowsing_trackingprotection.html
+
+# Link all revisions together
+
+In order to ensure that these commits depend on one another, lick on that
+last [`phabricator.services.mozilla.com`
+link](https://phabricator.services.mozilla.com/D2486), then click "Related
+Revisions" then "Edit Parent Revisions" in the right-hand side bar and then
+add the previous commit
+([D2485](https://phabricator.services.mozilla.com/D2485) in this example).
+
+Then go to [that parent
+revision](https://phabricator.services.mozilla.com/D2485) and repeat the
+same steps to set [D2484](https://phabricator.services.mozilla.com/D2484) as
+its parent.
+
+[[!tag mozilla]] [[!tag mercurial]]

Comment moderation
diff --git a/posts/recovering-from-botched-mercurial-bookmark-histedit/comment_2_95f87a12f7409c2774c54b9cf818cf2a._comment b/posts/recovering-from-botched-mercurial-bookmark-histedit/comment_2_95f87a12f7409c2774c54b9cf818cf2a._comment
new file mode 100644
index 0000000..108e753
--- /dev/null
+++ b/posts/recovering-from-botched-mercurial-bookmark-histedit/comment_2_95f87a12f7409c2774c54b9cf818cf2a._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="sphink@fbb18a7777e2e0ef4afb7f7c664405c496334047"
+ nickname="sphink"
+ avatar="http://cdn.libravatar.org/avatar/d269c0228684029dedb75d73b81a64c3"
+ subject="alternative"
+ date="2018-07-28T00:09:31Z"
+ content="""
+I would expect that you would do the unbundle, then move your bookmark back to 'tip' (which should be last unbundled changeset). I would think:
+
+    hg unbundle ~/devel/mozilla-unified/.hg/strip-backup/47906774d58d-ae1953e1-backup.hg
+    hg bookmark -r tip hashstore-crash-1434206-recovered
+
+though I would probably do `hg log -G` to verify it's the one you want. Or `hg log --template list -G`.
+
+"""]]

Comment moderation
diff --git a/posts/recovering-from-botched-mercurial-bookmark-histedit/comment_1_79745417458229f91cdb2f08049182d1._comment b/posts/recovering-from-botched-mercurial-bookmark-histedit/comment_1_79745417458229f91cdb2f08049182d1._comment
new file mode 100644
index 0000000..811601d
--- /dev/null
+++ b/posts/recovering-from-botched-mercurial-bookmark-histedit/comment_1_79745417458229f91cdb2f08049182d1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ ip="50.100.182.11"
+ claimedauthor="Connor"
+ subject="comment 1"
+ date="2018-07-27T14:04:56Z"
+ content="""
+You should check out the evolve extension. `pip install hg-evolve`
+"""]]

Add post on `hg histedit`
diff --git a/posts/recovering-from-botched-mercurial-bookmark-histedit.mdwn b/posts/recovering-from-botched-mercurial-bookmark-histedit.mdwn
new file mode 100644
index 0000000..a80567d
--- /dev/null
+++ b/posts/recovering-from-botched-mercurial-bookmark-histedit.mdwn
@@ -0,0 +1,92 @@
+[[!meta title="Recovering from a botched hg histedit on a mercurial bookmark"]]
+[[!meta date="2018-07-26T22:42:00:00.000-07:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+If you are in the middle of a failed
+[Mercurial](https://www.mercurial-scm.org/) `hg histedit`, you can normally
+do `hg histedit --abort` to cancel it, though sometimes you also have to
+reach out for `hg update -C`. This is the equivalent of
+[git](https://git-scm.com/)'s `git rebase --abort` and it does what you'd
+expect.
+
+However, if you go ahead and finish the history rewriting and only notice
+problems later, it's not as straighforward. With git, I'd look into the
+[reflog](https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog)
+(`git reflog`) for the previous value of the branch pointer and simply `git
+reset --hard` to that value. Done.
+
+Based on a [Stack Overflow
+answer](https://stackoverflow.com/questions/43742808/how-do-i-recover-from-a-botched-histedit-in-mercurial),
+I thought I could undo my botched histedit using:
+
+    hg unbundle ~/devel/mozilla-unified/.hg/strip-backup/47906774d58d-ae1953e1-backup.hg
+
+but it didn't seem to work. Maybe it doesn't work when using
+[bookmarks](https://www.mercurial-scm.org/wiki/Bookmarks).
+
+Here's what I ended up doing to fully revert my botched Mercurial
+[histedit](https://www.mercurial-scm.org/wiki/HisteditExtension). If you
+know of a simpler way to do this, feel free to leave a comment.
+
+# Collecting the commits to restore
+
+The first step was to collect all of the commits hashes I needed to restore.
+Luckily, I had sumitted my patch to
+[Try](https://wiki.mozilla.org/ReleaseEngineering/TryServer) before changing
+it and so I was able to look at the
+[pushlog](https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/hashstore-crash-1434206)
+to get all of the commits at once.
+
+If I didn't have that, I could also go to the [last bookmark I
+pushed](https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/hashstore-crash-1434206)
+and click on parent commits until I hit the [first one that's not
+mine](https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/ff8505d177b9).
+Then I could collect all of the commits using the browser's back button:
+
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/3c31c543e736>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/7ddfe5ae2fa6>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/c04b620136c7>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/2d1bf04fd155>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/e194843f5b7a>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/47906774d58d>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/f6a657bca64f>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/0d7a4e1c0079>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/976e25b49758>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/a1a382f2e773>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/b1565f3aacdb>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/3fdd157bb698>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/b1b041990577>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/220bf5cd9e2a>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/c927a5205abe>
+- <https://hg.mozilla.org/users/fmarier_mozilla.com/mozilla-unified/rev/4140cd9c67b0>
+
+For that last one, I had to click on the changeset commit hash link in order to
+get the commit hash instead of the name of the bookmark (`/rev/hashstore-crash-1434206`).
+
+# Recreating the branch from scratch
+
+This is what did to export patches for each commit and then re-import them
+one after the other:
+
+    for c in 3c31c543e736 7ddfe5ae2fa6 c04b620136c7 2d1bf04fd155 e194843f5b7a 47906774d58d f6a657bca64f 0d7a4e1c0079 976e25b49758 a1a382f2e773 b1565f3aacdb 3fdd157bb698 b1b041990577 220bf5cd9e2a c927a5205abe ; do hg export $c > ~/$c.patch ; done
+    hg up ff8505d177b9
+    hg bookmarks hashstore-crash-1434206-new
+    for c in 3c31c543e736 7ddfe5ae2fa6 c04b620136c7 2d1bf04fd155 e194843f5b7a 47906774d58d f6a657bca64f 0d7a4e1c0079 976e25b49758 a1a382f2e773 b1565f3aacdb 3fdd157bb698 b1b041990577 220bf5cd9e2a c927a5205abe 4140cd9c67b0 ; do hg import ~/$c.patch ; done
+
+# Copying a bookmark
+
+As an aside, if you want to make a copy of a bookmark before you do an `hg
+histedit`, it's not as simple as:
+
+    hg up hashstore-crash-1434206
+    hg bookmarks hashstore-crash-1434206-copy
+    hg up hashstore-crash-1434206
+
+While that seemed to work at the time, the `histedit` ended up messing with
+both of them.
+
+An alternative that works is to push the bookmark to another machine. That
+way if worse comes to worse, you can `hg clone` from there and `hg export`
+the commits you want to re-import using `hg import`.
+
+[[!tag mozilla]] [[!tag mercurial]]

Rephrase a sentence to hopefully force a regeneration of this page
diff --git a/posts.mdwn b/posts.mdwn
index 2bd0f1d..663a69d 100644
--- a/posts.mdwn
+++ b/posts.mdwn
@@ -1,3 +1,3 @@
-Here is a full list of posts to the [[blog|index]].
+Here's a full list of the posts on this [[blog|index]]:
 
 [[!inline pages="page(./posts/*) and !*/Discussion" archive=yes feedshow=10 quick=yes trail=yes]]

Fix post title again, hopefully for the last time
diff --git a/posts/asterisk-everyone-busy-congested-at-this-time.mdwn b/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
index a1a9b58..4fad7a3 100644
--- a/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
+++ b/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
@@ -1,5 +1,5 @@
-[[!meta title='Mysterious "everybody is busy/congested at this time" error in Asterisk']]
-[[!meta date="2018-06-10T18:55:00.000-07:00"]]
+[[!meta title="Mysterious 'everybody is busy/congested at this time' error in Asterisk"]]
+[[!meta date="2018-06-10T19:00:00.000-07:00"]]
 [[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
 
 I was trying to figure out why I was getting a BUSY signal from

Fix broken markup in post title
diff --git a/posts/asterisk-everyone-busy-congested-at-this-time.mdwn b/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
index b436139..a1a9b58 100644
--- a/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
+++ b/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
@@ -1,4 +1,4 @@
-[[!meta title="Mysterious \"everybody is busy/congested at this time\" error in Asterisk"]]
+[[!meta title='Mysterious "everybody is busy/congested at this time" error in Asterisk']]
 [[!meta date="2018-06-10T18:55:00.000-07:00"]]
 [[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
 

Fix post title
diff --git a/posts/asterisk-everyone-busy-congested-at-this-time.mdwn b/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
index 6181290..b436139 100644
--- a/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
+++ b/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
@@ -1,4 +1,4 @@
-[[!meta title="Running mythtv-setup over ssh"]]
+[[!meta title="Mysterious \"everybody is busy/congested at this time\" error in Asterisk"]]
 [[!meta date="2018-06-10T18:55:00.000-07:00"]]
 [[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
 

creating tag page tags/asterisk
diff --git a/tags/asterisk.mdwn b/tags/asterisk.mdwn
new file mode 100644
index 0000000..7389596
--- /dev/null
+++ b/tags/asterisk.mdwn
@@ -0,0 +1,4 @@
+[[!meta title="pages tagged asterisk"]]
+
+[[!inline pages="tagged(asterisk)" actions="no" archive="yes"
+feedshow=10]]

Add asterisk "busy/congested" post
diff --git a/posts/asterisk-everyone-busy-congested-at-this-time.mdwn b/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
new file mode 100644
index 0000000..6181290
--- /dev/null
+++ b/posts/asterisk-everyone-busy-congested-at-this-time.mdwn
@@ -0,0 +1,101 @@
+[[!meta title="Running mythtv-setup over ssh"]]
+[[!meta date="2018-06-10T18:55:00.000-07:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+I was trying to figure out why I was getting a BUSY signal from
+[Asterisk](https://www.asterisk.org/) while trying to ring a SIP phone even
+though that phone was not in use.
+
+My asterisk setup looks like this:
+
+    phone 1 <--SIP--> asterisk 1 <==IAX2==> asterisk 2 <--SIP--> phone 2
+
+While I couldn't call SIP phone #2 from SIP phone #1, the reverse was
+working fine (ringing #1 from #2). So it's not a network/firewall problem.
+The two SIP phones can talk to one another through their respective Asterisk
+servers.
+
+This is the error message I could see on the second asterisk server:
+
+    $ asterisk -r
+    ...
+      == Using SIP RTP TOS bits 184
+      == Using SIP RTP CoS mark 5
+        -- Called SIP/12345
+        -- SIP/12345-00000002 redirecting info has changed, passing it to IAX2/iaxuser-6347
+        -- SIP/12345-00000002 is busy
+      == Everyone is busy/congested at this time (1:1/0/0)
+        -- Executing [12345@local:2] Goto("IAX2/iaxuser-6347", "in12345-BUSY,1") in new stack
+        -- Goto (local,in12345-BUSY,1)
+        -- Executing [in12345-BUSY@local:1] Hangup("IAX2/iaxuser-6347", "17") in new stack
+      == Spawn extension (local, in12345-BUSY, 1) exited non-zero on 'IAX2/iaxuser-6347'
+        -- Hungup 'IAX2/iaxuser-6347'
+
+where:
+
+- `12345` is the extension of SIP phone #2 on Asterisk server #2
+- `iaxuser` is the user account on server #2 that server #1 uses
+- `local` is the *context* that for incoming IAX calls on server #1
+
+This `Everyone is busy/congested at this time (1:1/0/0)` was surprising
+since looking at each SIP channel on that server showed nobody as busy:
+
+    asterisk2*CLI> sip show inuse
+    * Peer name               In use          Limit           
+    12345                     0/0/0           2               
+
+So I enabled the raw SIP debug output and got the following (edited for
+clarity):
+
+    asterisk2*CLI> sip set debug on
+    SIP Debugging enabled
+    
+      == Using SIP RTP TOS bits 184
+      == Using SIP RTP CoS mark 5
+    
+    INVITE sip:12345@192.168.0.4:2048;line=m2vlbuoc SIP/2.0
+    Via: SIP/2.0/UDP 192.168.0.2:5060
+    From: "Francois Marier" <sip:67890@192.168.0.2>
+    To: <sip:12345@192.168.0.4:2048;line=m2vlbuoc>
+    CSeq: 102 INVITE
+    User-Agent: Asterisk PBX
+    Contact: <sip:67890@192.168.0.2:5060>
+    Content-Length: 274
+    
+        -- Called SIP/12345
+    
+    <--- SIP read from UDP:192.168.0.4:2048 --->
+    SIP/2.0 100 Trying
+    Via: SIP/2.0/UDP 192.168.0.2:5060
+    From: "Francois Marier" <sip:67890@192.168.0.2>
+    To: <sip:12345@192.168.0.4:2048;line=m2vlbuoc>
+    CSeq: 102 INVITE
+    User-Agent: snom300
+    Contact: <sip:12345@192.168.0.4:2048;line=m2vlbuoc>
+    Content-Length: 0
+    
+    <------------->
+    --- (9 headers 0 lines) ---
+    
+    <--- SIP read from UDP:192.168.0.4:2048 --->
+    SIP/2.0 480 Do Not Disturb
+    Via: SIP/2.0/UDP 192.168.0.2:5060
+    From: "Francois Marier" <sip:67890@192.168.0.2>
+    To: <sip:12345@192.168.0.4:2048;line=m2vlbuoc>
+    CSeq: 102 INVITE
+    User-Agent: snom300
+    Contact: <sip:12345@192.168.0.4:2048;line=m2vlbuoc>
+    Content-Length: 0
+
+where:
+
+- `12345` is the extension of SIP phone #2 on Asterisk server #2
+- `67890` is the extension of SIP phone #1 on Asterisk server #2
+- `192.168.0.4` is the IP address of SIP phone #2
+- `192.168.0.1` is the IP address of Asterisk server #2
+
+From there, I can see that SIP phone #2 is returning a status of `408 Do Not
+Disturb`. That's what the problem was: **the phone itself was in DnD mode
+and set to reject all incoming calls**.
+
+[[!tag asterisk]] [[!tag nzoss]]

Comment moderation
diff --git a/posts/time-synchronization-with-ntp-and-systemd/comment_5_eef2612fa5fd51ce24329641c0d25c86._comment b/posts/time-synchronization-with-ntp-and-systemd/comment_5_eef2612fa5fd51ce24329641c0d25c86._comment
new file mode 100644
index 0000000..f3fda45
--- /dev/null
+++ b/posts/time-synchronization-with-ntp-and-systemd/comment_5_eef2612fa5fd51ce24329641c0d25c86._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ ip="128.171.1.2"
+ claimedauthor="Robin"
+ subject="&quot;NTP synchronized&quot; => &quot;systemd-timesyncd.service active&quot;"
+ date="2018-05-25T03:01:43Z"
+ content="""
+NOTE: This commit changed the output:
+
+https://github.com/systemd/systemd/commit/3ec530a1890925efe347f739917dd4078c1b1942
+
+\"NTP synchronized\" => \"systemd-timesyncd.service active\"
+"""]]

Remove all affiliate links
I never got anything out of them and don't want to have to read about the
rules for how to do those correctly (e.g. FTC guidelines in the US).
diff --git a/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn b/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
index e18ea5e..c9aacdc 100644
--- a/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
+++ b/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu.mdwn
@@ -16,7 +16,7 @@ VPN is a faster way to connect to sites that already know you.
 
 Here are my instructions for setting up [OpenVPN](http://openvpn.net/) on
 Debian / Ubuntu machines where the VPN server is located on a cheap
-[Linode](https://www.linode.com/?r=4f882417aa3809652b227d6d9c25b2a0472c6cff)
+[Linode](https://www.linode.com/)
 virtual private server. They are largely based on the
 [instructions found on the Debian wiki](https://wiki.debian.org/openvpn%20for%20server%20and%20client).
 
@@ -70,9 +70,7 @@ and generate the keys:
 
 # Configuring the server
 
-On my server, a
-[Linode VPS](https://www.linode.com/?r=4f882417aa3809652b227d6d9c25b2a0472c6cff)
-called `hafnarfjordur.fmarier.org`, I installed the
+On my server, called `hafnarfjordur.fmarier.org`, I installed the
 [openvpn package](http://packages.debian.org/stable/openvpn):
 
     apt-get install openvpn
diff --git a/posts/ipv6-and-openvpn-on-linode.mdwn b/posts/ipv6-and-openvpn-on-linode.mdwn
index f118113..3560624 100644
--- a/posts/ipv6-and-openvpn-on-linode.mdwn
+++ b/posts/ipv6-and-openvpn-on-linode.mdwn
@@ -16,9 +16,7 @@ The first thing you need to do is get a new IPv6 address block (or "pool" as
 Linode calls it) from which you can allocate a single address to each VPN
 client that connects to the server.
 
-If you are using a
-[Linode VPS](https://www.linode.com/?r=4f882417aa3809652b227d6d9c25b2a0472c6cff),
-there are
+If you are using a [Linode VPS](https://www.linode.com/), there are
 [instructions on how to request a new IPv6 pool](https://www.linode.com/docs/networking/native-ipv6-networking#additional-ipv6-addresses).
 Note that you need to get an address block **between `/64` and `/112`**. A
 `/116` like Linode offers won't work in [OpenVPN](https://openvpn.net/). Thankfully, Linode
diff --git a/posts/letting-someone-ssh-into-your-laptop-using-pagekite.mdwn b/posts/letting-someone-ssh-into-your-laptop-using-pagekite.mdwn
index e16ca62..193242e 100644
--- a/posts/letting-someone-ssh-into-your-laptop-using-pagekite.mdwn
+++ b/posts/letting-someone-ssh-into-your-laptop-using-pagekite.mdwn
@@ -4,13 +4,13 @@
 
 In order to [investigate a bug I was running into](https://github.com/mozilla/rr/issues/1537), I recently had to give
 [my colleague](http://robert.ocallahan.org/) ssh access to my laptop behind a firewall. The easiest way
-I found to do this was to create an account for him on my laptop and setup a
-[pagekite](https://pagekite.net/wiki/OpenSource/) frontend on my
-[Linode server](https://www.linode.com/?r=4f882417aa3809652b227d6d9c25b2a0472c6cff) and a pagekite backend on my laptop.
+I found to do this was to create an account for him on my laptop, and setup a
+[pagekite](https://pagekite.net/wiki/OpenSource/) frontend on my personal server
+and a pagekite backend on my laptop.
 
 # Frontend setup
 
-Setting up my Linode server in order to make the ssh service accessible and
+Setting up my server in order to make the ssh service accessible and
 proxy the traffic to my laptop was fairly straightforward.
 
 First, I had to install the
diff --git a/posts/running-your-own-xmpp-server-debian-ubuntu.mdwn b/posts/running-your-own-xmpp-server-debian-ubuntu.mdwn
index 3213970..359938b 100644
--- a/posts/running-your-own-xmpp-server-debian-ubuntu.mdwn
+++ b/posts/running-your-own-xmpp-server-debian-ubuntu.mdwn
@@ -3,8 +3,7 @@
 [[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
 
 In order to get closer to my goal of reducing my dependence on centralized
-services, I decided to setup my own XMPP / Jabber server on a
-[Linode VPS](https://www.linode.com/?r=4f882417aa3809652b227d6d9c25b2a0472c6cff)
+services, I decided to setup my own XMPP / Jabber server on a server
 running [Debian wheezy](http://www.debian.org/releases/wheezy/). I chose
 [ejabberd](http://www.ejabberd.im/) since it was recommended by the
 [RTC Quick Start](http://www.rtcquickstart.org/) website and here's how I
diff --git a/posts/using-openvpn-on-android-lollipop.mdwn b/posts/using-openvpn-on-android-lollipop.mdwn
index ecc7bb6..74d3e6e 100644
--- a/posts/using-openvpn-on-android-lollipop.mdwn
+++ b/posts/using-openvpn-on-android-lollipop.mdwn
@@ -2,9 +2,7 @@
 [[!meta date="2015-04-03T16:45:00.000+13:00"]]
 [[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
 
-I use my
-[Linode VPS](https://www.linode.com/?r=4f882417aa3809652b227d6d9c25b2a0472c6cff)
-as a VPN endpoint for my laptop when I'm using untrusted networks and I
+I use my personal server as a VPN endpoint for my laptop when I'm using untrusted networks and I
 wanted to do the same on my Android 5 (Lollipop) phone.
 
 It turns out that it's quite easy to do (doesn't require rooting your phone)

Fix disappearing instruction in user comment
diff --git a/posts/reinstalling-grub-on-unbootable-debian/comment_1_a230444cac2eb55bee01b0ec698fda2a._comment b/posts/reinstalling-grub-on-unbootable-debian/comment_1_a230444cac2eb55bee01b0ec698fda2a._comment
index 0e51508..44ae82e 100644
--- a/posts/reinstalling-grub-on-unbootable-debian/comment_1_a230444cac2eb55bee01b0ec698fda2a._comment
+++ b/posts/reinstalling-grub-on-unbootable-debian/comment_1_a230444cac2eb55bee01b0ec698fda2a._comment
@@ -15,7 +15,7 @@ Or, if you'd rather just boot into the system and fix it from there, I use somet
   
     configfile (hd0,0)/boot/grub/menu.lst
 
-<press escape>
+(press escape)
 
 
 """]]

Improve formatting of user comments
diff --git a/posts/reinstalling-grub-on-unbootable-debian/comment_1_a230444cac2eb55bee01b0ec698fda2a._comment b/posts/reinstalling-grub-on-unbootable-debian/comment_1_a230444cac2eb55bee01b0ec698fda2a._comment
index de32904..0e51508 100644
--- a/posts/reinstalling-grub-on-unbootable-debian/comment_1_a230444cac2eb55bee01b0ec698fda2a._comment
+++ b/posts/reinstalling-grub-on-unbootable-debian/comment_1_a230444cac2eb55bee01b0ec698fda2a._comment
@@ -3,17 +3,18 @@
  subject=""
  date="2009-06-09T06:11:56.908+12:00"
  content="""
-The method I use is to boot another copy of Grub from somewhere (bootable CD, USB stick, or network boot -- it's easy to boot grub from any of these). Then, from the prompt, something like  
+The method I use is to boot another copy of Grub from somewhere (bootable CD, USB stick, or network boot -- it's easy to boot grub from any of these). Then, from the prompt, something like:
   
-root (hd0,0)  
-setup (hd0)  
-reboot  
+    root (hd0,0)
+    setup (hd0)
+    reboot
   
-is all you need to install grub onto the disk.  
+is all you need to install grub onto the disk.
   
-Or, if you'd rather just boot into the system and fix it from there, I use something like  
+Or, if you'd rather just boot into the system and fix it from there, I use something like:
   
-configfile (hd0,0)/boot/grub/menu.lst  
+    configfile (hd0,0)/boot/grub/menu.lst
+
 <press escape>
 
 
diff --git a/posts/reinstalling-grub-on-unbootable-debian/comment_2_262c218d575a3f8b0fe9c07f72434230._comment b/posts/reinstalling-grub-on-unbootable-debian/comment_2_262c218d575a3f8b0fe9c07f72434230._comment
index 703e75f..65ead62 100644
--- a/posts/reinstalling-grub-on-unbootable-debian/comment_2_262c218d575a3f8b0fe9c07f72434230._comment
+++ b/posts/reinstalling-grub-on-unbootable-debian/comment_2_262c218d575a3f8b0fe9c07f72434230._comment
@@ -4,5 +4,5 @@
  subject="Need one extra step on Debian Jessie"
  date="2018-05-13T20:26:19Z"
  content="""
-I followed your instruction but it did not work.  It turns out that I need to run one additional command, \"grub-mkconfig\" (because I have changed the boot partition).  After that, the computer was able to boot successfully.
+I followed your instruction but it did not work.  It turns out that I need to run one additional command, `grub-mkconfig` (because I have changed the boot partition).  After that, the computer was able to boot successfully.
 """]]

Comment moderation
diff --git a/posts/reinstalling-grub-on-unbootable-debian/comment_2_262c218d575a3f8b0fe9c07f72434230._comment b/posts/reinstalling-grub-on-unbootable-debian/comment_2_262c218d575a3f8b0fe9c07f72434230._comment
new file mode 100644
index 0000000..703e75f
--- /dev/null
+++ b/posts/reinstalling-grub-on-unbootable-debian/comment_2_262c218d575a3f8b0fe9c07f72434230._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ ip="108.200.55.112"
+ claimedauthor="Toan Tran"
+ subject="Need one extra step on Debian Jessie"
+ date="2018-05-13T20:26:19Z"
+ content="""
+I followed your instruction but it did not work.  It turns out that I need to run one additional command, \"grub-mkconfig\" (because I have changed the boot partition).  After that, the computer was able to boot successfully.
+"""]]

Add mythtv-setup over ssh post
diff --git a/posts/mythtv-setup-over-ssh.mdwn b/posts/mythtv-setup-over-ssh.mdwn
new file mode 100644
index 0000000..e77957f
--- /dev/null
+++ b/posts/mythtv-setup-over-ssh.mdwn
@@ -0,0 +1,30 @@
+[[!meta title="Running mythtv-setup over ssh"]]
+[[!meta date="2018-05-13T13:55:00.000-07:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+In order to configure a remote [MythTV](https://www.mythtv.org/) server, I
+had to run `mythtv-setup` remotely over an ssh connection with X forwarding:
+
+    ssh -X mythtv@machine
+
+For most config options, I can either use the configuration menus inside of
+of `mythfrontend` (over a [vnc
+connection](https://feeding.cloud.geek.nz/posts/high-latency-vnc-tech-support/))
+or the *Settings* section of
+[MythWeb](https://www.mythtv.org/detail/mythweb), but some of the backend
+and tuner settings are only available through the main setup program.
+
+Unfortunately, `mythtv-setup` won't work over an ssh connection by default
+and prints the following error in the terminal:
+
+    $ mythtv-setup
+    ...
+    W  OpenGL: Could not determine whether Sync to VBlank is enabled.
+    Handling Segmentation fault
+    Segmentation fault (core dumped)
+
+The fix for this was to specify a different theme engine:
+
+    mythtv-setup -O ThemePainter=qt
+
+[[!tag mythtv]]

Comment moderation
diff --git a/posts/recovering-from-unbootable-ubuntu-encrypted-lvm-root-partition/comment_1_dbf4ae9f9fe087f9b03cfb0961a4fe57._comment b/posts/recovering-from-unbootable-ubuntu-encrypted-lvm-root-partition/comment_1_dbf4ae9f9fe087f9b03cfb0961a4fe57._comment
new file mode 100644
index 0000000..76a00f1
--- /dev/null
+++ b/posts/recovering-from-unbootable-ubuntu-encrypted-lvm-root-partition/comment_1_dbf4ae9f9fe087f9b03cfb0961a4fe57._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ ip="107.181.176.98"
+ claimedauthor="William"
+ url="willinspire.us"
+ subject="Without using a live instance"
+ date="2018-05-06T20:54:15Z"
+ content="""
+I successfully used your recommended approach without booting via USB. This can be accomplished by selecting to boot into a previous kernel via the Grub boot menu during startup, and then (without the need to mount local partitions) simply ensure the latest version of lvm2 is installed and regenerating the initramfs for all of the installed kernels (as recommended). I also have a fully encrypted drive configuration and found no issues when performing these steps. 
+
+Thank you for putting this article together. While I normally find the forums to be of great assistance, this issue was not one that is easy to find real working solutions for. Keep up the great work.
+"""]]

Comment moderation
diff --git a/posts/setting-up-a-network-scanner-using-sane/comment_8_ea06287e4ee5254087011d534e543316._comment b/posts/setting-up-a-network-scanner-using-sane/comment_8_ea06287e4ee5254087011d534e543316._comment
new file mode 100644
index 0000000..68e4645
--- /dev/null
+++ b/posts/setting-up-a-network-scanner-using-sane/comment_8_ea06287e4ee5254087011d534e543316._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ ip="216.162.65.24"
+ claimedauthor="ajeh"
+ url="linuxlies.mee.nu"
+ subject="This still works well under Fedora 26 and Windows 7"
+ date="2018-04-29T15:10:44Z"
+ content="""
+The instructions in this blog are spot on: everything worked right away (well, except the FW rule, but this is a very minor issue) and I ended up doing some googling for the Windows SANE client and found SANEWinDS on source forge. Works standalone and from Open Office and I am happy camper.
+
+Thanks a lot for putting together this concise instruction, it saves my users from moving files around from the scanner sharing machine!
+"""]]

creating tag page tags/ham
diff --git a/tags/ham.mdwn b/tags/ham.mdwn
new file mode 100644
index 0000000..4ef4784
--- /dev/null
+++ b/tags/ham.mdwn
@@ -0,0 +1,4 @@
+[[!meta title="pages tagged ham"]]
+
+[[!inline pages="tagged(ham)" actions="no" archive="yes"
+feedshow=10]]

Add my Pat and D72 post
diff --git a/posts/using-kenwood-th-d72a-with-pat-linux-ax25.mdwn b/posts/using-kenwood-th-d72a-with-pat-linux-ax25.mdwn
new file mode 100644
index 0000000..4ddba68
--- /dev/null
+++ b/posts/using-kenwood-th-d72a-with-pat-linux-ax25.mdwn
@@ -0,0 +1,101 @@
+[[!meta title="Using a Kenwood TH-D72A with Pat on Linux and ax25"]]
+[[!meta date="2018-04-19T22:45:00.000-07:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+Here is how I managed to get my [Kenwood
+TH-D72A](http://www.kenwood.com/usa/com/amateur/th-d72a/) radio working with
+[Pat](http://getpat.io) on Linux using the built-in
+[TNC](https://en.wikipedia.org/wiki/Terminal_node_controller) and the
+[AX.25](http://linuxdocs.org/HOWTOs/AX25-HOWTO.html) mode
+
+# Installing Pat
+
+First of all, download and install the [latest Pat
+package](https://github.com/la5nta/pat/releases) from the GitHub project
+page.
+
+    dpkg -i pat_x.y.z_amd64.deb
+
+Then, follow the [installation
+instructions](https://github.com/la5nta/pat/wiki/AX25-Linux) for the AX.25
+mode and install the necessary packages:
+
+    apt install ax25-tools ax25-apps
+
+along with the systemd script that comes with Pat:
+
+    /usr/share/pat/ax25/install-systemd-ax25-unit.bash
+
+# Configuration
+
+Once the packages are installed, it's time to configure everything
+correctly:
+
+1. Power cycle the radio.
+2. Enable TNC in `packet12` mode (**band A***).
+3. Tune band A to [VECTOR
+   channel](https://vectorradio.ca/ops/frequency-list/) 420
+   (or [421](https://www.repeaterbook.com/repeaters/details.php?state_id=CA02&ID=3586)
+   if you can't reach `VA7EOC` on simplex).
+4. Put the following in `/etc/ax25/axports` (replacing `CALLSIGN` with your
+   own callsign):
+
+        wl2k    CALLSIGN    9600    128    4    Winlink
+
+5. Set `HBAUD` to **`1200`** in `/etc/default/ax25`.
+6. Download and compile the [`tmd710_tncsetup`
+   script](http://www.trinityos.com/HAM/CentosDigitalModes/usr/src/misc/D710/tmd710_tncsetup.c)
+   mentioned in a comment in `/etc/default/ax25`:
+
+        gcc -o tmd710_tncsetup tmd710_tncsetup.c
+
+7. Add the `tmd710_tncsetup` script in `/etc/default/ax25` and use these command
+   line parameters (`-B 0` specifies band A, use `-B 1` for band B):
+
+        tmd710_tncsetup -B 0 -S $DEV -b $HBAUD -s
+
+8. Start ax25 driver:
+
+        systemctl start ax25.service
+
+# Connecting to a winlink gateway
+
+To monitor what is being received and transmitted:
+
+    axlisten -cart
+
+Then create aliases like these in `~/.wl2k/config.json`:
+
+    {
+      "connect_aliases": {
+        "ax25-VA7EOC": "ax25://wl2k/VA7EOC-10",
+        "ax25-VE7LAN": "ax25://wl2k/VE7LAN-10"
+      },
+    }
+
+and use them to connect to your preferred Winlink gateways.
+
+# Troubleshooting
+
+If it doesn't look like ax25 can talk to the radio (i.e. the TX light
+doesn't turn ON), then it's possible that the `tmd710_tncsetup` script isn't
+being run at all, in which case the TNC isn't initialized correctly.
+
+On the other hand, if you can see the radio transmitting but are not seeing
+any **incoming packets** in `axlisten` then double check that the speed is
+set correctly:
+
+- `HBAUD` in `/etc/default/ax25` should be set to **1200**
+- line speed in `/etc/ax25/axports` should be set to **9600**
+- `SERIAL_SPEED` in `tmd710_tncsetup` should be set to **9600**
+- radio displays `packet12` in the top-left corner, not `packet96`
+
+If you can establish a connection, but it's very **unreliable**, make sure that
+you have enabled software flow control (the `-s` option in
+`tmd710_tncsetup`).
+
+If you can't connect to `VA7EOC-10` on UHF, you could also try the VHF BCFM
+repeater on Mt Seymour, [VE7LAN](http://www.bcfmca.bc.ca/lanvhf.php) (VECTOR
+channel 65).
+
+[[!tag ham]]

Emphasize the executable bit on the pre-up script
Also mention the log file as a way to confirm that everything
works.
diff --git a/posts/using-iptables-with-network-manager.mdwn b/posts/using-iptables-with-network-manager.mdwn
index 92a21d8..030c598 100644
--- a/posts/using-iptables-with-network-manager.mdwn
+++ b/posts/using-iptables-with-network-manager.mdwn
@@ -50,7 +50,7 @@ work on my Debian and Ubuntu machines. Instead, I had to create a new
     
     exit 0
 
-and then make that script executable:
+and then **make that script executable** (otherwise it won't run):
 
     chmod a+x /etc/NetworkManager/dispatcher.d/pre-up.d/iptables
 
@@ -59,4 +59,8 @@ With this in place, I can put my iptables rules in the usual place
 use the handy `iptables-apply` and `ip6tables-apply` commands to test
 any changes to my firewall rules.
 
+Looking at `/var/log/iptables.log`, you'll be able to confirm that
+it is being called correctly for each network interface as they
+are started.
+
 [[!tag nzoss]] [[!tag debian]] [[!tag iptables]]

Add SSDP multicast address to the iptables rules
diff --git a/posts/lxc-setup-on-debian-stretch.mdwn b/posts/lxc-setup-on-debian-stretch.mdwn
index 5fe6cc4..24422d0 100644
--- a/posts/lxc-setup-on-debian-stretch.mdwn
+++ b/posts/lxc-setup-on-debian-stretch.mdwn
@@ -50,6 +50,7 @@ world through the "host":
        -A FORWARD -d 10.0.3.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
        -A FORWARD -s 10.0.3.0/24 -j ACCEPT
        -A INPUT -d 224.0.0.251 -s 10.0.3.1 -j ACCEPT
+       -A INPUT -d 239.255.255.250 -s 10.0.3.1 -j ACCEPT
        -A INPUT -d 10.0.3.255 -s 10.0.3.1 -j ACCEPT
        -A INPUT -d 10.0.3.1 -s 10.0.3.0/24 -j ACCEPT
 

Add Libravatar shutdown post
diff --git a/posts/looking-back-on-starting-libravatar.mdwn b/posts/looking-back-on-starting-libravatar.mdwn
new file mode 100644
index 0000000..8b5bcab
--- /dev/null
+++ b/posts/looking-back-on-starting-libravatar.mdwn
@@ -0,0 +1,175 @@
+[[!meta title="Looking back on starting Libravatar"]]
+[[!meta date="2018-04-02T18:00:00.000-07:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+As noted on the [official Libravatar
+blog](https://blog.libravatar.org/posts/Libravatar.org_is_shutting_down_on_2018-09-01/),
+I will be shutting the service down on 2018-09-01.
+
+It has been an [incredible
+journey](https://ourincrediblejourney.tumblr.com/) but Libravatar has been
+more-or-less in maintenance mode for 5 years, so it's somewhat outdated in
+its technological stack and I no longer have much interest in doing the work
+that's required every two years when migrating to a new version of
+Debian/Django. The free software community prides itself on transparency and
+so while it is a [difficult decision to
+make](https://blog.liw.fi/posts/2017/08/13/retiring_obnam/), it's time to
+be upfront with the users who depend on the project and admit that the
+project is not sustainable in its current form.
+
+# Many things worked well
+
+The most motivating aspect of running Libravatar has been the steady organic
+growth within the FOSS community. Both in terms of traffic (in March 2018,
+we served a total of 5 GB of images and 12 GB of `302` redirects to
+Gravatar), integration with other sites and projects (Fedora, Debian,
+Mozilla, Linux kernel, Gitlab, Liberapay and many others), but also in terms
+of users:
+
+![](/posts/looking-back-on-starting-libravatar/cumulative_user_accounts.png)
+
+In addition, I wanted to validate that it is possible to run a FOSS service
+without having to pay for anything out-of-pocket, so that it would be
+financially sustainable. Hosting and domain registrations have been entirely
+funded by the community, thanks to the generosity of sponsors and donors.
+Most of the donations came through [Gittip/Gratipay](https://gratipay.com/)
+and [Liberapay](https://liberapay.com/). While Gratipay has now [shut
+down](https://gratipay.news/the-end-cbfba8f50981), I encourage you to
+[support Liberapay](https://liberapay.com/Liberapay/donate).
+
+Finally, I made an effort to host Libravatar on FOSS infrastructure. That
+meant shying away from popular proprietary services in order to make a point
+that these convenient and well-known services aren't actually needed to run
+a successful project.
+
+# A few things didn't pan out
+
+On the other hand, there were also a few disappointments.
+
+A lot of the [libraries and plugins](https://wiki.libravatar.org/libraries/)
+never implemented [DNS federation](https://wiki.libravatar.org/api/). That
+was the key part of the protocol that made Libravatar a decentralized
+service but unfortunately the rest of the protocol was must easier to
+implement and therefore many clients stopped there.
+
+In addition, it turns out that while the DNS system is essentially a
+federated caching system for IP addresses, many DNS resolvers aren't doing a
+good job caching records and that created unnecessary latency for clients
+that chose to support DNS federation.
+
+The main disappointment was that very few people stepped up to run mirrors.
+I designed the service so that it could scale easily in the same way that
+Linux distributions have coped with increasing user bases: "ftp" mirrors. By
+making the actual serving of images only require Apache and `mod_rewrite`, I
+had hoped that anybody running Apache would be able to add an extra vhost to
+their setup and start serving our static files. A few people did sign up for
+this over the years, but it mostly didn't work. Right now, there are no
+third-party mirrors online.
+
+The other aspect that was a little disappointing was the lack of code
+contributions. There were a handful from friends in the first couple of
+months, but it's otherwise been a one-man project. I suppose that when a
+service works well for what people use it for, there are less opportunities
+for contributions (or less desire for it). The fact [dev environment
+setup](https://wiki.libravatar.org/development_environment/) was not the
+easiest could definitely be a contributing factor, but I've only ever had a
+single person ask about it so it's not clear that this was the limiting
+factor. Also, while our source code repository was hosted on Github and open
+for pull requests, we never even received a single drive-by contribution,
+hinting at the fact that Github is not the magic bullet for community
+contributions that many people think it is.
+
+Finally, it turns out that it is harder to delegate sysadmin work (you need
+root, for one thing) which consumes the majority of the time in a mature
+project. The general administration and maintenance of Libravatar has never
+moved on beyond its core team of one. I don't have a lot of ideas here, but
+I do want to join
+[others](http://scanlime.org/2011/05/cia-vc-service-is-down-indefinitely/)
+who have flagged this as an area for "future work" in terms of project
+sustainability.
+
+# Personal goals
+
+While I was originally inspired by [Evan Prodromou's
+vision](http://static.fsf.org/nosvn/Evan_Prodromou_-_identi.ca_-_LibrePlanet_2009.spx)
+of a suite of FOSS services to replace the proprietary stack that everybody
+relies on, starting a free software project is an inherently personal
+endeavour: the shape of the project will be influenced by the personal goals
+of the founder.
+
+When I started the project in 2011, I had a few goals:
+
+- I wanted to get experience with Python, Django, and Bazaar.
+
+- I wanted to speak at a [Kiwi PyCon](https://python.nz/) which [I
+  did](https://web.archive.org/web/20110808005944/http://nz.pycon.org/2010/talks/talk/72/),
+  [twice](https://www.youtube.com/watch?v=wfDhGAMPS1g), but my Libravatar
+  experience also led to speak at
+  [DebConf](http://penta.debconf.org/dc10_schedule///////events/682.en.html)
+  [twice](https://summit.debconf.org/debconf14/meeting/16/outsourcing-your-webapp-maintenance-to-debian/),
+  [linux.conf.au](https://www.youtube.com/watch?v=ufkYjt9HV64) and
+  [OSCON](https://conferences.oreilly.com/oscon/oscon2011/public/schedule/detail/18773).
+
+- Career-wise, I wanted to move beyond PHP development, which I successfully
+  achieved by working for a [new client](https://logger.paua.org.nz/) while
+  I was at [Catalyst](https://catalyst.net.nz) and then getting hired by
+  [Mozilla](https://mozilla.org) to work on
+  [Persona](https://en.wikipedia.org/wiki/Mozilla_Persona) until it was
+  de-staffed following a [Mozilla reorg](http://arewereorganizedyet.com/).
+
+This project personally taught me a lot of different technologies and
+allowed me to try out various web development techniques I wanted to explore
+at the time. That was intentional: I chose my technologies so that even if
+the project was a complete failure, I would still have gotten something out
+of it.
+
+# A few things I've learned
+
+I learned many things along the way, but here are a few that might be useful
+to other people starting a new free software project:
+
+- Speak about your new project at every user group you can. It's important
+  to validate that you can get other people excited about your project. User
+  groups are a great (and cheap) way to kickstart your word of mouth
+  marketing.
+
+- When speaking about your project, ask simple things of the attendees (e.g.
+  create an account today, join the IRC channel). Often people want to
+  support you but they can't commit to big tasks. Make sure to take
+  advantage of all of the support you can get, especially early on.
+
+- Having your friends join (or lurk on!) an IRC channel means it's vibrant,
+  instead of empty, and there are people around to field simple questions or
+  tell people to wait until you're around. Nobody wants to be alone in a
+  channel with a stranger.
+
+# Thank you
+
+I do want to sincerely thank all of the people who contributed to the
+project over the years:
+
+- Jonathan Harker and Brett Wilkins for productive hack sessions in the
+  Catalyst office.
+- Lars Wirzenius, Andy Chilton and Jesse Noller for graciously hosting the
+  service.
+- Christian Weiske, Melissa Draper, Thomas Goirand and Kai Hendry for
+  running mirrors on their servers.
+- Chris Forbes, fr33domlover, Kang-min Liu and strk for writing and
+  maintaining client libraries.
+- The Wellington Perl Mongers for their invaluable feedback on an early prototype.
+- The `#equifoss` group for their ongoing suppport and numerous ideas.
+- Nigel Babu and Melissa Draper for producing the first (and only) project
+  stikers, as well as Chris Cormack for spreading so effectively.
+- Adolfo Jayme, Alfredo Hernández, Anthony Harrington, Asier Iturralde
+  Sarasola, Besnik, Beto1917, Daniel Neis, Eduardo Battaglia, Fernando P
+  Silveira, Gabriele Castagneti, Heimen Stoffels, Iñaki Arenaza, Jakob
+  Kramer, Jorge Luis Gomez, Kristina Hoeppner, Laura Arjona Reina, Léo
+  POUGHON, Marc Coll Carrillo, Mehmet Keçeci, Milan Horák, Mitsuhiro
+  Yoshida, Oleg Koptev, Rodrigo Díaz, Simone G, Stanislas Michalak, Volkan
+  Gezer, VPablo, Xuacu Saturio, Yuri Chornoivan, yurchor and zapman for
+  making Libravatar speak so many languages.
+
+I'm sure I have forgotten people who have helped over the years. If your
+name belongs in here and it's not, please email me or leave a comment.
+
+[[!tag debian]] [[!tag nzoss]] [[!tag libravatar]] [[!tag indieweb]]
diff --git a/posts/looking-back-on-starting-libravatar/cumulative_user_accounts.png b/posts/looking-back-on-starting-libravatar/cumulative_user_accounts.png
new file mode 100644
index 0000000..9358577
Binary files /dev/null and b/posts/looking-back-on-starting-libravatar/cumulative_user_accounts.png differ

Add missing step in lxc-net setup
https://wiki.debian.org/LXC#Networked_quickstart_for_Debian_Stretch_.28testing_as_of_Q3_2016.29
diff --git a/posts/lxc-setup-on-debian-stretch.mdwn b/posts/lxc-setup-on-debian-stretch.mdwn
index 6daa81b..5fe6cc4 100644
--- a/posts/lxc-setup-on-debian-stretch.mdwn
+++ b/posts/lxc-setup-on-debian-stretch.mdwn
@@ -20,6 +20,10 @@ change needed here):
     lxc.network.flags = up
     lxc.network.hwaddr = 00:FF:AA:xx:xx:xx
 
+and enable networking by putting the following in a new `/etc/default/lxc-net` file:
+
+    USE_LXC_BRIDGE="true"
+
 That configuration requires that the `veth` kernel module be loaded. If
 you have any kinds of module-loading restrictions enabled, you probably
 need to add the following to `/etc/modules` and **reboot**:

Remove spurious characters
This is probably mistyped emacs C-n.
diff --git a/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn b/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn
index 3107dea..d22ff84 100644
--- a/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn
+++ b/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn
@@ -54,7 +54,7 @@ for the "world" regulatory authority.
 
 Because [Gargoyle](https://www.gargoyle-router.com/) is based on
 [OpenWRT](https://openwrt.org/), there are a lot more
-nn[wireless configuration options](https://wiki.openwrt.org/doc/uci/wireless)
+[wireless configuration options](https://wiki.openwrt.org/doc/uci/wireless)
 available than what's exposed in the Web UI.
 
 In this case, the solution was to explicitly [set my country in the wireless options](https://feeding.cloud.geek.nz/posts/setting-wifi-regulatory-domain-linux-openwrt/) (where `CA` is the

Link to my regulatory authority post instead of hacking the config file
diff --git a/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn b/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn
index 438951f..3107dea 100644
--- a/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn
+++ b/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn
@@ -57,15 +57,9 @@ Because [Gargoyle](https://www.gargoyle-router.com/) is based on
 nn[wireless configuration options](https://wiki.openwrt.org/doc/uci/wireless)
 available than what's exposed in the Web UI.
 
-In this case, the solution was to explicitly set my country in the wireless
-options by putting:
-
-    country 'CA'
-
-(where `CA` is the
-[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) where the
-router is physically located) in the 5 GHz radio section of
-`/etc/config/wireless` on the router.
+In this case, the solution was to explicitly [set my country in the wireless options](https://feeding.cloud.geek.nz/posts/setting-wifi-regulatory-domain-linux-openwrt/) (where `CA` is the
+[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) for Canada, where my
+router is physically located).
 
 Then I rebooted and I was able to set the channel successfully via the Web UI.
 

Comment moderation
diff --git a/posts/dynamic-dns-on-own-domain/comment_2_86d0b5b701b44721af5d38a180e60df4._comment b/posts/dynamic-dns-on-own-domain/comment_2_86d0b5b701b44721af5d38a180e60df4._comment
new file mode 100644
index 0000000..c604845
--- /dev/null
+++ b/posts/dynamic-dns-on-own-domain/comment_2_86d0b5b701b44721af5d38a180e60df4._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="francois@665656f0ba400877c9b12e8fbb086e45aa01f7c0"
+ nickname="francois"
+ subject="Re: IPv6"
+ date="2018-03-20T23:44:16Z"
+ content="""
+> Do you use IPv6? How do you update the IPv6 ?
+
+Unfortunately, No-IP still [doesn't support IPv6 in their Dynamic DNS service](https://www.noip.com/blog/2009/06/19/ipv6-records-now-available/#comment-421947). My setup is IPv4-only.
+
+I'd be happy to consider other services that support IPv6 if they also support **custom domains** and are supported by a **client that's included in Debian**. If you know of one, please leave a comment.
+"""]]

Comment moderation
diff --git a/posts/dynamic-dns-on-own-domain/comment_1_193af8570ba24987f776b567180167e7._comment b/posts/dynamic-dns-on-own-domain/comment_1_193af8570ba24987f776b567180167e7._comment
new file mode 100644
index 0000000..dd367b2
--- /dev/null
+++ b/posts/dynamic-dns-on-own-domain/comment_1_193af8570ba24987f776b567180167e7._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ ip="2804:14d:5ce0:9e33:540a:d1c7:6490:c04a"
+ claimedauthor="S.V."
+ subject="IPv6"
+ date="2018-03-20T22:27:53Z"
+ content="""
+Hi,
+Do you use IPv6? How do you update the IPv6 ?
+Best,
+S.V.
+"""]]

Add missing tags to dynamic DNS post
diff --git a/posts/dynamic-dns-on-own-domain.mdwn b/posts/dynamic-dns-on-own-domain.mdwn
index a6a43e7..6fed580 100644
--- a/posts/dynamic-dns-on-own-domain.mdwn
+++ b/posts/dynamic-dns-on-own-domain.mdwn
@@ -88,3 +88,5 @@ The IP for that machine should now be visible on the [No-IP control
 panel](https://www.noip.com/members/dns/) and in DNS lookups:
 
     dig +short machinename.dyn.fmarier.org
+
+[[!tag debian]] [[!tag nzoss]] [[!tag dns]]

Add post on dynamic DNS using noip.com
diff --git a/posts/dynamic-dns-on-own-domain.mdwn b/posts/dynamic-dns-on-own-domain.mdwn
new file mode 100644
index 0000000..a6a43e7
--- /dev/null
+++ b/posts/dynamic-dns-on-own-domain.mdwn
@@ -0,0 +1,90 @@
+[[!meta title="Dynamic DNS on your own domain"]]
+[[!meta date="2018-03-18T13:45:00.000-07:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+I recently moved my dynamic DNS hostnames from
+[dyndns.org](https://dyn.com/dns/) (now owned by Oracle) to
+[No-IP](https://www.noip.com/remote-access). In the process, I moved all of
+my hostnames under a sub-domain that I control in case I ever want to
+self-host the authoritative DNS server for it.
+
+# Creating an account
+
+In order to use my own existing domain, I registered for the [Plus Managed
+DNS](https://www.noip.com/remote-access) service and provided my top-level
+domain (`fmarier.org`).
+
+Then I created a [support ticket](https://www.noip.com/ticket/) to ask for
+the **sub-domain feature**. Without that, No-IP expects you to delegate your
+entire domain to them, whereas I only wanted to delegate `*.dyn.fmarier.org`.
+
+Once that got enabled, I was able to create hostnames like `machine.dyn` in
+the No-IP control panel. Without the sub-domain feature, you can't have dots
+in hostnames.
+
+I used a bogus IP address (e.g. `1.2.3.4`) for all of the hostnames I
+created in order to easily confirm that the client software is working.
+
+# DNS setup
+
+On my registrar's side, here are the DNS records I had to add to delegate
+anything under `dyn.fmarier.org` to No-IP:
+
+    dyn NS ns1.no-ip.com.
+    dyn NS ns2.no-ip.com.
+    dyn NS ns3.no-ip.com.
+    dyn NS ns4.no-ip.com.
+    dyn NS ns5.no-ip.com.
+
+# Client setup
+
+In order to update its IP address whenever it changes, I installed
+[ddclient](https://sourceforge.net/p/ddclient/wiki/Home/) on each of my
+machines:
+
+    apt install ddclient
+
+While the [ddclient package](https://packages.debian.org/stretch/ddclient)
+[won't help you
+configure](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=625715) your
+No-IP service during installation or [enable the web IP lookup
+method](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=285007), this can
+all be done by editing the configuration after the fact.
+
+I put the following in `/etc/ddclient.conf`:
+
+    ssl=yes
+    protocol=noip
+    use=web, web=checkip.dyndns.com, web-skip='IP Address'
+    server=dynupdate.no-ip.com
+    login=myusername
+    password='Password1!'
+    machinename.dyn.fmarier.org
+
+and the following in `/etc/default/ddclient`:
+
+    run_dhclient="false"
+    run_ipup="false"
+    run_daemon="true"
+    daemon_interval="3600"
+
+Then restart the service:
+
+    systemctl restart ddclient.service
+
+Note that you do need to change the default update interval or the
+`checkip.dyndns.com` server [will ban your IP
+address](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=489997).
+
+# Testing
+
+To test that the client software is working, wait 6 minutes (there is an
+internal check which cancels any client invocations within 5 minutes of
+another), then run it manually:
+
+    ddclient --verbose --debug
+
+The IP for that machine should now be visible on the [No-IP control
+panel](https://www.noip.com/members/dns/) and in DNS lookups:
+
+    dig +short machinename.dyn.fmarier.org

Comment moderation
diff --git a/posts/upgrading-lenovo-thinkpad-bios-under-linux/comment_6_5b9ac5c6cdbe9ec824c914134327fdf7._comment b/posts/upgrading-lenovo-thinkpad-bios-under-linux/comment_6_5b9ac5c6cdbe9ec824c914134327fdf7._comment
new file mode 100644
index 0000000..41694b7
--- /dev/null
+++ b/posts/upgrading-lenovo-thinkpad-bios-under-linux/comment_6_5b9ac5c6cdbe9ec824c914134327fdf7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ ip="176.147.239.109"
+ claimedauthor="BigFan"
+ subject="faster dd"
+ date="2018-03-17T11:52:27Z"
+ content="""
+Use option 'bs=4M' for faster write to the usb key (otherwise it will take several minutes):  
+    $ dd bs=4M if=bios.img of=/dev/sdX
+
+"""]]

Use mpc-fade to stop music in the evening
diff --git a/posts/home-music-server-with-mpd.mdwn b/posts/home-music-server-with-mpd.mdwn
index 7974cec..e0d4baa 100644
--- a/posts/home-music-server-with-mpd.mdwn
+++ b/posts/home-music-server-with-mpd.mdwn
@@ -76,8 +76,12 @@ daily and stop the music automatically in the evening:
     # Refresh DB once an hour
     5 * * * *  mpd  test -r /run/mpd/socket && MPD_HOST=Password1@/run/mpd/socket /usr/bin/mpc --quiet update
     # Think of the neighbours
-    0 22 * * 0-4  mpd  test -r /run/mpd/socket && MPD_HOST=Password1@/run/mpd/socket /usr/bin/mpc --quiet stop
-    0 23 * * 5-6  mpd  test -r /run/mpd/socket && MPD_HOST=Password1@/run/mpd/socket /usr/bin/mpc --quiet stop
+    0 22 * * 0-4  mpd  test -r /run/mpd/socket && MPD_HOST=Password1@/run/mpd/socket /usr/local/bin/mpc-fade
+    0 23 * * 5-6  mpd  test -r /run/mpd/socket && MPD_HOST=Password1@/run/mpd/socket /usr/local/bin/mpc-fade
+
+My [`mpc-fade` script](https://github.com/fmarier/user-scripts/blob/master/mpc-fade),
+heavily inspired by [Guillaume's](http://guillaumeplayground.net/mpd-mpc-fade-in-out-script/),
+gradually brings the volume down instead of stopping the music abrutly.
 
 ## Album covers
 

Comment moderation
diff --git a/posts/redirecting-entire-site-except-certbot-webroot/comment_1_66c587e8b38d4ae2d0f24422f959f166._comment b/posts/redirecting-entire-site-except-certbot-webroot/comment_1_66c587e8b38d4ae2d0f24422f959f166._comment
new file mode 100644
index 0000000..0f20b27
--- /dev/null
+++ b/posts/redirecting-entire-site-except-certbot-webroot/comment_1_66c587e8b38d4ae2d0f24422f959f166._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ ip="2a02:8071:b581:3afc:25b1:3686:15d9:fce3"
+ claimedauthor="Uwe Kleine-König"
+ subject="conditions for letsencrypt certs"
+ date="2018-03-02T08:42:11Z"
+ content="""
+Hello,
+
+according to my experience having a redirect for `/.well-known/acme-challenge` works fine. So an unconditional redirect from `http://libravatar.org/(.*)` to `http://www.libravatar.org/$1` should do the trick a bit easier.
+
+Best regards
+Uwe
+"""]]
diff --git a/posts/redirecting-entire-site-except-certbot-webroot/comment_2_fa5e9bec263f4d7787b74b22f82e13ea._comment b/posts/redirecting-entire-site-except-certbot-webroot/comment_2_fa5e9bec263f4d7787b74b22f82e13ea._comment
new file mode 100644
index 0000000..f9e6b38
--- /dev/null
+++ b/posts/redirecting-entire-site-except-certbot-webroot/comment_2_fa5e9bec263f4d7787b74b22f82e13ea._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ ip="2a02:810d:4740:cc10:6e29:95ff:fe7c:2bad"
+ claimedauthor="Philipp Kern"
+ subject="HTTP redirects should be fine?"
+ date="2018-03-02T08:37:07Z"
+ content="""
+I was under the impression that 301 redirects will be followed by the CA. Is that not the case?
+"""]]

Add another letsencrypt/cerbot config post
diff --git a/posts/redirecting-entire-site-except-certbot-webroot.mdwn b/posts/redirecting-entire-site-except-certbot-webroot.mdwn
new file mode 100644
index 0000000..91ea91f
--- /dev/null
+++ b/posts/redirecting-entire-site-except-certbot-webroot.mdwn
@@ -0,0 +1,47 @@
+[[!meta title="Redirecting an entire site except for the certbot webroot"]]
+[[!meta date="2018-03-01T21:40:00.000-08:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+In order to be able to use the [webroot
+plugin](https://certbot.eff.org/docs/using.html#webroot) for
+[certbot](https://certbot.eff.org/) and automatically renew the [Let's
+Encrypt](https://letsencrypt.org/) certificate for `libravatar.org`, I
+had to put together an Apache config that would do the following on port 80:
+
+- Let `/.well-known/acme-challenge/*` through on the bare domain
+  (`http://libravatar.org/`).
+- Redirect anything else to `https://www.libravatar.org/`.
+
+The reason for this is that the main
+[Libravatar](https://www.libravatar.org) service listens on
+`www.libravatar.org` and not `libravatar.org`, but that cerbot needs to
+ascertain control of the bare domain.
+
+This is the configuration I ended up with:
+
+    <VirtualHost *:80>
+        DocumentRoot /var/www/acme
+        <Directory /var/www/acme>
+            Options -Indexes
+        </Directory>
+    
+        RewriteEngine on
+        RewriteCond "/var/www/acme%{REQUEST_URI}" !-f
+        RewriteRule ^(.*)$ https://www.libravatar.org/ [last,redirect=301]
+    </VirtualHost>
+
+The trick I used here is to make the redirection `RewriteRule` conditional
+on the requested file (`%{REQUEST_URI}`) not existing in the `/var/www/acme`
+directory, the one where I tell certbot to drop its temporary files.
+
+Here are the relevant portions of `/etc/letsencrypt/renewal/www.libravatar.org.conf`:
+
+    [renewalparams]
+    authenticator = webroot
+    account = 
+    
+    [[webroot_map]]
+    libravatar.org = /var/www/acme
+    www.libravatar.org = /var/www/acme
+
+[[!tag debian]] [[!tag letsencrypt]] [[!tag nzoss]] [[!tag apache]] [[!tag ssl]]

Fix typo
Can be verified using `uci show system`.
Thanks to CapnNarkolepso for reporting this.
diff --git a/posts/debugging-openwrt-routers-by-shipping.mdwn b/posts/debugging-openwrt-routers-by-shipping.mdwn
index 59f84df..335ec00 100644
--- a/posts/debugging-openwrt-routers-by-shipping.mdwn
+++ b/posts/debugging-openwrt-routers-by-shipping.mdwn
@@ -34,7 +34,7 @@ After logging into the router via ssh, I ran the following commands:
 
 
     uci set system.@system[0].log_ip=192.168.1.2  
-    uci set system.@system[0].conloglevel=7  
+    uci set system.@system[0].cronloglevel=7
     uci commit
 
 

Add cover URL config for MPDRemote on iOS
diff --git a/posts/home-music-server-with-mpd.mdwn b/posts/home-music-server-with-mpd.mdwn
index e45f73a..7974cec 100644
--- a/posts/home-music-server-with-mpd.mdwn
+++ b/posts/home-music-server-with-mpd.mdwn
@@ -164,4 +164,9 @@ since [MPoD](http://www.katoemba.net/makesnosenseatall/mpod/) and
 [MPaD](http://www.katoemba.net/makesnosenseatall/mpad/) don't appear to be
 available on the AppStore anymore.
 
+Of these, MPDRemote appears to be the better one. It also supports album art
+if you configure the profile with the following cover URL:
+
+    http://192.168.1.2/
+
 [[!tag debian]] [[!tag ubuntu]] [[!tag nzoss]] [[!tag mpd]] [[!tag ios]] [[!tag android]] [[!tag tor]] [[!tag systemd]]

Add album cover support via Apache web server
diff --git a/posts/home-music-server-with-mpd.mdwn b/posts/home-music-server-with-mpd.mdwn
index 8bbe5d6..e45f73a 100644
--- a/posts/home-music-server-with-mpd.mdwn
+++ b/posts/home-music-server-with-mpd.mdwn
@@ -79,12 +79,39 @@ daily and stop the music automatically in the evening:
     0 22 * * 0-4  mpd  test -r /run/mpd/socket && MPD_HOST=Password1@/run/mpd/socket /usr/bin/mpc --quiet stop
     0 23 * * 5-6  mpd  test -r /run/mpd/socket && MPD_HOST=Password1@/run/mpd/socket /usr/bin/mpc --quiet stop
 
+## Album covers
+
+In order to supply album cover art to clients which support grabbing covers
+from a local web server I have installed
+[Apache](https://httpd.apache.org/):
+
+    apt install apache2
+
+and configured it to serve the covers by putting the following in
+`/etc/apache2/conf-available/mpd.conf`:
+
+    <Directory /path/to/music>
+        AllowOverride None
+        Require all granted
+    </Directory>
+
+and then the following line in the default vhost section of
+`/etc/apache2/sites-available/000-default.conf`:
+
+    Alias /music /path/to/music
+
+Finally, I enabled the new configuration and restarted Apache:
+
+    a2enconf mpd.conf
+    systemctl restart apache2.service
+
 # Clients
 
-To let anybody on the local network connect, I opened **port 6600** on the
-firewall (`/etc/network/iptables.up.rules` since I'm using Debian's
+To let anybody on the local network connect, I opened **ports 80 and 6600**
+on the firewall (`/etc/network/iptables.up.rules` since I'm using Debian's
 `iptables-apply`):
 
+    -A INPUT -s 192.168.1.0/24 -p tcp --dport 80 -j ACCEPT
     -A INPUT -s 192.168.1.0/24 -p tcp --dport 6600 -j ACCEPT
 
 Then I looked at [the long list of clients](http://mpd.wikia.com/wiki/Clients) on the mpd wiki.
@@ -119,7 +146,12 @@ On Android, I got these two to work:
 - [M.A.L.P.](https://f-droid.org/repository/browse/?fdfilter=malp&fdid=org.gateshipone.malp) (requires Android 5 or later)
 - [MPDroid](https://f-droid.org/repository/browse/?fdfilter=mpdroid&fdid=com.namelessdev.mpdroid)
 
-I picked M.A.L.P. since it includes a nice widget for the homescreen.
+I picked M.A.L.P. since it includes a nice widget for the homescreen. In the
+profile settings, I enabled *Prefer [HTTP cover
+files](https://github.com/gateship-one/malp/wiki/FAQ#application-usage)* and
+used this URL:
+
+    http://192.168.1.2/%d
 
 ## iOS
 

Add MPDRemote AppStore link
This free software client is now available on the Apple AppStore.
diff --git a/posts/home-music-server-with-mpd.mdwn b/posts/home-music-server-with-mpd.mdwn
index 0f0e02a..8bbe5d6 100644
--- a/posts/home-music-server-with-mpd.mdwn
+++ b/posts/home-music-server-with-mpd.mdwn
@@ -125,7 +125,7 @@ I picked M.A.L.P. since it includes a nice widget for the homescreen.
 
 On iOS, these are the most promising clients I found:
 
-- [MPDRemote](https://github.com/Nyx0uf/MPDRemote) (free software, not on the AppStore)
+- [MPDRemote](https://github.com/Nyx0uf/MPDRemote) (free software, sold on the [AppStore](https://itunes.apple.com/us/app/mpdremote/id1202933180?ls=1&mt=8))
 - [MPDluxe](http://kineticfactory.com/MPDluxe/) (proprietary, sold on the [AppStore](https://itunes.apple.com/app/mpdluxe/id991758069?mt=8))
 
 since [MPoD](http://www.katoemba.net/makesnosenseatall/mpod/) and

Update DNSCrypt links
diff --git a/posts/using-dnssec-and-dnscrypt-in-debian.mdwn b/posts/using-dnssec-and-dnscrypt-in-debian.mdwn
index 3722667..a57c7ee 100644
--- a/posts/using-dnssec-and-dnscrypt-in-debian.mdwn
+++ b/posts/using-dnssec-and-dnscrypt-in-debian.mdwn
@@ -8,7 +8,7 @@ While there is real progress being made towards
 Internet service that still usually relies on unauthenticated cleartext.
 There are however a few efforts to try and fix this problem. Here is the
 setup I use on my Debian laptop to make use of both
-[DNSSEC](http://www.dnssec.net/) and [DNSCrypt](https://dnscrypt.org/).
+[DNSSEC](http://www.dnssec.net/) and [DNSCrypt](https://dnscrypt.info/).
 
 # DNSCrypt
 
@@ -29,7 +29,7 @@ if you are using a static network configuration or in
 if you rely on dynamic network configuration via [DHCP](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol).
 
 There are two things you might want to keep in mind when choosing your
-[DNSCrypt resolver](https://github.com/jedisct1/dnscrypt-proxy/blob/master/dnscrypt-resolvers.csv):
+[DNSCrypt resolver](https://github.com/DNSCrypt/dnscrypt-resolvers/tree/master/v1):
 
 - whether or not they keep any logs of the DNS traffic
 - whether or not they support DNSSEC

Linkify flashrom.org link in comment
diff --git a/posts/creating-freedos-bootable-usb-stick-to/comment_3_44ccac1abc9c63695fcec1942a2648a9._comment b/posts/creating-freedos-bootable-usb-stick-to/comment_3_44ccac1abc9c63695fcec1942a2648a9._comment
index 582f50f..aa9cd4b 100644
--- a/posts/creating-freedos-bootable-usb-stick-to/comment_3_44ccac1abc9c63695fcec1942a2648a9._comment
+++ b/posts/creating-freedos-bootable-usb-stick-to/comment_3_44ccac1abc9c63695fcec1942a2648a9._comment
@@ -3,7 +3,7 @@
  subject=""
  date="2012-03-13T20:14:08.798+13:00"
  content="""
-What about http://www.flashrom.org?
+What about <https://www.flashrom.org>?
 
 
 """]]

Remove comment with a suggestion that won't work
diff --git a/posts/creating-freedos-bootable-usb-stick-to/comment_2_0f744a1b053542b4118d9737433838c7._comment b/posts/creating-freedos-bootable-usb-stick-to/comment_2_0f744a1b053542b4118d9737433838c7._comment
deleted file mode 100644
index b546ab3..0000000
--- a/posts/creating-freedos-bootable-usb-stick-to/comment_2_0f744a1b053542b4118d9737433838c7._comment
+++ /dev/null
@@ -1,12 +0,0 @@
-[[!comment format=mdwn
- username="http://www.blogger.com/profile/02726867824497339744"
- nickname="gebi"
- subject=""
- date="2012-03-13T12:47:01.504+13:00"
- content="""
-An alternative method to get a freebsd bootable usb-stick:  
-  
-https://plus.google.com/101377063020971314139/posts/d5KMP7yBPRh
-
-
-"""]]
diff --git a/posts/creating-freedos-bootable-usb-stick-to/comment_5_29c0397ad176cf563ad33ee2eb69504a._comment b/posts/creating-freedos-bootable-usb-stick-to/comment_5_29c0397ad176cf563ad33ee2eb69504a._comment
deleted file mode 100644
index 46c4ada..0000000
--- a/posts/creating-freedos-bootable-usb-stick-to/comment_5_29c0397ad176cf563ad33ee2eb69504a._comment
+++ /dev/null
@@ -1,7 +0,0 @@
-[[!comment format=mdwn
- ip="142.177.126.65"
- subject="untried suggestions"
- date="2014-10-28T21:41:29Z"
- content="""
-Please if you are going to make a suggestion, make sure it does what is asked in the question. The OP wanted to add files to a FreeDOS USB stick, so he could update a BIOS. Presumably he would need the particular BIOS update executable plus a new BIOS image and possibly the ability to save a copy of the current BIOS in case something goes awry. The poster who suggested using balder10.img obviously hadn't tested it and didn't know that it boots as a 1.44 Mb floppy image.
-"""]]

Fix broken links and use HTTPS in all wget calls
diff --git a/posts/creating-freedos-bootable-usb-stick-to.mdwn b/posts/creating-freedos-bootable-usb-stick-to.mdwn
index bd8c6f9..b92aa99 100644
--- a/posts/creating-freedos-bootable-usb-stick-to.mdwn
+++ b/posts/creating-freedos-bootable-usb-stick-to.mdwn
@@ -1,67 +1,59 @@
 [[!meta title="Creating a FreeDOS bootable USB stick to upgrade BIOS"]]
 [[!meta date="2012-03-13T08:00:00.000+13:00"]]
 [[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
-I have an old motherboard that requires creating a DOS boot floppy in order to upgrade its BIOS. Fortunately, it's not too hard to do this with [FreeDOS](http://www.freedos.org/) and a USB stick.  
-  
-_The instructions below are based on an [FDos wiki article](http://wiki.fdos.info/Installation/BootDiskCreateUSB)._  
-  
+I have an old motherboard that requires creating a DOS boot floppy in order to upgrade its BIOS. Fortunately, it's not too hard to do this with [FreeDOS](http://www.freedos.org/) and a USB stick.
+
+_The instructions below are based on an [old FDos wiki article](https://web.archive.org/web/20090301055636/http://wiki.fdos.org/Installation/BootDiskCreateUSB).
+You maye have more luck with the [latest instructions from the official wiki](http://wiki.freedos.org/wiki/index.php/USB)_
+
 
 ### Downloading the dependencies
 
-The first step is to download the required files from your motherboard manufacturer:  
+The first step is to download the required files from your motherboard manufacturer:
 
   * the latest BIOS image
   * the BIOS flashing program
 
-and then install the tools you'll need:  
-
+and then install the tools you'll need:
 
     apt-get install makebootfat syslinux
 
-
-  
-
 ### Preparing the "floppy" image
 
-Start by collecting all of the files you need to install FreeDOS on the USB stick:  
-
-
-    cd /tmp  
-      
-    wget http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/commandx.zip  
-    wget http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/kernels.zip  
-    wget http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/substx.zip  
-    wget http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/unstablx.zip  
-      
-    for ZIP in *.zip; do unzip $ZIP; done  
-      
-    cp ./source/ukernel/boot/fat16.bin  .  
-    cp ./source/ukernel/boot/fat12.bin .  
-    cp ./source/ukernel/boot/fat32lba.bin .  
-      
-    cp /usr/lib/syslinux/mbr.bin .
+Start by collecting all of the files you need to install FreeDOS on the USB stick:
 
+    cd /tmp
+    
+    wget https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/commandx.zip
+    wget https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/kernels.zip
+    wget https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/substx.zip
+    wget https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/unstablx.zip
+    
+    for ZIP in *.zip; do unzip $ZIP; done
+    
+    cp ./source/ukernel/boot/fat16.bin  .
+    cp ./source/ukernel/boot/fat12.bin .
+    cp ./source/ukernel/boot/fat32lba.bin .
+    
+    cp /usr/lib/syslinux/mbr.bin .
 
 and then create a directory for the files that will end up in the root directory of the "floppy":
 
-    mkdir /tmp/fs-root  
-    cp ./bin/command.com /tmp/fs-root/  
-    cp ./bin/kernel.sys  /tmp/fs-root/  
-    
-
+    mkdir /tmp/fs-root
+    cp ./bin/command.com /tmp/fs-root/
+    cp ./bin/kernel.sys  /tmp/fs-root/
 
-and copy the BIOS image and update program into that same directory (`/tmp/fs-root/`).  
-  
+and copy the BIOS image and update program into that same directory (`/tmp/fs-root/`).
 
 ### Creating a bootable USB stick
 
-Plug in a [FAT](https://en.wikipedia.org/wiki/File_Allocation_Table)-formatted USB stick and look for the device it uses (`/dev/sdb` in the example below).  
-  
-Finally, run `makebootfat`:  
+Plug in a [FAT](https://en.wikipedia.org/wiki/File_Allocation_Table)-formatted USB stick and look for the device it uses (`/dev/sdb` in the example below).
+
+Finally, run `makebootfat`:
 
 <pre>
 /usr/bin/makebootfat -o <i>/dev/sdb</i> -E 255 -1 fat12.bin -2 fat16.bin -3 fat32lba.bin -m mbr.bin /tmp/fs-root
 </pre>
 
 
-[[!tag catalyst]] [[!tag debian]] [[!tag ubuntu]] [[!tag nzoss]] 
+[[!tag catalyst]] [[!tag debian]] [[!tag ubuntu]] [[!tag nzoss]]

Simplify the mount option
Thanks to madduck for pointing it out!
diff --git a/posts/lxc-setup-on-debian-stretch.mdwn b/posts/lxc-setup-on-debian-stretch.mdwn
index 994bc77..6daa81b 100644
--- a/posts/lxc-setup-on-debian-stretch.mdwn
+++ b/posts/lxc-setup-on-debian-stretch.mdwn
@@ -96,7 +96,7 @@ In order to have my home directory available within the container, I
 created a user account for myself inside the container and then added
 the following to the container config file (`/var/lib/lxc/sid64/config`):
 
-    lxc.mount.entry=/home/francois /var/lib/lxc/sid64/rootfs/home/francois none bind 0 0
+    lxc.mount.entry=/home/francois home/francois none bind 0 0
 
 before restarting the container:
 

Comment moderation
diff --git a/posts/lxc-setup-on-debian-stretch/comment_1_ea87a21cd2ed4968ed792df4d533bd43._comment b/posts/lxc-setup-on-debian-stretch/comment_1_ea87a21cd2ed4968ed792df4d533bd43._comment
new file mode 100644
index 0000000..fc829ea
--- /dev/null
+++ b/posts/lxc-setup-on-debian-stretch/comment_1_ea87a21cd2ed4968ed792df4d533bd43._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ ip="193.203.232.31"
+ claimedauthor="risca"
+ url="http://wiki.risca.eu"
+ subject="lxc-net configuration"
+ date="2018-01-24T10:10:54Z"
+ content="""
+Hi,
+
+about network configuration on LXC in debian stretch, it is possible to easy the setup through the lxc-net script (it's shipped with-in the lxc package itself). This way you only need:
+
+- to fill parameters in /etc/default/lxc-net
+- add bridge configuration for lxcbr0 in /etc/network/interfaces
+
+All of other steps pointed out in your \"Network setup\" are done by lxc-net itself.
+
+The only downside of the script is that it would be nice to use, instead of a script, an horde of systemd units (if using systemd). I tried to fill a request for it [1] but it's still a work in progress.
+
+[1] https://github.com/lxc/lxc/issues/2083
+"""]]
diff --git a/posts/time-synchronization-with-ntp-and-systemd/comment_4_6d6235632443890b9f5645bc745cdb41._comment b/posts/time-synchronization-with-ntp-and-systemd/comment_4_6d6235632443890b9f5645bc745cdb41._comment
new file mode 100644
index 0000000..64e11d4
--- /dev/null
+++ b/posts/time-synchronization-with-ntp-and-systemd/comment_4_6d6235632443890b9f5645bc745cdb41._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ ip="81.242.162.111"
+ claimedauthor="Patrick"
+ subject="NTP synchro"
+ date="2018-01-21T21:54:39Z"
+ content="""
+Hello,
+
+I'm interested cause my  NTP synchronized is always :no
+I done exactly the same commands on the blog and no change appears.
+
+Thank you for advice.
+"""]]

Replace xbacklight with new set-backlight script
diff --git a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
index 6c51008..5be5dbd 100644
--- a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
+++ b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
@@ -47,18 +47,18 @@ While keyboard shortcuts can be configured in GNOME, they don't work within i3,
     bindsym XF86AudioMute exec /usr/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle
 
     # brightness control
-    bindsym XF86MonBrightnessDown exec xbacklight -steps 1 -time 0 -dec 5
-    bindsym XF86MonBrightnessUp exec xbacklight -steps 1 -time 0 -inc 10
+    bindsym XF86MonBrightnessDown exec /home/francois/bin/set-brightness -
+    bindsym XF86MonBrightnessUp exec /home/francois/bin/set-brightness +
 
     # show battery stats
     bindsym XF86Battery exec gnome-power-statistics
 
 to make volume control, screen brightness and battery status buttons work as expected on my laptop.
 
-These bindings require the following packages:
+These bindings require the following packages or scripts:
 
 * [pulseaudio-utils](https://packages.debian.org/stable/pulseaudio-utils)
-* [xbacklight](https://packages.debian.org/stable/xbacklight)
+* [set-brightness](https://github.com/fmarier/user-scripts/blob/master/set-brightness)
 * [gnome-power-manager](https://packages.debian.org/stable/gnome-power-manager)
 
 # Keyboard layout switcher

Fix post title and remove unnecessary -d flags
diff --git a/posts/lxc-setup-on-debian-stretch.mdwn b/posts/lxc-setup-on-debian-stretch.mdwn
index a3516df..994bc77 100644
--- a/posts/lxc-setup-on-debian-stretch.mdwn
+++ b/posts/lxc-setup-on-debian-stretch.mdwn
@@ -1,4 +1,4 @@
-[[!meta title="LXC setup on Debian jessie"]]
+[[!meta title="LXC setup on Debian stretch"]]
 [[!meta date="2018-01-23T21:30:00.000-08:00"]]
 [[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
 
@@ -101,7 +101,7 @@ the following to the container config file (`/var/lib/lxc/sid64/config`):
 before restarting the container:
 
     lxc-stop -n sid64
-    lxc-start -n sid64 -d
+    lxc-start -n sid64
 
 # Fixing locale errors
 
@@ -139,13 +139,13 @@ work-around I found is to temporarily shutdown AppArmor on the host:
 
     lxc-stop -n sid64
     systemctl stop apparmor
-    lxc-start -n sid64 -d
+    lxc-start -n sid64
 
 and then start up it later once the locales have been updated:
 
     lxc-stop -n sid64
     systemctl start apparmor
-    lxc-start -n sid64 -d
+    lxc-start -n sid64
 
 # AppArmor support
 

Add LXC setup on stretch post
diff --git a/posts/lxc-setup-on-debian-stretch.mdwn b/posts/lxc-setup-on-debian-stretch.mdwn
new file mode 100644
index 0000000..a3516df
--- /dev/null
+++ b/posts/lxc-setup-on-debian-stretch.mdwn
@@ -0,0 +1,157 @@
+[[!meta title="LXC setup on Debian jessie"]]
+[[!meta date="2018-01-23T21:30:00.000-08:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+Here's how to setup LXC-based "chroots" on Debian stretch. While I [wrote about this on Debian jessie](https://feeding.cloud.geek.nz/posts/lxc-setup-on-debian-jessie/), I
+had to make some [networking changes for stretch](https://wiki.debian.org/LXC#Networked_quickstart_for_Debian_Stretch_.28testing_as_of_Q3_2016.29)
+and so here are the full steps that should work on stretch.
+
+Start by installing (as root) the necessary packages:
+
+    apt install lxc libvirt-clients debootstrap
+
+# Network setup
+
+I decided to use the default `/etc/lxc/default.conf` configuration (no
+change needed here):
+
+    lxc.network.type = veth
+    lxc.network.link = lxcbr0
+    lxc.network.flags = up
+    lxc.network.hwaddr = 00:FF:AA:xx:xx:xx
+
+That configuration requires that the `veth` kernel module be loaded. If
+you have any kinds of module-loading restrictions enabled, you probably
+need to add the following to `/etc/modules` and **reboot**:
+
+    veth
+
+Next, I had to make sure that the "guests" could connect to the outside
+world through the "host":
+
+1. Enable IPv4 forwarding by putting this in `/etc/sysctl.conf`:
+
+       net.ipv4.ip_forward=1
+
+2. and then applying it using:
+
+       sysctl -p
+
+3. Restart the network bridge:
+
+       systemctl restart lxc-net.service
+
+4. and ensure that it's not blocked by the host firewall, by putting this in `/etc/network/iptables.up.rules`:
+
+       -A FORWARD -d 10.0.3.0/24 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
+       -A FORWARD -s 10.0.3.0/24 -j ACCEPT
+       -A INPUT -d 224.0.0.251 -s 10.0.3.1 -j ACCEPT
+       -A INPUT -d 10.0.3.255 -s 10.0.3.1 -j ACCEPT
+       -A INPUT -d 10.0.3.1 -s 10.0.3.0/24 -j ACCEPT
+
+5. and applying the rules using:
+
+       iptables-apply
+
+# Creating a container
+
+Creating a new container (in `/var/lib/lxc/`) is simple:
+
+    sudo MIRROR=http://httpredir.debian.org/debian lxc-create -n sid64 -t debian -- -r sid -a amd64
+
+You can start or stop it like this:
+
+    sudo lxc-start -n sid64
+    sudo lxc-stop -n sid64
+
+# Connecting to a guest using ssh
+
+The ssh server is configured to require pubkey-based authentication for root
+logins, so you'll need to log into the console:
+
+    sudo lxc-stop -n sid64
+    sudo lxc-start -n sid64 -F
+
+Since the root password is randomly generated, you'll need to reset it before
+you can login as root:
+
+    sudo lxc-attach -n sid64 passwd
+
+Then login as root and install a text editor inside the container because the
+root image doesn't have one by default:
+
+    apt install vim
+
+then paste your public key in `/root/.ssh/authorized_keys`.
+
+Then you can exit the console (using `Ctrl+a q`) and ssh into the
+container. You can find out what IP address the container received from DHCP
+by typing this command:
+
+    sudo lxc-ls --fancy
+
+# Mounting your home directory inside a container
+
+In order to have my home directory available within the container, I
+created a user account for myself inside the container and then added
+the following to the container config file (`/var/lib/lxc/sid64/config`):
+
+    lxc.mount.entry=/home/francois /var/lib/lxc/sid64/rootfs/home/francois none bind 0 0
+
+before restarting the container:
+
+    lxc-stop -n sid64
+    lxc-start -n sid64 -d
+
+# Fixing locale errors
+
+If you see a bunch of errors like these when you start your container:
+
+    perl: warning: Setting locale failed.
+    perl: warning: Please check that your locale settings:
+	LANGUAGE = (unset),
+	LC_ALL = (unset),
+	LANG = "fr_CA.utf8"
+        are supported and installed on your system.
+    perl: warning: Falling back to the standard locale ("C").
+
+then log into the container as root and use:
+
+    dpkg-reconfigure locales
+
+to enable the same locales as the ones you have configured in the host.
+
+If you see these errors while reconfiguring the `locales` package:
+
+    Generating locales (this might take a while)...
+      en_US.UTF-8...cannot change mode of new locale archive: No such file or directory
+     done
+      fr_CA.UTF-8...cannot change mode of new locale archive: No such file or directory
+     done
+    Generation complete.
+
+and see the following `dmesg` output on the host:
+
+    [235350.947808] audit: type=1400 audit(1441664940.224:225): apparmor="DENIED" operation="chmod" info="Failed name lookup - deleted entry" error=-2 profile="/usr/bin/lxc-start" name="/usr/lib/locale/locale-archive.WVNevc" pid=21651 comm="localedef" requested_mask="w" denied_mask="w" fsuid=0 ouid=0
+
+then AppArmor is interfering with the `locale-gen` binary and the
+work-around I found is to temporarily shutdown AppArmor on the host:
+
+    lxc-stop -n sid64
+    systemctl stop apparmor
+    lxc-start -n sid64 -d
+
+and then start up it later once the locales have been updated:
+
+    lxc-stop -n sid64
+    systemctl start apparmor
+    lxc-start -n sid64 -d
+
+# AppArmor support
+
+If you are running AppArmor, your container probably won't start until you
+add the following to the container config (`/var/lib/lxc/sid64/config`):
+
+    lxc.aa_allow_incomplete = 1
+
+[[!tag debian]] [[!tag lxc]] [[!tag nzoss]]

Comment moderation
diff --git a/posts/encrypting-your-home-directory-using/comment_12_abdd8124a6af058ad8500bafa47dcc9e._comment b/posts/encrypting-your-home-directory-using/comment_12_abdd8124a6af058ad8500bafa47dcc9e._comment
new file mode 100644
index 0000000..de20f2b
--- /dev/null
+++ b/posts/encrypting-your-home-directory-using/comment_12_abdd8124a6af058ad8500bafa47dcc9e._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ ip="181.169.244.161"
+ claimedauthor="julio"
+ subject="LUKS key"
+ date="2017-12-04T23:46:28Z"
+ content="""
+Good post and good comments.
+I was wondering about the passphrase LUKS requires to decrypt.
+
+Where should I setup it up to decrypt files upon user login?
+
+Thanks!
+"""]]
diff --git a/posts/time-synchronization-with-ntp-and-systemd/comment_2_50d64a2eefb88b42770b9a45ed09a0b6._comment b/posts/time-synchronization-with-ntp-and-systemd/comment_2_50d64a2eefb88b42770b9a45ed09a0b6._comment
new file mode 100644
index 0000000..726d1a0
--- /dev/null
+++ b/posts/time-synchronization-with-ntp-and-systemd/comment_2_50d64a2eefb88b42770b9a45ed09a0b6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ ip="173.174.116.184"
+ claimedauthor="Graham"
+ subject="tumesyncd logging"
+ date="2017-12-06T14:05:52Z"
+ content="""
+In Jessie, systemd-timesyncd put out some logging information to syslog, everytime that it pinged the time server that gave you a time stamp, time correction and frequency correction information.  With Stretch, these log reports have been suppressed. Does anyone know how to get them back? I can't find anything in the documentation. 
+Thanks,
+--- Graham
+
+==
+"""]]
diff --git a/posts/time-synchronization-with-ntp-and-systemd/comment_3_51a20c86cc857bb7102b5c1648c624d5._comment b/posts/time-synchronization-with-ntp-and-systemd/comment_3_51a20c86cc857bb7102b5c1648c624d5._comment
new file mode 100644
index 0000000..52ae9d5
--- /dev/null
+++ b/posts/time-synchronization-with-ntp-and-systemd/comment_3_51a20c86cc857bb7102b5c1648c624d5._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ ip="91.123.239.210"
+ claimedauthor="Andrew McMillan"
+ url="https://plus.google.com/+andrewmcmillan"
+ subject="How long after enabling NTP should it show sync?"
+ date="2018-01-05T16:30:00Z"
+ content="""
+systemd-timesyncd seems to have some nice features - it touches `/var/lib/systemd/clock` (or perhaps `/var/lib/systemd/timesync/clock` on Debian) after each successful sync, so it will at least move forward after reboot even before the network is up.
+
+On the other hand there are situations where I would like a whole set of services to have a hard dependency on a successful time synchronisation before they will even try and start up, and this does not seem to be well-supported by systemd (see https://github.com/systemd/systemd/issues/5097 for more detail).
+
+You say you had to `timedatectl set-ntp true` after you got timesyncd running, but that's not working for me and I'm curious about how long I should spend watching it before I see a \"Yes\" in the NTP sync status, and I wonder what I might be missing if I'm not seeing this even though timesyncd appears to be running without errors.
+"""]]

calendar update
diff --git a/archives/2018.mdwn b/archives/2018.mdwn
new file mode 100644
index 0000000..e62c64e
--- /dev/null
+++ b/archives/2018.mdwn
@@ -0,0 +1 @@
+[[!calendar type=year year=2018 pages="page(posts/*) and !*/Discussion"]]
diff --git a/archives/2018/01.mdwn b/archives/2018/01.mdwn
new file mode 100644
index 0000000..21c038d
--- /dev/null
+++ b/archives/2018/01.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=01 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(01) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/02.mdwn b/archives/2018/02.mdwn
new file mode 100644
index 0000000..e6db08f
--- /dev/null
+++ b/archives/2018/02.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=02 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(02) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/03.mdwn b/archives/2018/03.mdwn
new file mode 100644
index 0000000..3c67a9f
--- /dev/null
+++ b/archives/2018/03.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=03 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(03) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/04.mdwn b/archives/2018/04.mdwn
new file mode 100644
index 0000000..89e91b0
--- /dev/null
+++ b/archives/2018/04.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=04 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(04) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/05.mdwn b/archives/2018/05.mdwn
new file mode 100644
index 0000000..76556e2
--- /dev/null
+++ b/archives/2018/05.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=05 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(05) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/06.mdwn b/archives/2018/06.mdwn
new file mode 100644
index 0000000..7244cd0
--- /dev/null
+++ b/archives/2018/06.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=06 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(06) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/07.mdwn b/archives/2018/07.mdwn
new file mode 100644
index 0000000..b7659d6
--- /dev/null
+++ b/archives/2018/07.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=07 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(07) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/08.mdwn b/archives/2018/08.mdwn
new file mode 100644
index 0000000..2044f98
--- /dev/null
+++ b/archives/2018/08.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=08 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(08) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/09.mdwn b/archives/2018/09.mdwn
new file mode 100644
index 0000000..ed51cd6
--- /dev/null
+++ b/archives/2018/09.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=09 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(09) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/10.mdwn b/archives/2018/10.mdwn
new file mode 100644
index 0000000..f916789
--- /dev/null
+++ b/archives/2018/10.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=10 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(10) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/11.mdwn b/archives/2018/11.mdwn
new file mode 100644
index 0000000..253e46a
--- /dev/null
+++ b/archives/2018/11.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=11 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(11) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]
diff --git a/archives/2018/12.mdwn b/archives/2018/12.mdwn
new file mode 100644
index 0000000..bc7c9c6
--- /dev/null
+++ b/archives/2018/12.mdwn
@@ -0,0 +1,5 @@
+[[!sidebar content="""
+[[!calendar type=month month=12 year=2018 pages="page(posts/*) and !*/Discussion"]]
+"""]]
+
+[[!inline pages="creation_month(12) and creation_year(2018) and page(posts/*) and !*/Discussion" show=0 feeds=no reverse=yes]]

Need to stop existing RAID0 array before re-creating it
diff --git a/posts/replacing-a-failed-raid-drive.mdwn b/posts/replacing-a-failed-raid-drive.mdwn
index 33622d6..43cf150 100644
--- a/posts/replacing-a-failed-raid-drive.mdwn
+++ b/posts/replacing-a-failed-raid-drive.mdwn
@@ -64,6 +64,7 @@ I used the following trick:
 
 Then, I recreated my RAID0 swap partition like this:
 
+    mdadm --stop /dev/md1
     mdadm /dev/md1 --create --level=0 --raid-devices=2 /dev/sda3 /dev/sdb3
     mkswap /dev/md1
 

Add post about 5GHz wifi channels
diff --git a/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn b/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn
new file mode 100644
index 0000000..438951f
--- /dev/null
+++ b/posts/using-all-5ghz-wifi-frequencies-in-gargoyle-router.mdwn
@@ -0,0 +1,76 @@
+[[!meta title="Using all of the 5 GHz WiFi frequencies in a Gargoyle Router"]]
+[[!meta date="2017-12-10T18:00:00:00.000-08:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+WiFi in the 2.4 GHz range is usually fairly congested in urban environments.
+The 5 GHz band used to be better, but an increasing number of routers now
+support it and so it has become fairly busy as well. It turns out that there
+are a
+[number of channels on that band](https://en.wikipedia.org/wiki/List_of_WLAN_channels#5_GHz_.28802.11a.2Fh.2Fj.2Fn.2Fac.29)
+that nobody appears to be using despite being legal in my region.
+
+## Why are the middle channels unused?
+
+I'm not entirely sure why these channels are completely empty in my area,
+but I would speculate that access point manufacturers don't want to deal
+with the extra complexity of the middle channels. Indeed these channels are
+not entirely unlicensed. They are also used by weather radars, for example.
+If you look at the regulatory rules that ship with your OS:
+
+    $ iw reg get
+    global
+    country CA: DFS-FCC
+    	(2402 - 2472 @ 40), (N/A, 30), (N/A)
+    	(5170 - 5250 @ 80), (N/A, 17), (N/A), AUTO-BW
+    	(5250 - 5330 @ 80), (N/A, 24), (0 ms), DFS, AUTO-BW
+    	(5490 - 5600 @ 80), (N/A, 24), (0 ms), DFS
+    	(5650 - 5730 @ 80), (N/A, 24), (0 ms), DFS
+    	(5735 - 5835 @ 80), (N/A, 30), (N/A)
+
+you will see that these channels are flagged with "DFS". That stands for
+[Dynamic Frequency Selection](http://wifi-insider.com/wlan/dfs.htm) and it
+means that WiFi equipment needs to be able to detect when the frequency is
+used by radars (by detecting their pulses) and automaticaly switch to a
+different channel for a few minutes.
+
+So an access point needs extra hardware and extra code to avoid interfering
+with priority users. Additionally, different channels have
+[different bandwidth limits](http://www.radio-electronics.com/info/wireless/wi-fi/80211-channels-number-frequencies-bandwidth.php)
+so that's something else to consider if you want to use 40/80 MHz at once.
+
+## Using all legal channels in Gargoyle
+
+The first time I tried setting my access point channel to one of the middle
+5 GHz channels, the SSID wouldn't show up in scans and the channel was still
+empty in [WiFi Analyzer](https://f-droid.org/packages/com.vrem.wifianalyzer/).
+
+I tried changing the channel again, but this time, I ssh'd into my router
+and looked at the errors messages using this command:
+
+    logread -f
+
+I found a number of errors claiming that these channels were not authorized
+for the "world" regulatory authority.
+
+Because [Gargoyle](https://www.gargoyle-router.com/) is based on
+[OpenWRT](https://openwrt.org/), there are a lot more
+nn[wireless configuration options](https://wiki.openwrt.org/doc/uci/wireless)
+available than what's exposed in the Web UI.
+
+In this case, the solution was to explicitly set my country in the wireless
+options by putting:
+
+    country 'CA'
+
+(where `CA` is the
+[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) where the
+router is physically located) in the 5 GHz radio section of
+`/etc/config/wireless` on the router.
+
+Then I rebooted and I was able to set the channel successfully via the Web UI.
+
+If you are interested, there is a lot more information about how all of this
+works in the
+[kernel documentation for the wireless stack](https://wireless.wiki.kernel.org/en/developers/regulatory/processing_rules#country_definition).
+
+[[!tag debian]] [[!tag nzoss]] [[!tag openwrt]] [[!tag gargoyle]]

Replace dead link with link to the Internet Archive copy
diff --git a/posts/raid1-alternative-for-ssd-drives.mdwn b/posts/raid1-alternative-for-ssd-drives.mdwn
index e7f2eb5..2176781 100644
--- a/posts/raid1-alternative-for-ssd-drives.mdwn
+++ b/posts/raid1-alternative-for-ssd-drives.mdwn
@@ -16,7 +16,7 @@ This setup has the benefit of using a very small SSD to speed up the main partit
 
 The first thing I did, given that I purchased a second-hand drive, was to **completely erase the drive** and mark all sectors as empty using an [ATA secure erase](http://en.wikipedia.org/wiki/Write_amplification#Secure_erase). Because SSDs have a tendency to get slower as data is added to them, it is necessary to clear the drive in a way that will let the controller know that every byte is now free to be used again.  
   
-There is a lot of advice on the web on how to do this and many tutorials refer to an old piece of software called [Secure Erase](http://cmrr.ucsd.edu/people/Hughes/SecureErase.shtml). There is a much better solution on Linux: [issuing the commands directly using **hdparm**](https://ata.wiki.kernel.org/index.php/ATA_Secure_Erase).  
+There is a lot of advice on the web on how to do this and many tutorials refer to an old piece of software called [Secure Erase](https://web.archive.org/web/20130511064320/http://cmrr.ucsd.edu:80/people/Hughes/SecureErase.shtml). There is a much better solution on Linux: [issuing the commands directly using **hdparm**](https://ata.wiki.kernel.org/index.php/ATA_Secure_Erase).  
   
 
 ## Partitioning the SSD

Comment moderation
diff --git a/posts/manipulating-debconf-settings-on/comment_4_3e0e8e7fe1639af6f0d2afdc4a69c3ec._comment b/posts/manipulating-debconf-settings-on/comment_4_3e0e8e7fe1639af6f0d2afdc4a69c3ec._comment
new file mode 100644
index 0000000..329a1b1
--- /dev/null
+++ b/posts/manipulating-debconf-settings-on/comment_4_3e0e8e7fe1639af6f0d2afdc4a69c3ec._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ ip="131.247.54.65"
+ claimedauthor="draeath"
+ subject="workaround"
+ date="2017-12-04T22:05:56Z"
+ content="""
+You can edit /var/cache/debconf/config.dat manually instead, but be aware that you can really break things by editing this.
+
+The file it uses for configuration is defined in /etc/debconf.conf, should it not be where you expect on your system
+
+    # World-readable, and accepts everything but passwords.
+    Name: config
+    Driver: File
+    Mode: 644
+    Reject-Type: password
+    Filename: /var/cache/debconf/config.dat
+"""]]

Add my letsencrypt ACME proxy
diff --git a/posts/proxy-acme-challenges-to-single-machine.mdwn b/posts/proxy-acme-challenges-to-single-machine.mdwn
new file mode 100644
index 0000000..aa2ebb5
--- /dev/null
+++ b/posts/proxy-acme-challenges-to-single-machine.mdwn
@@ -0,0 +1,93 @@
+[[!meta title="Proxy ACME challenges to a single machine"]]
+[[!meta date="2017-11-28T22:10:00:00.000-08:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+The [Libravatar mirrors](https://wiki.libravatar.org/run_a_mirror/) are
+setup using [DNS round-robin](https://en.wikipedia.org/wiki/Round-robin_DNS)
+which makes it a little challenging to automatically provision [Let's
+Encrypt](https://letsencrypt.org/) certificates.
+
+In order to be able to use [Certbot](https://certbot.eff.org/)'s
+[webroot](https://certbot.eff.org/docs/using.html#webroot) plugin, I need to
+be able to simultaneously host a randomly-named file into the webroot of
+each mirror. The reason is that the verifier will connect to
+`seccdn.libravatar.org`, but there's no way to know which of the DNS entries
+it will hit. I could copy the file over to all of the mirrors, but that
+would be annoying since some of the mirrors are run by volunteers and I
+don't have direct access to them.
+
+Thankfully, [Scott Helme](https://scotthelme.co.uk) has shared his elegant
+solution:
+[proxy the `.well-known/acme-challenge/` directory from all of the mirrors to a single validation host](https://scotthelme.ghost.io/lets-encrypt-with-dns-round-robin/).
+Here's the exact configuration I ended up with.
+
+# DNS Configuration
+
+In order to serve the certbot validation files separately from the main
+service, I created a new hostname, `acme.libravatar.org`, pointing to the
+main Libravatar server:
+
+    CNAME acme libravatar.org.
+
+# Mirror Configuration
+
+On each mirror, I created a new Apache vhost on port 80 to proxy the acme challenge
+files by putting the following in the existing port 443 vhost config
+(`/etc/apache2/sites-available/libravatar-seccdn.conf`):
+
+    <VirtualHost *:80>
+        ServerName __SECCDNSERVERNAME__
+        ServerAdmin __WEBMASTEREMAIL__
+    
+        ProxyPass /.well-known/acme-challenge/ http://acme.libravatar.org/.well-known/acme-challenge/
+        ProxyPassReverse /.well-known/acme-challenge/ http://acme.libravatar.org/.well-known/acme-challenge/
+    </VirtualHost>
+
+Then I enabled the right modules and restarted Apache:
+
+    a2enmod proxy
+    a2enmod proxy_http
+    systemctl restart apache2.service
+
+Finally, I added a cronjob in `/etc/cron.daily/commit-new-seccdn-cert` to
+commit the new cert to
+[etckeeper](https://packages.debian.org/sid/etckeeper) automatically:
+
+    #!/bin/sh
+    cd /etc/libravatar
+    /usr/bin/git commit --quiet -m "New seccdn cert" seccdn.crt seccdn.pem seccdn-chain.pem > /dev/null || true
+
+# Main Configuration
+
+On the main server, I created a new webroot:
+
+    mkdir -p /var/www/acme/.well-known
+
+and a new vhost in `/etc/apache2/sites-available/acme.conf`:
+
+    <VirtualHost *:80>
+        ServerName acme.libravatar.org
+        ServerAdmin webmaster@libravatar.org
+        DocumentRoot /var/www/acme
+        <Directory /var/www/acme>
+            Options -Indexes
+        </Directory>
+    </VirtualHost>
+
+before enabling it and restarting Apache:
+
+    a2ensite acme
+    systemctl restart apache2.service
+
+# Registering a new TLS certificate
+
+With all of this in place, I was able to register the cert easily using the
+webroot plugin on the main server:
+
+    certbot certonly --webroot -w /var/www/acme -d seccdn.libravatar.org
+
+The resulting certificate will then be
+[automatically renewed before it expires](https://feeding.cloud.geek.nz/posts/automatically-renewing-letsencrypt-certs-on-debian-using-certbot/).
+
+[[!tag debian]] [[!tag nzoss]] [[!tag letsencrypt]] [[!tag sysadmin]]
+[[!tag apache]] [[!tag ssl]]

Comment moderation
diff --git a/posts/setting-up-a-network-scanner-using-sane/comment_7_9bf228090795c3ee8f0867c6a41ac5ab._comment b/posts/setting-up-a-network-scanner-using-sane/comment_7_9bf228090795c3ee8f0867c6a41ac5ab._comment
new file mode 100644
index 0000000..e920f2f
--- /dev/null
+++ b/posts/setting-up-a-network-scanner-using-sane/comment_7_9bf228090795c3ee8f0867c6a41ac5ab._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ ip="80.177.21.246"
+ claimedauthor="copernicus"
+ subject="systemd and the scanner group"
+ date="2017-11-18T18:55:52Z"
+ content="""
+> In order for users to be able to see the scanner, they will need to be in the scanner group:
+
+On Debian jessie and stretch there is no need for a user to be in the scanner group.
+
+<https://wiki.debian.org/Scanner>
+
+Cheers,
+
+Brian
+"""]]

Comment moderation
diff --git a/posts/setting-up-a-network-scanner-using-sane/comment_6_d521247e1fd08189e6cc833effcc2916._comment b/posts/setting-up-a-network-scanner-using-sane/comment_6_d521247e1fd08189e6cc833effcc2916._comment
new file mode 100644
index 0000000..153a3f4
--- /dev/null
+++ b/posts/setting-up-a-network-scanner-using-sane/comment_6_d521247e1fd08189e6cc833effcc2916._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ ip="2607:f2c0:f00f:8f00:ed49:1678:801c:8c76"
+ claimedauthor="anarcat"
+ url="https://anarc.at/"
+ subject="what about auto-discovery?"
+ date="2017-11-15T23:44:58Z"
+ content="""
+i also wonder if we could get this simplified somehow. i don't mind configuring the server so much, but it's kind of painful to have to edit config files by hand on each client that needs to be configured...
+
+can't Avahi take care of this for us, just like it does for CUPS and printing? i looked around for this feature but so far all I've found are bug reports saying that it doesn't work ([ubuntu LP#508866](https://bugs.launchpad.net/ubuntu/+source/sane-backends/+bug/508866), [debian #743420](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=743420)). and indeed, with `SANE_DEBUG_NET=128 scanimage -L` says:
+
+    [net] sane_get_devices: local_only = 0
+    [net] sane_get_devices: finished (0 devices)
+    [net] net_avahi_browse_callback: CACHE_EXHAUSTED
+    [net] net_avahi_browse_callback: ALL_FOR_NOW
+    
+    No scanners were identified.
+
+So I'm not sure what's going on, but clearly this is not working...
+"""]]

Comment moderation
diff --git a/posts/setting-up-a-network-scanner-using-sane/comment_5_95f1c41889868ad977a645af03b75261._comment b/posts/setting-up-a-network-scanner-using-sane/comment_5_95f1c41889868ad977a645af03b75261._comment
new file mode 100644
index 0000000..5b37168
--- /dev/null
+++ b/posts/setting-up-a-network-scanner-using-sane/comment_5_95f1c41889868ad977a645af03b75261._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ ip="2607:f2c0:f00f:8f00:ed49:1678:801c:8c76"
+ claimedauthor="anarcat"
+ url="https://anarc.at/"
+ subject="why network and central docs"
+ date="2017-11-15T22:47:34Z"
+ content="""
+i setup a network scanner here because it is also a printer and already connected, by USB, to a print server so that many people can print on it without having to worry about cabling.
+
+yes, they need to move their feet to get actual paper in and out of there. crazy physics. but it beats fiddling with wires. :)
+
+also i figured i would mention there is a similar [guide in the Debian wiki](https://wiki.debian.org/SaneOverNetwork) - which seems to have slightly better SEO, so it comes up first. Therefore, I have reworked it to include the excellent suggestions here that were missing there. See if you can improve it further! :)
+"""]]
diff --git a/posts/setting-up-centralied-git-repository/comment_2_f78d1e13da378f9e71450f27fbcf1f80._comment b/posts/setting-up-centralied-git-repository/comment_2_f78d1e13da378f9e71450f27fbcf1f80._comment
new file mode 100644
index 0000000..df1dbc4
--- /dev/null
+++ b/posts/setting-up-centralied-git-repository/comment_2_f78d1e13da378f9e71450f27fbcf1f80._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ ip="107.77.202.230"
+ subject="Question"
+ date="2017-09-27T17:41:15Z"
+ content="""
+This command:
+git push /tmp/myrepo.git master
+
+Seems to be pushing an empty repo.  What am I missing?
+
+You touched a file in myrepo1, correct?
+
+Second:
+Don’t you need to specify the origin of myrepo1? Before pushing it?
+"""]]

Fix typo and add link to mutt homepage
diff --git a/posts/test-mail-server-ubuntu-debian.mdwn b/posts/test-mail-server-ubuntu-debian.mdwn
index 2ece0ec..6028b53 100644
--- a/posts/test-mail-server-ubuntu-debian.mdwn
+++ b/posts/test-mail-server-ubuntu-debian.mdwn
@@ -2,9 +2,9 @@
 [[!meta date="2017-11-13T17:30:00:00.000+08:00"]]
 [[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
 
-I wanted to setup a mailserver on a staging server that would send all
+I wanted to setup a mail service on a staging server that would send all
 outgoing emails to a local mailbox. This avoids sending emails out to real
-users when running the stating server using production data.
+users when running the staging server using production data.
 
 First, install the [postfix](http://www.postfix.org/) mail server:
 
@@ -26,7 +26,7 @@ and restart postfix:
 
 Once that's done, you can find all of the emails in `/var/mail/root`.
 
-So you can install mutt:
+So you can install [mutt](http://mutt.org):
 
     apt install mutt
 

Add a requirement on the "dunst" package
diff --git a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
index 53539aa..6c51008 100644
--- a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
+++ b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
@@ -20,6 +20,11 @@ Because of [a bug in gnome-settings-daemon](https://ask.fedoraproject.org/en/que
 
     dconf write /org/gnome/settings-daemon/plugins/cursor/active false
 
+While my startup script doesn't run this tool directly, installing the
+[dunst package](https://packages.debian.org/stable/dunst) is required to receive desktop notifications:
+
+    apt install dunst
+
 # Screensaver
 
 In addition, gnome-screensaver didn't automatically lock my screen, so I installed [xautolock](https://packages.debian.org/stable/xautolock) and added it to my startup script:

Revert "Add a section on my keyboard backlight script"
This reverts commit 9826c76ed6cdf99b58efc9168577a7a36cf8b02e.
Remove this unncessary configuration since the feature is built-in:
Fn+space
diff --git a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
index 31fe6b4..53539aa 100644
--- a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
+++ b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
@@ -64,23 +64,6 @@ To make it work, I wrote [a simple shell script](https://github.com/fmarier/user
 
     bindsym $mod+u exec /home/francois/bin/toggle-xkbmap
 
-# Keyboard backlight
-
-To control the keyboard backlight on my ThinkPad, I added the following
-shortcut:
-
-    bindsym Ctrl+Mod1+k exec /home/francois/bin/toggle-kbdlight
-
-That
-[script](https://github.com/fmarier/user-scripts/blob/master/toggle-kbdlight)
-simply cycles through these states: off, half brightness and full
-brightness.
-
-Because normal users can't control this setting though, I had to add the
-following to `/etc/sudoers`:
-
-    francois ALL=(ALL) NOPASSWD: /usr/bin/tee /proc/acpi/ibm/kbdlight
-
 # Suspend script
 
 Since I run lots of things in the background, I have set my laptop to avoid suspending when the lid is closed by putting the following in `/etc/systemd/login.conf`:
@@ -139,4 +122,4 @@ Finally, because X sometimes fail to detect my external monitor when docking/und
 
     bindsym XF86Display exec /home/francois/bin/external-monitor
 
-[[!tag debian]] [[!tag i3]] [[!tag gnome]] [[!tag nzoss]] [[!tag systemd]] [[!tag thinkpad]]
+[[!tag debian]] [[!tag i3]] [[!tag gnome]] [[!tag nzoss]] [[!tag systemd]]

Update monitor device names for stretch
diff --git a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
index 91e52de..31fe6b4 100644
--- a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
+++ b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
@@ -121,15 +121,15 @@ I run [Gajim](https://gajim.org/) on my first workspace and I have the following
 
 ## Automatically moving workspaces when docking
 
-Here's a neat configuration blurb which automatically moves my workspaces (and their contents) from the laptop screen (`eDP1`) to the external monitor (`DP2`) when I dock my laptop:
+Here's a neat configuration blurb which automatically moves my workspaces (and their contents) from the laptop screen (`eDP-1`) to the external monitor (`DP-3-1`) when I dock my laptop:
 
     # bind workspaces to the right monitors
-    workspace 1 output DP2
-    workspace 2 output DP2
-    workspace 3 output DP2
-    workspace 4 output DP2
-    workspace 5 output DP2
-    workspace 6 output eDP1
+    workspace 1 output DP-3-1
+    workspace 2 output DP-3-1
+    workspace 3 output DP-3-1
+    workspace 4 output DP-3-1
+    workspace 5 output DP-3-1
+    workspace 6 output eDP-1
 
 You can get these output names by running:
 

Add a section on my keyboard backlight script
diff --git a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
index 2b7a8db..91e52de 100644
--- a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
+++ b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
@@ -64,6 +64,23 @@ To make it work, I wrote [a simple shell script](https://github.com/fmarier/user
 
     bindsym $mod+u exec /home/francois/bin/toggle-xkbmap
 
+# Keyboard backlight
+
+To control the keyboard backlight on my ThinkPad, I added the following
+shortcut:
+
+    bindsym Ctrl+Mod1+k exec /home/francois/bin/toggle-kbdlight
+
+That
+[script](https://github.com/fmarier/user-scripts/blob/master/toggle-kbdlight)
+simply cycles through these states: off, half brightness and full
+brightness.
+
+Because normal users can't control this setting though, I had to add the
+following to `/etc/sudoers`:
+
+    francois ALL=(ALL) NOPASSWD: /usr/bin/tee /proc/acpi/ibm/kbdlight
+
 # Suspend script
 
 Since I run lots of things in the background, I have set my laptop to avoid suspending when the lid is closed by putting the following in `/etc/systemd/login.conf`:
@@ -122,4 +139,4 @@ Finally, because X sometimes fail to detect my external monitor when docking/und
 
     bindsym XF86Display exec /home/francois/bin/external-monitor
 
-[[!tag debian]] [[!tag i3]] [[!tag gnome]] [[!tag nzoss]] [[!tag systemd]]
+[[!tag debian]] [[!tag i3]] [[!tag gnome]] [[!tag nzoss]] [[!tag systemd]] [[!tag thinkpad]]

Update i3 config with Syncthing and Gajim
diff --git a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
index d0f9432..2b7a8db 100644
--- a/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
+++ b/posts/creating-a-modern-tiling-desktop-environment-using-i3.mdwn
@@ -14,7 +14,7 @@ As soon as I log into my desktop, my [startup script](https://github.com/fmarier
 * [gnome-keyring-daemon](https://packages.debian.org/stable/gnome-keyring): remembers ssh public keys for the duration of my session
 * [gnome-screensaver](https://packages.debian.org/stable/gnome-screensaver): locks the screen when I'm not around
 * [nm-applet](https://packages.debian.org/stable/network-manager-gnome): handles wifi and VPN connections
-* [git-annex](http://git-annex.branchable.com/): keeps my folders synchronized between machines
+* [syncthing](https://www.syncthing.net/): keeps my folders synchronized between machines
 
 Because of [a bug in gnome-settings-daemon](https://ask.fedoraproject.org/en/question/31186/my-mouse-cursor-dissapears-when-using-gnome3/) which makes the mouse cursor disappear as soon as gnome-settings-daemon is started, I had to run the following to disable the offending gnome-settings-daemon plugin:
 
@@ -98,9 +98,9 @@ before clicking on the window.
 
 ## Keeping IM windows on the first workspace
 
-I run [Pidgin](http://pidgin.im) on my first workspace and I have the following rule to keep any new window that pops up (e.g. in response to a new incoming message) on the same workspace:
+I run [Gajim](https://gajim.org/) on my first workspace and I have the following rule to keep any new window that pops up (e.g. in response to a new incoming message) on the same workspace:
 
-    assign [class="Pidgin"] 1
+    assign [class="Gajim"] 1
 
 ## Automatically moving workspaces when docking
 

Add posts on setting up a test mail server
diff --git a/posts/test-mail-server-ubuntu-debian.mdwn b/posts/test-mail-server-ubuntu-debian.mdwn
new file mode 100644
index 0000000..2ece0ec
--- /dev/null
+++ b/posts/test-mail-server-ubuntu-debian.mdwn
@@ -0,0 +1,37 @@
+[[!meta title="Test mail server on Ubuntu and Debian"]]
+[[!meta date="2017-11-13T17:30:00:00.000+08:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+I wanted to setup a mailserver on a staging server that would send all
+outgoing emails to a local mailbox. This avoids sending emails out to real
+users when running the stating server using production data.
+
+First, install the [postfix](http://www.postfix.org/) mail server:
+
+    apt install postfix
+
+and choose the "Local only" mail server configuration type.
+
+Then change the following in `/etc/postfix/main.cf`:
+
+    default_transport = error
+
+to:
+
+    default_transport = local:root
+
+and restart postfix:
+
+    systemctl restart postfix.service
+
+Once that's done, you can find all of the emails in `/var/mail/root`.
+
+So you can install mutt:
+
+    apt install mutt
+
+and then view the mailbox like this:
+
+    mutt -f /var/mail/root
+
+[[!tag debian]] [[!tag nzoss]] [[!tag postfix]]

Add postfix tag to monitoring post
diff --git a/posts/simple-remote-mail-queue-monitoring.mdwn b/posts/simple-remote-mail-queue-monitoring.mdwn
index 8296325..91c0a2a 100644
--- a/posts/simple-remote-mail-queue-monitoring.mdwn
+++ b/posts/simple-remote-mail-queue-monitoring.mdwn
@@ -60,4 +60,4 @@ server will want to send an email at 2am. However, all that does is send a
 spurious warning email in that case and so it's a pretty small price to pay
 for a dirt simple setup that's unlikely to break.
 
-[[!tag sysadmin]] [[!tag debian]] [[!tag nzoss]]
+[[!tag sysadmin]] [[!tag debian]] [[!tag nzoss]] [[!tag postfix]]

Comment moderation
diff --git a/posts/checking-your-passwords-against-hibp/comment_1_557b3f6294c8fdca37f5d69c9b0a91fd._comment b/posts/checking-your-passwords-against-hibp/comment_1_557b3f6294c8fdca37f5d69c9b0a91fd._comment
new file mode 100644
index 0000000..359a3b7
--- /dev/null
+++ b/posts/checking-your-passwords-against-hibp/comment_1_557b3f6294c8fdca37f5d69c9b0a91fd._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ ip="202.61.72.50"
+ claimedauthor="Russell Stuart"
+ subject="Taking a sledgehammer to an egg?"
+ date="2017-10-19T03:47:28Z"
+ content="""
+That pwned list of a password is a fantastic resource.  Thanks for posting a pointer to it.
+
+But Egad! - using postgres to index and search it??  You must have the patience of a saint.
+
+Given a false positive isn't a death sentence, a bloom filter is a better choice.  Setting the parameters to give a false positive range of 1e-9 (roughly 50/50 chance of getting 1 false positive if I checked a password with it every second for my entire life), the resulting filter occupies 2.6G - about 1/2 the size of the compressed original.  Creating the filter takes about 3 hours on my laptop (please forgive the butt ugly inline python):
+
+    sudo apt-get install python, python-pybloomfilter
+    wget http://.../pwned-*.txt.7z; for f in *.7z; do 7z x $f; done
+    python -c \"import pybloomfilter, sys; b = pybloomfilter.BloomFilter(500000000, 0.000000001, 'pwned.bf'); [b.update(open(f)) for f in sys.argv[1:]]\" pwned-passwords-*.txt
+
+Querying it:
+
+    python -c 'import hashlib,sys,pybloomfilter; b = pybloomfilter.BloomFilter.open(\"pwned.bf\"); sys.stdout.write(\"\".join(\"%s is pwned: %r\n\" % (p, hashlib.sha1(p).hexdigest().upper() + \"\r\n\" in b) for p in sys.argv[1:]))' password1 password2 ...
+
+"""]]
diff --git a/posts/checking-your-passwords-against-hibp/comment_2_5619343f4064a0aed19b23f8e91f223a._comment b/posts/checking-your-passwords-against-hibp/comment_2_5619343f4064a0aed19b23f8e91f223a._comment
new file mode 100644
index 0000000..f389ab3
--- /dev/null
+++ b/posts/checking-your-passwords-against-hibp/comment_2_5619343f4064a0aed19b23f8e91f223a._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ ip="2a00:23c5:69ce:df00:b7:aa91:48db:f9da"
+ claimedauthor="Jonathan"
+ url="jmtd.net"
+ subject="magnet URL for data"
+ date="2017-10-17T09:22:11Z"
+ content="""
+If it helps, I can vouch that this torrent magnet URL corresponds to the initial release of the password list. I found it the most convenient way to obtain the data. magnet:?xt=urn:btih:88145066d8d89cf426a22cfbeb1983dacb2a45d7&dn=pwned-passwords-1.0.txt.7z&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969
+"""]]

Post about my HIBP lookup tool
diff --git a/posts/checking-your-passwords-against-hibp.mdwn b/posts/checking-your-passwords-against-hibp.mdwn
new file mode 100644
index 0000000..adfa2bb
--- /dev/null
+++ b/posts/checking-your-passwords-against-hibp.mdwn
@@ -0,0 +1,31 @@
+[[!meta title="Checking Your Passwords Against the Have I Been Pwned List"]]
+[[!meta date="2017-10-16T22:10:00:00.000-07:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+Two months ago, Troy Hunt, the security professional behind
+[Have I been pwned?](https://haveibeenpwned.com/),
+[released](https://www.troyhunt.com/introducing-306-million-freely-downloadable-pwned-passwords/)
+an incredibly comprehensive
+[password list](https://haveibeenpwned.com/Passwords) in the hope that it
+would allow web developers to steer their users away from passwords that
+have been compromised in past breaches.
+
+While the list released by HIBP is hashed, the plaintext passwords are out
+there and one should assume that password crackers have access to them.
+So if you use a password on that list, you can be fairly confident
+that it's very easy to guess or crack your password.
+
+I wanted to check my **active** passwords against that list to check whether
+or not any of them are compromised and should be changed immediately. This
+meant that I needed to download the list and do these lookups locally since
+it's not a good idea to send your current passwords to this third-party
+service.
+
+I put my tool up on [Launchpad](https://launchpad.net/hibp-pwlookup) /
+[PyPI](https://pypi.python.org/pypi/hibp-pwlookup) and you are more than
+welcome to give it a go. Install [Postgres](https://www.postgresql.org/) and
+[Psycopg2](http://initd.org/psycopg/) and then follow the
+[README instructions](https://git.launchpad.net/hibp-pwlookup/tree/README.txt)
+to setup your database.
+
+[[!tag debian]] [[!tag nzoss]] [[!tag mozilla]] [[!tag security]]

Add license notice to the frontpage
diff --git a/index.mdwn b/index.mdwn
index d08446d..b37741c 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -1,3 +1,4 @@
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
 [[!if test="enabled(sidebar)" then="""
 [[!sidebar]]
 """ else="""

libvirt-bin is now called libvirt-clients
Even in jessie, libvirt-bin is a transitional package:
https://packages.debian.org/jessie/libvirt-bin
diff --git a/posts/lxc-setup-on-debian-jessie.mdwn b/posts/lxc-setup-on-debian-jessie.mdwn
index 417d043..5d764bf 100644
--- a/posts/lxc-setup-on-debian-jessie.mdwn
+++ b/posts/lxc-setup-on-debian-jessie.mdwn
@@ -8,7 +8,7 @@ a few things to get the networking to work on my machine.
 
 Start by installing (as root) the necessary packages:
 
-    apt install lxc libvirt-bin debootstrap
+    apt install lxc libvirt-clients debootstrap
 
 # Network setup
 

Comment moderation
diff --git a/posts/tls_authentication_freenode_and_oftc/comment_2_dac77c215afa19d55048c700d8fdd922._comment b/posts/tls_authentication_freenode_and_oftc/comment_2_dac77c215afa19d55048c700d8fdd922._comment
new file mode 100644
index 0000000..34cf11c
--- /dev/null
+++ b/posts/tls_authentication_freenode_and_oftc/comment_2_dac77c215afa19d55048c700d8fdd922._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ ip="38.109.115.130"
+ claimedauthor="Daniel Kahn Gillmor"
+ subject="Followup: "
+ date="2017-09-13T21:57:33Z"
+ content="""
+Thanks to this discussion, i just opened a [bug report on irssi](https://github.com/irssi/irssi/issues/756) to try to resolve the second issue above by sending client certificates in a renegotiated handshake.
+
+I've tested irssi, and it definitely does leak the user's public certificate to a passive network monitor.
+
+I haven't tested ZNC yet -- If someone wanted to open a similar report for ZNC, i'd appreciate it.
+
+If you want to test to see whether it's dumping traffic, you can do this with tshark:
+
+    tshark -O ssl  -Y 'ssl.handshake.certificates_length > 1 && ssl.record.content_type == 22'  -o http.ssl.port:6697 port 6697
+
+I don't have a patch to propose for either irssi or ZNC yet, and don't have much time to work on it myself.  I'd be happy to see that happen, because it would remove one of the major downsides to using certificates for IRC.
+"""]]

Comment moderation
diff --git a/posts/tls_authentication_freenode_and_oftc/comment_1_c11c1c8d07ec6290bdc3fe0a5c305de2._comment b/posts/tls_authentication_freenode_and_oftc/comment_1_c11c1c8d07ec6290bdc3fe0a5c305de2._comment
new file mode 100644
index 0000000..329d433
--- /dev/null
+++ b/posts/tls_authentication_freenode_and_oftc/comment_1_c11c1c8d07ec6290bdc3fe0a5c305de2._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ ip="38.109.115.130"
+ claimedauthor="Daniel Kahn Gillmor"
+ subject="problems with certificate-based TLS authentication for IRC"
+ date="2017-09-11T15:13:56Z"
+ content="""
+I used to use this approach myself, but i stopped using it a few years
+ago, for two reasons:
+
+ * certificate expiration -- when my registered certificate expires, i
+   still need to update the server with my new certificate.  to do that,
+   i need my password.  so my password still works, and i still have to
+   retain it and send it to (what i hope is the correct) nickserv
+   service at each cert renewal time.  so this doesn't actually remove
+   either my needing to remember/retain/record a password, and it
+   doesn't make my remembered/recorded password less powerful.
+
+ * client certificate leakage -- in TLS versions 1.2 and earlier (all
+   deployed versions of TLS), the client certificate is exchanged in the
+   clear, during the handshake.  (TLS 1.3 will fix this, but it is not yet fully standardized or in deployed production).  This means that client cert
+   authentication actually leaks your identity to any passive network
+   observer, whereas password-based authentication to nickserv does not.
+
+This pains me, because i generally *strongly* prefer pubkey-based
+authentication over password-based authentication.  But in this case, i
+think it's not enough of a win overall to make the transition.
+
+What do you think about these tradeoffs?  Are there mitigating factors that i should know about that makes them less troubling?
+
+"""]]

creating tag page tags/znc
diff --git a/tags/znc.mdwn b/tags/znc.mdwn
new file mode 100644
index 0000000..d2b3d6c
--- /dev/null
+++ b/tags/znc.mdwn
@@ -0,0 +1,4 @@
+[[!meta title="pages tagged znc"]]
+
+[[!inline pages="tagged(znc)" actions="no" archive="yes"
+feedshow=10]]

Add a post on TLS authentication for IRC
diff --git a/posts/hiding-network-disconnections-using-irc-bouncer.mdwn b/posts/hiding-network-disconnections-using-irc-bouncer.mdwn
index b4b35ee..7a705e3 100644
--- a/posts/hiding-network-disconnections-using-irc-bouncer.mdwn
+++ b/posts/hiding-network-disconnections-using-irc-bouncer.mdwn
@@ -107,4 +107,5 @@ kernel update, I keep the bouncer running. At the end of the day, I say yes
 to killing the bouncer. That way, I don't have a backlog to go through when
 I wake up the next day.
 
-[[!tag mozilla]] [[!tag debian]] [[!tag irc]] [[!tag irssi]] [[!tag nzoss]] [[!tag letsencrypt]]
+[[!tag mozilla]] [[!tag debian]] [[!tag irc]] [[!tag irssi]] [[!tag nzoss]]
+[[!tag letsencrypt]] [[!tag znc]]
diff --git a/posts/tls_authentication_freenode_and_oftc.mdwn b/posts/tls_authentication_freenode_and_oftc.mdwn
new file mode 100644
index 0000000..31f7f1a
--- /dev/null
+++ b/posts/tls_authentication_freenode_and_oftc.mdwn
@@ -0,0 +1,82 @@
+[[!meta title="TLS Authentication on Freenode and OFTC"]]
+[[!meta date="2017-09-08T21:50:00:00.000-07:00"]]
+[[!meta license="[Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)"]]
+
+In order to easily authenticate with IRC networks such as
+[OFTC](https://www.oftc.net/NickServ/CertFP/) and
+[Freenode](https://freenode.net/kb/answer/certfp), it is possible to use
+*client TLS certificates* (also known as *SSL certificates*). In fact, it
+turns out that it's very easy to setup both on [irssi](https://irssi.org/)
+and on [znc](https://wiki.znc.in/).
+
+# Generate your TLS certificate
+
+On a machine with [good entropy](http://altusmetrum.org/ChaosKey/), run the
+following command to create a keypair that will last for 10 years:
+
+    openssl req -nodes -newkey rsa:2048 -keyout user.pem -x509 -days 3650 -out user.pem -subj "/CN=<your nick>"
+
+Then extract your key fingerprint using this command:
+
+    openssl x509 -sha1 -noout -fingerprint -in user.pem | sed -e 's/^.*=//;s/://g'
+
+# Share your fingerprints with NickServ
+
+On each IRC network, do this:
+
+    /msg NickServ IDENTIFY Password1!
+    /msg NickServ CERT ADD <your fingerprint>
+
+in order to add your fingerprint to the access control list.
+
+# Configure ZNC
+
+To configure znc, start by putting the key in the right place:
+
+    cp user.pem ~/.znc/users/<your nick>/networks/oftc/moddata/cert/
+
+and then enable the built-in [cert plugin](https://wiki.znc.in/Cert) for
+each network in `~/.znc/configs/znc.conf`:
+
+    <Network oftc>
+        ...
+                LoadModule = cert
+        ...
+	</Network>
+        <Network freenode>
+        ...
+                LoadModule = cert
+        ...
+	</Network>
+
+# Configure irssi
+
+For irssi, do the same thing but put the cert in `~/.irssi/user.pem` and
+then change the OFTC entry in `~/.irssi/config` to look like this:
+
+    {
+      address = "irc.oftc.net";
+      chatnet = "OFTC";
+      port = "6697";
+      use_tls = "yes";
+      tls_cert = "~/.irssi/user.pem";
+      tls_verify = "yes";
+      autoconnect = "yes";
+    }
+
+and the Freenode one to look like this:
+
+    {
+      address = "chat.freenode.net";
+      chatnet = "Freenode";
+      port = "7000";
+      use_tls = "yes";
+      tls_cert = "~/.irssi/user.pem";
+      tls_verify = "yes";
+      autoconnect = "yes";
+    }
+
+That's it. That's all you need to replace password authentication with a
+much stronger alternative.
+
+[[!tag debian]] [[!tag nzoss]] [[!tag irc]] [[!tag irssi]] [[!tag znc]]

Mention the requirement for the veth kernel module
https://github.com/lxc/lxc/issues/1604
diff --git a/posts/lxc-setup-on-debian-jessie.mdwn b/posts/lxc-setup-on-debian-jessie.mdwn
index b46eab6..417d043 100644
--- a/posts/lxc-setup-on-debian-jessie.mdwn
+++ b/posts/lxc-setup-on-debian-jessie.mdwn
@@ -21,8 +21,14 @@ change needed here):
     lxc.network.hwaddr = 00:FF:AA:xx:xx:xx
     lxc.network.ipv4 = 0.0.0.0/24
 
-but I had to make sure that the "guests" could connect to the outside world
-through the "host":
+That configuration requires that the `veth` kernel module be loaded. If
+you have any kinds of module-loading restrictions enabled, you probably
+need to add the following to `/etc/modules` and **reboot**:
+
+    veth
+
+Next, I had to make sure that the "guests" could connect to the outside
+world through the "host":
 
 1. Enable IPv4 forwarding by putting this in `/etc/sysctl.conf`:
 

Add a section on fixing permissions for the scanner
diff --git a/posts/setting-up-a-network-scanner-using-sane.mdwn b/posts/setting-up-a-network-scanner-using-sane.mdwn
index 8dcaa26..e1c7147 100644
--- a/posts/setting-up-a-network-scanner-using-sane.mdwn
+++ b/posts/setting-up-a-network-scanner-using-sane.mdwn
@@ -29,8 +29,8 @@ detects your scanner:
 
     scanimage -L
 
-Note that you'll need to be in the `scanner` group for this to work
-(`adduser username scanner`).
+Note that you may need to be **root** for this to work. We'll fix that in
+the next section.
 
 This should give you output similar to this:
 
@@ -53,6 +53,33 @@ To do a test scan, simply run:
 
 and then take a look at the (greyscale) image it produced (`test.ppm`).
 
+# Letting normal users access the scanner
+
+In order for users to be able to see the scanner, they will need to be in
+the `scanner` group:
+
+    adduser francois scanner
+    adduser saned scanner
+
+with the second one being for remote users.
+
+Next, you'll need to put this in `/etc/udev/rules.d/55-libsane.rules`:
+
+    SUBSYSTEM=="usb", ATTRS{idVendor}=="04a9", MODE="0660", GROUP="scanner", ENV{libsane_matched}="yes"
+
+and then restart udev:
+
+    systemctl restart udev.service
+
+That `04a9` ID is the first part of what you saw in `lsusb`, but you can
+also see it in the output of `sane-find-scanner`.
+
+Finally, test the scanner as your normal user:
+
+    scanimage > test.ppm
+
+to confirm that everything is working.
+
 # Configure the server
 
 With the scanner working locally, it's time to expose it to network clients

Add missing firewall ports for SANE
diff --git a/posts/setting-up-a-network-scanner-using-sane.mdwn b/posts/setting-up-a-network-scanner-using-sane.mdwn
index bd8dfe8..8dcaa26 100644
--- a/posts/setting-up-a-network-scanner-using-sane.mdwn
+++ b/posts/setting-up-a-network-scanner-using-sane.mdwn
@@ -61,10 +61,11 @@ by adding the client IP addresses to `/etc/sane.d/saned.conf`:
     ## Access list
     192.168.1.3
 
-and then opening the appropriate port on your firewall
+and then opening the appropriate ports on your firewall
 (typically `/etc/network/iptables` in Debian):
 
     -A INPUT -s 192.168.1.3 -p tcp --dport 6566 -j ACCEPT
+    -A INPUT -s 192.168.1.3 -p udp -j ACCEPT
 
 Then you need to ensure that the SANE server is running by setting the
 following in `/etc/default/saned`:
@@ -98,7 +99,7 @@ where `myserver` is the hostname or IP address of the server running saned.
 If you have a firewall runnning on the client, make sure you allow
 SANE traffic from the server:
 
-    -A INPUT -s 192.168.1.2 -p tcp --sport 6566  -j ACCEPT
+    -A INPUT -s 192.168.1.2 -p tcp --sport 6566 -j ACCEPT
 
 # Test the scanner remotely
 

Restore lost comment
diff --git a/posts/setting-up-your-own-dnssec-aware/comment_5_650c2de462eaf647cf57a7989e8f67fd._comment b/posts/setting-up-your-own-dnssec-aware/comment_5_650c2de462eaf647cf57a7989e8f67fd._comment
new file mode 100644
index 0000000..4cc2a1a
--- /dev/null
+++ b/posts/setting-up-your-own-dnssec-aware/comment_5_650c2de462eaf647cf57a7989e8f67fd._comment
@@ -0,0 +1,47 @@
+[[!comment format=mdwn
+ ip="162.243.251.96"
+ claimedauthor="Eldin Hadzic"
+ subject="Solution"
+ date="2017-08-26T23:33:27Z"
+ content="""
+I figured it out.
+
+In order for OpenVPN to use the locally installed Unbound DNS resolver, do this:
+
+First check for the IP we should use with: `sudo ifconfig`
+
+The IP we need is the one listed at 
+
+    tun0: inet 10.8.0.1
+
+## UNBOUND
+
+Add this to `/etc/unbound/unbound.conf`:
+
+    server:
+        interface: 127.0.0.1
+        interface: 10.8.0.1
+        access-control: 127.0.0.1 allow
+        access-control: 10.8.0.1/24 allow
+
+Then restart Unbound with: `sudo service unbound restart`
+
+Test with: `dig @10.8.0.1 google.com`
+
+(SERVER should read: `SERVER: 10.8.0.1#53(10.8.0.1)`)
+
+## OPENVPN
+
+Add this to (or modify) `/etc/openvpn/server.conf`:
+
+    push \"redirect-gateway def1 bypass-dhcp\"
+    push \"dhcp-option DNS 10.8.0.1\"
+    push \"register-dns\"
+
+Then restart OpenVPN with: `sudo service openvpn restart`
+
+OpenVPN clients should now be using Unbound. Test at <http://dnsleak.com/>.
+
+Eldin Hadzic
+eldinhadzic@protonmail.com
+"""]]

removed
diff --git a/posts/setting-up-your-own-dnssec-aware/comment_5_650c2de462eaf647cf57a7989e8f67fd._comment b/posts/setting-up-your-own-dnssec-aware/comment_5_650c2de462eaf647cf57a7989e8f67fd._comment
deleted file mode 100644
index 42db2f0..0000000
--- a/posts/setting-up-your-own-dnssec-aware/comment_5_650c2de462eaf647cf57a7989e8f67fd._comment
+++ /dev/null
@@ -1,43 +0,0 @@
-[[!comment format=mdwn
- ip="162.243.251.96"
- subject="Re: OpenVPN settings"
- date="2017-08-26T22:19:01Z"
- content="""
-We figured it out:
-
-In order for OpenVPN to use the locally installed Unbound DNS resolver, do this:
-
-First check for the IP we should use with: `sudo ifconfig`
-
-The IP we need is the one listed at 
-
-    tun0: inet 10.8.0.1
-
-## UNBOUND
-
-Add this to `/etc/unbound/unbound.conf`:
-
-    server:
-        interface: 127.0.0.1
-        interface: 10.8.0.1
-        access-control: 127.0.0.1 allow
-        access-control: 10.8.0.1/24 allow
-
-Then restart Unbound with: `sudo service unbound restart`
-
-Test with: `dig @10.8.0.1 google.com`
-
-(SERVER should read: `SERVER: 10.8.0.1#53(10.8.0.1)`)
-
-## OPENVPN
-
-Add this to (or modify) `/etc/openvpn/server.conf`:
-
-    push \"redirect-gateway def1 bypass-dhcp\"
-    push \"dhcp-option DNS 10.8.0.1\"
-    push \"register-dns\"
-
-Then restart OpenVPN with: `sudo service openvpn restart`
-
-OpenVPN clients should now be using Unbound. Test at <http://dnsleak.com/>.
-"""]]

Add a blurb about integrating with OpenVPN
diff --git a/posts/setting-up-your-own-dnssec-aware.mdwn b/posts/setting-up-your-own-dnssec-aware.mdwn
index 247ca72..807277c 100644
--- a/posts/setting-up-your-own-dnssec-aware.mdwn
+++ b/posts/setting-up-your-own-dnssec-aware.mdwn
@@ -9,7 +9,7 @@ Now that the root DNS servers are [signed,](http://www.root-dnssec.org/2010/07/1
 Being already packaged in [Debian](http://packages.debian.org/source/unstable/unbound) and [Ubuntu](https://launchpad.net/ubuntu/+source/unbound), unbound is only an `apt-get` away:
 
 
-    apt-get install unbound
+    apt install unbound
 
 ## Optional settings
 
@@ -76,7 +76,6 @@ If you're not using DHCP, then you simply need to put this in your `/etc/resolv.
 
 
     nameserver 127.0.0.1
-  
 
 ## Testing DNSSEC resolution
 
@@ -94,4 +93,31 @@ $ dig +dnssec A www.dnssec.cz | grep ad
   
 Are there any other ways of making sure that DNSSEC is fully functional?
 
-[[!tag catalyst]] [[!tag debian]] [[!tag sysadmin]] [[!tag security]] [[!tag ubuntu]] [[!tag nzoss]] [[!tag dns]] [[!tag dnssec]]
+## Integration with OpenVPN
+
+If you are [running your own OpenVPN server](https://feeding.cloud.geek.nz/posts/creating-a-linode-based-vpn-setup-using_openvpn_on_debian_or_ubuntu/),
+you can tell clients to connect to the local unbound DNS client by putting the following in `/etc/unbound/unbound.conf.d/openvpn.conf`:
+
+    server:
+        interface: 127.0.0.1
+        interface: 10.8.0.1
+        access-control: 127.0.0.1 allow
+        access-control: 10.8.0.1/24 allow
+
+the following in `/etc/openvpn/server.conf`:
+
+    push "dhcp-option DNS 10.8.0.1"
+    push "register-dns"
+
+and opening the following port on your firewall (typically `/etc/network/iptables.up.rules` on Debian):
+
+    -A INPUT -p udp --dport 53 -s 10.8.0.0/24 -j ACCEPT
+
+Then restart both services and everything should work:
+
+    systemctl restart unbound.service
+    systemctl restart openvpn.service
+
+You can test it on <http://dnsleak.com>.
+
+[[!tag catalyst]] [[!tag debian]] [[!tag sysadmin]] [[!tag security]] [[!tag ubuntu]] [[!tag nzoss]] [[!tag dns]] [[!tag dnssec]] [[!tag openvpn]]