I am also behind CGNAT, here is how I got it working:
- I already had a PIA (Private Internet Access) subscription which supports port forwarding
- Used the split tunnel option in PIA to only route the storj node exe through the VPN.
- Enabled port forwarding in PIA
- Used GitHub - skibish/ddns: Personal DDNS client with Digital Ocean Networking DNS as backend. with a subdomain on a domain I own with the DNS hosted on DigitalOcean (note: also used split tunnel to only route the ddns.exe through the VPN to use the correct IP). I run this on startup with task scheduler with a delay of 1 minute to allow the VPN to start and connect.
- Finally I created a little python script that uses the PIA CLI to get the active forwarded port (the ports expire after 2 months) and if it changed it updates the storj config file and restarts the storage node windows service. I run this also every 5 minutes using task scheduler.
Here is what my config looks like (make a copy of your config before making any changes):
# I changed this to 0.0.0.0 to allow access from other computers in my internal network,
# This would be a security risk though if I am not behind CGNAT since it would allow access
# from the internet
console.address: 0.0.0.0:14002
# Here I put the subdomain I use for the DDNS
# The first time I just entered the port PIA shows, then my script changes this automatically
# when the port expires and PIA gets a new one
contact.external-address: <ddns-subdomain>.<your-domain>:31189
identity.cert-path: C:\Users\******\wh\storj\Identity\storagenode\identity.cert
identity.key-path: C:\Users\******\wh\storj\Identity\storagenode\identity.key
log.level: info
log.output: winfile:///C:\Program Files\Storj\Storage Node\\storagenode.log
operator.email: ***************************@gmail.com
operator.wallet: '0x******************************************'
operator.wallet-features: ''
# This needs to be the same as the port in contact.external-address, also updated
# automatically by my script when the PIA port changes, had to set it up the first time only
server.address: :31189
server.private-address: 127.0.0.1:7778
storage.allocated-bandwidth: 0 B
storage.allocated-disk-space: 550 GB
storage.path: B:\
Finally here is the python script (Must be run with admin privileges because it needs to access the program files directory to modify the storj node config):
Run at your own risk
Also has a dependency on PyYAML so you must install it using pip install pyyaml
import re
import yaml
import subprocess
from os import path
pia_exe = "C:\Program Files\Private Internet Access\piactl.exe"
cp = subprocess.run([pia_exe, "get", "portforward"],
capture_output=True, text=True)
stdout_pattern = r"[0-9]{5}"
stdout_match = re.match(stdout_pattern, cp.stdout, flags=re.IGNORECASE)
if not stdout_match:
exit(1)
portforward_status = stdout_match.group()
with open("C:\Program Files\Storj\Storage Node\config.yaml", "r+") as storj_config:
config = yaml.load(storj_config, Loader=yaml.SafeLoader)
if config["server.address"] != f":{portforward_status}":
# Delete existing contents and seek to start
storj_config.truncate(0)
storj_config.seek(0)
# Write modified config
config["server.address"] = f":{portforward_status}"
config["contact.external-address"] = f"subdomain.domain.example:{portforward_status}"
# Otherwise this will get dumped as an integer
config["operator.wallet"] = hex(config["operator.wallet"])
yaml.dump(config, storj_config)
# Stop & restart Storj service
subprocess.run(["net", "stop", "storagenode"], check=True)
subprocess.run(["net", "start", "storagenode"], check=True)