<p>A modern public-facing website should these days be served via encrypted
connections. So <codeclass="docutils literal notranslate"><spanclass="pre">https:</span></code> rather than <codeclass="docutils literal notranslate"><spanclass="pre">http:</span></code> for the website and
<codeclass="docutils literal notranslate"><spanclass="pre">wss:</span></code> rather than vs <codeclass="docutils literal notranslate"><spanclass="pre">ws:</span></code> for websocket connections used by webclient.</p>
<p>The reason is security - not only does it make sure a user ends up at the right
site (rather than a spoof that hijacked the original’s address), it stops an
evil middleman from snooping on data (like passwords) being sent across the
wire.</p>
<p>Evennia itself does not implement https/wss connections. This is something best
handled by dedicated tools able to keep up-to-date with the latest security
practices.</p>
<p>So what we’ll do is install <em>proxy</em> between Evennia and the outgoing ports of
your server. Essentially, Evennia will think it’s only running locally (on
localhost, IP 127.0.0.1) while the proxy will transparently map that to the
“real” outgoing ports and handle HTTPS/WSS for us.</p>
(outside-visible public IP/ports serving HTTPS/WSS)
|
Firewall
|
Internet
</pre></div>
</div>
<p>These instructions assume you run a server with Unix/Linux (very common if you
use remote hosting) and that you have root access to that server.</p>
<p>The pieces we’ll need:</p>
<ulclass="simple">
<li><p><aclass="reference external"href="https://www.haproxy.org/">HAProxy</a> - an open-source proxy program that is
easy to set up and use.</p></li>
<li><p><aclass="reference external"href="https://letsencrypt.org/getting-started/">LetsEncrypt</a> for providing the User
Certificate needed to establish an encrypted connection. In particular we’ll
use the excellent <aclass="reference external"href="https://certbot.eff.org/instructions">Certbot</a> program,
which automates the whole certificate setup process with LetsEncrypt.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">cron</span></code> - this comes with all Linux/Unix systems and allows to automate tasks
in the OS.</p></li>
</ul>
<p>Before starting you also need the following information and setup:</p>
<ulclass="simple">
<li><p>(optional) The host name of your game. This is
something you must previously have purchased from a <em>domain registrar</em> and set
up with DNS to point to the IP of your server. For the benefit of this
manual, we’ll assume your host name is <codeclass="docutils literal notranslate"><spanclass="pre">my.awesomegame.com</span></code>.</p></li>
<li><p>If you don’t have a domain name or haven’t set it up yet, you must at least
know the IP address of your server. Find this with <codeclass="docutils literal notranslate"><spanclass="pre">ifconfig</span></code> or similar from
inside the server. If you use a hosting service like DigitalOcean you can also
find the droplet’s IP address in the control panel. Use this as the host name
everywhere.</p></li>
<li><p>You must open port 80 in your firewall. This is used by Certbot below to
auto-renew certificates. So you can’t really run another webserver alongside
this setup without tweaking.</p></li>
<li><p>You must open port 443 (HTTPS) in your firewall. This will be the external
webserver port.</p></li>
<li><p>Make sure port 4001 (internal webserver port) is <em>not</em> open in your firewall
(it usually will be closed by default unless you explicitly opened it
previously).</p></li>
<li><p>Open port 4002 in firewall (we’ll use the same number for both internal-
and external ports, the proxy will only show the safe one serving wss).</p></li>
</ul>
<sectionid="getting-certificates">
<h2>Getting certificates<aclass="headerlink"href="#getting-certificates"title="Permalink to this headline">¶</a></h2>
<p>Certificates guarantee that you are you. Easiest is to get this with
<aclass="reference external"href="https://letsencrypt.org/getting-started/">Letsencrypt</a> and the
<aclass="reference external"href="https://certbot.eff.org/instructions">Certbot</a> program. Certbot has a lot of
install instructions for various operating systems. Here’s for Debian/Ubuntu:</p>
<p>You will get some questions you need to answer, such as an email to send
certificate errors to and the host name (or IP, supposedly) to use with this
certificate. After this, the certificates will end up in
<codeclass="docutils literal notranslate"><spanclass="pre">/etc/letsencrypt/live/<yourhostname>/*pem</span></code> (example from Ubuntu). The
critical files for our purposes are <codeclass="docutils literal notranslate"><spanclass="pre">fullchain.pem</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">privkey.pem</span></code>.</p>
<p>Certbot sets up a cron-job/systemd job to regularly renew the certificate. To
<p>The certificate is only valid for 3 months at a time, so make sure this test
works (it requires port 80 to be open). Look up Certbot’s page for more help.</p>
<p>We are not quite done. HAProxy expects these two files to be <em>one</em> file. More
specifically we are going to</p>
<olclass="simple">
<li><p>copy <codeclass="docutils literal notranslate"><spanclass="pre">privkey.pem</span></code> and copy it to a new file named <codeclass="docutils literal notranslate"><spanclass="pre"><yourhostname>.pem</span></code> (like
<li><p>Append the contents of <codeclass="docutils literal notranslate"><spanclass="pre">fullchain.pem</span></code> to the end of this new file. No empty
lines are needed.</p></li>
</ol>
<p>We could do this by copy&pasting in a text editor, but here’s how to do it with
shell commands (replace the example paths with your own):</p>
<p>The new <codeclass="docutils literal notranslate"><spanclass="pre">my.awesomegame.com.pem</span></code> file (or whatever you named it) is what we will
point to in the HAProxy config below.</p>
<p>There is a problem here though - Certbot will (re)generate <codeclass="docutils literal notranslate"><spanclass="pre">fullchain.pem</span></code> for
us automatically a few days before before the 3-month certificate runs out.
But HAProxy will not see this because it is looking at the combined file that
will still have the old <codeclass="docutils literal notranslate"><spanclass="pre">fullchain.pem</span></code> appended to it.</p>
<p>We’ll set up an automated task to rebuild the <codeclass="docutils literal notranslate"><spanclass="pre">.pem</span></code> file regularly by
using the <codeclass="docutils literal notranslate"><spanclass="pre">cron</span></code> program of Unix/Linux.</p>
<p>An editor will open to the crontab file. Add the following at the bottom (all
on one line, and change the paths to your own!):</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>0 5 * * * cd /etc/letsencrypt/live/my.awesomegame.com/ &&
cp privkey.pem my.awesomegame.com.pem &&
cat fullchain.pem >> my.awesomegame.com.pem
</pre></div>
</div>
<p>Save and close the editor. Every night at 05:00 (5 AM), the
<codeclass="docutils literal notranslate"><spanclass="pre">my.awesomegame.com.pem</span></code> will now be rebuilt for you. Since Certbot updates
the <codeclass="docutils literal notranslate"><spanclass="pre">fullchain.pem</span></code> file a few days before the certificate runs out, this should
be enough time to make sure HaProxy never sees an outdated certificate.</p>
</section>
<sectionid="installing-and-configuring-haproxy">
<h2>Installing and configuring HAProxy<aclass="headerlink"href="#installing-and-configuring-haproxy"title="Permalink to this headline">¶</a></h2>
<p>Installing HaProxy is usually as simple as:</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span># Debian derivatives (Ubuntu, Mint etc)
sudo apt install haproxy
# Redhat derivatives (dnf instead of yum for very recent Fedora distros)
sudo yum install haproxy
</pre></div>
</div>
<p>Configuration of HAProxy is done in a single file. This can be located wherever
you like, for now put in your game dir and name it <codeclass="docutils literal notranslate"><spanclass="pre">haproxy.cfg</span></code>.</p>
<p>Here is an example tested on Centos7 and Ubuntu. Make sure to change the file to
put in your own values.</p>
<p>We use the <codeclass="docutils literal notranslate"><spanclass="pre">my.awesomegame.com</span></code> example here and here are the ports</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">443</span></code> is the standard SSL port</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">4001</span></code> is the standard Evennia webserver port (firewall closed!)</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">4002</span></code> is the default Evennia websocket port (we use the same number for
the outgoing wss port, so this should be open in firewall).</p></li>
</ul>
<divclass="highlight-shell notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># base stuff to set up haproxy</span>
<p>Make sure you can connect to your game from your browser and that you end up
with an <codeclass="docutils literal notranslate"><spanclass="pre">https://</span></code> page and can use the websocket webclient.</p>
<p>Once everything works you may want to start the proxy automatically and in the
background. Stop the proxy with <codeclass="docutils literal notranslate"><spanclass="pre">Ctrl-C</span></code> and make sure to uncomment the line <codeclass="docutils literal notranslate"><spanclass="pre">#</span><spanclass="pre">daemon</span></code> in the config file.</p>
<p>If you have no other proxies running on your server, you can copy your
haproxy.conf file to the system-wide settings:</p>
<p>The proxy will now start on reload and you can control it with</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>sudo service haproxy start|stop|restart|status
</pre></div>
</div>
<p>If you don’t want to copy stuff into <codeclass="docutils literal notranslate"><spanclass="pre">/etc/</span></code> you can also run the haproxy purely
out of your current location by running it with <codeclass="docutils literal notranslate"><spanclass="pre">cron</span></code> on server restart. Open