Fathom is watching you
January 17, 2019 - 19 min
After a very succesful launch (okay, maybe that’s a bit of an overstatement…), I realised I had no idea how many people actually visited my site and read my first blog article.
Hey Twitter, I just 🚀 launched 🚀my blog using @gatsbyjs (can't thank you enough for this great tool!) and @Netlify (likewise! 😱😱 so easy!). Can't believe how smooth it was!
— Robin Cussol (@RobinCsl) January 9, 2019
Get ready for posts, they're coming. https://t.co/TtYLCOBIuF
In a world dominated by Google, I wanted to stay away from Google Analytics, even though the Gatsby starter I used has a plugin for that out of the box.
It’s overkill for what I need, I would not own the data, and Google would certainly use it to profile my visitors. Yes, you! And I care deeply about your privacy.
Lucky you, not everyone has a choice…, Photo by Matthew Henry on Unsplash
After listening to episode 102 Paul Jarvis - Staying Small of Full Stack Radio, I knew which tool I would be using.
Fathom, a privacy oriented website analytics tool
Fathom is an open-source project which was created by Paul Jarvis and Danny van Kooten. The README file on their GitHub repository reads as follows:
Fathom Analytics is a simpler and more privacy-focused alternative to Google Analytics.
Collecting information on the internet is important, but it’s broken. We’ve become complacent in trading information for free access to web services, and then complaining when those web services do crappy things with that data.
And I have to agree with them, we often don’t realise that we’re trading information when, and sadly not limited to, something is offered for free.
This analytics tool also respects people’s wishes not to be tracked if “Do Not Track” is enabled in their browser settings.
Not only it is open-source, but they also provide instructions on how to install Fathom on your own server.
That seemed to be exactly what I needed: an ethical solution to understand how my website is performing!
The power of open-source
After receiving my Hacktoberfest 2018 T-Shirt and stickers, I saw that the coaster provided in the pack had some promo-code to use on Digital Ocean, with some free credit. I’ve always found their write-ups to be useful (some are listed in Resources) and they do support Open Source. Why not use a Droplet to deploy my own analytics then?
The rest of this article will dive into how you can deploy your own instance of Fathom for your website.
Note: I will use Digital Ocean, but most of the following instructions should be applicable to other providers.
1. Creating a Droplet
Go over to Digital Ocean and create an account - no obligation, but you can use the following referral link: it will give you $100 in credit for 60 days, and if you ever spend more than $25 on their platform, I will be rewarded with $25. So it’s a win-win.
A Droplet is the cute name Digital Ocean gives to their Virtual Machines, Photo by Aaron Burden on Unsplash
They will first ask you to create a project, which might be useful in the future if you want to regroup resources for a specific …project. You could name it “My Cool and Ethical Analytics with Fathom” but if that is a bit too dull for you, you could get even more creative with it. But don’t waste too much time on it: you could always edit that later in the Settings tab of your project.
Now is the moment you’ve been waiting for: click on the green button Create in the top right corner and select Droplets. You should see the following screen:
Select Ubuntu 18.10 x64 like I did if you want to live on the edge, but the default Ubuntu 16.04 x64 should be fine too.
Unless you need more performances, I would stick with the default Droplet at $5/mo. It should be more than enough, and it is always possible to resize your Droplet in the future if need be.
I chose to ignore the following sections about adding backups and block storage.
As for the datacentre region, I chose Frankfurt, which sits in Europe. It’s closer to me and there should be better privacy laws here in Europe than in the USA; that is, if you count the UK out of Europe. Oh wait, Brexit! I digress.
Next, I did not select any extra services, but I added an SSH key in the following section. You can use this guide on GitHub to generate a new SSH key. Copy the content of the resulting .pub file in the text input on Digital Ocean.
Leave the number of Droplets to create to 1 and the pre-selected project as “My Cool and Ethical Analytics with Fathom”. Click on Create, wait for the Droplet to be initialised and voilà.
2. Hacker’s time: SSH into the Droplet
Inspect your Droplet and click on the ipv4 address to copy it. Leave your favourite browser aside for now and open a terminal. (You might already have one open if you followed the instructions above to generate a new SSH key.)
Note: lines in code blocks starting with
$
oruser@machine:~#
correspond to the terminal prompt; the rest corresponds to outputs from command executions. e.g.$ ls folder1 folder2 file1
or equivalently
user@machine:~# ls folder1 folder2 file1
Complete and run the following command
$ ssh root@<copy here the ipv4 address>
and you should see something similar as below printed in the terminal. Isn’t it magic?
Welcome to Ubuntu 18.10 (GNU/Linux 4.18.0-10-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Jan 15 21:37:52 UTC 2019
System load: 0.92 Processes: 90
Usage of /: 4.5% of 24.06GB Users logged in: 0
Memory usage: 14% IP address for ens3: <some IP address>
Swap usage: 0%
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
0 packages can be updated.
0 updates are security updates.
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
root@<name of your droplet>:~#
Congratulations, you just connected as user root
on your virtual machine.
3. Securing your Droplet
Leaving root
as the only user is usually a bad idea: whoever owns root
has administrator privilege on your virtual machine. Also, disabling the ways to connect to your server which you won’t be using is an accepted best practice - and it’s quite easy to set up thanks to ufw
, the Uncomplicated FireWall utility.
A good place to start to secure your Droplet is the following guide from Digitial Ocean: Initial Server Setup with Ubuntu 18.04. But as a tl;dr, I will describe below the necessary steps.
3.1 Add a new user
Run the following command
$ adduser jonsnow
which should yield:
Adding user `jonsnow' ...
Adding new group `jonsnow' (1000) ...
Adding new user `jonsnow' (1000) with group `jonsnow' ...
Creating home directory `/home/jonsnow' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
It’s a good idea to use a strong password, or maybe I should say passphrase. I will choose handball-waterski-nectar-holster-snail
.
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for jonsnow
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n]
So far so good. That command even created your own user folder:
$ ls /home
jonsnow
3.2 Granting jonsnow
admin privilege
To indicate you would like to execute a command with admin (called superuser) privilege, you would prefix it with sudo
, as in “superuser do”. Since we might need to execute commands requiring admin role, we run
$ usermod -aG sudo jonsnow
which means “add user jonsnow
to the superuser group”.
3.3 Enabling the firewall
We want to make sure we can still use ssh
to login on our Droplet (otherwise, we can just kill it from the Digital Ocean admin panel).
$ ufw allow OpenSSH
Rules updated
Rules updated (v6)
Now we can enable the firewall to protect us from unwanted connections (answer y
as “yes” to the question):
$ ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
Congratulations, all connections, apart from SSH, are blocked!
3.4 Enabling ssh
access for jonsnow
If you open a new terminal and try to connect to your server:
$ ssh jonsnow@<ipv4 address>
you will realise it’s not possible: Permission denied (publickey)
. This is because we have not configured jonsnow
’s authorized ssh
keys. The easiest is to copy the authorized key from the root
user account. In the same terminal where you should have root@<machine name>:~#
in front of the prompt, execute:
$ rsync --archive --chown=jonsnow:jonsnow ~/.ssh /home/jonsnow
and now in a different terminal, try again to ssh
into your Droplet as jonsnow
. Hurray, we’re now connected as root
and jonsnow
.
3.5 Disabling ssh
access for root
Finally, we can disable connections as root
; the following command replaces “PermitRootLogin yes” by “PermitRootLogin no” in the configuration file for sshd
, the program (called ssh daemon) which deals with ssh
connections:
$ sed --in-place 's/^PermitRootLogin yes$/PermitRootLogin no/g' /etc/ssh/sshd_config
We can now restart the SSH daemon to take into account this new configuration:
$ systemctl restart sshd
To verify this worked, open a new terminal and try to connect as root
to your Droplet. The good answer should be Permission denied (publickey)
.
We should now have a proper and somewhat secure setup to install our Fathom instance.
4. Installing Fathom
We will follow the instructions from Fathom’s GitHub repository.
Note: The instructions assume you are connected to your Droplet as
jonsnow
.
4.1. Download the latest release
At the time of writing, the latest release is version 1.2.1. On the release page, make sure to copy the link from the release ending in linuxamd64.tar.gz_. To download it, execute in the terminal of the virtual machine:
$ wget https://github.com/usefathom/fathom/releases/download/v1.2.1/fathom_1.2.1_linux_amd64.tar.gz
If you want to see that the downloaded file is really there, you can run ls
- short for list - to see the content of the current directory.
jonsnow@<name of your droplet>:~# ls
fathom_1.2.1_linux_amd64.tar.gz snap
To make sure we downloaded the right file as the authors of this project intended, we should verify the integrity of the file. Using a hash function, like SHA-256, we can get some kind of fingerprint of any text/file. To do so, run:
$ sha256sum fathom_1.2.1_linux_amd64.tar.gz
which should print
d09a81f8bd7c844a4214a500a3de8c20b3fbff292b5a0fa648e9efdc05ecd769 fathom_1.2.1_linux_amd64.tar.gz
Going back to the release page, we can download checksums.txt and verify that the output we got matches the one written in that .txt file.
4.2. Extract the archive to /usr/local/bin
This is almost achieved by
$ tar -C /usr/local/bin -xzf fathom_1.2.1_linux_amd64.tar.gz
Indeed, we get some errors:
$ tar -C /usr/local/bin -xzf fathom_1.2.1_linux_amd64.tar.gz
tar: LICENSE: Cannot open: File exists
tar: README.md: Cannot open: File exists
tar: fathom: Cannot open: File exists
tar: Exiting with failure status due to previous errors
This is because we are trying to extract the content of the file we downloaded into a special folder on your virtual machine: /usr/local/bin
is the usual folder to put executables that you downloaded, but you need admin privilege to write there. That’s why we need to prefix that command with sudo
:
$ sudo tar -C /usr/local/bin -xzf fathom_1.2.1_linux_amd64.tar.gz
However, it is not yet executable. We can remedy this by executing
$ chmod +x /usr/local/bin/fathom
chmod
is a utility to change permissions (read/write/execute) on a file or folder and the argument +x
means add executability (or searchability in the case of folders).
We can now verify that Fathom is installed properly:
$ fathom --version
Fathom version 1.2.1, commit 8f7c6d2e45ebb28651208e2a7320e29948ecdb2c, built at 2018-11-30T09:21:37Z
4.3 Optional Steps
Configuring Fathom and Register your admin user are optional steps in the documentation.
The first one would be interesting to consider in case you would like to use a different database and make sure that the secret Fathom uses is one that you generated (in case you did not trust Fathom to provide you with a good secret).
The second one would be necessary in case you would like to make your dashboard private:
$ fathom user add --email="[email protected]" --password="strong-password"
That command would create a user with email and password of your choosing, for your Fathom instance. Not only that, but when trying to access the Fathom dashboard, you should be greeted with a login page instead of your analytics.
Registering a user is also necessary if you would like to manage several websites on the same Fathom instance. Have a look at this GitHub comment to know more.
4.4 Fathom server
We can now execute the almighty command
$ fathom server
INFO[0000] Fathom version 1.2.1, commit 8f7c6d2e45ebb28651208e2a7320e29948ecdb2c, built at 2018-11-30T09:21:37Z
WARN[0000] Error reading configuration. File `.env` does not exist.
INFO[0000] Connected to sqlite3 database: /home/jonsnow/fathom.db
INFO[0000] Applied 26 database migrations!
Try and go over to http://< ipv4 address >:8080. Sadly, we do not see yet the desired output:
I want to see this, pretty please!
4.5 Your patience will be rewarded, pinky promise
Our security measures were a bit too strict: remember how we blocked all connections apart from SSH? The good news is that in this step, we are not only going to make the connection to our dashboard possible, but we will also make sure our Fathom instance restarts if the server is shut down or restarted for any reason. Just wait to see the icing on the cake.
4.5.1. Setting up NGINX
NGINX is going to provide us with a web server that can be seen as an app by ufw
, so that we can allow it.
BEFORE
$ sudo ufw app list
Available applications:
OpenSSH
AFTER
$ sudo ufw app list
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
To install it, we execute:
$ sudo apt install nginx
and remove the default configuration
$ sudo rm /etc/nginx/sites-enabled/default
Let us create a site configuration:
$ sudo nano /etc/nginx/sites-available/tracking.example.com
where tracking.example.com
is the domain where you plan to access your dashboard.
Your terminal should transform into
Paste the following content:
server {
server_name tracking.example.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
}
Press successively CTRL+O to Write Out and CTRL+X to Exit.
If you read carefully in the previous command, we only created a configuration file in the available-sites
folder. We now need to enable it by creating a symbolic link (it’s like a desktop shortcut, sort of) to the enabled-sites
folder:
$ sudo ln -s /etc/nginx/sites-available/tracking.example.com /etc/nginx/sites-enabled/tracking.example.com
For this to come into effect, we must test our configuration and reload nginx
:
$ sudo nginx -t # this is to test our configuration
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo service nginx reload # this is to reload nginx
We just need to tell the firewall to let us through
$ sudo ufw allow 'Nginx Full'
Rule added
Rule added (v6)
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
$ sudo ufw status # just to verify
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx Full (v6) ALLOW Anywhere (v6)
Run fathom server
and go to < ipv4 address > in your browser:
Hallelujah, hallelujah, hallelujah, ~Handel’s Messiah
4.5.2 Creating a system service
Before you go on and get your tracking code and show all your friends, family, pets the feat you just achieved, we really should tackle two remaining issues, and we will deal with the first in this part.
If your server goes down for any reason, is restarted, etc., your Fathom instance will not be restarted. And let’s be honest, leaving a terminal open with an open SSH connection to your Droplet with a fathom server
active is not very practical. This is precisely what system services are for.
Following the isntructions from Automatically starting Fathom on boot will get the job done.
- Creating the service
$ sudo nano /etc/systemd/system/tracking.example.com.service
and copy-paste
[Unit]
Description=Starts the fathom server
Requires=network.target
After=network.target
[Service]
Type=simple
User=jonsnow
Restart=always
RestartSec=3
WorkingDirectory=/home/jonsnow
ExecStart=/usr/local/bin/fathom server
[Install]
WantedBy=multi-user.target
- Reload the service controller daemon
$ sudo systemctl daemon-reload
- Enable your service
$ sudo systemctl enable tracking.example.com
Created symlink /etc/systemd/system/multi-user.target.wants/tracking.example.com.service → /etc/systemd/system/tracking.example.com.service.
- Start your server (forever and ever)
$ sudo systemctl start tracking.example.com
Going back to the browser and refreshing the page after the last command should work, just as if you had had fathom server
running in the terminal. It’s now running in the background thanks to the service we just created.
4.5.3 The icing on the cake
Back to my promise: let’s do a grand finish and serve our analytics over a secure HTTPS connection. To endow our Fathom instance with an SSL certificate, we need to install certbot
(Interactive Installation Guide). In our setup, we should do the following:
$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-nginx
Make sure that your DNS is properly configured to point an A record to the < ipv4 address > of your Droplet, before executing the following step.
Once that’s done, we can issue a certificate for our Fathom instance.
$ sudo certbot --nginx -d tracking.example.com
5. Using your Fathom instance
You can now go to your Fathom instance in the browser and fill in the name of your site.
You now obtained your tracking snippet.
If, in the previous step, you added a Fathom user and had to log in, you would see a slightly different dashboard, with the ability to manage several sites:
Note: The cog is only visible if you are logged in.
The joys of tracking your website’s traffic is about to start: insert the snippet you obtained at the previous step or copy paste this one by adding the relevant information in < domain > and < SITETRACKINGID >.
You would usually insert this in the head tag of your HTML pages, or you could use react-helmet
if your site is powered by React.
<!-- Fathom - simple website analytics - https://github.com/usefathom/fathom -->
<script>
;(function (f, a, t, h, o, m) {
a[h] =
a[h] ||
function () {
;(a[h].q = a[h].q || []).push(arguments)
}
;(o = f.createElement('script')), (m = f.getElementsByTagName('script')[0])
o.async = 1
o.src = t
o.id = 'fathom-script'
m.parentNode.insertBefore(o, m)
})(document, window, '//< domain >/tracker.js', 'fathom')
fathom('set', 'siteId', '< SITE_TRACKING_ID >')
fathom('trackPageview')
</script>
<!-- / Fathom -->
Happy tracking!!
Result and future improvements
I did not make my dashboard private (for people from the future: I might have changed my mind, apologies if that’s the case) and you can look at my impressive statistics at https://tracking.robincussol.com/
You can see that currently there are several root endpoints /
, and they correspond to my local dev environment, my Netlify deployments and my real website. I might erase the stats and start afresh once I disable the tracking snippet in these different unwanted contexts.
Finally, in case my Droplet ever goes down and my data is lost (sure, I could set up some backup of my Droplet through Digital Ocean, but what’s the fun in that?), I would like to create a cron job that would send me the stats of the day to my email, and maybe backup the database to some other location.
That’s it for now, thank you for reading this very far. You will find below the resources mentioned in this article and that helped me to get up and running with Fathom. Stay tuned for more.
Resources
Personal blog written by Robin Cussol
I like math and I like code. Oh, and writing too.