Install your own Firefox Sync server with PHP-FPM and Nginx

Jean Baptiste FAVRE

2011 february

La version Française est disponible ici: Installer son propre serveur Firefox sync avec PHP-FPM et Nginx

Introduction

Mozilla foundation offers synchronisation facilities, so that you can get back you browser environment when you work on another desktop. If you can just use Mozilla's storage infrastructure, you also have the choice to build your own.

The most paranoid of us will see the opportunity to get rid of Mozilla foundation for that purpose and ensure that Mozilla won't ever have the opportunity to get into their privacy. Personnaly, I don't believe that could happen: this is not the way Mozilla wants to spread the web and all informations you send to them are encrypted.

But deploying and maintaining an IT infrastructure to support Sync facilities cost money, a lot of... Installing your own Sync server makes Mozilla save some. Not a lot of course, but if millions of Firefox users install their own Sync server, Mozilla could save a lot of money.

Finally, as I operate my own web server, my own mail server, my own jabber server, and so on..., and since I like discovering new things, I decided to install my own Sync server. A matter of independance :)

Préparation

Here we are. So, I want to setup my own Firefox Sync server onto my Nginx and PHP-FPM stack.

Base setup is described here:

Based on the configuration describe above, we have to setup an "application pool". That means that Firefox Sync server will be available for different domains and, of course, for many users.

Lets create directories tree:

Create application environment
mkdir -p /var/www/apps/fsync/{config,docroot,logs,private,tmp}
addgroup --system --gid 10001 fsync
adduser --home /var/www/apps/fsync --shel /bin/false --no-create-home \
     --uid 10001 --gid 10001 --disabled-password --disabled-login fsync
chmod 7777 /var/www/apps/fsync/tmp
chown appname: /var/www/apps/fsync/private
chmod -R u=rwX,g=rX,o= /var/www/apps/fsync/private

Once done, we can configure PHP-FPM:

cat /var/www/apps/fsync/config/fpm-pool.conf
[fsync]
    listen                 = 127.0.0.1:10001
    listen.backlog         = -1
    listen.allowed_clients = 127.0.0.1
    listen.owner           = fsync
    listen.group           = fsync
    listen.mode            = 0666

    user  = fsync
    group = fsync

    pm                   = dynamic
    pm.max_requests      = 0
    pm.max_children      = 10
    pm.start_servers     = 5
    pm.min_spare_servers = 5
    pm.max_spare_servers = 5
    pm.status_path       = /php_pool_fsync_status

    ping.path     = /fsync_ping
    ping.response =  fsync_pong
 
    request_terminate_timeout = 5
    request_slowlog_timeout   = 2
    slowlog                   = /var/www/apps/fsync/logs/php-slow.log
 
    ;rlimit_files = 1024
    ;rlimit_core = 0
 
    chroot = /var/www/apps/fsync/
    chdir = /docroot/

    catch_workers_output = yes
 
    env[HOSTNAME] = $HOSTNAME
    env[TMP]      = /tmp
    env[TMPDIR]   = /tmp
    env[TEMP]     = /tmp

    ;   php_value/php_flag             - you can set classic ini defines which can
    ;                                    be overwritten from PHP call 'ini_set'. 
    ;   php_admin_value/php_admin_flag - these directives won't be overwritten by
    ;                                     PHP call 'ini_set'
    php_flag[display_errors]       = on
    php_admin_value[error_log]     = /logs/php_err.log
    php_admin_flag[log_errors]     = on
    php_admin_value[memory_limit]  = 2M

Yes, you read it, Firefox Sync minimal server can run in chroot. Happy :)

Firefox Sync minimal server needs SQlite support in PHP. Lets install it:

php5-sqlite installation on GNU/Linux Debianaptitude install php5-sqlite

Here we are with PHP. It's now time to configure NGinx. README file suggest to use an Alias, with Apache. Since we use NGinx, we can't do this way. In fact, It's just about making sure that every request will be rewritted to use index.php with PATH_INFO variable setted. Here's what you can do with NGinx:

cat /etc/nginx/apps-available/fsync
location /fsync {

    root /var/www/apps/fsync/docroot;

    #error_log /var/www/apps/fsync/logs/error.log debug;

    rewrite ^/[^/]+/(.*)$ /docroot/index.php$request_uri break;

    fastcgi_split_path_info ^(.+\.php)([^?]*).*$;
    # A handy function that became available in 0.7.31 that breaks down
    # The path information based on the provided regex expression
    # This is handy for requests such as file.php/some/paths/here/

    fastcgi_pass   127.0.0.1:10001;
    # Forward request to "fsync" pool

    fastcgi_connect_timeout          15;
    fastcgi_send_timeout             15;
    fastcgi_read_timeout             15;
    fastcgi_buffer_size              128k;
    fastcgi_buffers                4 256k;
    fastcgi_busy_buffers_size        256k;
    fastcgi_temp_file_write_size     256k;
    fastcgi_intercept_errors         on;

    include /etc/nginx/conf.d/fastcgi.conf;
}

Beware with fastcgi_split_path_info directive. In official NGinx documentation, used regex is ^(.+\.php)(.*)$. Unfortunatly, Firefox Sync client performs a request like /1.0/user/username/info/collections?v=1.6.2. With regex from documentation, the query string ?v=1.6.2 is included in PATH_INFO declaration, which makes first connection failed. Even if further synchronisations will complete, you won't be able, as an example, to see tabs from other computers. Bad, isn't it ? :-/

This regex: ^(.+\.php)([^?]*).*$; solves the problem.

Now, you juste have to include this configuration file into the vhost one, like:

cat /etc/nginx/sites-enabled/domain.tld
server {
        listen 80;
        server_name domain.tld *.domain.tld;
        root /var/www/domains/domain.tld;

        ########## Log definition ##########
        access_log /var/www/domains/domain.tld/logs/access.log vhosts;
        error_log /var/www/domains/domain.tld/logs/error.log info;
        ########## SSL settings ##########
        listen 443;
        ssl on;
        ssl_certificate /var/www/domains/domain.tld/config/domain.tld.pem;
        ssl_certificate_key /var/www/domains/domain.tld/config/domain.tld.pem;
        ssl_session_timeout 5m;
        ssl_protocols SSLv3 TLSv1;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers on;

[...]

        ##### Enabled PHP apps support for specific subdomain #####
        include /etc/nginx/apps-available/fsync;

[...]

}

Firefox Sync minimal server installation

Now, you just have to install PHP code. Nothing difficult here:

Source code installation
cd /tmp/
wget //people.mozilla.org/~telliott/weave_minimal.tgz
tar xzf weave_minimal.tgz
mv weave_minimal/* /var/www/apps/fsync/docroot/
rm -rf weave_minimal.tgz weave_minimal
cd /var/www/apps/fsync/docroot/
chown fsync: .

Last command is important since SQlite DB will be written is root directory. Therefore, the user fsync needs write grants.

Database initialisation

DB creation will be made upon first connection. Just use your favorite brower (who say Chrome O_o ?) and point it to //fsync.domain.tld/1.0/blah/info/collection using login blah and password garbage. Authentication will fail but DB should be now created.

Last step, populate you DB with users:

Sync account creation
cd /var/www/apps/fsync/docroot/
php create_user
(c)reate, (d)elete or change (p)assword: c
Please enter username: username
Please enter password: password

Simple, efficient.

Now you can configure you Sync account on you browser. Don't forget to use Custom Sync server to point you own one. It seems that Modification of an existing account is not enough, so I suggest you to delete it and create a completely new one.

Have fun !

Sources and references

Firefox sync

Firefox Sync
  • //mozillalabs.com/sync/
  • https://wiki.mozilla.org/Labs/Weave/Sync/1.0/API
Minimal server
  • //tobyelliott.wordpress.com/2009/09/11/weave-minimal-server/
  • //rabenau.org/blog/posts/creating-your-own-firefox-sync-server

NGinx

fastcgi_split_path_info
  • //nginx-maillist.blogspot.com/2011/01/re-fastcgisplitpathinfo-capture-group_20.html
  • //forum.nginx.org/read.php?2,168078,168097#msg-168097

About Jean Baptiste FAVRE

I spend most of my free time on the Internet working on GNU/Linux with Debian or CentOS, virtualization with Xen and KVM technology, as well as cluster stacks with corosync and OpenAIS. Particularly interested in Linux, Netfilter, virtualization, monitoring and clusters, most of my personal works are published on this website and others should not delay. By way professional, I manage servers running RedHat or CentOS and VMware ESXi farm.
From time to time, I manage to drop my keyboard and read a book while listening to music, but it never lasts long.

License

Creative Commons License Cette publication est publiée sous contrat Creative Common by-nc-sa

Valid XHTML 1.0 Strict |  Valid CSS |  license Creative Common by-nc-sa

Index

  1. Introduction
  2. Environment setup
  3. Firefox Sync minimal server installation
  4. Database initialisation
  5. Sources and references
  6. About ...
  7. License