I’m developing an app and I need nodes to be reachable behind NAT.
I create a new node like so and it works perfectly:
host, err := libp2p.New(
ctx,
libp2p.ListenAddrStrings(nodeAddrStrings...),
libp2p.Identity(privKey),
libp2p.EnableNATService(),
libp2p.NATPortMap(),
libp2p.EnableRelay(circuit.OptHop),
)
if err != nil{
return errors.Wrap(err, "creating libp2p host")
}
If I put my app inside docker, a node can no longer find its public address. From the docs:
The default NATManager will attempt to open a port in your network’s firewall using UPnP.
So I assume the problem is that there is no appropriate connection from the dockerized app to my network’s firewall.
Is there any solution to this?
Unfortunately, you’re likely double-natted at this point. One NAT for your computer, one NAT for the container. Libp2p likely can’t even find your outer NAT device. The simple solution for now is to use host networking in docker (as long as you don’t need network isolation).
Ideally go-libp2p would handle this case, but it’s a bit tricky. We’d need to:
- Traceroute to a well-known IP address (or maybe just some subset of our peers).
- For all private IP addresses encountered before we hit a public IP address, attempt to map ports with UPnP from the inside out.
Unfortunately, nobody’s working on this right now.
@moratsam You can discover the public IP by making an API call to http://ip-api.com/json/ and add the public IP to the address factory of the libp2p host.
I hope this helps, @stebalien Does this approach have any attack vectors.