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.