Here are some notes on how to setup the main server after you've installed Debian and the usual server packages.

Basic setup

  • Install Debian and tweak a few things
  • Install rssh and uncomment allowrsync in /etc/rssh.conf
  • Setup appropriate mail aliases

    • Add these to /etc/aliases

      root: francois
      www-data: root
      libravatar-master: root
    • Run newaliases to update /etc/aliases.db

    • Test the aliases by running mail root
  • Ensure that the only entry for localhost in /etc/hosts is for (if you leave the one for ::1, it will confuse gearman)

  • Copy the local logcheck rules from the old server and add the following to /etc/logcheck/logcheck.logfiles:



  • In /etc/network/iptables.up.rules, put the following:

    # Set default policies
    :INPUT DROP [0:0]
    :FORWARD DROP [0:0]
    :OUTPUT DROP [0:0]
    # Allow unlimited outbound traffic
    # Annoying attack bots
    -A INPUT -s -j DROP
    # Accept all other traffic
  • Enable the rules using iptables-apply

  • In /etc/network/ip6tables.up.rules, put the following:

    # Set default policies
    :INPUT DROP [0:0]
    :FORWARD DROP [0:0]
    :OUTPUT DROP [0:0]
    # Allow unlimited outbound traffic
    # Allow unlimited traffic on the loopback interface
    -A INPUT -i lo -j ACCEPT
    # TODO: ban attackers!
    # Accept all other traffic
  • Enable the rules using ip6tables-apply

  • Set something like this in /etc/network/interfaces:

    auto eth0
    iface eth0 inet static
        address x.x.x.x
        gateway x.x.x.x
        pre-up iptables-restore /etc/network/iptables.up.rules
    iface eth0 inet6 static
        address x::x
        netmask 64
        gateway x::x
        pre-up ip6tables-restore /etc/network/ip6tables.up.rules


  • Install Postgres:

    • In /etc/postgresql/*/main/pg_hba.conf, change all local connections to trust
    • In /etc/postgresql/*/main/postgresql.conf, set these:

      log_min_duration_statement =  1000
      ssl = off
    • Create postgres users:

      sudo -u postgres createuser -s francois
      createuser -s root
      createuser -S -R -D djangouser
  • Install pgbouncer

    apt install pgbouncer
    • Turn it on in /etc/default/pgbouncer

    • Put the following in /etc/pgbouncer/pgbouncer.ini:

      libravatar = dbname=libravatar
      admin_users = postgres
    • Put the following in /etc/pgbouncer/userlist.txt:

      "djangouser" ""
      "postgres" ""
    • Restart the daemon:

      systemctl restart pgbouncer

Web server

  • Create a global TLS configuration in /etc/apache2/conf-available/tls.conf:

    SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
    SSLHonorCipherOrder     on
    SSLCompression          off
    SSLUseStapling          on
    SSLStaplingResponderTimeout 5
    SSLStaplingReturnResponderErrors off
    SSLStaplingCache        shmcb:/var/run/ocsp(128000)
  • Enable TLS and mod_rewrite:

    a2enconf tls
    a2enmod ssl
    a2enmod rewrite
  • Setup some Apache vhosts:

    • /etc/apache2/sites-enabled/000-default:

      <VirtualHost *:80>
          RewriteEngine On
          RewriteRule ^ [redirect=301,last]
    • /etc/apache2/sites-enabled/default-ssl:

      <VirtualHost *:443>
          SSLEngine on
          SSLCertificateFile /etc/libravatar/www.crt
          SSLCertificateKeyFile /etc/libravatar/www.pem
          SSLCertificateChainFile /etc/libravatar/www-chain.pem
          RewriteEngine On
          RewriteRule ^ [redirect=301,last]
    • /etc/apache2/sites-available/stats:

      <VirtualHost *:443>
          DocumentRoot /var/cache/awstats
          Alias /awstats-icon/ /usr/share/awstats/icon/
          Alias /favicon.ico /usr/share/libravatar/libravatar/favicon.ico
          SSLEngine on
          SSLCertificateFile /etc/libravatar/stats.crt
          SSLCertificateKeyFile /etc/libravatar/stats.pem
          SSLCertificateChainFile /etc/libravatar/stats-chain.pem
          Header add Strict-Transport-Security: "max-age=15768000"
          <Location />
              AuthType Basic
              AuthName "Libravatar Stats"
              AuthUserFile /etc/apache2/stats.passwd
              Require valid-user
              Order allow,deny
              allow from all
              Options +indexes
  • Copy the stats password file (/etc/apache2/stats.passwd).

  • Enable the new vhost:

    a2ensite default-ssl
    a2ensite stats
  • Copy seccdn SSL certs in /etc/libravatar/ from the old server.

  • Install certbot and then create two separate certs:

    systemctl stop apache2
    certbot certonly -d -d -d
    certbot certonly -d
    systemctl start apache2
  • Symlink the letsencrypt certs in the right place:

    cd /etc/libravatar/
    ln -s ../letsencrypt/ stats.pem
    ln -s ../letsencrypt/ stats.crt
    ln -s ../letsencrypt/ stats-chain.pem
    ln -s ../letsencrypt/ www.pem
    ln -s ../letsencrypt/ www.crt
    ln -s ../letsencrypt/ www-chain.pem
  • Install a cronjob to automatically renew these certs in /etc/cron.daily/certbot-renew-libravatar:

    /usr/bin/certbot renew --quiet --pre-hook "/bin/systemctl stop apache2.service" --post-hook "/bin/systemctl start apache2.service"
    pushd /etc/ > /dev/null
    /usr/bin/git add letsencrypt
    DIFFSTAT="$(/usr/bin/git diff --cached --stat)"
    if [ -n "$DIFFSTAT" ] ; then
        /usr/bin/git commit --quiet -m "Renewed letsencrypt certs"
        echo "$DIFFSTAT"
    popd > /dev/null
  • Install awstats and add this to /etc/awstats/awstats.conf.local:



  • Add this script to /usr/local/sbin/libravatar_backups:

    # Perform fresh backup
    DUMP_FILE="$DUMP_DIR/`date +%Y%m%dT%H%M%S`.pg"
    pg_dump -Fc libravatar > $DUMP_FILE
    chmod 600 $DUMP_FILE
    # Encrypt backup
    gpg --recipient 007c98d1 --encrypt $DUMP_FILE
    rm $DUMP_FILE
    # Purge old backups
    find $DUMP_DIR -ctime +7 -delete
  • Create an empty /var/backups/libravatar directory

  • Install duplicity (apt install duplicity)
  • Add my duplicity backup script to /home/francois/.backup/ and update:
    • GPG passhrase
    • Destination directory (which includes the hostname)
  • Create this cronjob in /etc/cron.d/libravatar_backups:

    # Local DB backups
    4 1,13 * * *       root    ionice -c3 nice -n10 /usr/local/sbin/libravatar_backups
    # Full backups to Amazon S3
    6 14 * * *      root    /home/francois/.backup/backup-selfoss
    6 23 * * 3      root    /home/francois/.backup/backup-selfoss --full
  • Run an initial backup:

    sudo /home/francois/.backup/backup-selfoss

Install application

  • Install Libravatar packages

    • Start by installing the apt-transport-https package
    • Add the Libravatar repository to /etc/apt/sources.list:

      deb jessie main
    • Then install server packages:

      apt update
      apt install libravatar{,-common,-cdn,-cdn-common,-deployment,-www,-master}
    • Use 6432 for the database port number, otherwise accept all of the defaults

  • Install gearman-job-server:

    apt install --no-install-recommends gearman-job-server

Git mirrors

  • Install hg:

    apt install mercurial
  • Enable the convert mercurial extension by putting this in /etc/mercurial/hgrc:

    convert =
  • Add this script in /usr/local/bin/git-mirror:

    cd $DIR/git
    git fetch --quiet origin 2> /dev/null
    git reset --quiet --hard origin/master
    git push --quiet github master 2> /dev/null
    exit 0
  • Add this script in /usr/local/bin/hg-mirror:

    cd $DIR/git
    git fetch --quiet origin 2> /dev/null
    git reset --quiet --hard origin/master
    cd $DIR
    hg --quiet convert git libravatar-hg
    cd $DIR/libravatar-hg
    hg --quiet update
    hg --quiet push ssh:// 2> /dev/null
    exit 0
  • Add this to /home/francois/.ssh/config:

      User hg
      IdentityFile ~/.ssh/repository_mirrors
      User git
      IdentityFile ~/.ssh/repository_mirrors
      AddressFamily inet
  • Copy repository_mirrors ssh key from old server into /home/francois/.ssh/

  • Create directory for mercurial mirror: mkdir -p /home/francois/git-mirrors/libravatar-hg
  • Prepare directory for git repository:

    cd /home/francois/git-mirrors/
    git clone git
    cd git
    git remote add github
  • Create the following cron jobs in /etc/cron.d/libravatar_git-mirrors:

    50 * * * *      francois        /usr/local/bin/git-mirror
    55 * * * *      francois        /usr/local/bin/hg-mirror

From the old server

If migrating from one server to another:

  • Setup the database

    • Get a DB dump from the old server:

      pg_dump -Fc libravatar >
    • Create a new database:

      createdb -O djangouser -E utf8 libravatar
    • Restore the database:

      pg_restore -d libravatar <
  • Copy the contents of /var/lib/libravatar/ from the old server and fix the file permissions:

    chown -R root:root /var/lib/libravatar/avatar/* /var/lib/libravatar/user/*