Fight­ing the Coro­n­avirus with FreeB­SD (Folding@Home)

Pho­to by Fusion Med­ical Ani­ma­tion on Unsplash

Here is a quick HOWTO for those which want to pro­vide some FreeB­SD based com­pute resources to help find­ing vac­cines. I have not made a port out of this and do not know yet if I get the time to make one. If some­one wants to make a port, go ahead, do not wait for me.

UPDATE 2020-03-22: 0mp@ made a port out of this, it is in “biology/lin­ux-foldin­gath­ome”.

  • Down­load the lin­ux RPM of the Folding@Home client (this cov­ers fah­client only).
  • Enable the lin­ux­u­la­tor (ker­nel moduls and linux_base (first part of chap­ter 10.2) is enough).
  • Make sure linprocfs/linsysfs are mount­ed in /com­pat/lin­ux/{proc|sys}.
  • cd /compat/linux
  • tar -xf /path/to/fahclient....rpm
  • add the “fah­client” user (give it a real home direc­to­ry)
  • make sure there is no /compat/linux/dev or alter­na­tive­ly mount devfs there
  • mkdir /compat/linux/etc/fahclient
  • cp /compat/linux/usr/share/doc/fahclient/sample-config.xml /compat/linux/etc/fahclient/config.xml
  • chown -R fahclient /compat/linux/etc/fahclient
  • edit /compat/linux/fahclient/config.xml: mod­i­fy user (manda­to­ry) / team (option­al: FreeB­SD team is 11743) / passkey (option­al) as appro­pri­ate (if you want to con­trol the client remote­ly, you need to mod­i­fy some more parts, but some­how the client “los­es” a filedescrip­tor and stops work­ing as it should if you do that on FreeB­SD)
  • If you have the home direc­to­ries of the users as no-exec (e.g. seper­ate ZFS datasets with exec=off): make sure the home direc­to­ry of the fah­client user has exec per­mis­sions enabled
  • cd ~fahclient (impor­tant! it tries to write to the cur­rent work direc­to­ry when you start it)
  • Start it: /usr/sbin/daemon /compat/linux/usr/bin/FAHClient /compat/linux/etc/fahclient/config.xml --run-as fahclient --pid-file=/var/run/ >/dev/null 2>&1

Per default it will now pick up some SARS-CoV‑2 (COVID-19) relat­ed fold­ing tasks. There are some more con­fig options (e.g. how much of the sys­tem resources are used). Please refer to the offi­cial Folding@Home site for more infor­ma­tion about that. Be also aware that there is a big rise in com­pute resources donat­ed to Folding@Home, so the pool of avail­able work units may be emp­ty from time to time, but they are work­ing on adding more work units. Be patient.

Send to Kin­dle

iocage: HOWTO cre­ate a base­jail from src (instead of from an offi­cial release)


So far I have used ezjail to man­age FreeB­SD jails. I use jails since years to have dif­fer­ent parts of a soft­ware stack in some kind of a con­tain­er (in a ZFS dataset for the filesys­tem side of the con­tain­er). On one hand to not let depen­den­cies of one part of the soft­ware stack have influ­ence of oth­er parts of the soft­ware stack. On the oth­er hand to have the pos­si­bil­i­ty to move parts of the soft­ware stack to a dif­fer­ent sys­tem if nec­es­sary. Nor­mal­ly I run -sta­ble or -cur­rent or more gen­er­al­ly speak­ing, a self-compiled FreeB­SD on those sys­tems. In ezjail I like the fact that all jails on a sys­tem have one com­mon base­jail under­ly­ing, so that I update one place for the user­land and all jails get the updat­ed code.

Since a while I heard good things about iocage and how it inte­grates ZFS, so I decid­ed to give it a try myself. As iocage does not come with an offi­cial way of cre­at­ing a base­jail (respec­tive­ly a release) from a self-compiled FreeB­SD (at least doc­u­ment­ed in those places I looked, and yes, I am aware that I can cre­ate a FreeB­SD release myself and use it, but I do not like to have to cre­ate a release addi­tion­al­ly to the build­world I use to update the host sys­tem) here now the short HOWTO achieve this.


In the fol­low­ing I assume the iocage ZFS parts are already cre­at­ed in dataset ${POOLNAME}/iocage which is mount­ed on ${IOCAGE_BASE}/iocage. Addi­tion­al­ly the build­world in /usr/src (or wher­ev­er you have the FreeB­SD source) should be fin­ished.


To have the nec­es­sary dataset-infrastructure cre­at­ed for own basejails/releases, at least one offi­cial release needs to be fetched before. So run the com­mand below (if there is no ${IOCAGE_BASE}/iocage/releases direc­to­ry) and fol­low the on-screen instruc­tions.

iocage fetch


Some vari­ables:

SRC_REV=r$(cd /usr/src; svnliteversion)

Cre­at­ing the iocage basejail-datasets for this ${SRC_REV}:

zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/bin
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/boot
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/lib
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/libexec
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/rescue
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/sbin
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/bin
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/include
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/lib
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/lib32
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/libdata
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/libexec
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/sbin
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/share
zfs create -o compression=lz4 ${POOLNAME}/iocage/base/${SRC_REV}-RELEASE/root/usr/src

Install from /usr/src (the exe­cutable “chown” is hardlinked across an iocage base­jail dataset bound­ary, this fails in the nor­mal install­world, so we have to ignore this error and install a copy of the chown bina­ry to the place where the hardlink nor­mal­ly is):

cd /usr/src
make -i installworld DESTDIR=${IOCAGE_BASE}/iocage/base/${SRC_REV}-RELEASE/root >&! iocage_installworld_base.log
cp -pv ${IOCAGE_BASE}/iocage/base/${SRC_REV}-RELEASE/root/usr/sbin/chown ${IOCAGE_BASE}/iocage/base/${SRC_REV}-RELEASE/root/usr/bin/chgrp
make distribution DESTDIR=${IOCAGE_BASE}/iocage/base/${SRC_REV}-RELEASE/root >>& iocage_installworld_base.log

While we are here, also cre­ate a release and not only a base­jail:

zfs create -o compression=lz4 ${POOLNAME}/iocage/releases/${SRC_REV}-RELEASE
zfs create -o compression=lz4 ${POOLNAME}/iocage/releases/${SRC_REV}-RELEASE/root
make installworld DESTDIR=${IOCAGE_BASE}/iocage/releases/${SRC_REV}-RELEASE/root >&! iocage_installworld_release.log
make distribution DESTDIR=${IOCAGE_BASE}/iocage/releases/${SRC_REV}-RELEASE/root >>& iocage_installworld_release.log

And final­ly make this the default release which iocage uses when cre­at­ing new jails (this is option­al):

iocage set release=${SRC_REV}-RELEASE default

Now the self-build FreeB­SD is avail­able in iocage for new jails.

Send to Kin­dle

Tran­si­tion to nginx: part 4 – CGI scripts

I still have some CGI scripts on this web­site. They still work, and they are good enough for my needs. When I switched this web­site to nginx (the word­press set­up was a lit­tle bit more com­plex than what I wrote in part 1, part 2 and part 3… the con­fig will be one of my next blog posts) I was a lit­tle bit puz­zled how to do that with nginx. It took me some min­utes to get an idea how to do it and to find the right FreeB­SD port for this.

  • Install www/fcgiwrap
  • Add the fol­low­ing to rc.conf:


  • Run “ser­vice fcgi­wrap start”
  • Add the fol­low­ing to your nginx con­fig:
location ^~ /cgi-bin/ {
    gzip off; #gzip makes scripts feel slower since they have to complete before getting gzipped
    fastcgi_pass  unix:/var/run/fcgiwrap/fcgiwrap.sock;
    fastcgi_index index.cgi;
    fastcgi_param SCRIPT_FILENAME /path/to/location$fastcgi_script_name;
    fastcgi_param GATEWAY_INTERFACE  CGI/1.1;

Send to Kin­dle

Tran­si­tion to nginx: part 3 — short and easy con­fig snip­pets

After some medium-difficoulty tran­si­tions in part 1 and part 2, here some easy ones:

php­MyAd­min: take the basics from one of the two oth­er blog posts (see above) with­out loca­tion direc­tives. For “loca­tion /” set the doc­u­ment root and copy the “loca­tion ~ \.php” from the con­fig of one of the parts above. Done.

TT-RSS: take the con­fig like for php­MyAd­min and add (assum­ing it is in the root of the serv­er, else you have to add the path in the front of the loca­tion)

location ^~ /(utils|templates|schema|cache|lock|locale|classes) {
     deny all;

Allow client-side caching for sta­t­ic con­tent:

location ~* \.(?:jpe?g|gif|png|ico|cur|gz|bz2|xz|tbz|tgz|txz|svg|svgz|mp4|ogg|ogv|webm|htc|css|js|
pdf|zip|rar|tar|txt|conf)$ {
    try_files $uri =404;

    expires 1w;     # If you are not a big site,

                    # and don't change static content often,

                    # 1 week is not bad.
    access_log off; # If you don't need the logs
    add_header Cache-Control "public";

Secu­ri­ty: Despite the fact that the docs I’ve read tell that no-SSLv3 is the default, the first set­ting makes a dif­fer­ence (test­ed via SSLlabs’ SSLtest).

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # No SSLv 2/3
ssl_dhparam /path/to/dhparams.pem;   # generate via "openssl dhparam -out /path/to/dhparams.pem 2048"


Send to Kin­dle

Tran­si­tion to nginx: part 2 – con­vert­ing a gallery v2 instal­la­tion

In my first tran­si­tion to nginx I wrote that I was hap­py about the speed increase I got for my Horde web­mail set­up. After­wards I con­vert­ed a Gallery v2 instal­la­tion (yes, old, not under active devel­op­ment any­more, but inter­nal and still work­ing). There I have not seen any obvi­ous speed dif­fer­ence.

I did not con­vert all .htac­cess rewrite rules, the one for the “easy and beau­ti­ful” URL names was too com­plex for the con­vert­er for rewrite I found. As it is just for inter­nal use, I just switched back to the not so nice “tech­ni­cal” URL names.

The impor­tant part of the apache 2.2 instal­la­tion:

ExpiresActive On
ExpiresDefault "now plus 1 hour"
ExpiresByType image/* "now plus 1 month"
ExpiresByType text/javascript "now plus 1 month"
ExpiresByType application/x-javascript "now plus 1 month"
ExpiresByType text/css "now plus 1 month"

<Location />
# Insert filter
SetOutputFilter DEFLATE

# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html

# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip

# MSIE masquerades as Netscape, but it is fine
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# Don't compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|gz|bz2|zip|pdf)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary

The nginx con­fig:

worker_processes  1;

error_log  <filename>;

events {
        worker_connections      1024;
        use                     kqueue;

http {
    include       mime.types;
    default_type  application/octet-stream;

    access_log  <filename>;

    sendfile    on;

        keepalive_timeout       15;
        client_body_timeout     300;
        client_header_timeout   12;
        send_timeout            300;
        client_body_in_file_only clean;
        client_body_buffer_size 128k;
        client_max_body_size 40M;

        gzip on;
        gzip_min_length 1000;
        gzip_types       text/plain text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript;
        gzip_disable     "msie6";

        include blacklist.conf;

    server {
        listen       80;
        server_name  <hostname>;

        add_header   x-frame-options            "sameorigin";
        add_header   x-xss-protection           "1; mode=block";
        add_header   x-content-type-options     "nosniff";

        charset utf-8;

        #access_log  logs/host.access.log  main;
        if ($bad_client) { return 403; }

        location / {
            root   /usr/local/www/gallery2;
            index  index.php;
                location ~ \.php {
                        # Zero-day exploit defense.
                        # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
                        # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
                        try_files $uri =404;

                        fastcgi_split_path_info ^(.+\.php)(/.+)$;
                        fastcgi_keep_conn       on;
                        fastcgi_index      index.php;
                        include          fastcgi_params;
                        fastcgi_param      SCRIPT_FILENAME $document_root$fastcgi_script_name;
                        fastcgi_pass        unix:/var/run/php.fcgi;

        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/local/www/nginx-dist;

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        location ~ /\.ht {
            deny  all;
        location ~ \.(inc|class)$ {
                deny all;
        location ^~ /lib/tools/po/ {
                deny all;
Send to Kin­dle