Protecting an IPFS node with nginx reverse proxy and http basic auth on Ubuntu 18.04

I needed to set up an IPFS node, and I’d like to share how I secured it, because I couldn’t find a great guide to this.

First, setup and install IPFS using the instructions here: https://docs.ipfs.io/introduction/install/

I used the prebuilt binary for Ubuntu, and moved it to /usr/local/bin. After you’ve moved it, run this: ipfs init; ipfs config profile apply server

Install Nginx, and then install Certbot for it using the instructions here: https://certbot.eff.org/lets-encrypt/ubuntuxenial-nginx.html

I created a systemd init script for ipfs to make sure it stays running and starts on reboot, but this is optional. If you’d like the init script, put the text below into /lib/systemd/system/ipfs.service

[Unit]
Description=IPFS Daemon
[Service]
Type=simple
User=ubuntu
Environment=HOME=/home/ubuntu
Restart=always
ExecStart=/usr/local/bin/ipfs daemon
[Install]
WantedBy=multi-user.target

If you’d like to start the service, you can do so with sudo systemctl start ipfs and if you’d like to make sure it runs automatically on startup, you should run sudo systemctl enable ipfs

Next, you’ll want to set up the nginx reverse proxy. To do this, I ran sudo certbot --nginx and put in my domain name when prompted. This set up my nginx config file at /etc/nginx/sites-enabled/default There was already another server{} entry at the top of the file, so I deleted it and just left the one created by certbot. I also had certbot create an entry to redirect http to https. I added a location{} entry to pass incoming requests to the IPFS api exposed on localhost:5001.

I also added authentication using HTTP basic auth, which can be done by follwing these instructions: https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/ but I used /etc/nginx/.htpasswd for my .htpasswd path because /etc/apache2 does not exist on my machine because I only have nginx.

I also want to only expose the /api/v0/add endpoint because that’s all I need right now. So in the nginx config file, traffic to that endpoint is allowed, and all other traffic is denied.

The end result is this nginx config file at /etc/nginx/sites-enabled/default

server {
server_name ipfs.deco.network; # managed by Certbot
    location /api/v0/add {
proxy_pass http://localhost:5001;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
allow all;
}
    location / {
proxy_pass http://localhost:5001;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
deny all;
}
    auth_basic           "Authentication Required";
auth_basic_user_file /etc/nginx/.htpasswd;
    listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/ipfs.deco.network/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/ipfs.deco.network/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 = ipfs.deco.network) {
return 301 https://$host$request_uri;
} # managed by Certbot
    listen 80 ;
server_name ipfs.deco.network;
return 404; # managed by Certbot
}

Good luck!