How to setup IPFS behind a secure reverse proxy using a domain name

Pre-requisites

  • Make sure your system is up to date. I am using Ubuntu 20.04 in this example.
  • Your server should be hardened. I suggest following the guide first to make sure everything works first before locking the server down.
sudo -i
apt update
apt upgrade

Install IPFS

  1. Identify the latest version of IPFS here: https://dist.ipfs.io/go-ipfs.
  2. Download the latest IPFS binary.
wget https://dist.ipfs.io/go-ipfs/v0.5.1/go-ipfs_v0.4.14_linux-amd64.tar.gz
tar xfv go-ipfs_v0.5.1_linux-amd64.tar.gz
cp go-ipfs/ipfs /usr/local/bin/
  1. Create a new user and give them superuser privileges.
adduser ipfs
su ipfs
  1. Initialize IPFS
ipfs init --profile=server

Add IPFS as a service so it will automatically run at system boot

  1. Switch to the root user and enable user-lingering.
sudo -i
loginctl enable-linger ipfs
  1. Create the IPFS service by creating the file /etc/systemd/system/ipfs.service with the following content:
[Unit]
Description=IPFS daemon

[Service]
User=ipfs
Group=ipfs
ExecStart=/usr/local/bin/ipfs daemon --enable-gc
Restart=on-failure

[Install]
WantedBy=multi-user.target
  1. Enable and start the service
systemctl enable ipfs
systemctl start ipfs
  1. Add your static website to IPFS
~$ ipfs add -r site

added QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH site/cat.jpeg
added QmXrjnnXnTQEkhvYCvayRsJZ2W2oMxyG16QKwukRhf8AMy site/gobsmack.svg
added QmVXjiQB3ghwnN1Mv9UGfvbUdcWiJo5bm6FFpE5Sj2PvE9 site/index.html
added QmfGLJ3mryLvicQqzdsghq4QRhptKJtBAPe7yDJxsBGSuy site/styles.css
added QmXqNmf4ipTN3R9yAdGvkoxnijsggifLVKeezkKHfjJ9nz site/test.html
added QmTBeoRbhksH5pbmwywsYba5ZmzcnHvK3UBZQZHEZpLeXM site

At this point you should be able to view your website via the IPFS gateway at the url:

https://ipfs.io/ipfs/QmTBeoRbhksH5pbmwywsYba5ZmzcnHvK3UBZQZHEZpLeXM

The hash of your website will obviously be different.

Whenever you change the contents of the files in the site directory you must run the ipfs add -r site command again.

Install Nginx

  1. Install the package.
apt-get install nginx
  1. Add the virtual host configuration at /etc/nginx/sites-available/default (I suggest backing up the file first).
server {
    server_name example.com ipfs.example.com;
    server_tokens off;

    listen 80;
    listen [::]:80;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

  1. Reload Nginx.
systemctl reload nginx

Install and configure Certbot and Letsencrypt.

  1. Install Certbot.
add-apt-repository ppa:certbot/certbot
apt-get update
apt-get install python3-certbot-nginx
  1. Register your domains with Certbot.
certbot --nginx -d example.com -d ipfs.example.com
  1. When given the option choose to have HTTP requests redirected to HTTPS.
  2. Reload Nginx.
systemctl reload nginx
  1. Add a cron schedule that will automatically check and renew the Letencrypt SSL certificate.
crontab -e
15 3 * * * /usr/bin/certbot renew --quiet

Access your website via your own domain name

  1. Go to your domain control panel. In this example I am using the 123-reg control panel, but they are all similar in function.
  2. Add an A record for subdomain ipfs and point it at your servers IP address.
  3. Add an A record for * and point it at your servers IP address.
  4. Add a TXT/SPF record for _dnslink with the value of dnslink=/ipfs/QmTBeoRbhksH5pbmwywsYba5ZmzcnHvK3UBZQZHEZpLeXM where the hash is the site directory.
  5. Allow some time for the DNS changes to propogate then navigate to your web domain and you should see the site directory structure on the webpage.

Use IPNS to map changes to your website

  1. Publish your website
ipfs name publish QmTBeoRbhksH5pbmwywsYba5ZmzcnHvK3UBZQZHEZpLeXM
Published to QmYWWepdwC4rQm1qCvims4YC4iBKfptuEtJSGpQ4ptmXvy: /ipfs/QmTBeoRbhksH5pbmwywsYba5ZmzcnHvK3UBZQZHEZpLeXM
  1. Modify the _dnslink record for your domain so it is using the IPNS hash that is mapped to the site hash.
dnslink=/ipfs/QmTBeoRbhksH5pbmwywsYba5ZmzcnHvK3UBZQZHEZpLeXM
  1. Whenever you update your website you must republish it to bind the IPNS hash to the new site hash.

Run IPFS with Systemd

  1. Create the Systemd configuration file.
sudo nano /etc/systemd/system/ipfs.service
  1. Paste the following contents:
[Unit]
Description=IPFS Daemon

[Service]
ExecStart=/usr/local/bin/ipfs daemon
User=chris
Restart=always
LimitNOFILE=10240

[Install]
WantedBy=multi-user.target
  1. Refresh Systemd
sudo systemctl daemon-reload
sudo systemctl enable ipfs
sudo systemctl start ipfs
  1. Start IPFS
sudo systemctl start ipfs
  1. Verify that IPFS started successfully
systemctl status ipfs

Notes on systemd

    See high-level information on how the IPFS daemon is doing:
    $ systemctl status ipfs
    Stop the daemon:
    $ systemctl stop ipfs
    Start the daemon:
    $ systemctl start ipfs
    See all logs from the daemon:
    $ journalctl -u ipfs
    See only most recent logs, and show new logs as they’re written:
    $ journalctl -f -u ipfs

Common IPFS commands

CommandDescription
ipfs initInitializes a new IPFS server node.
ipfs daemon > ipfs.log &Start the IPFS daemon in the background and output to the log file.
ipfs add -r siteRecursively add a directory (and all of its contents) to IPFS.
ipfs name publishMap the directory (or file) hash to the Nodes CID.