Self Hosting Firefox Send

Ahmed Musaad
Ahmed Musaad
Self Hosting Firefox Send
Table of Contents
Table of Contents

Firefox Send is a great file sharing service with E2EE and automatic deletion. In this post, I walk you through the steps to self host your own instance.

Last Updated: 2020-09-30 (Fixed a mistake in the Nginx configuration)

Firefox Send is an open-source file sharing service from Mozilla, it lets you share files with end-to-end encryption and a link that automatically expires. So you can keep what you share private and make sure your stuff doesn’t stay online forever.

Benefits of Send

  • End-end encryption.
  • Short lifetime for sharing links.
  • Password protection for files.
  • Up to 2.5GB per file.

Self Hosting Your Own Send Instance

You are going to need:

  • A VPS running Ubuntu 18.04.
  • A Subdomain pointing to your VPS (let's assume we are using send.ahmedmusaad.com)
  • (Optional) S3 or GCP Bucket for file storage.

Install

Install git curl nginx nodejs npm

sudo apt install git curl nginx nodejs npm

Install Docker &  Docker-Compose

sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce

sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Clone The Code

cd /opt
mkdir send
git clone https://github.com/mozilla/send.git send/
cd send/

Configure Send & Web Server

You can find the configuration file for Send at server/config.js. The most important configuration options are:

s3_bucket: The name of your S3 bucket.
gcs_bucket: The name of you GCS bucket.
listen_address & listen_port: The listening address and port.
base_url: The base url of the application.

Configure Size Limits

The configuration file contains a section for size limit configuration, adjust the values to your desired limit. The default limit is 2.5 GB.

max_file_size: {
    format: Number,
    default: 1024 * 1024 * 1024 * 2.5,
    env: 'MAX_FILE_SIZE'
}

Configure Nginx Reverse Proxy

Below you can find the nginx configuration you need to use to get things working properly. Remember to:

  • Fetch a SSL certificate using Let's Encrypt
  • Replace <(sub)Domain> with your domain/subdomain.
upstream websocket {
                server 127.0.0.1:1443;
}

map $http_upgrade $connection_upgrade {
                default upgrade;
                '' close;
}

server {

        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name send.ahmedmusaad.com;

        location / {
                proxy_pass http://127.0.0.1:1443;
                proxy_redirect / $scheme://$http_host/;
                proxy_set_header Upgrade $http_upgrade;
                proxy_http_version 1.1;
                proxy_set_header Connection $connection_upgrade;
        }

        location /api {
                proxy_pass http://websocket;
                proxy_redirect / $scheme://$http_host/;
                proxy_set_header Upgrade $http_upgrade;
                proxy_http_version 1.1;
                proxy_set_header Connection $connection_upgrade;
                proxy_set_header Host $host;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/send.ahmedmusaad.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/send.ahmedmusaad.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}


server {
    if ($host = send.ahmedmusaad.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80 default_server;
        listen [::]:80 default_server;

        server_name send.ahmedmusaad.com;
    return 404; # managed by Certbot

}

Run Send

sudo docker-compose up -d
sudo systemctl restart nginx.service

Add Basic HTTP Authentication

If we leave the Send instance open on the internet, a malicious actor will find and abuse it. In this section, we will add a basic HTTP authentication to our Send instance to prevent abuse or unwanted attention.

Install apache2-Utils

sudo apt-get update
sudo apt-get install apache2-utils

Create a username/password

sudo htpasswd -c /etc/nginx/.htpasswd <USERNAME> #Replace USERNAME with the username you want to use. 

Update Nginx Configuration

You updated Nginx configuration should look like this:

upstream websocket {
                server 127.0.0.1:1443;
}

map $http_upgrade $connection_upgrade {
                default upgrade;
                '' close;
}

server {

        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name send.ahmedmusaad.com;

        auth_basic           "Firefox Send";
        auth_basic_user_file /etc/apache2/.htpasswd;

        location / {
                proxy_pass http://127.0.0.1:1443;
                proxy_redirect / $scheme://$http_host/;
                proxy_set_header Upgrade $http_upgrade;
                proxy_http_version 1.1;
                proxy_set_header Connection $connection_upgrade;
        }

        location /download/ {
                auth_basic off;
                proxy_pass http://127.0.0.1:1443;
                proxy_redirect / $scheme://$http_host/;
                proxy_set_header Upgrade $http_upgrade;
                proxy_http_version 1.1;
                proxy_set_header Connection $connection_upgrade;
        }

        location /api {
                auth_basic off;
                proxy_pass http://websocket;
                proxy_redirect / $scheme://$http_host/;
                proxy_set_header Upgrade $http_upgrade;
                proxy_http_version 1.1;
                proxy_set_header Connection $connection_upgrade;
                proxy_set_header Host $host;
        }

        location ~* \.(js|css|png|svg|woff2)$
        {
                auth_basic off;
                proxy_pass http://127.0.0.1:1443;
                proxy_redirect / $scheme://$http_host/;
                proxy_set_header Upgrade $http_upgrade;
                proxy_http_version 1.1;
                proxy_set_header Connection $connection_upgrade;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/send.ahmedmusaad.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/send.ahmedmusaad.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}


server {
    if ($host = send.ahmedmusaad.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80 default_server;
        listen [::]:80 default_server;

        server_name send.ahmedmusaad.com;
    return 404; # managed by Certbot

}

Restart Nginx

sudo service nginx restart

That's it.

via GIPHY

References



Great! Next, complete checkout for full access to Ahmed Musaad
Welcome back! You've successfully signed in
You've successfully subscribed to Ahmed Musaad
Success! Your account is fully activated, you now have access to all content
Success! Your billing info has been updated
Your billing was not updated