A couple of months ago I started setting up several services on my own servers to get rid of many third party dependencies like Google. Even though Mozilla is nothing like a big Mega-Corp I still like the idea of not depending on third parties ( or even if you do, that you can migrate easily to another provider).
In this post I will explain how I have set-up my own Firefox Sync Server. Most of my information has been extracted from here and here.
I, obviously, did some research online before I started doing something like this from scratch. I found several posts like this one or this one but all of them look like people just want to make things work without digging too much into how things really function. Indicators for this were the usage of
SYNCSERVER_FORCE_WSGI_ENVIRON were I could see that they were not really understanding what was happening under the hood.
Here you can find my docker-compose:
version: '3.5' networks: world: external: true services: syncserver: image: mozilla/syncserver:latest container_name: syncserver restart: on-failure networks: - world volumes: - /srv/syncserver:/data expose: - "5000" environment: - "SYNCSERVER_ALLOW_NEW_USERS=false" - "SYNCSERVER_PUBLIC_URL=https://your.fqdn.here" - "SYNCSERVER_SECRET=$SYNCSERVER_SECRET" - "SYNCSERVER_SQLURI=sqlite:////data/syncserver.db" - "SYNCSERVER_FORWARDED_ALLOW_IPS=127.0.0.1,172.18.0.2,172.18.0.1" - "SYNCSERVER_BATCH_UPLOAD_ENABLED=true" - "SYNCSERVER_FORCE_WSGI_ENVIRON=false" - "PORT=5000" labels: - "traefik.frontend.rule=Host:your.fqdn.here" - "traefik.docker.network=world" - "traefik.enable=true" - "traefik.frontend.passHostHeader=true" - "traefik.frontend.headers.STSPreload=true" - "traefik.frontend.headers.STSSeconds=31536000" - "traefik.frontend.headers.ForceSTSHeader=true" - "traefik.frontend.headers.STSIncludeSubdomains=true" - "traefik.frontend.headers.contentTypeNosniff=true" - "traefik.frontend.headers.frameDeny=true" - "traefik.frontend.headers.customFrameOptionsValue=SAMEORIGIN" - "traefik.frontend.headers.browserXSSFilter=true" - "traefik.frontend.headers.referrerPolicy=no-referrer" - "traefik.frontend.headers.contentSecurityPolicy=default-src 'self'; script-src 'self'"
In this setup I run syncserver behind traefik configured automatically via labels. Notice
SYNCSERVER_FORCE_WSGI_ENVIRON=false. We do not need to set this to true due to the usage of
SYNCSERVER_FORWARDED_ALLOW_IPS=127.0.0.1,172.18.0.2,172.18.0.1 and the header X-Forwarded-For that we receive via trafik (configured to do so via the label
The SYNCSERVER_SECRET environment variable has been generated with the command:
head -c 20 /dev/urandom | sha1sumAnd inserted in a .env file containing:
# This file is used to define environment variables to be used
# for variable substitution in your docker compose file.
Now, in order for Firefox to attack our Sync Server, we need to set it up as follows (I blatantly copy from this blog post):
- Go to
about:configand search for
- Now change replace
https://yourawesomeurl.tld/token/1.0/sync/1.5. Don’t forget the
token, because the self hosted Firefox sync server is exposing the token server in a subdicrectory.
- Just to make sure everything is set up correctly, log out of Firefox (if you logged in before) and restart the browser.
- Now go to the settings, login with your Firefox account and the synchronization can start.
As you might know already, we still need the Firefox Account service from Mozilla for all these to work. I am pretty sure I will be trying to set it up myself in a not too distant future… 🙂