Self hosting Firefox Sync on CentOS 7 ·
another meaningless subtitle

Self hosting Firefox Sync on CentOS 7

· by fabio · Read in about 5 min · (894 Words)
Android CentOS Firefox syncserver

Configuring this piece of poorly documented bloated shit Mozilla came up with was a huge pain in the ass, so excuse the colored language but I am fucking pissed.
The idea was to finally implement a system to synchronize Firefox’s bookmarks across multiple devices without giving Mozilla all my personal data.
After some minutes spent researching the subject on the interweb I found out the synchronization system is a huge clusterfuck comprised of multiple components:
1. a massive authentication server made of two big components running on node.js (fuck this shit, seriously):
1a. fxa-auth-server, documentation is lacking but at least there is some, it can be found here:
1b. fxa-content-server, which DOES NOT HAVE ANY KIND OF DOCUMENTATION WHATSOEVER or at least there isn’t any sign of it where it should be: on the official Mozilla documentation.
2. syncserver, documentation is decent but still lacking even for this one, it can be found here: docs.
How the fuck am I supposed to know how to install and properly configure your fucking shit product if you don’t tell me how to do it?

1.a fxa-auth-server

I followed the very brief instructions, stopped after watching fucking npm install shit for a good 10 minutes and eating up RAM like there was no tomorrow.

1.b fxa-content-server

This one I didn’t even bother to download since no fucking documentation.

2. syncserver

This one I managed to install and configure I hope properly.
I followed the instructions:

$ yum install python-virtualenv make gcc-c++ make
$ cd /opt
$ mkdir syncserver-db
$ git clone
$ cd syncserver
$ make build

This was easy, now comes the fun.
Mozilla suggests to not expose its syncserver to the web but instead run a webserver in front of it, so lets use nginx as a reverse proxy:

location /ffsync/ {
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_redirect off;
    proxy_read_timeout 120;
    proxy_connect_timeout 10;

Edit syncserver’s configuration file.
Host, port, public_url, sqluri and secret should be set and configured correctly, especially public_url must be the same url on which nginx is listening for incoming connections.

use = egg:gunicorn
host =
port = 5000
workers = 1
timeout = 30
syslog = true
syslog_prefix = ffsync
syslog_facility = daemon

use = egg:syncserver

# This must be edited to point to the public URL of your server,
# i.e. the URL as seen by Firefox.
public_url = https://domain/ffsync/

# This defines the database in which to store all server data.
sqluri = sqlite://///opt/syncserver-db/syncserver.db

# This is a secret key used for signing authentication tokens.
# It should be long and randomly-generated.
# The following command will give a suitable value on *nix systems:
#    head -c 20 /dev/urandom | sha1sum
# If not specified then the server will generate a temporary one at startup.
#secret = fuck_you_mozilla

# Set this to "false" to disable new-user signups on the server.
# Only request by existing accounts will be honoured.
allow_new_users = false

# Set this to "true" to work around a mismatch between public_url and
# the application URL as seen by python, which can happen in certain reverse-
# proxy hosting setups.  It will overwrite the WSGI environ dict with the
# details from public_url.  This could have security implications if e.g.
# you tell the app that it's on HTTPS but it's really on HTTP, so it should
# only be used as a last resort and after careful checking of server config.
force_wsgi_environ = true

# Uncomment and edit the following to use a local BrowserID verifier
# rather than posting assertions to the mozilla-hosted verifier.
# Audiences should be set to your public_url without a trailing slash.
#backend = tokenserver.verifiers.LocalVerifier
#audiences = https://localhost:5000

They make no mention on how to run syncserver as unprivileged user, luckily it is quite easy to do so, first create a user:

$ useradd ffsync -s /bin/false --no-create-home
$ cd /opt
$ chown ffsync:ffsync -R syncserver*

Now I would expect to see some kind of script one can use to start syncserver at boot time; guess what? There is fucking none.
A quick and dirty solution to the problem was adding a custom line to /etc/rc.local and enable rc-local service:

$ echo /opt/syncserver/local/bin/gunicorn --paste /opt/syncserver/syncserver.ini --daemon --user ffsync --group ffsync >> /etc/rc.local
$ chmod +x /etc/rc.local
$ systemctl enable rc-local && systemctl start rc-local

To check if the server is working properly open Firefox and navigate syncserver’s url (https://domain/ffsync/), a blank page containing the phrase “it works!” should appear.

.:. Configure Firefox

First of all, navigate “about:config” and edit “identity.sync.tokenserver.uri” with a string resembling the following one: “https://domain/ffsync/token/1.0/sync/1.5“.
This step works also on Firefox for Android, obviously replace the word “domain” with a valid domain name assigned to the syncserver.
Register a Firefox account and authenticate on every device you want to synchronize.
If for some reason you decide to switch to another domain or change the syncserver url it is required to disconnect and reconnect the account in Firefox settings.
Syncserver logs can be found by typing about:sync-log in Firefox’s address bar.

A word of advice for those fucks in charge at Mozilla: stop spending money on bullshit outreach programs no one gives a shit about and invest some more resource on writing decent documentation for the shit you produce.