Web Key Directory is an approach for simple distribution of public PGP keys. The idea is that a mail client checks for a needed key automatically and the user can simply encrypt a mail, without further interaction (no searching on a keyserver or manual downloading and importing into GnuPG).
The first site you find searching for it is GnuPG's WKD wiki page. But – just speaking of me – this page is quite confusing, and setting up WKD seems to be quite complicated. Happily, it isn't ;-)
A nice blog post describes what has to be done when you want to setup WKD. Just in case the linked blog post is removed: Providing PGP keys via WKD using the "direct" method (there's also an "advanced" method I didn't use) strips down to:
Inside the web root of yout HTTP server, create .well-known/openpgpkey/hu/
Touch .well-known/openpgpkey/policy
Find out your key's WKD hash (the letter salad before the @): gpg --with-wkd-hash -k address@your-server.org
Export the key without ASCII-armoring it to a file named like the hash: gpg --export address@your-server.org > a3tboyto3mewxb6wip98xkoepyqqxy94
Put the file in .well-known/openpgpkey/hu/
Finally, you need to tell the HTTP server to deliver the correct MIME type for the key file(s). As usual, the article only contains configuration examples for Apache and nginx. As a lighttpd user, you're used to that ;-)
To make life a bit easier for the lighttpd users out there wanting to setup WKD, here's the snippet you need to make lighttpd deliver the correct MIME type and HTTP headers:
Whilst porting my old graduating class's homepage abi2002amschiller.de to Jekyll, I faced a problem on how to implement the menu. It's a dynamic menu with nested submenus, without a defined level count. The old PHP implementation always showed a "path" which leads to the the currently opened menu, and the actual menu itself.
Doing this in Jekyll/Liquid was a bit tricky. In Jekyll's Navigation Tutorial, one can find a Nested tree navigation with recursion, but this always dumps the whole menu. Not what I wanted. After some research and coding I ended up getting the very menu I had before, with the help of a data file and three scripts partly called recursively, all in pure Liquid. Not too hard, but also not quite trivial.
I publish this stuff as CC0 1.0. Do what you want with it. Here we are:
The menu definition
The data file navigation.yml consists of menu elements with names and links each, and possibly a sub-menu. There's one root element holding the top-level menu. Menus can be nested arbitrarily deep:
The menu itself consists of two unordered lists. One is the "path" to the currently opened menu, the other one is the menu itself. I indented the code here for better readability here. For the output linked below, there's no indentation and empty lines, because I really have a rough time each time I mess with Liquid's white space control for nice HTML output ;-)
Here's the main menu code navigation.html:
<nav id="navigation_path">
<ul>
{% include navigation_path.html menu = site.data.navigation %}
</ul>
</nav>
<nav id="navigation_menu">
<ul>
{% include navigation_find_menu.html menu = site.data.navigation %}
{% unless open_menu %}
{% assign open_menu = site.data.navigation[0].submenu %}
{% endunless %}
{% for item in open_menu %}
{% if page.dir == item.link %}
<li><span>{{ item.name }}</span></li>
{% else %}
<li><a href="{{ item.link }}">{{ item.name }}</a></li>
{% endif %}
{% endfor %}
</ul>
</nav>
Here's navigation_path.html. This one walks along the menu structure and recursively includes itself until the path is built, always passing itself a part of the original menu data:
{% for item in include.menu %}
{% if page.dir contains item.link %}
{% if item.submenu %}
{% if page.dir == item.link %}
<li><span>{{ item.name }}</span></li>
{% else %}
<li><a href="{{ item.link }}">{{ item.name }}</a></li>
{% endif %}
{% endif %}
{% endif %}
{% if item.submenu %}
{% include navigation_path.html menu = item.submenu %}
{% endif %}
{% endfor %}
And here's navigation_find_menu.html, which – also by including itself recursively – finds the currently opened menu. If no open menu is found (because we're on the first level), open_menu stays empty. In this case, site.data.navigation[0].submenu, the top-level submenu of the root element, is displayed by navigation.html.
{% for item in include.menu %}
{% if page.dir == item.link %}
{% if item.submenu %}
{% assign open_menu = item.submenu %}
{% else %}
{% assign open_menu = include.menu %}
{% endif %}
{% endif %}
{% if item.submenu %}
{% include navigation_find_menu.html menu = item.submenu %}
{% endif %}
{% endfor %}
Nach gut 15 Jahren habe ich es – ob man’s glaubt oder nicht – tatsächlich geschafft, nasauber.de zu überarbeiten. Gut, die Seite sieht im Großen und Ganzen noch fast genauso aus wie vorher, aber die Internas erstrahlen in neuem Glanz.
Da der ganze Web-2.0-Kram eh bloß sinnlose Kommentare und zugespammte Gästebücher produziert, gibt es jetzt wieder – wie in den guten, alten Zeiten – eine statische Homepage. Nur statische HTML-Dateien und sonst nix. Generiert von Jekyll.
Als KDE beschlossen hat, man solle jetzt statische Seiten benutzen, die von Jekyll generiert werden, fand ich das zunächst höchst suspekt. Allein schon deswegen, weil Jekyll in Ruby geschrieben ist. Und damit hatte ich bisher nichts zu tun. Nach ein bisschen Einarbeiten habe ich Jekyll aber wirklich liebgewonnen. Ich verwende es mittlerweile auch für muckturnier.org und zahnarzt-selbitz.de. und jetzt eben auch endlich für nasauber.de.
Endlich Schluss mit dem PHP-Kram, den ich noch vor der Währung geschrieben habe ;-)
I recently noticed that this howto was gone due to the "Linux Know How" section being removed some time ago. This one is actually useful though, thus I re-add it as a blog post now.
Virtual users (users with no real account on the system) can be easily set up for vsftpd. We will use PAM's pam_userdb module to authenticate the virtual users.
We need one real user for this to work. I simply used the ftp user, as this one is normally already there and has no shell login anyway. Of course, you can use or create any user you want for this. Set the home directory of this user to the root of the FTP directories we want to serve. E. g.:
usermod -d /srv/ftp ftp
Here we have the relevant part of the /etc/vsftpd/vsftpd.conf I use:
Of course, you are free to add other options, like logging, umask, etc.
The config says it uses vsftpd.virtual to authenticate the virtual users. So let's also create the respective PAM config file /etc/pam.d/vsftpd.virtual:
Notice the reference to /etc/vsftpd/users, not /etc/vsftpd/users.db (which will be the actual filename used). We append crypt=crypt to indicate we want to use crypted passwords (nobody wants to store clear text passwords, does anybody?).
Finally, we need to add one or more virtual users to the userdb. I wrote a script called userdbadm to do this in an easy way. Of course, you can create the database in whatever way you want to. When using userdbadm, it's something like:
userdbadm /etc/vsftpd/users.db add virtual_user
Notice the .db here! You will be prompted for a password. The user and the salted crypted password will be stored in the database.
Finally, the virtual user needs a home directory which will be served by vsftpd when the user logs in. It has to be owned by the real user vsftpd uses. For the above example, we simply do