Skip to content

Instantly share code, notes, and snippets.

@arrogantrabbit
Last active October 18, 2025 04:58
Show Gist options
  • Select an option

  • Save arrogantrabbit/217a9845eaf9642537eb80d2f700a434 to your computer and use it in GitHub Desktop.

Select an option

Save arrogantrabbit/217a9845eaf9642537eb80d2f700a434 to your computer and use it in GitHub Desktop.
Hosting services, like Storj, behind firewall/GNAT, using Wireguard on a VPS and DNAT (Port Forwarding) with iptables.

This is a short description of how to host storj node if you are behind GNAT, or for some other reasons cannot get routable address with DNAT to your node, but have a relatively fast VPS nearby.

As an example I will use an Oracle Cloud instance. Free tier still provides 10TB of monthly traffic, and is a pretty good deal otherwise. Just make sure that you create an account in a datacenter closest to you to minimize extra latency.

Notes on configuring the instance

  1. Create the oracle compute instance (ideally, Ampere, because they are awesome, but if that is not availabe, any other will do too.
  2. Pick any OS you prefer, I've picked ubuntu here, simply beacause most people is familiar with it.
  3. Configure public IP address (this is the default), and upload SSH key to access the instance.
  4. Then edit the default security list associated with the virtual network adapter and add two rules to allow connection from anywhere 0.0.0.0/0 from any port, to destination port 28967, one for udp, one for tcp. This is for storj. Also add udp port 51820, for WireGuard. Does not need to be this specific port, any will do, just adjust the rest accordingly. That's all that needs to be done in Oracle console
  5. Optionaly configure the public IP as an A record on your DNS provider, to use DNS name and not an ugly IP address in the subsequent configuration and in your storj node.

Installing and configuring wireguard tunnel

  1. ssh to your new instance, update software, and install wireguard:

        sudo apt update && sudo apt upgrade
        sudo reboot
        sudo apt install wireguard -y
  2. Configure wireguard tunnel between your node and VPS. There are tons of tutorials, here are the steps for reference:

    On the VPS:

    1. Initialize the config file
        (umask 077 && printf "[Interface]\nPrivateKey= " | sudo tee /etc/wireguard/wg0.conf > /dev/null)
        wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
    1. Add peer info from below

    2. Enable ipv4 forwarding: in /etc/sysctl.conf uncomment

      # Uncomment the next line to enable packet forwarding for IPv4
      net.ipv4.ip_forward=1   

      and for the change to take effect:

      sudo sysctl -p
      sudo sysctl --system
    3. Enable and start the service

      sudo systemctl enable wg-quick@wg0
      sudo systemctl start wg-quick@wg0

    On the client, assuming it's a TrueNAS and storj runs in the jail, we would need few things:

    1. In the jail properties tick the allow_tun flag. (e.g. iocage set allow_tun=1 jailname)
    2. On the host under System -> Tunables add LOADER variable if_wg_load with the value YES, to load wireguard kernel module.
    3. Initialize the wireguard config file and create keys just like above, noting that in FreeBSD the configuration file location will be /usr/local/etc/wireguard/wg0.conf
    4. In the jail in the /etc/rc.conf add
      wireguard_enable="YES"
      wireguard_interfaces="wg0"

    Generally, the config files shall look like so:

    1. On the server: /etc/wireguard/wg0.conf

      [Interface]
      PrivateKey = <private key of a server>
      
      ListenPort = 51820
      Address = 10.0.60.1
      
      # Allow WireGuard through the firwall
      PreUp = iptables -I INPUT 6 -p udp --dport 51820 -j ACCEPT
      PostDown = iptables -D INPUT -p udp --dport 51820 -j ACCEPT
      
      [Peer]
      PublicKey = <public key of a client>
      AllowedIPs = 10.0.60.2
    2. On the client: /usr/local/etc/wireguard/wg0.conf

      [Interface]
      PrivateKey = <private key of the client>
      Address = 10.0.60.2
      [Peer]
      PublicKey = <public key of a server>
      AllowedIPs = 10.0.60.1/32
      Endpoint = sub.example.com:51820
      PersistentKeepalive = 25
    3. Start the service on the client:

      service wireguard start

    At this point the client shall be able to ping the server and the server shall be able to ping the clinet at 10.0.60.1 and 10.0.60.2 addresses respectively.

Packet forwarding.

Now the very last thing. In the [Interface] section on the server in the /etc/wireguard/wg0.conf add the following rules

# Allow forwarding
PreUp = iptables -I FORWARD -i %i -j ACCEPT
PreUp = iptables -I FORWARD -o %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -o %i -j ACCEPT

# Turn on masquarading
PreUp = iptables -t nat -I POSTROUTING -o %i -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o %i -j MASQUERADE


# Allow STORJ and Wireguard ports through the firewall
# Note we are inserting the ACCEPT rule at position 6, before the REJECT rule
PreUp = iptables -I INPUT 6 -p tcp -m state --state NEW --dport 28967 -j ACCEPT
PreUp = iptables -I INPUT 6 -p udp --dport 28967 -j ACCEPT
PreUp = iptables -I INPUT 6 -p udp --dport 51820 -j ACCEPT
PostDown = iptables -D INPUT -p tcp -m state --state NEW --dport 28967 -j ACCEPT
PostDown = iptables -D INPUT -p udp --dport 28967 -j ACCEPT
PostDown = iptables -D INPUT -p udp --dport 51820 -j ACCEPT

# DNAT it
PreUp = iptables -t nat -I PREROUTING -p tcp --dport 28967 -j DNAT --to-destination 10.0.60.2:28967
PreUp = iptables -t nat -I PREROUTING -p udp --dport 28967 -j DNAT --to-destination 10.0.60.2:28967
PostDown = iptables -t nat -D PREROUTING -p tcp --dport 28967 -j DNAT --to-destination 10.0.60.2:28967
PostDown = iptables -t nat -D PREROUTING -p udp --dport 28967 -j DNAT --to-destination 10.0.60.2:28967

These acomplish few things:

  1. Allow new tcp and udp connections to Storj port (note inserting the rule before rule 6, on oracle instances rule 6 is reject) as wel as wireguard server itself.
  2. Allow Storj packet forwarding to wireguard interface
  3. Turn on NAT

Now restart the wireguard server:

sudo systemctl restart wg-quick@wg0

Restart wireguard client:

service wireguard restart

In the config.yaml of the storage node modify the external address to point to your vps:

# the public address of the node, useful for nodes behind NAT
contact.external-address: sub.example.com:28967

[Re]start the node, and check the status page. It shall be now happily connected.

@DeflateAwning
Copy link

Is there a way to do everything on the "Storj client computer" within the Dockerfile or within a docker-compose, so that it is fully modular and does not impact the host OS on the Storj client computer.

@woodendoors7
Copy link

Beautiful!! I was able to make it work with storj

@ItsHass
Copy link

ItsHass commented Mar 15, 2024

any videos on this ?

@arrogantrabbit
Copy link
Author

It would be the most boring video on the planet -- some dude copy pasting commands and clicking buttons :) You can do it from text at your own pace ;) Don't forget to click subscribe and hit the bell icon to get notified about all future videos!

@arrogantrabbit
Copy link
Author

Is there a way to do everything on the "Storj client computer" within the Dockerfile or within a docker-compose, so that it is fully modular and does not impact the host OS on the Storj client computer.

Sure. I guess you could create your own image based on the storagenode image, and add wireguard configuration as a separate layer. Still, someone needs to configure the server part of it, and it's easier to do manually since it only needs to done once.

@robertgpeterson
Copy link

Thank you for this framework. I recently discovered Technitium DNS (recommended!) and would like to move my Oracle Free tier to docker with WG-Easy and a Technitium docker instance. I have the WG up and running and can access the GUI interface from either the WG or WG Container IP. (first real container project!). Now i am try to do the same with Technitium. It is installed and running. I can get a nslookup reply from the IP listed in the container. But I cannot get to the GUI using an internal IP (either that of the WG or the container) nor can I get it to reply to a DNS query. Do I need pre/post rules to get from the WG IP to the Technitium IP or some type of networking configuration between containers on the VM ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment