with apologies

Hosting HotCRP

Richard Mortier · October 17, 2021 · #old #linux #academic #publishing

I once had cause to setup HotCRP for local hosting. Specifically on a local Lab-hosted VM image. Some of what follows is specific to the CUCL VM hosting service, but I think most of it is HotCRP generic and so may be of use. Anyway, here’s the crib sheet, starting from https://mbtech.github.io/Setting-up-hotcrp/

# setup some variables
YOUR-DOMAIN="hotcrp-test.cl.cam.ac.uk"
YOUR-WORKSHOP="sysws18"
YOUR-PASSWORD="mybestpassword"
YOUR-EMAIL="postmaster@example.com"

Lab specifics

Assume we start from a default Ubuntu template VM, and then…

  1. Configure the VM
cl-asuser passwd # set UNIX password for sudo

# create some space
for d in /usr/src/* ; do
    export K=$(uname -r | sed 's/-generic$//')
    echo -n $K $d ...
    case $d in
        "/usr/src/linux-headers-$K" | "/usr/src/linux-headers-${K}-generic" )
            echo keep
            ;;
        * )
            echo remove
            sudo rm -rf $d
            ;;
    esac
done

# THIS IS UNSAFE! BE CAREFUL! IT CALLS `sudo rm -rf`!
for d in /lib/modules/* ; do
    echo $d ...
    case $d in
        "/lib/modules/$(uname -r)" )
            echo keep
            ;;
        * )
            echo remove
            sudo rm -rf $d
            ;;
    esac
done

# if necessary, resize the partition. this shouldn't be necessary with the new
# VM image! if you need more than ~1GB space for papers, setup xvdb1
sudo fdisk /dev/xvda <<EOF
p
d
n




w
EOF
sudo partprobe

# resize the default filesystem to use the entire partition
sudo resize2fs /dev/xvda1 # blank SIZE means use whole partition
  1. Install packages
# sort out packages
export TZ=Europe/London
sudo apt update && sudo apt install --no-install-recommends -qq -yy \
    apache2 \
    ca-certificates \
    git \
    libapache2-mod-php \
    mailutils \
    mysql-server
    php-curl \
    php-json \
    php-mysql \
    poppler-utils \
    postfix \
    zip
  1. Configure postfix
# configure postfix: accept defaults if offered, setup postfix to use ppsw
sudo sed -i 's/relayhost =/relayhost = ppsw.cam.ac.uk/' /etc/postfix/main.cf
sudo /etc/init.d/postfix reload
sudo systemctl restart postfix.service
# test mail sending
echo "Test mail from postfix" | mail -s "Test Postfix" ${YOUR-EMAIL}

For more email help, see https://help.uis.cam.ac.uk/email-telephony-and-collaboration/email/specialist-email-advice/sending-email using YOUR-DOMAIN as mail domain, and ppsw.cam.ac.uk as relay host.

  1. Install HotCRP

Get latest release:

git clone https://github.com/kohler/hotcrp.git
cd hotcrp
git checkout tags/v2.101 -b v2.101
  1. Setup root account for MySQL
sudo /etc/init.d/mysql stop # stop the running service

# configure and run mysql in the console
sudo mkdir -p /var/run/mysqld
sudo chown mysql:mysql /var/run/mysqld
sudo mysqld_safe --skip-grant-tables & sleep 5

# smash a new `root` password in place 
sudo mysql
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '${YOUR-PASSWORD}';  
FLUSH PRIVILEGES;
exit;

# restart mysql properly as a service
mysqladmin -uroot -p${YOUR-PASSWORD} -h127.0.0.1 --protocol=tcp shutdown
sudo /etc/init.d/mysql start

…alternatively

mysql -uroot<<_EOF
USE mysql;

UPDATE mysql.user SET authentication_string = PASSWORD('${YOUR-PASSWORD}')
WHERE User = 'root' AND Host = 'localhost';
FLUSH PRIVILEGES;

QUIT
_EOF
  1. Secure your MySQL installation
sudo systemctl stop mysql
sudo mkdir -p /var/run/mysqld
sudo chown mysql:mysql /var/run/mysqld
sudo mysqld_safe --skip-grant-tables --skip-networking &
sudo mysql_secure_installation -p${YOUR-PASSWORD}<<EOF
n
n
y
y
y
y
EOF
  1. Setup the HotCRP MySQL tables and config
lib/createdb.sh --user=root --password=${YOUR-PASSWORD} <<EOF
ok
YOUR-WORKSHOP
EOF

# edit conf/options.php
# - contactName
# - contactEmail
# - sendEmail
# - emailFrom
# - emailSender
# - timezone
# - upload_max_filesize [ if you care ]
  1. Turn on the HotCRP site in your Apache configuration
# apache2: turn on hotcrp site
sudo sh -c 'cat >>/etc/apache2/conf-available/hotcrp.conf <<_EOF
<Directory "$(pwd -P)">
    Options Indexes Includes FollowSymLinks
    AllowOverride all
    Require all granted
</Directory>
Alias /YOUR-WORKSHOP $(pwd -P)
_EOF
'

sudo a2enconf <<EOF
hotcrp
EOF

sudo chgrp www-data conf/options.php
sudo service apache2 reload
sudo apache2ctl graceful

…and you should now be able to access your hotcrp site at http://${YOUR-DOMAIN}/${YOUR-WORKSHOP}

  1. Use Let’s Encrypt to create and configure certificates for HTTPS support
sudo apt install -yy software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install -yy certbot-auto
wget https://dl.eff.org/certbot-auto
chmod a+x ./certbot-auto
sudo ./certbot-auto -n --os-packages-only

sudo ./certbot-auto -a webroot -i apache -w $(pwd -P) \
     --agree-tos --redirect --uir --hsts --staple-ocsp \
     -d YOUR-DOMAIN --email YOUR-EMAIL

sudo ./certbot-auto --install-only
  1. Set permissions on the certificate directories
sudo chgrp www-data /etc/letsencrypt/live
sudo chmod g+rx /etc/letsencrypt/live
sudo chgrp www-data /etc/letsencrypt/archive/
sudo chmod g+rx /etc/letsencrypt/archive/

End state is the Apache config looks something like the following, with unindented lines being those I added:

$ cat /etc/apache2/sites-available/hotcrp.conf
<IfModule mod_ssl.c>

SSLStaplingCache shmcb:/var/run/apache2/stapling_cache(128000)

	<VirtualHost _default_:443>
		ServerAdmin webmaster@localhost
		DocumentRoot /home/hotcrp/hotcrp
		ErrorLog ${APACHE_LOG_DIR}/error.log
		CustomLog ${APACHE_LOG_DIR}/access.log combined
		SSLEngine on

SSLCACertificateFile /etc/letsencrypt/live/hotcrp.sysws.org.uk/fullchain.pem
SSLUseStapling on

		<FilesMatch "\.(cgi|shtml|phtml|php)$">
				SSLOptions +StdEnvVars
		</FilesMatch>
		<Directory /usr/lib/cgi-bin>
				SSLOptions +StdEnvVars
		</Directory>

ServerName hotcrp.sysws.org.uk
SSLCertificateFile /etc/letsencrypt/live/hotcrp.sysws.org.uk-0001/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/hotcrp.sysws.org.uk-0001/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
Header always set Strict-Transport-Security "max-age=31536000"
Header always set Content-Security-Policy upgrade-insecure-requests

	</VirtualHost>
</IfModule>

11. Add DNS entry for the name assigned (in my case, `hotcrp.DOMAIN`).