Recent changes to this wiki:

Publish log entry
diff --git a/posts/2018/02/17/what_is_debian_all_about_really_or_friction_packaging_complex_applications.mdwn b/posts/2018/02/17/what_is_debian_all_about_really_or_friction_packaging_complex_applications.mdwn
new file mode 100644
index 0000000..e244da0
--- /dev/null
+++ b/posts/2018/02/17/what_is_debian_all_about_really_or_friction_packaging_complex_applications.mdwn
@@ -0,0 +1,419 @@
+[[!meta title="What is Debian all about, really? Or: friction, packaging complex applications"]]
+[[!meta date="2018-02-17 15:05"]]
+[[!tag debian opinion]]
+
+[discussion]: https://lists.debian.org/debian-devel/2018/02/msg00295.html
+[blog post]: https://apebox.org/wordpress/linux/1229
+
+Another weekend, another big mailing list thread
+=============================================================================
+
+This weekend, those interested in Debian development have been having
+a [discussion][] on the debian-devel mailing list about "What can
+Debian do to provide complex applications to its users?". I'm
+commenting on that in my blog rather than the mailing list, since this
+got a bit too long to be usefully done in an email.
+
+directhex's recent [blog post][] "Packaging is hard. Packager-friendly
+is harder." is also relevant.
+
+
+The problem
+=============================================================================
+
+To start with, I don't think the email that started this discussion
+poses the right question. The problem not really about complex
+applications, we already have those in Debian. See, for example,
+LibreOffice. The discussion is really about how Debian should deal
+with the way some types of applications are developed upstream these
+days. They're not all complex, and they're not all big, but as usual,
+things only get interesting when _n_ is big.
+
+A particularly clear example is the whole nodejs ecosystem, but it's
+not limited to that and it's not limited to web applications. This is
+also not the first time this topic arises, but we've never come to any
+good conclusion.
+
+My understanding of the problem is as follows:
+
+> A current trend in software development is to use programming
+> languages, often interpreted high level languages, combined with
+> heavy use of third-party libraries, and a language-specific package
+> manager for installing libraries for the developer to use, and
+> sometimes also for the sysadmin installing the software for
+> production to use. This bypasses the Linux distributions entirely.
+> The benefit is that it has allowed ecosystems for specific
+> programming languages where there is very little _friction_ for
+> using libraries written in that language to be used by developers,
+> speeding up development cycles a lot.
+
+
+When I was young(er) the world was horrible
+=============================================================================
+
+In comparison, in the old days, which for me means the 1990s, and
+before Debian took over my computing life, the cycle was something
+like this: 
+
+> I would be writing an application, and would need to use a library
+> to make some part of my application easier to write. To use that
+> library, I would download the source code archive of the latest
+> release, and laboriously decipher and follow the build and
+> installation instructions, fix any problems, rinse, repeat. After
+> getting the library installed, I would get back to developing my
+> application. Often the installation of the dependency would take
+> hours, so not a thing to be undertaken lightly.
+
+
+Debian made some things better
+=============================================================================
+
+With Debian, and apt, and having access to hundreds upon hundreds of
+libraries packaged for Debian, this become a much easier process.
+But only for the things packaged for Debian.
+
+For those developing and publishing libraries, Debian didn't make the
+process any easier. They would still have to publish a source code
+archive, but also hope that it would eventually be included in Debian.
+And updates to libraries in the Debian stable release would not get
+into the hands of users until the next Debian stable release. This is
+a lot of friction. For C libraries, that friction has traditionally
+been tolerable. The effort of making the library in the first place is
+considerable, so any friction added by Debian is small by comparison.
+
+
+The world has changed around Debian
+=============================================================================
+
+In the modern world, developing a new library is much easier, and so
+also the friction caused by Debian is much more of a hindrance. My
+understanding is that things now happen more like this:
+
+> I'm developing an application. I realise I could use a library. I
+> run the language-specific package manager (pip, cpan, gem, npm,
+> cargo, etc), it downloads the library, installs it in my home
+> directory or my application source tree, and in less than the time
+> it takes to have sip of tea, I can get back to developing my
+> application.
+
+This has a lot less friction than the Debian route. The attraction to
+application programmers is clear. For library authors, the process is
+also much streamlined. Writing a library, especially in a high-level
+language, is fairly easy, and publishing it for others to use is quick
+and simple. This can lead to a virtuous cycle where I write a useful
+little library, you use and tell me about a bug or a missing feature,
+I add it, publish the new version, you use it, and we're both happy as
+can be. Where this might have taken weeks or months in the old days,
+it can now happen in minutes.
+
+
+The big question: why Debian?
+=============================================================================
+
+In this brave new world, **why would anyone bother with Debian
+anymore?** Or any traditional Linux distribution, since this isn't
+particularly specific to Debian. (But I mention Debian specifically,
+since it's what I now best.)
+
+A number of things have been mentioned or alluded to in the
+[discussion][] mentioned above, but I think it's good for the
+discussion to be explicit about them. As a computer user, software
+developer, system administrator, and software freedom _enthusiast_, I
+see the following reasons to continue to use Debian:
+
+* The freeness of software included in Debian has been vetted. I have
+  a **strong guarantee** that software included in Debian is free
+  software. This goes beyond the licence of that particular piece of
+  software, but includes practical considerations like the software
+  can actually be built using free tooling, and that I have access to
+  that tooling, because the tooling, too, is included in Debian.
+
+    * There was a time when Debian debated (with itself) whether it
+      was OK to include a binary that needed to be built using a
+      proprietary C compiler. We decided that it isn't, or not in the
+      main package archive.
+
+    * These days we have the question of whether "minimised
+      Javascript" is OK to be included in Debian, if it can't be
+      produced using tools packaged in Debian. My understanding is
+      that we have already decided that it's not, but the discussion
+      continues. To me, this seems equivalent to the above case.
+
+* I have a **strong guarantee** that software in a stable Debian
+  release won't change underneath me in incompatible ways, except in
+  special circumstances. This means that if I'm writing my application
+  and targeting Debian stable, the library API won't change, at least
+  not until the next Debian stable release. Likewise for every other
+  bit of software I use. Having things to continue to work without
+  having to worry is a good thing.
+
+    * Note that a side-effect of the low friction of library
+      development current ecosystems sometimes results in the library
+      API changing. This would mean my application would need to
+      change to adapt to the API change. That's friction for my work.
+
+* I have a **strong guarantee** that a dependency won't just
+  disappear. Debian has a large mirror network of its package archive,
+  and there are easy tools to run my own mirror, if I want to. While
+  running my own mirror is possible for other package management
+  systems, each one adds to the friction.
+
+    * The nodejs NPM ecosystem seems to be especially vulnerable to
+      this. More than once packages have gone missing, resulting other
+      projects, which depend on the missing packages, to start
+      failing.
+
+    * The way the Debian project is organised, it is almost impossible
+      for this to happen in Debian. Not only are package removals
+      carefully co-ordinated, packages that are depended on on by other
+      packages aren't removed.
+
+* I have a **strong guarantee** that a Debian package I get from a
+  Debian mirror is the official package from Debian: either the actual
+  package uploaded by a Debian developer or a binary package built by
+  a trusted Debian build server. This is because Debian uses
+  cryptographic signatures of the package lists and I have a trust
+  path to the Debian signing key.
+
+    * At least some of the language specific package managers fail to
+      have such a trust path. This means that I have no guarantees
+      that the library package I download today, was the same code
+      uploaded by library author.
+
+    * Note that https does not help here. It protects the transfer
+      from the package manger's web server to me, but makes absolutely
+      no guarantees about the validity of the package. There's been
+      enough cases of the package repository having been attacked that
+      this matters to me. Debian's signatures protect against malicious
+      changes on mirror hosts.
+
+* I have a **reasonably strong guarantee** that any problem I find can
+  be fixed, by me or someone else. This is not a strong guarantee,
+  because Debian can't do anything about insanely complicated code,
+  for example, but at least I can rely on being able to rebuild the
+  software. That's a basic requirement for fixing a bug.

(Diff truncated)
Fix: add missing link to Qvisqve
diff --git a/posts/2018/02/09/qvisqve_-_an_authorisation_server_first_alpha_release.mdwn b/posts/2018/02/09/qvisqve_-_an_authorisation_server_first_alpha_release.mdwn
index 1c21af9..7def4f9 100644
--- a/posts/2018/02/09/qvisqve_-_an_authorisation_server_first_alpha_release.mdwn
+++ b/posts/2018/02/09/qvisqve_-_an_authorisation_server_first_alpha_release.mdwn
@@ -3,9 +3,10 @@
 [[!tag announce qvisqve]]
 
 [QvarnLabs Ab]: http://qvarnlabs.com/
+[Qvisqve]: http://qvarn.org/qvisqve
 
 My company, [QvarnLabs Ab][], has today released the first alpha
-version of our new product, Qvisqve. Below is the press release. I
+version of our new product, [Qvisqve][]. Below is the press release. I
 wrote pretty much all the code, and it's free software (AGPL+).
 
 ---

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

Publish log entry
diff --git a/posts/2018/02/09/qvisqve_-_an_authorisation_server_first_alpha_release.mdwn b/posts/2018/02/09/qvisqve_-_an_authorisation_server_first_alpha_release.mdwn
new file mode 100644
index 0000000..1c21af9
--- /dev/null
+++ b/posts/2018/02/09/qvisqve_-_an_authorisation_server_first_alpha_release.mdwn
@@ -0,0 +1,39 @@
+[[!meta title="Qvisqve - an authorisation server, first alpha release"]]
+[[!meta date="2018-02-09 16:30"]]
+[[!tag announce qvisqve]]
+
+[QvarnLabs Ab]: http://qvarnlabs.com/
+
+My company, [QvarnLabs Ab][], has today released the first alpha
+version of our new product, Qvisqve. Below is the press release. I
+wrote pretty much all the code, and it's free software (AGPL+).
+
+---
+
+Helsinki, Finland - 2018-02-09. QvarnLabs Ab is happy to announce the
+first public release of Qvisqve, an authorisation server and identity
+provider for web and mobile applications. Qvisqve aims to be secure,
+lightweight, fast, and easy to manage. "We have big plans for Qvisqve,
+and helping customers' manage cloud identities" says Kaius Häggblom,
+CEO of QvarnLabs.
+
+In this alpha release, Qvisqve supports the OAuth2 client credentials
+grant, which is useful for authenticating and authorising automated
+systems, including IoT devices. Qvisqve can be integrated with any web
+service that can use OAuth2 and JWT tokens for access control.
+
+Future releases will provide support for end-user authentication by
+implementing the OpenID Connect protocol, with a variety of
+authentication methods, including username/password, U2F, TOTP, and
+TLS client certificates. Multi-factor authentication will also be
+supported. "We will make Qvisqve be flexible for any serious use case",
+says Lars Wirzenius, software architect at QvarnLabs. "We hope Qvisqve
+will be useful to the software freedom ecosystem in general" Wirzenius
+adds.
+
+Qvisqve is developed and supported by QvarnLabs Ab, and works together
+with the Qvarn software, which is award-winning free and open-source
+software for managing sensitive personal information. Qvarn is in
+production use in Finland and Sweden and manages over a million
+identities. Both Qvisqve and Qvarn are released under the Affero
+General Public Licence.

Publish log entry
diff --git a/posts/2018/01/22/ick_a_continuous_integration_system.mdwn b/posts/2018/01/22/ick_a_continuous_integration_system.mdwn
new file mode 100644
index 0000000..6c4c6bb
--- /dev/null
+++ b/posts/2018/01/22/ick_a_continuous_integration_system.mdwn
@@ -0,0 +1,137 @@
+[[!meta title="Ick: a continuous integration system"]]
+[[!meta date="2018-01-22 20:11"]]
+[[!tag announcement ick]]
+
+**TL;DR:** Ick is a continuous integration or CI system. See
+<http://ick.liw.fi/> for more information.
+
+More verbose version follows.
+
+First public version released
+-----------------------------------------------------------------------------
+
+The world may not need yet another continuous integration system (CI),
+but I do. I've been unsatisfied with the ones I've tried or looked at.
+More importantly, I am interested in a few things that are more
+powerful than what I've ever even heard of. So I've started writing my
+own.
+
+My new personal hobby project is called ick. It is a CI system, which
+means it can run automated steps for building and testing software.
+The home page is at <http://ick.liw.fi/>, and the [download][] page
+has links to the source code and .deb packages and an Ansible playbook
+for installing it.
+
+[download]: http://ick.liw.fi/download/
+
+I have now made the first publicly advertised release, dubbed ALPHA-1,
+version number 0.23. It is of alpha quality, and that means it doesn't
+have all the intended features and if any of the features it does have
+work, you should consider yourself lucky.
+
+Invitation to contribute
+-----------------------------------------------------------------------------
+
+Ick has so far been my personal project. I am hoping to make it more
+than that, and invite contributions. See the [governance][] page for
+the constitution, the [getting started][] page for tips on how to
+start contributing, and the [contact][] page for how to get in touch.
+
+[governance]: http://ick.liw.fi/governance/
+[getting started]: http://ick.liw.fi/getting-started/
+[contact]: http://ick.liw.fi/contact/
+
+Architecture
+-----------------------------------------------------------------------------
+
+Ick has an architecture consisting of several components that
+communicate over HTTPS using RESTful APIs and JSON for structured
+data. See the [architecture][] page for details.
+
+[architecture]: http://ick.liw.fi/architecture/
+
+Manifesto
+-----------------------------------------------------------------------------
+
+Continuous integration (CI) is a powerful tool for software
+development.
+It should not be tedious, fragile, or annoying. It should be quick and
+simple to set up, and work quietly in the background unless there's a
+problem in the code being built and tested.
+
+A CI system should be simple, easy, clear, clean, scalable, fast,
+comprehensible, transparent, reliable, and boost your productivity to
+get things done. It should not be a lot of effort to set up, require a
+lot of hardware just for the CI, need frequent attention for it to
+keep working, and developers should never have to wonder why something
+isn't working.
+
+A CI system should be flexible to suit your build and test needs. It
+should support multiple types of workers, as far as CPU architecture
+and operating system version are concerned.
+
+Also, like all software, CI should be fully and completely free
+software and your instance should be under your control.
+
+(Ick is little of this yet, but it will try to become all of it. In
+the best possible taste.)
+
+Dreams of the future
+-----------------------------------------------------------------------------
+
+In the long run, I would ick to have features like ones described
+below. It may take a while to get all of them implemented.
+
+* A build may be triggered by a variety of events. Time is an obvious
+  event, as is source code repository for the project changing. More
+  powerfully, any build dependency changing, regardless of whether the
+  dependency comes from another project built by ick, or a package
+  from, say, Debian: ick should keep track of all the packages that
+  get installed into the build environment of a project, and if any of
+  their versions change, it should trigger the project build and tests
+  again.
+
+* Ick should support building in (or against) any reasonable target,
+  including any Linux distribution, any free operating system, and any
+  non-free operating system that isn't brain-dead.
+
+* Ick should manage the build environment itself, and be able to do
+  builds that are isolated from the build host or the network. This
+  partially works: one can ask ick to build a container and run a
+  build in the container. The container is implemented using
+  systemd-nspawn. This can be improved upon, however. (If you think
+  Docker is the only way to go, please contribute support for that.)
+
+* Ick should support any workers that it can control over ssh or a
+  serial port or other such neutral communication channel, without
+  having to install an agent of any kind on them. Ick won't assume
+  that it can have, say, a full Java run time, so that the worker can
+  be, say, a micro controller.
+
+* Ick should be able to effortlessly handle very large numbers of
+  projects. I'm thinking here that it should be able to keep up with
+  building everything in Debian, whenever a new Debian source package
+  is uploaded. (Obviously whether that is feasible depends on whether
+  there are enough resources to actually build things, but ick itself
+  should not be the bottleneck.)
+
+* Ick should optionally provision workers as needed. If all workers of
+  a certain type are busy, and ick's been configured to allow using
+  more resources, it should do so. This seems like it would be easy to
+  do with virtual machines, containers, cloud providers, etc.
+
+* Ick should be flexible in how it can notify interested parties,
+  particularly about failures. It should allow an interested party to
+  ask to be notified over IRC, Matrix, Mastodon, Twitter, email, SMS,
+  or even by a phone call and speech syntethiser. "Hello, interested
+  party. It is 04:00 and you wanted to be told when the hello package
+  has been built for RISC-V."
+
+
+Please give feedback
+-----------------------------------------------------------------------------
+
+If you try ick, or even if you've just read this far, please share
+your thoughts on it. See the [contact][] page for where to send it.
+Public feedback is preferred over private, but if you prefer private,
+that's OK too.

Publish: pull request commentary
diff --git a/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn b/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn
index 2392d4b..f224e68 100644
--- a/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn
+++ b/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn
@@ -1,6 +1,6 @@
 [[!meta title="On using Github and a PR based workflow"]]
 [[!meta date="2018-01-09 17:25"]]
-[[!tag draft git github pull-request workflow]]
+[[!tag git github pull-request workflow]]
 
 In mid-2017, I decided to experiment with using pull-requests (PRs) on
 Github. I've read that they make development using git much nicer. The

Fix: typos and other language fixes
diff --git a/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn b/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn
index 1dd37c8..2392d4b 100644
--- a/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn
+++ b/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn
@@ -2,18 +2,18 @@
 [[!meta date="2018-01-09 17:25"]]
 [[!tag draft git github pull-request workflow]]
 
-In 2017, I decided to experiment with using pull-requests (PRs) on
+In mid-2017, I decided to experiment with using pull-requests (PRs) on
 Github. I've read that they make development using git much nicer. The
 end result of my experiment is that I'm not going to adopt a PR based
 workflow.
 
-The project is [vmdb2][], a tool for generating disk images with
-Debian. I put it up on Github, and invited people to send pull
-requests or patches, as they wished. I got a bunch of PRs, mostly from
-two people. For a little while, there was a flurry of activity. It has
-has now calmed down, I think primarily because the software has
-reached a state where the two contributors find it useful and don't
-need it to be fixed or have new features added.
+The project I chose for my experiment is [vmdb2][], a tool for
+generating disk images with Debian. I put it up on Github, and invited
+people to send pull requests or patches, as they wished. I got a bunch
+of PRs, mostly from two people. For a little while, there was a flurry
+of activity. It has has now calmed down, I think primarily because the
+software has reached a state where the two contributors find it useful
+and don't need it to be fixed or have new features added.
 
 [vmdb2]: https://github.com/larswirzenius/vmdb2
 
@@ -23,7 +23,7 @@ PRs and a workflow based on them:
 
 * they reduce some of the friction of contributing, making it easier
   for people to contribute; from a contributor point of view PRs
-  certainly seems like a better way than sending patches over email or
+  certainly seem like a better way than sending patches over email or
   sending a message asking to pull from a remote branch
 * merging a PR in the web UI is very easy
 
@@ -35,14 +35,14 @@ I also found some bad things:
   basic "something happened" notification, which prompt me to check
   the web UI
 * PRs are a centralised feature, which is something I prefer to avoid;
-  further, thery's tied to Github, which is something I object to on
+  further, they're tied to Github, which is something I object to on
   principle, since it's not free software
   - note that Gitlab provides support for PRs as well, but I've not
     tried it; it's an "open core" system, which is not fully free
     software in my opinion, and so I'm wary of Gitlab; it's also a
     centralised solution
   - a "distributed PR" system would be nice
-* mering a PR is perhaps too easy, and I worry that it leads me to
+* merging a PR is perhaps too easy, and I worry that it leads me to
   merging without sufficient review (that is of course a personal
   flaw)
 

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

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

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

Publish log entry
diff --git a/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn b/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn
new file mode 100644
index 0000000..1dd37c8
--- /dev/null
+++ b/posts/2018/01/09/on_using_github_and_a_pr_based_workflow.mdwn
@@ -0,0 +1,55 @@
+[[!meta title="On using Github and a PR based workflow"]]
+[[!meta date="2018-01-09 17:25"]]
+[[!tag draft git github pull-request workflow]]
+
+In 2017, I decided to experiment with using pull-requests (PRs) on
+Github. I've read that they make development using git much nicer. The
+end result of my experiment is that I'm not going to adopt a PR based
+workflow.
+
+The project is [vmdb2][], a tool for generating disk images with
+Debian. I put it up on Github, and invited people to send pull
+requests or patches, as they wished. I got a bunch of PRs, mostly from
+two people. For a little while, there was a flurry of activity. It has
+has now calmed down, I think primarily because the software has
+reached a state where the two contributors find it useful and don't
+need it to be fixed or have new features added.
+
+[vmdb2]: https://github.com/larswirzenius/vmdb2
+
+This was my first experience with PRs. I decided to give it until the
+end of 2017 until I made any conclusions. I've found good things about
+PRs and a workflow based on them:
+
+* they reduce some of the friction of contributing, making it easier
+  for people to contribute; from a contributor point of view PRs
+  certainly seems like a better way than sending patches over email or
+  sending a message asking to pull from a remote branch
+* merging a PR in the web UI is very easy
+
+I also found some bad things:
+
+* I really don't like the Github UI or UX, in general or for PRs in
+  particular
+* especially the emails Github sends about PRs seemed useless beyond a
+  basic "something happened" notification, which prompt me to check
+  the web UI
+* PRs are a centralised feature, which is something I prefer to avoid;
+  further, thery's tied to Github, which is something I object to on
+  principle, since it's not free software
+  - note that Gitlab provides support for PRs as well, but I've not
+    tried it; it's an "open core" system, which is not fully free
+    software in my opinion, and so I'm wary of Gitlab; it's also a
+    centralised solution
+  - a "distributed PR" system would be nice
+* mering a PR is perhaps too easy, and I worry that it leads me to
+  merging without sufficient review (that is of course a personal
+  flaw)
+
+In summary, PRs seem to me to prioritise making life easier for
+contributors, especially occasional contributors or "drive-by"
+contributors. I think I prefer to care more about frequent
+contributors, and myself as the person who merges contributions. For
+now, I'm not going to adopt a PR based workflow.
+
+(I expect people to mock me for this.)

Fix: drop meta author
diff --git a/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn b/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn
index 44f18a3..655cf28 100644
--- a/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn
+++ b/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn
@@ -1,6 +1,5 @@
 [[!meta title="The proof is in the pudding"]]
 [[!meta date="2017-12-17 11:09"]]
-[[!meta author=liw]]
 [[!tag philosophical sofware-development success]]
 
 I wrote these when I woke up one night and had trouble getting back to

Fix: meta directive
diff --git a/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn b/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn
index 6bf542c..44f18a3 100644
--- a/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn
+++ b/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn
@@ -1,6 +1,6 @@
 [[!meta title="The proof is in the pudding"]]
 [[!meta date="2017-12-17 11:09"]]
-[[!mete author=liw]]
+[[!meta author=liw]]
 [[!tag philosophical sofware-development success]]
 
 I wrote these when I woke up one night and had trouble getting back to

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

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

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

Publish log entry
diff --git a/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn b/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn
new file mode 100644
index 0000000..6bf542c
--- /dev/null
+++ b/posts/2017/12/17/the_proof_is_in_the_pudding.mdwn
@@ -0,0 +1,25 @@
+[[!meta title="The proof is in the pudding"]]
+[[!meta date="2017-12-17 11:09"]]
+[[!mete author=liw]]
+[[!tag philosophical sofware-development success]]
+
+I wrote these when I woke up one night and had trouble getting back to
+sleep, and spent a while in a very philosophical mood thinking about
+life, success, and productivity as a programmer.
+
+Imagine you're developing a piece of software.
+
+* You don't know it works, unless you've used it.
+
+* You don't know it's good, unless people tell you it is.
+
+* You don't know you can do it, unless you've already done it.
+
+* You don't know it can handle a given load, unless you've already tried it.
+
+* The real bottlenecks are always a surprise, the first time you measure.
+
+* It's not ready for production until it's been used in production.
+
+* Your automated tests always miss something, but with only manual
+  tests, you always miss more.

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

Publish log entry
diff --git a/posts/2017/11/13/unit_and_integration_testing_an_analogy_with_cars.mdwn b/posts/2017/11/13/unit_and_integration_testing_an_analogy_with_cars.mdwn
new file mode 100644
index 0000000..a542de2
--- /dev/null
+++ b/posts/2017/11/13/unit_and_integration_testing_an_analogy_with_cars.mdwn
@@ -0,0 +1,21 @@
+[[!meta title="Unit and integration testing: an analogy with cars"]]
+[[!meta date="2017-11-13 00:09"]]
+[[!tag programming analogy testing]]
+
+A unit is a part of your program you can test in isolation. You write
+unit tests to test all aspects of it that you care about. If all your
+unit tests pass, you should know that your unit works well.
+
+Integration tests are for testing that when your various well-tested,
+high quality units are combined, integrated, they work together.
+Integration tests test the integration, not the individual units.
+
+You could think of building a car. Your units are the ball bearings,
+axles, wheels, brakes, etc. Your unit tests for the ball bearings
+might test, for example, that they can handle a billion rotations, at
+various temperatures, etc. Your integration test would assume the ball
+bearings work, and should instead test that the ball bearings are
+installed in the right way so that the car, as whole, can run a
+kilometers, and accelerate and brake every kilometer, uses only so
+much fuel, produces only so much pollution, and doesn't kill
+passengers in case of a crash.

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

Publish log entry
diff --git a/posts/2017/10/10/debian_and_the_gdpr.mdwn b/posts/2017/10/10/debian_and_the_gdpr.mdwn
new file mode 100644
index 0000000..6d15a20
--- /dev/null
+++ b/posts/2017/10/10/debian_and_the_gdpr.mdwn
@@ -0,0 +1,54 @@
+[[!meta title="Debian and the GDPR"]]
+[[!meta date="2017-10-10 18:08"]]
+[[!tag debian gdpr privacy]]
+
+[GDPR][] is a new EU regulation for privacy. The name is short for
+"General Data Protection Regulation" and it covers all organisations
+that handle personal data of EU citizens and EU residents. It will
+become enforceable May 25, 2018 ([Towel Day][]). This will affect
+Debian. I think it's time for Debian to start working on compliance,
+mainly because the GDPR requires sensible things.
+
+[GDPR]: https://en.wikipedia.org/wiki/General_Data_Protection_Regulation
+[Towel Day]: https://en.wikipedia.org/wiki/Towel_Day
+
+I'm not an expert on GDPR legislation, but here's my understanding of
+what we in Debian should do:
+
+* do a privacy impact assessment, to review and **document** what
+  data we have, and collect, and what risks that has for the people
+  whose personal data it is if the data leaks
+
+* only collect personal information for specific purposes, and only
+  use the data for those purposes
+
+* get explicit consent from each person for all collection and use of
+  their personal information; archive this consent (e.g., list
+  subscription confirmations)
+
+* allow each person to get a copy of all the personal information
+  we have about them, in a portable manner, and let them correct it if
+  it's wrong
+
+* allow people to have their personal information erased
+
+* maybe appoint one or more data protection officers (not sure this is
+  required for Debian)
+
+There's more, but let's start with those.
+
+I think Debian has at least the following systems that will need to be
+reviewed with regards to the GDPR:
+
+* db.debian.org - Debian project members, "Debian developers"
+* nm.debian.org
+* contributors.debian.org
+* lists.debian.org - **at least** membership lists, maybe archives
+* possibly irc servers and log files
+* mail server log files
+* web server log files
+* version control services and repositories
+
+There may be more; these are just off the top of my head.
+
+I expect that mostly Debian will be OK, but we can't just assume that.

Drop: comments from front page, comment feed
diff --git a/comments.mdwn b/comments.mdwn
deleted file mode 100644
index e22b50a..0000000
--- a/comments.mdwn
+++ /dev/null
@@ -1,10 +0,0 @@
-[[!sidebar content="""
-[[!inline pages="comment_pending(./posts/*)" feedfile=pendingmoderation
-description="comments pending moderation" show=-1]]
-Comments in the [[!commentmoderation desc="moderation queue"]]:
-[[!pagecount pages="comment_pending(./posts/*)"]]
-"""]]
-
-Recent comments on posts in the [[blog|index]]:
-[[!inline pages="./posts/*/Discussion or comment(./posts/*)"
-template="comment"]]
diff --git a/index.mdwn b/index.mdwn
index 65fdc03..0343655 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -1,9 +1,8 @@
 Welcome to my web log. See the [[first_post|posts/welcome]] for an
-introduction. See the [[archive|posts]] page for all posts, and
-[[comments]] for a feed of comments only. (There is an
+introduction. See the [[archive|posts]] page for all posts. (There is an
 [[english language feed|englishfeed]] if you don't want to see Finnish.)
 
-[[Archives|posts]] [[Tags|tag]] [[Recent Comments|comments]]
+[[Archives|posts]] [[Tags|tag]]
 [Moderation policy](http://liw.fi/moderation/)
 [Main site](http://liw.fi/)
 
@@ -11,12 +10,8 @@ All content outside of comments is copyrighted by Lars Wirzenius, and
 licensed under a <a rel="license"
 href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons
 Attribution-Share Alike 3.0 Unported License</a>. Comments are
-copyrighted by their authors.
+copyrighted by their authors. (No new comments are allowed.)
 
 ---
 
 [[!inline pages="page(posts/*) and !Discussion and !tagged(draft)"]]
-
----
-
-For more, see [[the archive|posts]].

Publish: draft article on attractig contributors
diff --git a/posts/2017/10/01/attracting_contributors_to_a_new_project.mdwn b/posts/2017/10/01/attracting_contributors_to_a_new_project.mdwn
index 363f0ef..c462f51 100644
--- a/posts/2017/10/01/attracting_contributors_to_a_new_project.mdwn
+++ b/posts/2017/10/01/attracting_contributors_to_a_new_project.mdwn
@@ -1,6 +1,6 @@
 [[!meta title="Attracting contributors to a new project"]]
 [[!meta date="2017-10-01 10:21"]]
-[[!tag draft meta community]]
+[[!tag meta community]]
 
 How do you attract contributors to a new free software project?
 

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

Publish log entry
diff --git a/posts/2017/10/01/attracting_contributors_to_a_new_project.mdwn b/posts/2017/10/01/attracting_contributors_to_a_new_project.mdwn
new file mode 100644
index 0000000..363f0ef
--- /dev/null
+++ b/posts/2017/10/01/attracting_contributors_to_a_new_project.mdwn
@@ -0,0 +1,72 @@
+[[!meta title="Attracting contributors to a new project"]]
+[[!meta date="2017-10-01 10:21"]]
+[[!tag draft meta community]]
+
+How do you attract contributors to a new free software project?
+
+I'm in the very early stages of a new personal project. It is
+irrelevant for this blog post what the new project actually is.
+Instead, I am thinking about the following question:
+
+> Do I want the project to be mainly for myself, and maybe a handful
+> of others, or do I want to try to make it a more generally useful,
+> possibly even a well-known, popular project? In other words, do I
+> want to just solve a specific problem I have or try to solve it for
+> a large group of people?
+
+If it's a personal project, I'm all set. I can just start writing
+code. (In fact, I have.) If it's the latter, I'll need to attract
+contributions from others, and how do I do that?
+
+I asked that question on [Twitter][] and [Mastodon][] and got several
+suggestions. This is a summary of those, with some editorialising from
+me.
+
+[Twitter]: https://twitter.com/larswirzenius/status/913758747666862081
+[Mastodon]: https://mastodon.acc.sunet.se/@liw/79046
+
+* The most important thing is probably that the project should aim for
+  something that interests other people. The more people it interests,
+  the easier it will be to attract contributors. This should be
+  written up and displayed prominently: what does (or will) the
+  software do and what can it e used for.
+
+* Having something that kind of works, and easy to improve, seems to
+  also be key. An empty project is daunting to do anything with. Part
+  of this is that the software the project is producing should be easy
+  to install and get running. It doesn't have to be fully featured. It
+  doesn't even have to be alpha level quality. It needs to do
+  **something**.
+
+  If the project is about producing a spell checker, say, and it
+  doesn't even try to read an input file, it's probably too early for
+  anyone else to contribute. A spell checker that lists every word in
+  the input file as badly spelt is probably more attractive to
+  contribute to.
+
+* It helps to document where a new contributor should start, and how
+  they would submit their contribution. A list of easy things to work
+  on may also help. Having a roadmap of near future developent steps
+  and a long-term vision will make things easier. Having an
+  architectural document to explain how the system hangs together will
+  help.
+
+* A welcoming, constructive atmosphere helps. People should get quick
+  feedback to questions, issues, patches, in order to build momentum.
+  Make it fun for people to contibute, and they'll contribute more.
+
+* A public source code repository, and a public ticketing system, and
+  public discussion forums (mailing lists, web forums, IRC channels,
+  etc) will help.
+
+* Share the power in the project. Give others the power to make
+  decisions, or merge things from other contributors. Having a clear,
+  functioning governance structure from the start helps.
+
+I don't know if these things are all correct, or that they're enough
+to grow a successful, popular project.
+
+Karl Foger'l seminal book [Producing Open Source Software][] should
+also be mentioned.
+
+[Producing Open Source Software]: http://producingoss.com/

Publish log entry
diff --git a/posts/2017/08/13/retiring_obnam.mdwn b/posts/2017/08/13/retiring_obnam.mdwn
new file mode 100644
index 0000000..6a7b195
--- /dev/null
+++ b/posts/2017/08/13/retiring_obnam.mdwn
@@ -0,0 +1,85 @@
+[[!meta title="Retiring Obnam"]]
+[[!meta date="2017-08-13 21:48"]]
+[[!tag announcement obnam]]
+
+This is a difficult announcement to write. The summary is if you use
+Obnam you should switch to another backup program in the coming
+months.
+
+The first commit to Obnam's current code base is this:
+
+    commit 7eaf5a44534ffa7f9c0b9a4e9ee98d312f2fcb14
+    Author: Lars Wirzenius <liw@iki.fi>
+    Date:   Wed Sep 6 18:35:52 2006 +0300
+
+        Initial commit.
+
+It's followed by over 5200 more commits until the latest one, which is
+from yesterday. The NEWS file contains 58 releases. There are 20761
+lines of Python, 15384 words in the English language manual, with
+translations in German and French. The yarn test suite, which is a
+kind of a manual, is another 13382 words in English and
+pseudo-English. That's a fair bit of code and prose. Not all of it
+mine, I've had help from some wonderful people. But most of it mine.
+
+I wrote all of that because backups were fun. It was pleasing to use
+my own program to guarantee the safety of my own data. The technical
+challenges of implmenting the kind of backup program I wanted were
+interesting, and solving interesting problems is a big part of why 
+I am a programmer.
+
+Obnam has a kind user base. It's not a large user base: the Debian
+"popularity contest" service estimates it at around 500. But it's a
+user base that is kind and has treated me well. I have tried to
+reciprocate.
+
+Unfortunately, I have not had fun while developing Obnam for some time
+now. This has changed. A few years ago, I lived in Manchester, UK, and
+commuted by train to work. It was a short train ride, about 15
+minutes. At times I would sit on the floor with my laptop on my knees,
+writing code or the manual. Back then Obnam was a lot of fun. I was
+excited, and enthusiastic.
+
+In the past two years or so, I've not been able to feel that
+excitement again. My native language, Finnish, has an expression
+describing unpleasant tasks: something is as much fun as drinking tar.
+That describes Obnam in recent years for me.
+
+Obnam has not turned out well, from a maintainability point of view.
+It seems that every time I try to fix something, I break something
+else. Usuaully what breaks is speed or memory use: Obnam gets slower
+or starts using even more memory.
+
+For several years now I've been working on a new repository format for
+Obnam, code names GREEN ALBATROSS. It was meant to solve Obnam's
+problems as far as extensibility, performance, and resource use were
+concerned. It seems to have failed.
+
+I'm afraid I've had enough. I'm going to retire Obnam as a project and
+as a program, and move on to doing something else, so I can feel
+excitement and pleasure again.
+
+After some careful thought, I fear that the maintainability problems
+of Obnam can realistically only be solved by a complete rewrite from
+scratch, and I'm not up to doing that.
+
+If you use Obnam, you should migrate to some other backup solution.
+Don't worry, you have until the end of the year. I will be around and
+I intend to fix any serious bugs in Obnam; in particular, security
+flaws. But you should start looking for a replacement sooner rather
+than later.
+
+I will be asking Obnam to be removed from the Debian unstable and
+testing branches. The next Debian release (buster, Debian 10) won't
+include Obnam.
+
+The Obnam mailing lists are kindly hosted by Daniel Silverstone, and
+they will remain, but later this year I will change them to be
+moderated. The Obnam git repository will remain. The web site will
+remain, but I will add a note that Obnam is no longer maintained.
+Other Obnam online resources may disappear.
+
+If you would like to take over the Obnam project, and try to resolve
+the various issues, please contact me to discuss that.
+
+Thank you, and may you never need to restore.

Publish the TRIM blog post
diff --git a/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn b/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn
index 3ad8fba..3bfcb72 100644
--- a/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn
+++ b/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn
@@ -1,6 +1,6 @@
 [[!meta title="Enabling TRIM/DISCARD on Debian, ext4, luks, and lvm"]]
 [[!meta date="2017-08-05 20:58"]]
-[[!tag debian sysadmin luks discard ssd draft]]
+[[!tag debian sysadmin luks discard ssd]]
 
 I realised recently that my laptop isn't set up to send [TRIM][] or
 DISCARD commands to its SSD. That means the SSD firmware has a harder

Fix: drop unnecessary mount option
diff --git a/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn b/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn
index 1a41f23..3ad8fba 100644
--- a/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn
+++ b/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn
@@ -14,8 +14,6 @@ Since the information is a bit scattered, here's the details, for
 Debian stretch, as much for my own memory as to make sure this is
 collected into one place.
 
-* Add the `discard` option to `/etc/fstab` to all filesystems that
-  support it.
 * Append `,discard` to the fourth column on relevant lines in
   `/etc/crypttab`. For me, this means the fourth column should be
   `luks,discard`.

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

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

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

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

Publish log entry
diff --git a/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn b/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn
new file mode 100644
index 0000000..1a41f23
--- /dev/null
+++ b/posts/2017/08/05/enabling_trim_discard_on_debian_ext4_luks_and_lvm.mdwn
@@ -0,0 +1,50 @@
+[[!meta title="Enabling TRIM/DISCARD on Debian, ext4, luks, and lvm"]]
+[[!meta date="2017-08-05 20:58"]]
+[[!tag debian sysadmin luks discard ssd draft]]
+
+I realised recently that my laptop isn't set up to send [TRIM][] or
+DISCARD commands to its SSD. That means the SSD firmware has a harder
+time doing garbage collection (see whe linked Wikipedia page for more
+details.)
+
+After some searching, I found two articles by [Christopher Smart][]:
+[one][], [update][]. Those, plus some addition reading of
+documentation, and a little experimentation, allowed me to do this.
+Since the information is a bit scattered, here's the details, for
+Debian stretch, as much for my own memory as to make sure this is
+collected into one place.
+
+* Add the `discard` option to `/etc/fstab` to all filesystems that
+  support it.
+* Append `,discard` to the fourth column on relevant lines in
+  `/etc/crypttab`. For me, this means the fourth column should be
+  `luks,discard`.
+* Change in `/etc/lvm/lvm.conf` that says `issue_discards` to enable
+  it (assign 1 instead of 0).
+* Append `rd.luks.options=discard` to the `GRUB_CMDLINE_LINUX_DEFAULT`
+  value in `/etc/default/grub`
+* Run `sudo update-grub`
+* Run `sudo update-initramfs -u`
+* Reboot.
+* Run `sudo fstrim -av` - if this works, you're good! If it gives you
+  errors, then you get to debug. I have no idea what I'm talking
+  about.
+* Copy
+  `/usr/share/doc/util-linux/examples/fstrim.*` to
+  `/etc/systemd/system` and run `sudo systemctl enable fstrim.timer`.
+  This will tell systemd to run fstrim every week. (If you don't use
+  systemd you'll have to adapt the systemd bits mentioned here. I've
+  no idea how.)
+
+Note that it seems to be a possible information leak to TRIM encryped
+devices. I don't know the details, but if that bothers you, don't do
+it.
+
+I don't know of any harmful effects for enabling TRIM for everything,
+except the crypto bit above, so I wonder if it wouldn't make sense for
+the Debian installer to do this by default.
+
+[TRIM]: https://en.wikipedia.org/wiki/Trim_(computing)
+[Christopher Smart]: https://blog.christophersmart.com/about/
+[one]: https://blog.christophersmart.com/2013/06/05/trim-on-lvm-on-luks-on-ssd/
+[update]: https://blog.christophersmart.com/2016/05/12/trim-on-lvm-on-luks-on-ssd-revisited/

Publish log entry
diff --git a/posts/2017/07/19/dropping_yakking_from_planet_debian.mdwn b/posts/2017/07/19/dropping_yakking_from_planet_debian.mdwn
new file mode 100644
index 0000000..d92efbd
--- /dev/null
+++ b/posts/2017/07/19/dropping_yakking_from_planet_debian.mdwn
@@ -0,0 +1,6 @@
+[[!meta title="Dropping Yakking from Planet Debian"]]
+[[!meta date="2017-07-19 08:53"]]
+[[!tag yakking debian]]
+
+A couple of people objected to having Yakking on Planet Debian, so
+I've removed it.

Publish log entry
diff --git a/posts/2017/07/13/adding_yakking_to_planet_debian.mdwn b/posts/2017/07/13/adding_yakking_to_planet_debian.mdwn
new file mode 100644
index 0000000..60dce93
--- /dev/null
+++ b/posts/2017/07/13/adding_yakking_to_planet_debian.mdwn
@@ -0,0 +1,24 @@
+[[!meta title="Adding Yakking to Planet Debian"]]
+[[!meta date="2017-07-13 13:01"]]
+[[!tag ]]
+
+In a case of blatant self-promotion, I am going to add the [Yakking][]
+RSS feed to the Planet Debian aggregation. (But really because I think
+some of the readership of Planet Debian may be interested in the
+content.)
+
+Yakking is a group blog by a few friends aimed at new free software
+contributors. From the front page description:
+
+> Welcome to Yakking.
+>
+> This is a blog for topics relevant to someone new to free software
+> development. We assume you are already familiar with computers, and
+> are curious about participating in the production of free software.
+> You don't need to be a programmer: software development requires a
+> wide variety of skills, and you can be a valued core contributor to
+> a project without being a programmer.
+
+If anyone objects, please let me know.
+
+[Yakking]: https://yakking.branchable.com/

Publish log entry
diff --git a/posts/2017/06/25/obnam_1_22_released_backup_application.mdwn b/posts/2017/06/25/obnam_1_22_released_backup_application.mdwn
new file mode 100644
index 0000000..1a30785
--- /dev/null
+++ b/posts/2017/06/25/obnam_1_22_released_backup_application.mdwn
@@ -0,0 +1,39 @@
+[[!meta title="Obnam 1.22 released (backup application)"]]
+[[!meta date="2017-06-25 15:40"]]
+[[!tag obnam announcement]]
+
+I've just released version 1.22 of Obnam, my backup application. It is
+the first release for this year. Packages are available on
+code.liw.fi/debian and in Debian unstable, and source is in git. A
+summary of the user-visible changes is below.
+
+For those interested in living dangerously and accidentally on purpose
+deleting all their data, the link below shows that status and roadmap
+for FORMAT GREEN ALBATROSS.
+<http://distix.obnam.org/obnam-dev/182bd772889544d5867e1a0ce4e76652.html>
+
+Version 1.22, released 2017-06-25
+----------------------------------
+
+* Lars Wirzenius made Obnam log the full text of an Obnam
+  exception/error message with more than one line. In particular this
+  applies to encryption error messages, which now log the gpg output.
+
+* Lars Wirzenius made `obnam restore` require absolute paths for files
+  to be restored.
+
+* Lars Wirzenius made `obnam forget` use a little less memory. The
+  amount depends on the number of genrations and the chunks they
+  refer to.
+
+* Jan Niggemann updated the German translation of the Obnam manual to
+  match recent changes in the English version.
+
+* SanskritFritz and Ian Cambell fixed the kdirstat plugin.
+
+* Lars Wirzenius changed Obnam to hide a Python stack trace when
+  there's a problem with the SSH connection (e.g., failure to
+  authenticate, or existing connection breaks).
+
+* Lars Wirzenius made the Green Albatross version of `obnam forget`
+  actually free chunks that are no longer used.

Publish
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index a8c4674..c5d0f4b 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -1,6 +1,6 @@
 [[!meta title="Vmdb2 first alpha release: Debian disk image creation tool"]]
 [[!meta date="2017-06-04 15:08"]]
-[[!tag draft vmdb2 vmdebootstrap announcement]]
+[[!tag vmdb2 vmdebootstrap announcement]]
 
 tl;dr: Get vmdebootstrap replacement from <http://git.liw.fi/vmdb2> and
 run it from the source tree. Tell me if something doesn't work. Send

Fix: remove smiley
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index bc29c40..a8c4674 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -205,7 +205,6 @@ Debian maintainership and bug handling duties.
 
 If you would like vmdb2 to do more things to suit you better, I'm
 happy to explain how to write plugins to provide more types of steps.
-:)
 
 If you are currently using vmdebootstrap, either directly or as part
 of another tool, I encourage you to have a look at vmdb2. In the long

Fix: typo
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 7879c53..bc29c40 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -191,7 +191,7 @@ image and running Ansible over ssh.
 
 Finally, install a boot loader, grub. This shows the BIOS variant,
 UEFI is also supported. This also configures grub and the kernel to use a
-serial console. There's a "yarn" (test suite) to build and smoke gtest
+serial console. There's a "yarn" (test suite) to build and smoke test
 an image with vmdb2 to make sure at least the basic functionality
 works. The smoke test boots the image under Qemu, logs in as root, and
 tells the VM to power off. Very, very basic, but has already found

Fix: clean up wording
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 55bf4a5..7879c53 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -190,7 +190,7 @@ image and running Ansible over ssh.
         console: serial
 
 Finally, install a boot loader, grub. This shows the BIOS variant,
-UEFI is also supported. This also configures everything to use a
+UEFI is also supported. This also configures grub and the kernel to use a
 serial console. There's a "yarn" (test suite) to build and smoke gtest
 an image with vmdb2 to make sure at least the basic functionality
 works. The smoke test boots the image under Qemu, logs in as root, and

Fix: typo
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index a913e86..55bf4a5 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -180,7 +180,7 @@ the step.
 This is a good point to mention that writing customize scripts gets
 quite repetitive and tedious after a while, so vmdb2 has a plugin to
 run Ansible instead. You can customize your image with that instead,
-while the image is beint built and not have to wait until you boot the
+while the image is being built and not have to wait until you boot the
 image and running Ansible over ssh.
 
       - grub: bios

Fix: add self-depracation
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index f3e589a..a913e86 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -154,9 +154,9 @@ the tarball is created if it didn't exist. This way the tarball is
 used by all but the first run, which saves a bit of time. On my laptop
 and with a local mirror, debootstrap and kernel installation takes on the
 order of nine minutes (500 to 600 seconds), whereas unpacking the tar
-archive is a lot faster (around 30 seconds). When iterating over
+archive is a bit faster (takes around 30 seconds). When iterating over
 things other than debootstrap, this speeds things up something
-wonderful.
+wonderful, and seems worth the complexity.
 
 The "unless:" mechanism is generic. All the steps share some state,
 and the unpack-rootfs step sets the "rootfs_unpacked" flag in the

Fix: clarify wording
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 2af42ac..f3e589a 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -152,7 +152,7 @@ The above will run debootstrap and install a kernel into the
 filesystem, but skip doing that if the rootfs tarball was used. Also,
 the tarball is created if it didn't exist. This way the tarball is
 used by all but the first run, which saves a bit of time. On my laptop
-and local mirror, debootstrap and kernel installation takes on the
+and with a local mirror, debootstrap and kernel installation takes on the
 order of nine minutes (500 to 600 seconds), whereas unpacking the tar
 archive is a lot faster (around 30 seconds). When iterating over
 things other than debootstrap, this speeds things up something

Fix: mount points are directories, not files
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 74469b9..2af42ac 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -127,7 +127,7 @@ have an EFI partition.
         fs-tag: root-fs
 
 The above formats the partition with the ext4 filesystem, and then
-mounts it. The mount point will be a temporary file created by vmdb2,
+mounts it. The mount point will be a temporary directory created by vmdb2,
 and a tag is again given to the mount point so it can be referred to.
 
       - unpack-rootfs: root-fs

Fix: clarify, sentence structure
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 1abe3ab..74469b9 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -93,9 +93,10 @@ you, please do have a look.
 
 A short tutorial: vmdb2 wants you to give it a "specification file"
 (conventionally suffixed .vmdb, because someone stole the .spec
-suffix, but vmdb2 doesn't care about the name). Below is an example
-vmdb2 image specification file are in YAML, since I like YAML, and
-specify a sequence of steps to take to build the image.
+suffix, but vmdb2 doesn't care about the name). Below is an example.
+vmdb2 image specification files are in YAML, since I like YAML, and
+specify a sequence of steps to take to build the image. Each step is a
+tiny piece of self-contained functionality provided by a plugin.
 
     steps:
       - mkimg: "{{ output }}"

Fix: remove extra period
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 80cf0af..1abe3ab 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -93,7 +93,7 @@ you, please do have a look.
 
 A short tutorial: vmdb2 wants you to give it a "specification file"
 (conventionally suffixed .vmdb, because someone stole the .spec
-suffix, but vmdb2 doesn't care about the name). Below is an example.
+suffix, but vmdb2 doesn't care about the name). Below is an example
 vmdb2 image specification file are in YAML, since I like YAML, and
 specify a sequence of steps to take to build the image.
 

Fix: word form
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 92b795b..80cf0af 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -88,7 +88,7 @@ people tell me it doesn't work, it's probably not happening.)
 
 Why would you be interested in vmdb2? There's a lot of other tools to
 do what it does, so perhaps you shouldn't care. That's fine. I like
-write tools for myself. But if this kind of tool is of interest to
+writing tools for myself. But if this kind of tool is of interest to
 you, please do have a look.
 
 A short tutorial: vmdb2 wants you to give it a "specification file"

Fix: wording
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index f4e00f8..92b795b 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -55,7 +55,7 @@ At the Cambridge mini-Debconf of November, 2016, I gave a short
 presentation of what I was going to do. I also posted about my
 [plans] to the debian-cloud list. In short, I would write a new, more
 flexible and cleaner replacement to be called vmdb2. For various
-personal reasons, I've not been able to spend a lot of time on vmdb2
+personal reasons, I've not been able to spend as much time on vmdb2
 as I'd like to, but I've now reached the point where I'd like to
 announce the first alpha version publically.
 

Fix: typo
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 3968037..f4e00f8 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -55,7 +55,7 @@ At the Cambridge mini-Debconf of November, 2016, I gave a short
 presentation of what I was going to do. I also posted about my
 [plans] to the debian-cloud list. In short, I would write a new, more
 flexible and cleaner replacement to be called vmdb2. For various
-personal reaons, I've not been able to spend a lot of time on vmdb2
+personal reasons, I've not been able to spend a lot of time on vmdb2
 as I'd like to, but I've now reached the point where I'd like to
 announce the first alpha version publically.
 

Fix: typo
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index a47be06..3968037 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -52,7 +52,7 @@ to burden a new program with my past mistakes. All new mistakes were
 called for.
 
 At the Cambridge mini-Debconf of November, 2016, I gave a short
-presentation of what I was going to do. I also possted about my
+presentation of what I was going to do. I also posted about my
 [plans] to the debian-cloud list. In short, I would write a new, more
 flexible and cleaner replacement to be called vmdb2. For various
 personal reaons, I've not been able to spend a lot of time on vmdb2

Fix: typo
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index d417ed0..a47be06 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -40,7 +40,7 @@ except if that option is given, do the other thing"), how many black
 box tests do you need to test all the functionality? If one run of the
 program takes half an hour, how long will a full test suite run?
 
-I did some hard thining about vmdebootstrap, and came to the sad
+I did some hard thinking about vmdebootstrap, and came to the sad
 conclusion that it had reached the end of its useful life as a living
 software project. There was no reasonable way to add most of the
 additional functionality people were asking for, and even maintaining

Add: secret identity
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 7ae81ac..d417ed0 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -28,7 +28,12 @@ wasn't very good, and there weren't any tests.
 Neil did heroic work forcing my crappy software into doing things I never
 envisioned. Last year he needed a break and asked me to take
 vmdebootstrap back. I did, and have been hiding from the public eye
-ever since, since I was so ashamed of the code.
+ever since, since I was so ashamed of the code. (I created a new
+identity and pretended to be an international assassin and backup
+specialist, travelling the world forcing people to have at least one
+tested backup of their system. If you've noticed reports in the press
+about people reporting near-death experiences while holding a shiny
+new USB drive, that would've been my fault.)
 
 Pop quiz: if you have a program with ten boolean options ("do this,
 except if that option is given, do the other thing"), how many black

Fix: add missing word
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index 3b00769..7ae81ac 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -25,7 +25,7 @@ who added a ton of new features. Unfortunately, it turned out that my
 initial architecture was not scaleable, and also the code I wrote
 wasn't very good, and there weren't any tests.
 
-Neil did heroic work forcing my crappy software into things I never
+Neil did heroic work forcing my crappy software into doing things I never
 envisioned. Last year he needed a break and asked me to take
 vmdebootstrap back. I did, and have been hiding from the public eye
 ever since, since I was so ashamed of the code.

Fix: add <> around link
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
index d7ef7d6..3b00769 100644
--- a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -2,7 +2,7 @@
 [[!meta date="2017-06-04 15:08"]]
 [[!tag draft vmdb2 vmdebootstrap announcement]]
 
-tl;dr: Get vmdebootstrap replacement from http://git.liw.fi/vmdb2 and
+tl;dr: Get vmdebootstrap replacement from <http://git.liw.fi/vmdb2> and
 run it from the source tree. Tell me if something doesn't work. Send
 patches.
 

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

Publish log entry
diff --git a/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
new file mode 100644
index 0000000..d7ef7d6
--- /dev/null
+++ b/posts/2017/06/04/vmdb2_first_alpha_release_debian_disk_image_creation_tool.mdwn
@@ -0,0 +1,214 @@
+[[!meta title="Vmdb2 first alpha release: Debian disk image creation tool"]]
+[[!meta date="2017-06-04 15:08"]]
+[[!tag draft vmdb2 vmdebootstrap announcement]]
+
+tl;dr: Get vmdebootstrap replacement from http://git.liw.fi/vmdb2 and
+run it from the source tree. Tell me if something doesn't work. Send
+patches.
+
+Many years ago I wrote [vmdebootstrap][], a tool for installing Debian
+on a disk image for virtual machines. I had a clear personal need: I
+was setting up a CI system and it needed six workers: one each for
+Debian oldstable, stable, and unstable, on two architectures (i386,
+amd64). Installing Debian six times in the same way is a lot of work,
+so I figured how difficult can it be to automate it. Turns out that
+not difficult at all, except to install a bootloader.
+
+(Don't ask me why I didn't use any of the other tools for this. It was
+long ago, and while some of the tools that now exist probably did
+exist then, I like writing code and learning things while doing it.)
+
+After a while I was happy with what the program did, but didn't want
+to upload it to Debian, and didn't want to add the kinds of things
+other people wanted, so I turned vmdebootstrap over to Neil Williams,
+who added a ton of new features. Unfortunately, it turned out that my
+initial architecture was not scaleable, and also the code I wrote
+wasn't very good, and there weren't any tests.
+
+Neil did heroic work forcing my crappy software into things I never
+envisioned. Last year he needed a break and asked me to take
+vmdebootstrap back. I did, and have been hiding from the public eye
+ever since, since I was so ashamed of the code.
+
+Pop quiz: if you have a program with ten boolean options ("do this,
+except if that option is given, do the other thing"), how many black
+box tests do you need to test all the functionality? If one run of the
+program takes half an hour, how long will a full test suite run?
+
+I did some hard thining about vmdebootstrap, and came to the sad
+conclusion that it had reached the end of its useful life as a living
+software project. There was no reasonable way to add most of the
+additional functionality people were asking for, and even maintaining
+the current code was too tedious a task to consider seriously. It was
+time to make a clean break of the past and start over, without caring
+about backwards compatibility. After all, the old code wasn't going
+anywhere so anyone who needed it could still use it. There was no need
+to burden a new program with my past mistakes. All new mistakes were
+called for.
+
+At the Cambridge mini-Debconf of November, 2016, I gave a short
+presentation of what I was going to do. I also possted about my
+[plans] to the debian-cloud list. In short, I would write a new, more
+flexible and cleaner replacement to be called vmdb2. For various
+personal reaons, I've not been able to spend a lot of time on vmdb2
+as I'd like to, but I've now reached the point where I'd like to
+announce the first alpha version publically.
+
+The source code is hosted here: http://git.liw.fi/vmdb2 . There are
+.deb packages at my personal public APT repo (http://liw.fi/code/),
+but vmdb2 is easy enough to run directly from a git checkout:
+
+    sudo ./vmdb2 foo.vmdb --output foo.img
+
+There's no need to install it to try it.
+
+What works:
+
+* vmdb2 can build a disk image with Debian installed, for amd64 only
+  at this time
+* the boot loader is GRUB, either for UEFI or BIOS
+* the image boots under Qemu / KVM and also on actual hardware
+
+What doesn't work:
+
+* other architecures, including building for a foreign archiecture
+* live CD building (no squashfs support)
+
+I'm not opposed to adding support for those, but they're not directly
+interesting to me. For example, I only have amd64 machines. The best
+way to get support for additional features is to tell me how,
+preferably in the form of patches. (If I have to read tons of docs, or
+other people's code, and then write code and iterate while other
+people tell me it doesn't work, it's probably not happening.)
+
+Why would you be interested in vmdb2? There's a lot of other tools to
+do what it does, so perhaps you shouldn't care. That's fine. I like
+write tools for myself. But if this kind of tool is of interest to
+you, please do have a look.
+
+A short tutorial: vmdb2 wants you to give it a "specification file"
+(conventionally suffixed .vmdb, because someone stole the .spec
+suffix, but vmdb2 doesn't care about the name). Below is an example.
+vmdb2 image specification file are in YAML, since I like YAML, and
+specify a sequence of steps to take to build the image.
+
+    steps:
+      - mkimg: "{{ output }}"
+        size: 4G
+
+      - mklabel: msdos
+        device: "{{ output }}"
+
+      - mkpart: primary
+        device: "{{ output }}"
+        start: 0%
+        end: 100%
+        part-tag: root-part
+
+The above create an image (name is specified with the --output
+option), which is four gigabytes in size, and create a partitition
+table and a single partition that fills the whole disk. The "tag" is
+given so that later steps can easily refer to the partition.
+
+If you prefer another way to partition the disk, you can achieve that
+by adding more "mkpart" steps. For example, for UEFI you'll want to
+have an EFI partition.
+
+      - mkfs: ext4
+        partition: root-part
+
+      - mount: root-part
+        fs-tag: root-fs
+
+The above formats the partition with the ext4 filesystem, and then
+mounts it. The mount point will be a temporary file created by vmdb2,
+and a tag is again given to the mount point so it can be referred to.
+
+      - unpack-rootfs: root-fs
+
+The above unpacks a tar archive to put content into the filesystem, if
+the tar archive exists. The tar archive is specified with the
+--rootfs-tarball command line option.
+
+      - debootstrap: stretch
+        mirror: http://http.debian.net/debian
+        target: root-fs
+        unless: rootfs_unpacked
+
+      - apt: linux-image-amd64
+        fs-tag: root-fs
+        unless: rootfs_unpacked
+
+      - cache-rootfs: root-fs
+        unless: rootfs_unpacked
+
+The above will run debootstrap and install a kernel into the
+filesystem, but skip doing that if the rootfs tarball was used. Also,
+the tarball is created if it didn't exist. This way the tarball is
+used by all but the first run, which saves a bit of time. On my laptop
+and local mirror, debootstrap and kernel installation takes on the
+order of nine minutes (500 to 600 seconds), whereas unpacking the tar
+archive is a lot faster (around 30 seconds). When iterating over
+things other than debootstrap, this speeds things up something
+wonderful.
+
+The "unless:" mechanism is generic. All the steps share some state,
+and the unpack-rootfs step sets the "rootfs_unpacked" flag in the
+shared state. The "unless:" field tells vmdb2 to check for the flag
+and if it is not set, or if it is set to false ("unless it is set to
+true"), vmdb2 will execute the step. vmdb2 may get more such flags in
+the future, if there's need.
+
+      - chroot: root-fs
+        shell: |
+          sed -i '/^root:[^:]*:/s//root::/' /etc/passwd
+          echo pc-vmdb2 > /etc/hostname
+
+The above executes a couple of shell commands in a chroot of the root
+filesystem we've just created. In this case they remove a login
+password from root, and set the hostname. This is a replacement of the
+vmdebootstrap "customize" script, but it can be inserted anywhere into
+the sequence of steps. There's boot chroot and non-chroot variants of
+the step.
+
+This is a good point to mention that writing customize scripts gets
+quite repetitive and tedious after a while, so vmdb2 has a plugin to
+run Ansible instead. You can customize your image with that instead,
+while the image is beint built and not have to wait until you boot the
+image and running Ansible over ssh.
+
+      - grub: bios
+        root-fs: root-fs
+        root-part: root-part
+        device: "{{ output }}"
+        console: serial
+
+Finally, install a boot loader, grub. This shows the BIOS variant,
+UEFI is also supported. This also configures everything to use a
+serial console. There's a "yarn" (test suite) to build and smoke gtest
+an image with vmdb2 to make sure at least the basic functionality
+works. The smoke test boots the image under Qemu, logs in as root, and
+tells the VM to power off. Very, very basic, but has already found
+actual bugs in vmdb2. The smoke test needs the serial console to work.
+
+As with vmdebootstrap originally, I don't particularly want to

(Diff truncated)
Fix gpg -K output
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index eb199a4..0b9414a 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -400,7 +400,7 @@ $ <b style="color: red">gpg --import subkeys.key</b></code></blockquote>
 $ <b style="color: red">gpg -K</b> <br/>
 /home/liw/.gnupg/pubring.kbx <br/>
 ---------------------------- <br/>
-sec   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
+sec#  rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
 uid           [ultimate] Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
 ssb   rsa4096 2017-05-29 [S] [expires: 2018-05-29] <br/>
@@ -629,3 +629,7 @@ the above.
 * [Riseup.net's OpenPGP best practices](https://riseup.net/en/security/message-security/openpgp/best-practices)
 * [bootc's GnuPG / ssh agent setup](http://www.bootc.net/archives/2013/06/09/my-perfect-gnupg-ssh-agent-setup/)
 * [anarcat's Yubikey NEO howto](https://anarc.at/blog/2015-12-14-yubikey-howto/)
+
+Edited to fix:
+
+* Output of `gpg -K` after removing secret master key.

Publish article
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 223d11d..eb199a4 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -1,6 +1,6 @@
 [[!meta title="Using a Yubikey 4 for ensafening one's encryption"]]
 [[!meta date="2017-05-29 18:03"]]
-[[!tag draft yubikey gpg]]
+[[!tag yubikey gpg]]
 
 [[!toc ]]
 

Add section headers, table of contetns
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index e0d9ff0..223d11d 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -2,6 +2,10 @@
 [[!meta date="2017-05-29 18:03"]]
 [[!tag draft yubikey gpg]]
 
+[[!toc ]]
+
+# Introduction
+
 I've written before about [using a U2F key with PAM][]. This post
 continues the theme and explains how to use a smartcard with GnuPG for
 storing OpenPGP private keys. Specifically, a Yubikey 4 card, because
@@ -28,6 +32,8 @@ versions or between Linux distributions. You will need:
 
 [ChaosKey]: http://altusmetrum.org/ChaosKey/
 
+# Terminology
+
 Some terminology:
 
 * OpenPGP is a standard of encryption keys.
@@ -70,6 +76,8 @@ Some terminology:
   corresponding secret key, so only you can send the random number
   back to the server, and thereby the server knows you're you.
 
+# Outline
+
 The process outline is:
 
 1. Create a new, signing-only master key with GnuPG.
@@ -93,6 +101,8 @@ The process outline is:
 6. Use gpg-agent as your SSH agent, and the authentication-only subkey
    on the Yubikey is used as your ssh key.
 
+# Configure GnuPG
+
 The process in more detail:
 
 * Configure GnuPG with regards to checksum and encryption algorithms.
@@ -108,6 +118,8 @@ The process in more detail:
         personal-cipher-preferences TWOFISH CAMELLIA256 AES 3DES
         keyserver pool.sks-keyservers.net
 
+# Create new keys
+
 * Create new sign-only master key.
 
 <blockquote><code>$ <b style="color: red">gpg --full-generate-key</b> <br/>
@@ -352,6 +364,8 @@ ssb  rsa4096/4477EB0AEF1C440A <br/>
  <br/>
 gpg> <b style="color: red">save</b> </code></blockquote>
 
+# Export secret keys to files, make a backup
+
 * You now have a master key and three subkeys. They are hidden in the
   `~/.gnupg` directory. It is time to "export" the secret keys out
   from there.
@@ -394,6 +408,8 @@ ssb   rsa4096 2017-05-29 [E] [expires: 2018-05-29] <br/>
 ssb   rsa4096 2017-05-29 [A] [expires: 2018-05-29] <br/>
 </code></blockquote>
 
+# Install subkeys on a Yubikey
+
 *  Now insert the Yubikey in a USB slot. We can start transferring the
    secret subkeys to the Yubikey. If you want, you can set your name
    and other information, and change PIN codes. There's several types
@@ -553,6 +569,8 @@ gpg> <b style="color: red">save</b></code></blockquote>
    subkeys on the Yubikey, and will tell you to insert it in a USB
    port if it can't find the key.
 
+# Use subkey on Yubikey as your SSH key
+
 *  To actually use the authentication-only subkey on the Yubikey for
    ssh, you need to configure your system to use gpg-agent as the SSH
    agent. Add the following line to `.gnupg/gpg-agent.conf`:
@@ -603,6 +621,8 @@ gpg> <b style="color: red">save</b></code></blockquote>
 
 *  Happy hacking.
 
+# See also
+
 See also the following links. I've used them to learn enough to write
 the above.
 

Add space before "add comment" footer
diff --git a/style.css b/style.css
index e29e61c..b70b94f 100644
--- a/style.css
+++ b/style.css
@@ -117,6 +117,10 @@ ul li, ol li {
     margin-bottom: 0.5em;
 }
 
+div.addcomment {
+    margin-top: 5em;
+}
+
 div#comments div.feedlink {
     margin-top: 2em;
 }

Typo fixes
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index c9ed2a8..e0d9ff0 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -53,7 +53,7 @@ Some terminology:
   with a single master key.
 
 * Subkeys can be dedicated for encryption, signing, and
-  authantication. You can have one of each.
+  authentication. You can have one of each.
 
 * Encryption is the process of taking a file and making it illegible
   to everyone except the owner of a secret key. When the public key is
@@ -90,7 +90,7 @@ The process outline is:
    (because there's PIN codes or passphrases and getting them wrong
    several times locks up the smartcard).
 
-6. Use gpg-agent as your SSH agent, and the authenticaion-only subkey
+6. Use gpg-agent as your SSH agent, and the authentication-only subkey
    on the Yubikey is used as your ssh key.
 
 The process in more detail:
@@ -176,7 +176,7 @@ uid           [ultimate] Lars Wirzenius (test key) &lt;liw@liw.fi&gt; </code></b
 * You now have the signing-only master key. You should now create
   three subkeys (`keyid` is the key identifier shown in the key
   listing, `A734C10BF2DF39D19DC0F6C025FB738D6EE435F7` above). Use the
-  `--expert` option to be able to add an authenticaion-only subkey.
+  `--expert` option to be able to add an authentication-only subkey.
 
 <blockquote><code>$ <b style="color: red">gpg --edit-key --expert A734C10BF2DF39D19DC0F6C025FB738D6EE435F7z</b> <br/>
 gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
@@ -545,7 +545,7 @@ ssb* rsa4096/4477EB0AEF1C440A <br/>
 gpg> <b style="color: red">save</b></code></blockquote>
 
 *  If you want to use several Yubikeys, or have a spare one just in
-   case, repeate the previous four steps (starting from importing
+   case, repeat the previous four steps (starting from importing
    subkeys back into `~/.gnupg`).
 
 *  You're now done, as far GnuPG use is concerned. Any time you need
@@ -554,13 +554,13 @@ gpg> <b style="color: red">save</b></code></blockquote>
    port if it can't find the key.
 
 *  To actually use the authentication-only subkey on the Yubikey for
-   ssh, you need to configure you systrem to use gpg-agent as the SSH
+   ssh, you need to configure your system to use gpg-agent as the SSH
    agent. Add the following line to `.gnupg/gpg-agent.conf`:
 
         enable-ssh-support
 
 *  On a Debian stretch system with GNOME, edit
-   `/etc/xdg/autostart/gnome-keyring-ssh.desktop` to have the follwing
+   `/etc/xdg/autostart/gnome-keyring-ssh.desktop` to have the following
    line, to prevent the GNOME ssh agent from starting up:
 
         Hidden=true

Tweak line-height to a bit smaller
diff --git a/style.css b/style.css
index 9861834..e29e61c 100644
--- a/style.css
+++ b/style.css
@@ -4,7 +4,7 @@ html {
     margin-left: 3em;
     margin-right: 2em;
     margin-top: 2em;
-    line-height: 150%;
+    line-height: 130%;
 }
 
 table {

Increase line heigh; fix typo
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 5ef1ae0..c9ed2a8 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -3,7 +3,7 @@
 [[!tag draft yubikey gpg]]
 
 I've written before about [using a U2F key with PAM][]. This post
-continue the theme and explains how to use a smartcard with GnuPG for
+continues the theme and explains how to use a smartcard with GnuPG for
 storing OpenPGP private keys. Specifically, a Yubikey 4 card, because
 that's what I have, but any good GnuPG compatible card should work.
 The Yubikey is both a GnuPG compatible smart card, and a U2F card. The
diff --git a/style.css b/style.css
index 73e8bab..9861834 100644
--- a/style.css
+++ b/style.css
@@ -4,6 +4,7 @@ html {
     margin-left: 3em;
     margin-right: 2em;
     margin-top: 2em;
+    line-height: 150%;
 }
 
 table {

Drop a fixme
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 2b5bae2..5ef1ae0 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -13,7 +13,7 @@ handle keys up to 2095 bits.
 [using a U2F key with PAM]: https://blog.liw.fi/posts/u2f-pam/
 
 The reason to do this is to make it harder for an attacker to steal
-your encryption keys. FIXME: Expand on this section.
+your encryption keys.
 
 I will assume you don't already have an OpenPGP key, or are willing to
 generate a new one. I will also assume you run Debian stretch; some of

Add links to ChaosKey
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index fbe2732..2b5bae2 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -26,6 +26,8 @@ versions or between Linux distributions. You will need:
   to generate a lot of entropy for the kernel. Entropy is used by
   GnuPG to create encryption keys.
 
+[ChaosKey]: http://altusmetrum.org/ChaosKey/
+
 Some terminology:
 
 * OpenPGP is a standard of encryption keys.

Add referenece to whte gpg config values come from
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 85d8f1e..fbe2732 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -95,8 +95,9 @@ The process in more detail:
 
 * Configure GnuPG with regards to checksum and encryption algorithms.
   You can use the defaults, but depending on the version of GnuPG you
-  have, they may be weaker than is recommended.
-  FIXME: Give ref to where these come from.
+  have, they may be weaker than is recommended. These values are from
+  Riseup.net OpenPGP guide, see link at the end.
+
   Add the following lines to `~/.gnupg/gpg.conf`:
 
         personal-digest-preferences SHA512

Remove finishs fixme
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index f7e5989..85d8f1e 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -2,10 +2,6 @@
 [[!meta date="2017-05-29 18:03"]]
 [[!tag draft yubikey gpg]]
 
-FIXME: The long terminal session listings need a way to mark up
-(boldface?) the parts the user types, but a code block in markdown
-doesn't allow that.
-
 I've written before about [using a U2F key with PAM][]. This post
 continue the theme and explains how to use a smartcard with GnuPG for
 storing OpenPGP private keys. Specifically, a Yubikey 4 card, because

Add links for more info
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index d77d4d8..f7e5989 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -19,7 +19,10 @@ handle keys up to 2095 bits.
 The reason to do this is to make it harder for an attacker to steal
 your encryption keys. FIXME: Expand on this section.
 
-I will assume you don't already have an OpenPGP key. You will need:
+I will assume you don't already have an OpenPGP key, or are willing to
+generate a new one. I will also assume you run Debian stretch; some of
+the desktop environment setup details may differ between Debian
+versions or between Linux distributions. You will need:
 
 * A Yubikey 4 (or other GnuPG compatible smartcard).
 * Two USB memory sticks to store master copies of the key you create.
@@ -599,4 +602,11 @@ gpg> <b style="color: red">save</b></code></blockquote>
 
 <blockquote><code>$ <b style="color: red">gpg --export-ssh-key keyid > ssh.pub</b></code></blockquote>
 
-*  FIXME: Add notes for how to set up gpg-agent as an ssh-agent.
+*  Happy hacking.
+
+See also the following links. I've used them to learn enough to write
+the above.
+
+* [Riseup.net's OpenPGP best practices](https://riseup.net/en/security/message-security/openpgp/best-practices)
+* [bootc's GnuPG / ssh agent setup](http://www.bootc.net/archives/2013/06/09/my-perfect-gnupg-ssh-agent-setup/)
+* [anarcat's Yubikey NEO howto](https://anarc.at/blog/2015-12-14-yubikey-howto/)

Add note about export auth-only subkey as ssh key
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 8339ae2..d77d4d8 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -593,4 +593,10 @@ gpg> <b style="color: red">save</b></code></blockquote>
 
         4096 SHA256:PDCzyQPpd9tiWsELM8LwaLBsMDMm42J8/eEfezNgnVc cardno:000604626953 (RSA)
 
+*  You need to export the authentication-only subkey in the SSH key
+   format. You need this for adding to `.ssh/authorized_keys`, if
+   nothing else.
+
+<blockquote><code>$ <b style="color: red">gpg --export-ssh-key keyid > ssh.pub</b></code></blockquote>
+
 *  FIXME: Add notes for how to set up gpg-agent as an ssh-agent.

Add notes on how to use gpg-agent as ssh agent
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index c1096d2..8339ae2 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -551,4 +551,46 @@ gpg> <b style="color: red">save</b></code></blockquote>
    subkeys on the Yubikey, and will tell you to insert it in a USB
    port if it can't find the key.
 
+*  To actually use the authentication-only subkey on the Yubikey for
+   ssh, you need to configure you systrem to use gpg-agent as the SSH
+   agent. Add the following line to `.gnupg/gpg-agent.conf`:
+
+        enable-ssh-support
+
+*  On a Debian stretch system with GNOME, edit
+   `/etc/xdg/autostart/gnome-keyring-ssh.desktop` to have the follwing
+   line, to prevent the GNOME ssh agent from starting up:
+
+        Hidden=true
+
+*  Edit `/etc/X11/Xsession.options` and remove or comment out the line
+   that says `use-ssh-agent`. This stops a system-started ssh-agent
+   from being started when the desktop start.
+
+*  Create the file `~/.config/autostart/gpg-agent.desktop` with the
+   following content:
+
+        [Desktop Entry]
+        Type=Application
+        Name=gpg-agent
+        Comment=gpg-agent
+        Exec=/usr/bin/gpg-agent --daemon
+        OnlyShowIn=GNOME;Unity;MATE;
+        X-GNOME-Autostart-Phase=PreDisplayServer
+        X-GNOME-AutoRestart=false
+        X-GNOME-Autostart-Notify=true
+        X-GNOME-Bugzilla-Bugzilla=GNOME
+        X-GNOME-Bugzilla-Product=gnome-keyring
+        X-GNOME-Bugzilla-Component=general
+        X-GNOME-Bugzilla-Version=3.20.0
+
+*  To test, log out, and back in again, run the following in a
+   terminal:
+
+<blockquote><code>$ <b style="color: red">ssh-add -l</b></code></blockquote>
+
+  The output should contain a line that looks like this:
+
+        4096 SHA256:PDCzyQPpd9tiWsELM8LwaLBsMDMm42J8/eEfezNgnVc cardno:000604626953 (RSA)
+
 *  FIXME: Add notes for how to set up gpg-agent as an ssh-agent.

Markup block
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 65415ce..c1096d2 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -408,8 +408,139 @@ $ <b style="color: red">gpg -card-edit</b> <br/>
    not a copy, and the subkeys will be removed from your `~/.gnupg`
    (check with `gpg -K`).
 
-        $ gpg --edit-key keyid
-        ...
+<blockquote><code>$ <b style="color: red">gpg --edit-key liw</b> <br/>
+gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
+This is free software: you are free to change and redistribute it. <br/>
+There is NO WARRANTY, to the extent permitted by law. <br/>
+ <br/>
+Secret key is available. <br/>
+ <br/>
+pub  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+ssb  rsa4096/05F88308DFB71774 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+ssb  rsa4096/2929E8A96CBA57C7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+ssb  rsa4096/4477EB0AEF1C440A <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ <br/>
+gpg> <b style="color: red">key 1</b> <br/>
+ <br/>
+pub  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+ssb* rsa4096/05F88308DFB71774 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+ssb  rsa4096/2929E8A96CBA57C7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+ssb  rsa4096/4477EB0AEF1C440A <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ <br/>
+gpg> <b style="color: red">keytocard</b> <br/>
+Please select where to store the key: <br/>
+   (1) Signature key <br/>
+   (3) Authentication key <br/>
+Your selection? <b style="color: red">1</b> <br/>
+ <br/>
+pub  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+ssb* rsa4096/05F88308DFB71774 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+ssb  rsa4096/2929E8A96CBA57C7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+ssb  rsa4096/4477EB0AEF1C440A <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ <br/>
+gpg> <b style="color: red">key 1</b> <br/>
+ <br/>
+pub  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+ssb  rsa4096/05F88308DFB71774 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+ssb  rsa4096/2929E8A96CBA57C7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+ssb  rsa4096/4477EB0AEF1C440A <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ <br/>
+gpg> <b style="color: red">key 2</b> <br/>
+ <br/>
+pub  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+ssb  rsa4096/05F88308DFB71774 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+ssb* rsa4096/2929E8A96CBA57C7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+ssb  rsa4096/4477EB0AEF1C440A <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ <br/>
+gpg> <b style="color: red">keytocard</b> <br/>
+Please select where to store the key: <br/>
+   (2) Encryption key <br/>
+Your selection? <b style="color: red">2</b> <br/>
+ <br/>
+pub  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+ssb  rsa4096/05F88308DFB71774 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+ssb* rsa4096/2929E8A96CBA57C7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+ssb  rsa4096/4477EB0AEF1C440A <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ <br/>
+gpg> <b style="color: red">key 2</b> <br/>
+ <br/>
+pub  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+ssb  rsa4096/05F88308DFB71774 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+ssb  rsa4096/2929E8A96CBA57C7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+ssb  rsa4096/4477EB0AEF1C440A <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ <br/>
+gpg> <b style="color: red">key 3</b> <br/>
+ <br/>
+pub  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+ssb  rsa4096/05F88308DFB71774 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+ssb  rsa4096/2929E8A96CBA57C7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+ssb* rsa4096/4477EB0AEF1C440A <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ <br/>
+gpg> <b style="color: red">keytocard</b> <br/>
+Please select where to store the key: <br/>
+   (3) Authentication key <br/>
+Your selection? <b style="color: red">3</b> <br/>
+ <br/>
+pub  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+ssb  rsa4096/05F88308DFB71774 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+ssb  rsa4096/2929E8A96CBA57C7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+ssb* rsa4096/4477EB0AEF1C440A <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ <br/>
+gpg> <b style="color: red">save</b></code></blockquote>
 
 *  If you want to use several Yubikeys, or have a spare one just in
    case, repeate the previous four steps (starting from importing

Note --card-edit
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index d811a5b..65415ce 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -398,10 +398,11 @@ ssb   rsa4096 2017-05-29 [A] [expires: 2018-05-29] <br/>
    of PIN codes: normal use, unblocking a locked card, and a third PIN
    code for admin operations. Changing the PIN codes is a good idea,
    otherwise everyone will just try the default of 123456 (admin
-   12345678).
+   12345678). However, I'm skipping that in the interest of brevity.
 
-        $ gpg --card-edit
-        ...
+<blockquote><code>
+$ <b style="color: red">gpg -card-edit</b> <br/>
+...</code></blockquote>
 
 *  Actually move the subkeys to the card. Note that this does a move,
    not a copy, and the subkeys will be removed from your `~/.gnupg`

Continue markin up code blocks
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index ecb2117..d811a5b 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -138,7 +138,7 @@ Real name: <b style="color: red">Lars Wirzenius</b> <br/>
 Email address: <b style="color: red">liw@liw.fi</b> <br/>
 Comment: <b style="color: red">test key</b> <br/>
 You selected this USER-ID: <br/>
-&nbsp;&nbsp;&nbsp;&nbsp;"Lars Wirzenius (test key) <liw@liw.fi>" <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;"Lars Wirzenius (test key) &lt;liw@liw.fi&gt>" <br/>
  <br/>
 Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? <b style="color: red">o</b> <br/>
 We need to generate a lot of random bytes. It is a good idea to perform <br/>
@@ -155,7 +155,7 @@ the command "--edit-key" to generate a subkey for this purpose. <br/>
 pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
-uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockquote>
+uid                      Lars Wirzenius (test key) &lt;liw@liw.fi&gt; </code></blockquote>
 
 * Note that I set a 1-year expiration for they key. The expiration
   can be extended at any time (if you have the master secret key),
@@ -169,7 +169,7 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
 ---------------------------- <br/>
 sec   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>A734C10BF2DF39D19DC0F6C025FB738D6EE435F7</i> <br/>
-uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi> </code></blockquote>
+uid           [ultimate] Lars Wirzenius (test key) &lt;liw@liw.fi&gt; </code></blockquote>
 
 * You now have the signing-only master key. You should now create
   three subkeys (`keyid` is the key identifier shown in the key
@@ -186,7 +186,7 @@ Secret key is available. <br/>
 sec  rsa4096/25FB738D6EE435F7 <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trust: ultimate      validity: ultimate <br/>
-[ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi> <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
  <br/>
 gpg> <b style="color: red">addkey</b> <br/>
 Please select what kind of key you want: <br/>
@@ -224,7 +224,7 @@ sec  rsa4096/25FB738D6EE435F7 <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trust: ultimate      validity: ultimate <br/>
 ssb  rsa4096/05F88308DFB71774 <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
-[ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi> <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
  <br/>
 gpg> <b style="color: red">addkey</b> <br/>
 Please select what kind of key you want: <br/>
@@ -264,7 +264,7 @@ ssb  rsa4096/05F88308DFB71774 <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
 ssb  rsa4096/2929E8A96CBA57C7 <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
-[ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi> <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
  <br/>
 gpg> <b style="color: red">addkey</b> <br/>
 Please select what kind of key you want: <br/>
@@ -346,7 +346,7 @@ ssb  rsa4096/2929E8A96CBA57C7 <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
 ssb  rsa4096/4477EB0AEF1C440A <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: A    <br/>
-[ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi> <br/>
+[ultimate] (1). Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
  <br/>
 gpg> <b style="color: red">save</b> </code></blockquote>
 
@@ -380,15 +380,17 @@ $ <b style="color: red">gpg --import subkeys.key</b></code></blockquote>
    mark, which indicates the key isn't available), and three lines
    starting with `ssb` (no hash mark).
 
-        $ gpg -K
-        /home/liw/.gnupg/pubring.kbx
-        ----------------------------
-        sec   rsa4096 2017-05-29 [SC] [expires: 2018-05-29]
-              A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
-        uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi>
-        ssb   rsa4096 2017-05-29 [S] [expires: 2018-05-29]
-        ssb   rsa4096 2017-05-29 [E] [expires: 2018-05-29]
-        ssb   rsa4096 2017-05-29 [A] [expires: 2018-05-29]
+<blockquote><code>
+$ <b style="color: red">gpg -K</b> <br/>
+/home/liw/.gnupg/pubring.kbx <br/>
+---------------------------- <br/>
+sec   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
+uid           [ultimate] Lars Wirzenius (test key) &lt;liw@liw.fi&gt; <br/>
+ssb   rsa4096 2017-05-29 [S] [expires: 2018-05-29] <br/>
+ssb   rsa4096 2017-05-29 [E] [expires: 2018-05-29] <br/>
+ssb   rsa4096 2017-05-29 [A] [expires: 2018-05-29] <br/>
+</code></blockquote>
 
 *  Now insert the Yubikey in a USB slot. We can start transferring the
    secret subkeys to the Yubikey. If you want, you can set your name

Markup another block
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index afdf1a3..ecb2117 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -372,8 +372,8 @@ $ <b style="color: red">gpg --export-secret-subkeys --armor keyid > subkeys.key<
    deleting the master secret key also removes the secret subkeys. But
    we can import those without importing the master secret key.
 
-        $ gpg --delete-secret-key keyid
-        $ gpg --import subkeys.key
+<blockquote><code>$ <b style="color: red">gpg --delete-secret-key keyid</b><br/>
+$ <b style="color: red">gpg --import subkeys.key</b></code></blockquote>
 
 *  Now verify that you have the secret subkeys, but not the master
    key. There should be one line starting with `sec#` (note the hash

Markup another block
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index c4de4a8..afdf1a3 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -354,8 +354,8 @@ gpg> <b style="color: red">save</b> </code></blockquote>
   `~/.gnupg` directory. It is time to "export" the secret keys out
   from there.
 
-        $ gpg --export-secret-key --armor keyid > master.key
-        $ gpg --export-secret-subkeys --armor keyid > subkeys.key
+<blockquote><code>$ <b style="color: red">gpg --export-secret-key --armor keyid > master.key</b><br/>
+$ <b style="color: red">gpg --export-secret-subkeys --armor keyid > subkeys.key</b></code></blockquote>
 
 *  You should keep these files safe. You don't want to lose them, and
    you don't want anyone else to get access to them. I recommend you

Markup indents
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index aaab34e..c4de4a8 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -184,32 +184,32 @@ There is NO WARRANTY, to the extent permitted by law. <br/>
 Secret key is available. <br/>
  <br/>
 sec  rsa4096/25FB738D6EE435F7 <br/>
-     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
-     trust: ultimate      validity: ultimate <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trust: ultimate      validity: ultimate <br/>
 [ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi> <br/>
  <br/>
 gpg> <b style="color: red">addkey</b> <br/>
 Please select what kind of key you want: <br/>
-   (3) DSA (sign only) <br/>
-   (4) RSA (sign only) <br/>
-   (5) Elgamal (encrypt only) <br/>
-   (6) RSA (encrypt only) <br/>
-   (7) DSA (set your own capabilities) <br/>
-   (8) RSA (set your own capabilities) <br/>
-  (10) ECC (sign only) <br/>
-  (11) ECC (set your own capabilities) <br/>
-  (12) ECC (encrypt only) <br/>
-  (13) Existing key <br/>
+&nbsp;&nbsp;&nbsp;(3) DSA (sign only) <br/>
+&nbsp;&nbsp;&nbsp;(4) RSA (sign only) <br/>
+&nbsp;&nbsp;&nbsp;(5) Elgamal (encrypt only) <br/>
+&nbsp;&nbsp;&nbsp;(6) RSA (encrypt only) <br/>
+&nbsp;&nbsp;&nbsp;(7) DSA (set your own capabilities) <br/>
+&nbsp;&nbsp;&nbsp;(8) RSA (set your own capabilities) <br/>
+&nbsp;&nbsp;(10) ECC (sign only) <br/>
+&nbsp;&nbsp;(11) ECC (set your own capabilities) <br/>
+&nbsp;&nbsp;(12) ECC (encrypt only) <br/>
+&nbsp;&nbsp;(13) Existing key <br/>
 Your selection? <b style="color: red">4</b> <br/>
 RSA keys may be between 1024 and 4096 bits long. <br/>
 What keysize do you want? (2048) <b style="color: red">4096</b> <br/>
 Requested keysize is 4096 bits <br/>
 Please specify how long the key should be valid. <br/>
-         0 = key does not expire <br/>
-      <n>  = key expires in n days <br/>
-      <n>w = key expires in n weeks <br/>
-      <n>m = key expires in n months <br/>
-      <n>y = key expires in n years <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0 = key does not expire <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>  = key expires in n days <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>w = key expires in n weeks <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>m = key expires in n months <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>y = key expires in n years <br/>
 Key is valid for? (0) <b style="color: red">1y</b> <br/>
 Key expires at Tue 29 May 2018 06:44:52 PM EEST <br/>
 Is this correct? (y/N) <b style="color: red">y</b> <br/>
@@ -220,34 +220,34 @@ disks) during the prime generation; this gives the random number <br/>
 generator a better chance to gain enough entropy. <br/>
  <br/>
 sec  rsa4096/25FB738D6EE435F7 <br/>
-     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
-     trust: ultimate      validity: ultimate <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trust: ultimate      validity: ultimate <br/>
 ssb  rsa4096/05F88308DFB71774 <br/>
-     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
 [ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi> <br/>
  <br/>
 gpg> <b style="color: red">addkey</b> <br/>
 Please select what kind of key you want: <br/>
-   (3) DSA (sign only) <br/>
-   (4) RSA (sign only <br/>
-   (5) Elgamal (encrypt only) <br/>
-   (6) RSA (encrypt only) <br/>
-   (7) DSA (set your own capabilities) <br/>
-   (8) RSA (set your own capabilities) <br/>
-  (10) ECC (sign only) <br/>
-  (11) ECC (set your own capabilities) <br/>
-  (12) ECC (encrypt only) <br/>
-  (13) Existing key <br/>
+&nbsp;&nbsp;&nbsp;(3) DSA (sign only) <br/>
+&nbsp;&nbsp;&nbsp;(4) RSA (sign only <br/>
+&nbsp;&nbsp;&nbsp;(5) Elgamal (encrypt only) <br/>
+&nbsp;&nbsp;&nbsp;(6) RSA (encrypt only) <br/>
+&nbsp;&nbsp;&nbsp;(7) DSA (set your own capabilities) <br/>
+&nbsp;&nbsp;&nbsp;(8) RSA (set your own capabilities) <br/>
+&nbsp;&nbsp;(10) ECC (sign only) <br/>
+&nbsp;&nbsp;(11) ECC (set your own capabilities) <br/>
+&nbsp;&nbsp;(12) ECC (encrypt only) <br/>
+&nbsp;&nbsp;(13) Existing key <br/>
 Your selection? <b style="color: red">6</b> <br/>
 RSA keys may be between 1024 and 4096 bits long. <br/>
 What keysize do you want? (2048) <b style="color: red">4096</b> <br/>
 Requested keysize is 4096 bits <br/>
 Please specify how long the key should be valid <br/>
-         0 = key does not expire <br/>
-      <n>  = key expires in n days <br/>
-      <n>w = key expires in n weeks <br/>
-      <n>m = key expires in n months <br/>
-      <n>y = key expires in n years <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0 = key does not expire <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>  = key expires in n days <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>w = key expires in n weeks <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>m = key expires in n months <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>y = key expires in n years <br/>
 Key is valid for? (0) <b style="color: red">1y</b> <br/>
 Key expires at Tue 29 May 2018 06:45:22 PM EEST <br/>
 Is this correct? (y/N) <b style="color: red">y</b> <br/>
@@ -258,76 +258,76 @@ disks) during the prime generation; this gives the random number <br/>
 generator a better chance to gain enough entropy. <br/>
  <br/>
 sec  rsa4096/25FB738D6EE435F7 <br/>
-     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
-     trust: ultimate      validity: ultimate <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trust: ultimate      validity: ultimate <br/>
 ssb  rsa4096/05F88308DFB71774 <br/>
-     created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: S    <br/>
 ssb  rsa4096/2929E8A96CBA57C7 <br/>
-     created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;created: 2017-05-29  expires: 2018-05-29  usage: E    <br/>
 [ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi> <br/>
  <br/>
 gpg> <b style="color: red">addkey</b> <br/>
 Please select what kind of key you want: <br/>
-   (3) DSA (sign only) <br/>
-   (4) RSA (sign only) <br/>
-   (5) Elgamal (encrypt only) <br/>
-   (6) RSA (encrypt only) <br/>
-   (7) DSA (set your own capabilities) <br/>
-   (8) RSA (set your own capabilities) <br/>
-  (10) ECC (sign only) <br/>
-  (11) ECC (set your own capabilities) <br/>
-  (12) ECC (encrypt only) <br/>
-  (13) Existing key <br/>
+&nbsp;&nbsp;&nbsp;(3) DSA (sign only) <br/>
+&nbsp;&nbsp;&nbsp;(4) RSA (sign only) <br/>
+&nbsp;&nbsp;&nbsp;(5) Elgamal (encrypt only) <br/>
+&nbsp;&nbsp;&nbsp;(6) RSA (encrypt only) <br/>
+&nbsp;&nbsp;&nbsp;(7) DSA (set your own capabilities) <br/>
+&nbsp;&nbsp;&nbsp;(8) RSA (set your own capabilities) <br/>
+&nbsp;&nbsp;(10) ECC (sign only) <br/>
+&nbsp;&nbsp;(11) ECC (set your own capabilities) <br/>
+&nbsp;&nbsp;(12) ECC (encrypt only) <br/>
+&nbsp;&nbsp;(13) Existing key <br/>
 Your selection? <b style="color: red">8</b> <br/>
  <br/>
 Possible actions for a RSA key: Sign Encrypt Authenticate  <br/>
 Current allowed actions: Sign Encrypt  <br/>
  <br/>
-   (S) Toggle the sign capability <br/>
-   (E) Toggle the encrypt capability <br/>
-   (A) Toggle the authenticate capability <br/>
-   (Q) Finished <br/>
+&nbsp;&nbsp;&nbsp;(S) Toggle the sign capability <br/>
+&nbsp;&nbsp;&nbsp;(E) Toggle the encrypt capability <br/>
+&nbsp;&nbsp;&nbsp;(A) Toggle the authenticate capability <br/>
+&nbsp;&nbsp;&nbsp;(Q) Finished <br/>
  <br/>
 Your selection? <b style="color: red">a</b> <br/>
  <br/>
 Possible actions for a RSA key: Sign Encrypt Authenticate  <br/>
 Current allowed actions: Sign Encrypt Authenticate  <br/>
  <br/>
-   (S) Toggle the sign capability <br/>
-   (E) Toggle the encrypt capability <br/>
-   (A) Toggle the authenticate capability <br/>
-   (Q) Finished <br/>
+&nbsp;&nbsp;&nbsp;(S) Toggle the sign capability <br/>
+&nbsp;&nbsp;&nbsp;(E) Toggle the encrypt capability <br/>
+&nbsp;&nbsp;&nbsp;(A) Toggle the authenticate capability <br/>
+&nbsp;&nbsp;&nbsp;(Q) Finished <br/>
  <br/>
 Your selection? <b style="color: red">s</b> <br/>
  <br/>
 Possible actions for a RSA key: Sign Encrypt Authenticate  <br/>
 Current allowed actions: Encrypt Authenticate  <br/>
  <br/>
-   (S) Toggle the sign capability <br/>
-   (E) Toggle the encrypt capability <br/>
-   (A) Toggle the authenticate capability <br/>
-   (Q) Finished <br/>
+&nbsp;&nbsp;&nbsp;(S) Toggle the sign capability <br/>
+&nbsp;&nbsp;&nbsp;(E) Toggle the encrypt capability <br/>
+&nbsp;&nbsp;&nbsp;(A) Toggle the authenticate capability <br/>
+&nbsp;&nbsp;&nbsp;(Q) Finished <br/>
  <br/>
 Your selection? <b style="color: red">e</b> <br/>
  <br/>
 Possible actions for a RSA key: Sign Encrypt Authenticate  <br/>
 Current allowed actions: Authenticate  <br/>
  <br/>
-   (S) Toggle the sign capability <br/>
-   (E) Toggle the encrypt capability <br/>
-   (A) Toggle the authenticate capability <br/>
-   (Q) Finished <br/>
+&nbsp;&nbsp;&nbsp;(S) Toggle the sign capability <br/>
+&nbsp;&nbsp;&nbsp;(E) Toggle the encrypt capability <br/>
+&nbsp;&nbsp;&nbsp;(A) Toggle the authenticate capability <br/>
+&nbsp;&nbsp;&nbsp;(Q) Finished <br/>

(Diff truncated)
Markup another block
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 1e739b3..aaab34e 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -176,179 +176,179 @@ uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
   listing, `A734C10BF2DF39D19DC0F6C025FB738D6EE435F7` above). Use the
   `--expert` option to be able to add an authenticaion-only subkey.
 
-        $ gpg --edit-key --expert A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
-        gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc.
-        This is free software: you are free to change and redistribute it.
-        There is NO WARRANTY, to the extent permitted by law.
-        
-        Secret key is available.
-        
-        sec  rsa4096/25FB738D6EE435F7
-             created: 2017-05-29  expires: 2018-05-29  usage: SC  
-             trust: ultimate      validity: ultimate
-        [ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi>
-        
-        gpg> addkey
-        Please select what kind of key you want:
-           (3) DSA (sign only)
-           (4) RSA (sign only)
-           (5) Elgamal (encrypt only)
-           (6) RSA (encrypt only)
-           (7) DSA (set your own capabilities)
-           (8) RSA (set your own capabilities)
-          (10) ECC (sign only)
-          (11) ECC (set your own capabilities)
-          (12) ECC (encrypt only)
-          (13) Existing key
-        Your selection? 4
-        RSA keys may be between 1024 and 4096 bits long.
-        What keysize do you want? (2048) 4096
-        Requested keysize is 4096 bits
-        Please specify how long the key should be valid.
-                 0 = key does not expire
-              <n>  = key expires in n days
-              <n>w = key expires in n weeks
-              <n>m = key expires in n months
-              <n>y = key expires in n years
-        Key is valid for? (0) 1y
-        Key expires at Tue 29 May 2018 06:44:52 PM EEST
-        Is this correct? (y/N) y
-        Really create? (y/N) y
-        We need to generate a lot of random bytes. It is a good idea to perform
-        some other action (type on the keyboard, move the mouse, utilize the
-        disks) during the prime generation; this gives the random number
-        generator a better chance to gain enough entropy.
-        
-        sec  rsa4096/25FB738D6EE435F7
-             created: 2017-05-29  expires: 2018-05-29  usage: SC  
-             trust: ultimate      validity: ultimate
-        ssb  rsa4096/05F88308DFB71774
-             created: 2017-05-29  expires: 2018-05-29  usage: S   
-        [ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi>
-        
-        gpg> addkey
-        Please select what kind of key you want:
-           (3) DSA (sign only)
-           (4) RSA (sign only
-           (5) Elgamal (encrypt only)
-           (6) RSA (encrypt only)
-           (7) DSA (set your own capabilities)
-           (8) RSA (set your own capabilities)
-          (10) ECC (sign only)
-          (11) ECC (set your own capabilities)
-          (12) ECC (encrypt only)
-          (13) Existing key
-        Your selection? 6
-        RSA keys may be between 1024 and 4096 bits long.
-        What keysize do you want? (2048) 4096
-        Requested keysize is 4096 bits
-        Please specify how long the key should be valid
-                 0 = key does not expire
-              <n>  = key expires in n days
-              <n>w = key expires in n weeks
-              <n>m = key expires in n months
-              <n>y = key expires in n years
-        Key is valid for? (0) 1y
-        Key expires at Tue 29 May 2018 06:45:22 PM EEST
-        Is this correct? (y/N) y
-        Really create? (y/N) y
-        We need to generate a lot of random bytes. It is a good idea to perform
-        some other action (type on the keyboard, move the mouse, utilize the
-        disks) during the prime generation; this gives the random number
-        generator a better chance to gain enough entropy.
-        
-        sec  rsa4096/25FB738D6EE435F7
-             created: 2017-05-29  expires: 2018-05-29  usage: SC  
-             trust: ultimate      validity: ultimate
-        ssb  rsa4096/05F88308DFB71774
-             created: 2017-05-29  expires: 2018-05-29  usage: S   
-        ssb  rsa4096/2929E8A96CBA57C7
-             created: 2017-05-29  expires: 2018-05-29  usage: E   
-        [ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi>
-        
-        gpg> addkey
-        Please select what kind of key you want:
-           (3) DSA (sign only)
-           (4) RSA (sign only)
-           (5) Elgamal (encrypt only)
-           (6) RSA (encrypt only)
-           (7) DSA (set your own capabilities)
-           (8) RSA (set your own capabilities)
-          (10) ECC (sign only)
-          (11) ECC (set your own capabilities)
-          (12) ECC (encrypt only)
-          (13) Existing key
-        Your selection? 8
-        
-        Possible actions for a RSA key: Sign Encrypt Authenticate 
-        Current allowed actions: Sign Encrypt 
-        
-           (S) Toggle the sign capability
-           (E) Toggle the encrypt capability
-           (A) Toggle the authenticate capability
-           (Q) Finished
-        
-        Your selection? a
-        
-        Possible actions for a RSA key: Sign Encrypt Authenticate 
-        Current allowed actions: Sign Encrypt Authenticate 
-        
-           (S) Toggle the sign capability
-           (E) Toggle the encrypt capability
-           (A) Toggle the authenticate capability
-           (Q) Finished
-        
-        Your selection? s
-        
-        Possible actions for a RSA key: Sign Encrypt Authenticate 
-        Current allowed actions: Encrypt Authenticate 
-        
-           (S) Toggle the sign capability
-           (E) Toggle the encrypt capability
-           (A) Toggle the authenticate capability
-           (Q) Finished
-        
-        Your selection? e
-        
-        Possible actions for a RSA key: Sign Encrypt Authenticate 
-        Current allowed actions: Authenticate 
-        
-           (S) Toggle the sign capability
-           (E) Toggle the encrypt capability
-           (A) Toggle the authenticate capability
-           (Q) Finished
-        
-        Your selection? q
-        RSA keys may be btween 1024 and 4096 bits long.
-        What keysize do you want? (2048) 4096
-        Requested keysize is 4096 bits
-        Please specify how long the key should be valid.
-                 0 = key does not expire
-              <n>  = key expires in n days
-              <n>w = key expires in n weeks
-              <n>m = key expires in n months
-              <n>y = key expires in n years
-        Key is valid for? (0) 1y
-        Key expires at Tue 29 May 2018 06:45:56 PM EEST
-        Is this correct? (y/N) y
-        Really create? (y/N) y
-        We need to generate a lot of random bytes. It is a good idea to perform
-        some other action (type on the keyboard, move the mouse, utilize the
-        disks) during the prime generation; this gives the random number
-        generator a better chance to gain enough entropy.
-        
-        sec  rsa4096/25FB738D6EE435F7
-             created: 2017-05-29  expires: 2018-05-29  usage: SC  
-             trust: ultimate      validity: ultimate
-        ssb  rsa4096/05F88308DFB71774
-             created: 2017-05-29  expires: 2018-05-29  usage: S   
-        ssb  rsa4096/2929E8A96CBA57C7
-             created: 2017-05-29  expires: 2018-05-29  usage: E   
-        ssb  rsa4096/4477EB0AEF1C440A
-             created: 2017-05-29  expires: 2018-05-29  usage: A   
-        [ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi>
-        
-        gpg> save
+<blockquote><code>$ <b style="color: red">gpg --edit-key --expert A734C10BF2DF39D19DC0F6C025FB738D6EE435F7z</b> <br/>
+gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
+This is free software: you are free to change and redistribute it. <br/>
+There is NO WARRANTY, to the extent permitted by law. <br/>
+ <br/>
+Secret key is available. <br/>
+ <br/>
+sec  rsa4096/25FB738D6EE435F7 <br/>
+     created: 2017-05-29  expires: 2018-05-29  usage: SC   <br/>
+     trust: ultimate      validity: ultimate <br/>
+[ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi> <br/>
+ <br/>
+gpg> <b style="color: red">addkey</b> <br/>
+Please select what kind of key you want: <br/>
+   (3) DSA (sign only) <br/>
+   (4) RSA (sign only) <br/>
+   (5) Elgamal (encrypt only) <br/>
+   (6) RSA (encrypt only) <br/>
+   (7) DSA (set your own capabilities) <br/>

(Diff truncated)
Note what the key id in the example is
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 0c2c31f..1e739b3 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -173,8 +173,8 @@ uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
 
 * You now have the signing-only master key. You should now create
   three subkeys (`keyid` is the key identifier shown in the key
-  listing). Use the `--expert` option to be able to add an
-  authenticaion-only subkey.
+  listing, `A734C10BF2DF39D19DC0F6C025FB738D6EE435F7` above). Use the
+  `--expert` option to be able to add an authenticaion-only subkey.
 
         $ gpg --edit-key --expert A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
         gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc.

Mark key id in italic
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index e671ff5..0c2c31f 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -168,7 +168,7 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
 /home/liw/.gnupg/pubring.kbx <br/>
 ---------------------------- <br/>
 sec   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>A734C10BF2DF39D19DC0F6C025FB738D6EE435F7</i> <br/>
 uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi> </code></blockquote>
 
 * You now have the signing-only master key. You should now create

Fix indentation
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 671202d..e671ff5 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -168,7 +168,7 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
 /home/liw/.gnupg/pubring.kbx <br/>
 ---------------------------- <br/>
 sec   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
-      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
 uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi> </code></blockquote>
 
 * You now have the signing-only master key. You should now create

Markup another code block
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 80e06cd..671202d 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -164,12 +164,12 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
 
 * Review the key:
 
-        $ gpg --list-secret-keys
-        /home/liw/.gnupg/pubring.kbx
-        ----------------------------
-        sec   rsa4096 2017-05-29 [SC] [expires: 2018-05-29]
-              A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
-        uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi>
+<blockquote><code> $ <b style="color: red">gpg --list-secret-keys</b> <br/>
+/home/liw/.gnupg/pubring.kbx <br/>
+---------------------------- <br/>
+sec   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
+      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
+uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi> </code></blockquote>
 
 * You now have the signing-only master key. You should now create
   three subkeys (`keyid` is the key identifier shown in the key

Change markup for list to be bullets, not numbers
Markdown gets the numbering wrong.
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 563656c..80e06cd 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -94,11 +94,11 @@ The process outline is:
 
 The process in more detail:
 
-1. Configure GnuPG with regards to checksum and encryption algorithms.
-   You can use the defaults, but depending on the version of GnuPG you
-   have, they may be weaker than is recommended.
-   FIXME: Give ref to where these come from.
-   Add the following lines to `~/.gnupg/gpg.conf`:
+* Configure GnuPG with regards to checksum and encryption algorithms.
+  You can use the defaults, but depending on the version of GnuPG you
+  have, they may be weaker than is recommended.
+  FIXME: Give ref to where these come from.
+  Add the following lines to `~/.gnupg/gpg.conf`:
 
         personal-digest-preferences SHA512
         cert-digest-algo SHA512
@@ -106,7 +106,7 @@ The process in more detail:
         personal-cipher-preferences TWOFISH CAMELLIA256 AES 3DES
         keyserver pool.sks-keyservers.net
 
-1. Create new sign-only master key.
+* Create new sign-only master key.
 
 <blockquote><code>$ <b style="color: red">gpg --full-generate-key</b> <br/>
 gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
@@ -157,12 +157,12 @@ pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
 uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockquote>
 
-1. Note that I set a 1-year expiration for they key. The expiration
-   can be extended at any time (if you have the master secret key),
-   but unless you do, the key won't accidentally live longer than the
-   chosen time.
+* Note that I set a 1-year expiration for they key. The expiration
+  can be extended at any time (if you have the master secret key),
+  but unless you do, the key won't accidentally live longer than the
+  chosen time.
 
-1. Review the key:
+* Review the key:
 
         $ gpg --list-secret-keys
         /home/liw/.gnupg/pubring.kbx
@@ -171,10 +171,10 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
               A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
         uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi>
 
-1. You now have the signing-only master key. You should now create
-   three subkeys (`keyid` is the key identifier shown in the key
-   listing). Use the `--expert` option to be able to add an
-   authenticaion-only subkey.
+* You now have the signing-only master key. You should now create
+  three subkeys (`keyid` is the key identifier shown in the key
+  listing). Use the `--expert` option to be able to add an
+  authenticaion-only subkey.
 
         $ gpg --edit-key --expert A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
         gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc.
@@ -350,14 +350,14 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
         
         gpg> save
 
-1. You now have a master key and three subkeys. They are hidden in the
-   `~/.gnupg` directory. It is time to "export" the secret keys out
-   from there.
+* You now have a master key and three subkeys. They are hidden in the
+  `~/.gnupg` directory. It is time to "export" the secret keys out
+  from there.
 
         $ gpg --export-secret-key --armor keyid > master.key
         $ gpg --export-secret-subkeys --armor keyid > subkeys.key
 
-1. You should keep these files safe. You don't want to lose them, and
+*  You should keep these files safe. You don't want to lose them, and
    you don't want anyone else to get access to them. I recommend you
    format two USB memory sticks, format them using full-disk
    encryption, and copy the exported files to both of them. Then keep
@@ -366,7 +366,7 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
    There's ways of making this part more sophisticated, but that's for
    another time.
 
-1. The next step involves some hoop-jumping. What we want is to have
+*  The next step involves some hoop-jumping. What we want is to have
    the master secret key NOT on you machine, so we tell GnuPG to
    remove it. We exported it above, so we won't lose it. However,
    deleting the master secret key also removes the secret subkeys. But
@@ -375,7 +375,7 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
         $ gpg --delete-secret-key keyid
         $ gpg --import subkeys.key
 
-1. Now verify that you have the secret subkeys, but not the master
+*  Now verify that you have the secret subkeys, but not the master
    key. There should be one line starting with `sec#` (note the hash
    mark, which indicates the key isn't available), and three lines
    starting with `ssb` (no hash mark).
@@ -390,7 +390,7 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
         ssb   rsa4096 2017-05-29 [E] [expires: 2018-05-29]
         ssb   rsa4096 2017-05-29 [A] [expires: 2018-05-29]
 
-1. Now insert the Yubikey in a USB slot. We can start transferring the
+*  Now insert the Yubikey in a USB slot. We can start transferring the
    secret subkeys to the Yubikey. If you want, you can set your name
    and other information, and change PIN codes. There's several types
    of PIN codes: normal use, unblocking a locked card, and a third PIN
@@ -401,20 +401,20 @@ uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockqu
         $ gpg --card-edit
         ...
 
-1. Actually move the subkeys to the card. Note that this does a move,
+*  Actually move the subkeys to the card. Note that this does a move,
    not a copy, and the subkeys will be removed from your `~/.gnupg`
    (check with `gpg -K`).
 
         $ gpg --edit-key keyid
         ...
 
-1. If you want to use several Yubikeys, or have a spare one just in
+*  If you want to use several Yubikeys, or have a spare one just in
    case, repeate the previous four steps (starting from importing
    subkeys back into `~/.gnupg`).
 
-1. You're now done, as far GnuPG use is concerned. Any time you need
+*  You're now done, as far GnuPG use is concerned. Any time you need
    to sign, encrypt, or decrypt something, GnuPG will look for your
    subkeys on the Yubikey, and will tell you to insert it in a USB
    port if it can't find the key.
 
-1. FIXME: Add notes for how to set up gpg-agent as an ssh-agent.
+*  FIXME: Add notes for how to set up gpg-agent as an ssh-agent.

Fix indents
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index e7e4a19..563656c 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -112,22 +112,22 @@ The process in more detail:
 gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
 This is free software: you are free to change and redistribute it. <br/>
 There is NO WARRANTY, to the extent permitted by law. <br/>
- <br/>
+&nbsp;<br/>
 Please select what kind of key you want: <br/>
-   (1) RSA and RSA (default) <br/>
-   (2) DSA and Elgamal <br/>
-   (3) DSA (sign only) <br/>
-   (4) RSA (sign only) <br/>
+&nbsp;&nbsp;&nbsp;(1) RSA and RSA (default) <br/>
+&nbsp;&nbsp;&nbsp;(2) DSA and Elgamal <br/>
+&nbsp;&nbsp;&nbsp;(3) DSA (sign only) <br/>
+&nbsp;&nbsp;&nbsp;(4) RSA (sign only) <br/>
 Your selection? <b style="color: red">4</b> <br/>
 RSA keys may be between 1024 and 4096 bits long. <br/>
 What keysize do you want? (2048) <b style="color: red">4096</b> <br/>
 Requested keysize is 4096 bits <br/>
 Please specify how long the key should be valid. <br/>
-         0 = key does not expire <br/>
-      <n>  = key expires in n days <br/>
-      <n>w = key expires in n weeks <br/>
-      <n>m = key expires in n months <br/>
-      <n>y = key expires in n years <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0 = key does not expire <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>  = key expires in n days <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>w = key expires in n weeks <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>m = key expires in n months <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<n>y = key expires in n years <br/>
 Key is valid for? (0) <b style="color: red">1y</b> <br/>
 Key expires at Tue 29 May 2018 06:43:54 PM EEST <br/>
 Is this correct? (y/N) <b style="color: red">y</b> <br/>
@@ -138,7 +138,7 @@ Real name: <b style="color: red">Lars Wirzenius</b> <br/>
 Email address: <b style="color: red">liw@liw.fi</b> <br/>
 Comment: <b style="color: red">test key</b> <br/>
 You selected this USER-ID: <br/>
-    "Lars Wirzenius (test key) <liw@liw.fi>" <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;"Lars Wirzenius (test key) <liw@liw.fi>" <br/>
  <br/>
 Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? <b style="color: red">o</b> <br/>
 We need to generate a lot of random bytes. It is a good idea to perform <br/>
@@ -153,8 +153,8 @@ public and secret key created and signed. <br/>
 Note that this key cannot be used for encryption.  You may want to use <br/>
 the command "--edit-key" to generate a subkey for this purpose. <br/>
 pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
-      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
-      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
 uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockquote>
 
 1. Note that I set a 1-year expiration for they key. The expiration

Drop prompt at end
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 8ed84d1..e7e4a19 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -155,9 +155,7 @@ the command "--edit-key" to generate a subkey for this purpose. <br/>
 pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
       A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
       A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
-uid                      Lars Wirzenius (test key) <liw@liw.fi> <br/>
- <br/>
-$</code></blockquote>
+uid                      Lars Wirzenius (test key) <liw@liw.fi> </code></blockquote>
 
 1. Note that I set a 1-year expiration for they key. The expiration
    can be extended at any time (if you have the master secret key),

Add more red to boldface
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index ebd9894..8ed84d1 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -118,9 +118,9 @@ Please select what kind of key you want: <br/>
    (2) DSA and Elgamal <br/>
    (3) DSA (sign only) <br/>
    (4) RSA (sign only) <br/>
-Your selection? <b>4</b> <br/>
+Your selection? <b style="color: red">4</b> <br/>
 RSA keys may be between 1024 and 4096 bits long. <br/>
-What keysize do you want? (2048) <b>4096</b> <br/>
+What keysize do you want? (2048) <b style="color: red">4096</b> <br/>
 Requested keysize is 4096 bits <br/>
 Please specify how long the key should be valid. <br/>
          0 = key does not expire <br/>
@@ -128,19 +128,19 @@ Please specify how long the key should be valid. <br/>
       <n>w = key expires in n weeks <br/>
       <n>m = key expires in n months <br/>
       <n>y = key expires in n years <br/>
-Key is valid for? (0) <b>1y</b> <br/>
+Key is valid for? (0) <b style="color: red">1y</b> <br/>
 Key expires at Tue 29 May 2018 06:43:54 PM EEST <br/>
-Is this correct? (y/N) <b>y</b> <br/>
+Is this correct? (y/N) <b style="color: red">y</b> <br/>
  <br/>
 GnuPG needs to construct a user ID to identify your key. <br/>
  <br/>
-Real name: <b>Lars Wirzenius</b> <br/>
-Email address: <b>liw@liw.fi</b> <br/>
-Comment: <b>test key</b> <br/>
+Real name: <b style="color: red">Lars Wirzenius</b> <br/>
+Email address: <b style="color: red">liw@liw.fi</b> <br/>
+Comment: <b style="color: red">test key</b> <br/>
 You selected this USER-ID: <br/>
     "Lars Wirzenius (test key) <liw@liw.fi>" <br/>
  <br/>
-Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? <b>o</b> <br/>
+Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? <b style="color: red">o</b> <br/>
 We need to generate a lot of random bytes. It is a good idea to perform <br/>
 some other action (type on the keyboard, move the mouse, utilize the <br/>
 disks) during the prime generation; this gives the random number <br/>

Would red work?
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 6a17999..ebd9894 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -108,7 +108,7 @@ The process in more detail:
 
 1. Create new sign-only master key.
 
-<blockquote><code>$ <b>gpg --full-generate-key</b> <br/>
+<blockquote><code>$ <b style="color: red">gpg --full-generate-key</b> <br/>
 gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
 This is free software: you are free to change and redistribute it. <br/>
 There is NO WARRANTY, to the extent permitted by law. <br/>

Markup more as boldface
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index d28b647..6a17999 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -112,15 +112,15 @@ The process in more detail:
 gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
 This is free software: you are free to change and redistribute it. <br/>
 There is NO WARRANTY, to the extent permitted by law. <br/>
-&nbsp; <br/>
+ <br/>
 Please select what kind of key you want: <br/>
    (1) RSA and RSA (default) <br/>
    (2) DSA and Elgamal <br/>
    (3) DSA (sign only) <br/>
    (4) RSA (sign only) <br/>
-Your selection? 4 <br/>
+Your selection? <b>4</b> <br/>
 RSA keys may be between 1024 and 4096 bits long. <br/>
-What keysize do you want? (2048) 4096 <br/>
+What keysize do you want? (2048) <b>4096</b> <br/>
 Requested keysize is 4096 bits <br/>
 Please specify how long the key should be valid. <br/>
          0 = key does not expire <br/>
@@ -128,19 +128,19 @@ Please specify how long the key should be valid. <br/>
       <n>w = key expires in n weeks <br/>
       <n>m = key expires in n months <br/>
       <n>y = key expires in n years <br/>
-Key is valid for? (0) 1y <br/>
+Key is valid for? (0) <b>1y</b> <br/>
 Key expires at Tue 29 May 2018 06:43:54 PM EEST <br/>
-Is this correct? (y/N) y <br/>
+Is this correct? (y/N) <b>y</b> <br/>
  <br/>
 GnuPG needs to construct a user ID to identify your key. <br/>
  <br/>
-Real name: Lars Wirzenius <br/>
-Email address: liw@liw.fi <br/>
-Comment: test key <br/>
+Real name: <b>Lars Wirzenius</b> <br/>
+Email address: <b>liw@liw.fi</b> <br/>
+Comment: <b>test key</b> <br/>
 You selected this USER-ID: <br/>
     "Lars Wirzenius (test key) <liw@liw.fi>" <br/>
  <br/>
-Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o <br/>
+Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? <b>o</b> <br/>
 We need to generate a lot of random bytes. It is a good idea to perform <br/>
 some other action (type on the keyboard, move the mouse, utilize the <br/>
 disks) during the prime generation; this gives the random number <br/>

Add nbsp; to force empty line
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 585805a..d28b647 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -112,7 +112,7 @@ The process in more detail:
 gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
 This is free software: you are free to change and redistribute it. <br/>
 There is NO WARRANTY, to the extent permitted by law. <br/>
- <br/>
+&nbsp; <br/>
 Please select what kind of key you want: <br/>
    (1) RSA and RSA (default) <br/>
    (2) DSA and Elgamal <br/>

Start using boldface to indicate user input
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index eff78c5..585805a 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -108,7 +108,7 @@ The process in more detail:
 
 1. Create new sign-only master key.
 
-<blockquote><code>$ gpg --full-generate-key <br/>
+<blockquote><code>$ <b>gpg --full-generate-key</b> <br/>
 gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
 This is free software: you are free to change and redistribute it. <br/>
 There is NO WARRANTY, to the extent permitted by law. <br/>

Use <code>
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index e4f0307..eff78c5 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -108,7 +108,7 @@ The process in more detail:
 
 1. Create new sign-only master key.
 
-<blockquote>$ gpg --full-generate-key <br/>
+<blockquote><code>$ gpg --full-generate-key <br/>
 gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
 This is free software: you are free to change and redistribute it. <br/>
 There is NO WARRANTY, to the extent permitted by law. <br/>
@@ -157,7 +157,7 @@ pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
       A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
 uid                      Lars Wirzenius (test key) <liw@liw.fi> <br/>
  <br/>
-$</blockquote>
+$</code></blockquote>
 
 1. Note that I set a 1-year expiration for they key. The expiration
    can be extended at any time (if you have the master secret key),

Add <br> to force linebreaks
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index ddb22b9..e4f0307 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -108,55 +108,55 @@ The process in more detail:
 
 1. Create new sign-only master key.
 
-<blockquote>$ gpg --full-generate-key
-gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc.
-This is free software: you are free to change and redistribute it.
-There is NO WARRANTY, to the extent permitted by law.
-
-Please select what kind of key you want:
-   (1) RSA and RSA (default)
-   (2) DSA and Elgamal
-   (3) DSA (sign only)
-   (4) RSA (sign only)
-Your selection? 4
-RSA keys may be between 1024 and 4096 bits long.
-What keysize do you want? (2048) 4096
-Requested keysize is 4096 bits
-Please specify how long the key should be valid.
-         0 = key does not expire
-      <n>  = key expires in n days
-      <n>w = key expires in n weeks
-      <n>m = key expires in n months
-      <n>y = key expires in n years
-Key is valid for? (0) 1y
-Key expires at Tue 29 May 2018 06:43:54 PM EEST
-Is this correct? (y/N) y
-
-GnuPG needs to construct a user ID to identify your key.
-
-Real name: Lars Wirzenius
-Email address: liw@liw.fi
-Comment: test key
-You selected this USER-ID:
-    "Lars Wirzenius (test key) <liw@liw.fi>"
-
-Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
-We need to generate a lot of random bytes. It is a good idea to perform
-some other action (type on the keyboard, move the mouse, utilize the
-disks) during the prime generation; this gives the random number
-generator a better chance to gain enough entropy.
-gpg: key 25FB738D6EE435F7 marked as ultimately trusted
-gpg: directory '/home/liw/.gnupg/openpgp-revocs.d' created
-gpg: revocation certificate stored as '/home/liw/.gnupg/openpgp-revocs.d/A734C10BF2DF39D19DC0F6C025FB738D6EE435F7.rev'
-public and secret key created and signed.
-
-Note that this key cannot be used for encryption.  You may want to use
-the command "--edit-key" to generate a subkey for this purpose.
-pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29]
-      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
-      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
-uid                      Lars Wirzenius (test key) <liw@liw.fi>
-
+<blockquote>$ gpg --full-generate-key <br/>
+gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc. <br/>
+This is free software: you are free to change and redistribute it. <br/>
+There is NO WARRANTY, to the extent permitted by law. <br/>
+ <br/>
+Please select what kind of key you want: <br/>
+   (1) RSA and RSA (default) <br/>
+   (2) DSA and Elgamal <br/>
+   (3) DSA (sign only) <br/>
+   (4) RSA (sign only) <br/>
+Your selection? 4 <br/>
+RSA keys may be between 1024 and 4096 bits long. <br/>
+What keysize do you want? (2048) 4096 <br/>
+Requested keysize is 4096 bits <br/>
+Please specify how long the key should be valid. <br/>
+         0 = key does not expire <br/>
+      <n>  = key expires in n days <br/>
+      <n>w = key expires in n weeks <br/>
+      <n>m = key expires in n months <br/>
+      <n>y = key expires in n years <br/>
+Key is valid for? (0) 1y <br/>
+Key expires at Tue 29 May 2018 06:43:54 PM EEST <br/>
+Is this correct? (y/N) y <br/>
+ <br/>
+GnuPG needs to construct a user ID to identify your key. <br/>
+ <br/>
+Real name: Lars Wirzenius <br/>
+Email address: liw@liw.fi <br/>
+Comment: test key <br/>
+You selected this USER-ID: <br/>
+    "Lars Wirzenius (test key) <liw@liw.fi>" <br/>
+ <br/>
+Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o <br/>
+We need to generate a lot of random bytes. It is a good idea to perform <br/>
+some other action (type on the keyboard, move the mouse, utilize the <br/>
+disks) during the prime generation; this gives the random number <br/>
+generator a better chance to gain enough entropy. <br/>
+gpg: key 25FB738D6EE435F7 marked as ultimately trusted <br/>
+gpg: directory '/home/liw/.gnupg/openpgp-revocs.d' created <br/>
+gpg: revocation certificate stored as '/home/liw/.gnupg/openpgp-revocs.d/A734C10BF2DF39D19DC0F6C025FB738D6EE435F7.rev' <br/>
+public and secret key created and signed. <br/>
+ <br/>
+Note that this key cannot be used for encryption.  You may want to use <br/>
+the command "--edit-key" to generate a subkey for this purpose. <br/>
+pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29] <br/>
+      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
+      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7 <br/>
+uid                      Lars Wirzenius (test key) <liw@liw.fi> <br/>
+ <br/>
 $</blockquote>
 
 1. Note that I set a 1-year expiration for they key. The expiration

Use <blockquote> instead of indent
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index b697ea4..ddb22b9 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -108,56 +108,56 @@ The process in more detail:
 
 1. Create new sign-only master key.
 
-        $ gpg --full-generate-key
-        gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc.
-        This is free software: you are free to change and redistribute it.
-        There is NO WARRANTY, to the extent permitted by law.
-
-        Please select what kind of key you want:
-           (1) RSA and RSA (default)
-           (2) DSA and Elgamal
-           (3) DSA (sign only)
-           (4) RSA (sign only)
-        Your selection? 4
-        RSA keys may be between 1024 and 4096 bits long.
-        What keysize do you want? (2048) 4096
-        Requested keysize is 4096 bits
-        Please specify how long the key should be valid.
-                 0 = key does not expire
-              <n>  = key expires in n days
-              <n>w = key expires in n weeks
-              <n>m = key expires in n months
-              <n>y = key expires in n years
-        Key is valid for? (0) 1y
-        Key expires at Tue 29 May 2018 06:43:54 PM EEST
-        Is this correct? (y/N) y
-
-        GnuPG needs to construct a user ID to identify your key.
-
-        Real name: Lars Wirzenius
-        Email address: liw@liw.fi
-        Comment: test key
-        You selected this USER-ID:
-            "Lars Wirzenius (test key) <liw@liw.fi>"
-
-        Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
-        We need to generate a lot of random bytes. It is a good idea to perform
-        some other action (type on the keyboard, move the mouse, utilize the
-        disks) during the prime generation; this gives the random number
-        generator a better chance to gain enough entropy.
-        gpg: key 25FB738D6EE435F7 marked as ultimately trusted
-        gpg: directory '/home/liw/.gnupg/openpgp-revocs.d' created
-        gpg: revocation certificate stored as '/home/liw/.gnupg/openpgp-revocs.d/A734C10BF2DF39D19DC0F6C025FB738D6EE435F7.rev'
-        public and secret key created and signed.
-
-        Note that this key cannot be used for encryption.  You may want to use
-        the command "--edit-key" to generate a subkey for this purpose.
-        pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29]
-              A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
-              A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
-        uid                      Lars Wirzenius (test key) <liw@liw.fi>
-
-        $ 
+<blockquote>$ gpg --full-generate-key
+gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+Please select what kind of key you want:
+   (1) RSA and RSA (default)
+   (2) DSA and Elgamal
+   (3) DSA (sign only)
+   (4) RSA (sign only)
+Your selection? 4
+RSA keys may be between 1024 and 4096 bits long.
+What keysize do you want? (2048) 4096
+Requested keysize is 4096 bits
+Please specify how long the key should be valid.
+         0 = key does not expire
+      <n>  = key expires in n days
+      <n>w = key expires in n weeks
+      <n>m = key expires in n months
+      <n>y = key expires in n years
+Key is valid for? (0) 1y
+Key expires at Tue 29 May 2018 06:43:54 PM EEST
+Is this correct? (y/N) y
+
+GnuPG needs to construct a user ID to identify your key.
+
+Real name: Lars Wirzenius
+Email address: liw@liw.fi
+Comment: test key
+You selected this USER-ID:
+    "Lars Wirzenius (test key) <liw@liw.fi>"
+
+Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
+We need to generate a lot of random bytes. It is a good idea to perform
+some other action (type on the keyboard, move the mouse, utilize the
+disks) during the prime generation; this gives the random number
+generator a better chance to gain enough entropy.
+gpg: key 25FB738D6EE435F7 marked as ultimately trusted
+gpg: directory '/home/liw/.gnupg/openpgp-revocs.d' created
+gpg: revocation certificate stored as '/home/liw/.gnupg/openpgp-revocs.d/A734C10BF2DF39D19DC0F6C025FB738D6EE435F7.rev'
+public and secret key created and signed.
+
+Note that this key cannot be used for encryption.  You may want to use
+the command "--edit-key" to generate a subkey for this purpose.
+pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29]
+      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
+      A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
+uid                      Lars Wirzenius (test key) <liw@liw.fi>
+
+$</blockquote>
 
 1. Note that I set a 1-year expiration for they key. The expiration
    can be extended at any time (if you have the master secret key),

Add fixme for markup
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 788d402..b697ea4 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -2,6 +2,10 @@
 [[!meta date="2017-05-29 18:03"]]
 [[!tag draft yubikey gpg]]
 
+FIXME: The long terminal session listings need a way to mark up
+(boldface?) the parts the user types, but a code block in markdown
+doesn't allow that.
+
 I've written before about [using a U2F key with PAM][]. This post
 continue the theme and explains how to use a smartcard with GnuPG for
 storing OpenPGP private keys. Specifically, a Yubikey 4 card, because

Start section on why smartcard for gpg
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 609da4e..788d402 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -12,6 +12,9 @@ handle keys up to 2095 bits.
 
 [using a U2F key with PAM]: https://blog.liw.fi/posts/u2f-pam/
 
+The reason to do this is to make it harder for an attacker to steal
+your encryption keys. FIXME: Expand on this section.
+
 I will assume you don't already have an OpenPGP key. You will need:
 
 * A Yubikey 4 (or other GnuPG compatible smartcard).

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

Add tags
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
index 94a78c7..609da4e 100644
--- a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -1,6 +1,6 @@
 [[!meta title="Using a Yubikey 4 for ensafening one's encryption"]]
 [[!meta date="2017-05-29 18:03"]]
-[[!tag ]]
+[[!tag draft yubikey gpg]]
 
 I've written before about [using a U2F key with PAM][]. This post
 continue the theme and explains how to use a smartcard with GnuPG for

Publish log entry
diff --git a/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
new file mode 100644
index 0000000..94a78c7
--- /dev/null
+++ b/posts/2017/05/29/using_a_yubikey_4_for_ensafening_one_s_encryption.mdwn
@@ -0,0 +1,415 @@
+[[!meta title="Using a Yubikey 4 for ensafening one's encryption"]]
+[[!meta date="2017-05-29 18:03"]]
+[[!tag ]]
+
+I've written before about [using a U2F key with PAM][]. This post
+continue the theme and explains how to use a smartcard with GnuPG for
+storing OpenPGP private keys. Specifically, a Yubikey 4 card, because
+that's what I have, but any good GnuPG compatible card should work.
+The Yubikey is both a GnuPG compatible smart card, and a U2F card. The
+Yubikey 4 can handle keys up to 4096 bits. Older Yubikeys can only
+handle keys up to 2095 bits.
+
+[using a U2F key with PAM]: https://blog.liw.fi/posts/u2f-pam/
+
+I will assume you don't already have an OpenPGP key. You will need:
+
+* A Yubikey 4 (or other GnuPG compatible smartcard).
+* Two USB memory sticks to store master copies of the key you create.
+* Either a lot of patience, or a [ChaosKey][] or something else
+  to generate a lot of entropy for the kernel. Entropy is used by
+  GnuPG to create encryption keys.
+
+Some terminology:
+
+* OpenPGP is a standard of encryption keys.
+
+* GnuPG (also known as GPG or gpg) is an encryption program that
+  supports OpenPGP.
+
+* Encryption key or key pair is a secret and a public key for
+  encryption. Key and key pair are often used as synonyms.
+
+* The secret keys is yours, and only you will have it or be able to
+  you use. The public key is public, anyone can have a copy. The two
+  are linked and you can't create a secret key linked to a public key.
+  (If you can, you will become a famous cryptographer. Like Isaac
+  Newton famous among apple growers.)
+
+* Master key is the important thing to keep track of. In the
+  encryption world, the master key is what identifies you.
+
+* A subkey is a secondary key or key pair for encryption, derived from
+  the master key. Subkeys can be created and revoked almost at will,
+  and there can be any number of them. Subkeys are always associated
+  with a single master key.
+
+* Subkeys can be dedicated for encryption, signing, and
+  authantication. You can have one of each.
+
+* Encryption is the process of taking a file and making it illegible
+  to everyone except the owner of a secret key. When the public key is
+  used to encrypt, only the secret key can decrypt.
+
+* Signing is using a secret key to make a separate file that others
+  can verify using the corresponding public key. This means the
+  signer can "prove" they have the file. For example, you might sign
+  emails to prove they came from you.
+
+* Authentication is the process of proving you're you. Typically, for
+  example, a server will know your public key, and will give a large
+  random number encrypted with your public key. Only you have the
+  corresponding secret key, so only you can send the random number
+  back to the server, and thereby the server knows you're you.
+
+The process outline is:
+
+1. Create a new, signing-only master key with GnuPG.
+
+2. Create three "subkeys", one each for encryption, signing, and
+   authentication. These subkeys are what everyone else uses.
+
+3. Export copies of the master key pair and the subkey pairs and put
+   them in a safe place.
+
+4. Put the subkeys on the Yubikey.
+
+5. GnuPG will automatically use the keys from the card. You have to
+   have the card plugged into a USB port for things to work. If
+   someone steals your laptop, they won't get the private subkeys.
+   Even if they steal your Yubikey, they won't get them (the smartcard
+   is physically designed to prevent that), and can't even use them
+   (because there's PIN codes or passphrases and getting them wrong
+   several times locks up the smartcard).
+
+6. Use gpg-agent as your SSH agent, and the authenticaion-only subkey
+   on the Yubikey is used as your ssh key.
+
+The process in more detail:
+
+1. Configure GnuPG with regards to checksum and encryption algorithms.
+   You can use the defaults, but depending on the version of GnuPG you
+   have, they may be weaker than is recommended.
+   FIXME: Give ref to where these come from.
+   Add the following lines to `~/.gnupg/gpg.conf`:
+
+        personal-digest-preferences SHA512
+        cert-digest-algo SHA512
+        default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
+        personal-cipher-preferences TWOFISH CAMELLIA256 AES 3DES
+        keyserver pool.sks-keyservers.net
+
+1. Create new sign-only master key.
+
+        $ gpg --full-generate-key
+        gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc.
+        This is free software: you are free to change and redistribute it.
+        There is NO WARRANTY, to the extent permitted by law.
+
+        Please select what kind of key you want:
+           (1) RSA and RSA (default)
+           (2) DSA and Elgamal
+           (3) DSA (sign only)
+           (4) RSA (sign only)
+        Your selection? 4
+        RSA keys may be between 1024 and 4096 bits long.
+        What keysize do you want? (2048) 4096
+        Requested keysize is 4096 bits
+        Please specify how long the key should be valid.
+                 0 = key does not expire
+              <n>  = key expires in n days
+              <n>w = key expires in n weeks
+              <n>m = key expires in n months
+              <n>y = key expires in n years
+        Key is valid for? (0) 1y
+        Key expires at Tue 29 May 2018 06:43:54 PM EEST
+        Is this correct? (y/N) y
+
+        GnuPG needs to construct a user ID to identify your key.
+
+        Real name: Lars Wirzenius
+        Email address: liw@liw.fi
+        Comment: test key
+        You selected this USER-ID:
+            "Lars Wirzenius (test key) <liw@liw.fi>"
+
+        Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
+        We need to generate a lot of random bytes. It is a good idea to perform
+        some other action (type on the keyboard, move the mouse, utilize the
+        disks) during the prime generation; this gives the random number
+        generator a better chance to gain enough entropy.
+        gpg: key 25FB738D6EE435F7 marked as ultimately trusted
+        gpg: directory '/home/liw/.gnupg/openpgp-revocs.d' created
+        gpg: revocation certificate stored as '/home/liw/.gnupg/openpgp-revocs.d/A734C10BF2DF39D19DC0F6C025FB738D6EE435F7.rev'
+        public and secret key created and signed.
+
+        Note that this key cannot be used for encryption.  You may want to use
+        the command "--edit-key" to generate a subkey for this purpose.
+        pub   rsa4096 2017-05-29 [SC] [expires: 2018-05-29]
+              A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
+              A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
+        uid                      Lars Wirzenius (test key) <liw@liw.fi>
+
+        $ 
+
+1. Note that I set a 1-year expiration for they key. The expiration
+   can be extended at any time (if you have the master secret key),
+   but unless you do, the key won't accidentally live longer than the
+   chosen time.
+
+1. Review the key:
+
+        $ gpg --list-secret-keys
+        /home/liw/.gnupg/pubring.kbx
+        ----------------------------
+        sec   rsa4096 2017-05-29 [SC] [expires: 2018-05-29]
+              A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
+        uid           [ultimate] Lars Wirzenius (test key) <liw@liw.fi>
+
+1. You now have the signing-only master key. You should now create
+   three subkeys (`keyid` is the key identifier shown in the key
+   listing). Use the `--expert` option to be able to add an
+   authenticaion-only subkey.
+
+        $ gpg --edit-key --expert A734C10BF2DF39D19DC0F6C025FB738D6EE435F7
+        gpg (GnuPG) 2.1.18; Copyright (C) 2017 Free Software Foundation, Inc.
+        This is free software: you are free to change and redistribute it.
+        There is NO WARRANTY, to the extent permitted by law.
+        
+        Secret key is available.
+        
+        sec  rsa4096/25FB738D6EE435F7
+             created: 2017-05-29  expires: 2018-05-29  usage: SC  
+             trust: ultimate      validity: ultimate
+        [ultimate] (1). Lars Wirzenius (test key) <liw@liw.fi>
+        
+        gpg> addkey
+        Please select what kind of key you want:
+           (3) DSA (sign only)
+           (4) RSA (sign only)
+           (5) Elgamal (encrypt only)
+           (6) RSA (encrypt only)
+           (7) DSA (set your own capabilities)
+           (8) RSA (set your own capabilities)
+          (10) ECC (sign only)

(Diff truncated)