Brottweiler’s Logbook

Running a static web server for Minecraft maps

Between 2012–2017, the Minecraft PvP server oc.tc had a map index running on maps.oc.tc1. This was a directory listing of the private git repository showing all the maps loaded on the server. You could not download any map region files since all maps were proprietary, but you could read the map.xml files that decide how the map is played, and view the map images.

I have wanted to recreate that web based repository, and I decided to try run a map index for my server Project Enyo. This might sound more interesting than it is, but it was a fun project for me to work on.

The Map Repo

The map repository is in the Minecraft server directory at /opt/pvp/maps and owned by a unique account. The files have permission 644 which means other accounts can read the files. The web server runs as the www-data user, which is the account you “view” as when you browse the repository via the browser at maps.projectenyo.eu. I do not intend to redistribute maps via this repository, so I needed to remove read access to sensitive map files for other users.

To remove read access on all .mca and .dat files for other users, I used chmod:

$ chmod -R 640 ./**/*{.mca,.dat}

The Web Server

I have used Apache in the past. It worked and everyone used it, but it is old and infamous for its security issues. I have also used lighttpd since it was easier to use and configure, and was lighter to run. Today most people seem to use nginx and I would recommend that to most people, but what if that is more power than you need?

I only run static sites, so I do not need the power of these web servers. Checking the Archlinux Wiki on web servers, I found a list of static web servers.

webfs has not been updated in a while but if it works, do not fix it. The directory listing was styled a bit and showed owner, size, modification date of files. Files you do not have access to are not clickable. darkhttpd only shows the size of files, and have a more vanilla styling. webfs was in Ubuntu repos and was controlled with systemd, while darkhttpd is one .c file to compile and run.

I decided to go with darkhttpd. I have not tried quark but I might in the future.

Running darkhttpd

The current 1.13 version does not support HTTPS forwarding. I wanted HTTPS forwarding support, so I cloned the repo and followed the one step build instructions.

The following command is run with superuser privileges to bind the web server to port 80 (default).

$ sudo ./darkhttpd /opt/pvp/maps --port 80 --chroot --uid www-data --gid www-data --forward-https

Superuser privileges are immediately dropped because the server should not run as root for security reasons. All map files are owned by enyo, and I already controlled what files www-data can read. .dat and .mca files will show up as forbidden by the browsing user.

Getting HTTPS Working

All websites today should run HTTPS2, and since we can get certificates for free there is no reason not to. The tricky part was to figure out how to do it, especially with a web server that does not directly support it.

certbot

I followed the instructions to generate a certificate with certbot. It is available in Ubuntu's app repository. With a valid certificate, I needed to run a SSL proxy.

The certificate is located in /etc/letsencrypt/live/maps.projectenyo.eu/ together with the private key.

The SSL Proxy

To run the SSL proxy, there are different approaches. Some alternatives I have found are socat, stunnel or hitch. My friend linked me two guides on how to use both socat3 and stunnel4 with darkhttpd, but they are either outdated or have information that is not relevant. I will credit these guides, but also write about how I use these two programs.

socat

The socat guide generates a self signed certificate which I will not be using. I already have a certificate from LetsEncrypt.

Since the web server is already running on port 80, I installed socat and ran it with this command.

sudo socat "ssl-l:443,cert=/etc/letsencrypt/live/maps.projectenyo.eu/cert.pem,key=/etc/letsencrypt/live/maps.projectenyo.eu/privkey.pem,verify=0,fork,reuseaddr" \
    'tcp4:0.0.0.0:80'

stunnel

Socat is powerful, but I do not need all that overhead for this purpose. Instead I tried stunnel. stunnel is installed from the Ubuntu repos as the stunnel4 package. I created a config file at /etc/stunnel/stunnel.conf with the following data.

output  = /var/log/stunnel.log
cert    = /etc/letsencrypt/live/maps.projectenyo.eu/cert.pem
key     = /etc/letsencrypt/live/maps.projectenyo.eu/privkey.pem

[https]
client  = no
accept  = 443
connect = 80

Then all I needed to do was to start the stunnel daemon.

$ sudo stunnel

Final Words

Now there is a directory listing running at maps.projectenyo.eu. It is powered by darkhttpd and stunnel is used to provide an SSL proxy using a LetsEncrypt certificate.

Footnotes

  1. Archived versions can be accessed at the archive.org.

  2. doesmysiteneedhttps.com

  3. Simple HTTPS Server

  4. darkhttpd with stunnel

#darkhttps #https #web server