# Getting a public IP behind NAT

**URL:** <https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212>\
**Category:** Networking\
**Created:** [June 28, 2024, 5:42am UTC](https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212 "2024-06-28T05:42:22Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![gkraemer](https://avatars.discourse-cdn.com/v4/letter/g/6de8d8/32.png) [@gkraemer](https://discuss.ipfs.tech/u/gkraemer)\
**Post date:** [June 28, 2024, 5:42am UTC](https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212/1 "2024-06-28T05:42:22Z")

</div>

I have a question on routing and networking:

- I have an IPFS server that I want to be reachable on the local network and publicly.
- The server is inside a university network with a local IP and can access the internet through NAT
- Because I wanted a public IP, university IT has set up their loadbalancer to route port 4001 (TCP and UDP) of a public IP directly to the IPFS server.
- The IP of the NAT and the one from the loadbalancer are different
- Running `ipfs id` does not show the public IP of the loadbalancer but the IPs of some random other IPFS nodes.
- I have asked if IT can set up routing so that the outgoing traffic shows the same IP as the loadbalancer but that is not possible.

Questions:

- Is there a way to have my IPFS node get a public IP?
- Are there performance implications if my node is only accessible through a different node?

---

<div class="post-metadata">

**Author:** ![Jorropo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/jorropo/32/3230_2.png) [@Jorropo](https://discuss.ipfs.tech/u/Jorropo)\
**Post date:** [June 28, 2024, 8:42am UTC](https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212/2 "2024-06-28T08:42:38Z")

</div>

Have you taken a look at [Configure NAT and port forwarding | IPFS Docs](https://docs.ipfs.tech/how-to/nat-configuration/) yet ?

---

<div class="post-metadata">

**Author:** ![gkraemer](https://avatars.discourse-cdn.com/v4/letter/g/6de8d8/32.png) [@gkraemer](https://discuss.ipfs.tech/u/gkraemer)\
**Post date:** [June 28, 2024, 10:24am UTC](https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212/3 "2024-06-28T10:24:44Z")

</div>

Our IT suggested to add this to the config:

```auto
"AppendAnnounce": [
  "/ip4/<public-ip>/tcp/<port>",
  "/ip4/<public-ip>/udp/<port>/quic",
  "/ip4/<public-ip>/udp/<port>/quic-v1",
  "/ip4/<public-ip>/udp/<port>/quic-v1/webtransport"
 ],

```

I’ll try that and then report back

---

<div class="post-metadata">

**Author:** ![gkraemer](https://avatars.discourse-cdn.com/v4/letter/g/6de8d8/32.png) [@gkraemer](https://discuss.ipfs.tech/u/gkraemer)\
**Post date:** [February 7, 2025, 5:48pm UTC](https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212/4 "2025-02-07T17:48:44Z")

</div>

I have been running this setup for quite some time now and other peers do no not automatically connect to the advertised connection:

I have added

```json
    "AppendAnnounce": [
      "/ip4/139.18.16.88/tcp/4001",
      "/ip4/139.18.16.88/udp/4001/quic-v1",
      "/ip4/139.18.16.88/udp/4001/quic-v1/webtransport"
    ]

```

to the config.  
From another instance I can also

```json
$ ipfs swarm connect /ip4/139.18.16.88/tcp/4001/p2p/12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv
connect 12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv success

```

from my home internet I should get a ping of around 20ms (network is busy at the moment)

```bash
$ ping 139.18.16.88
PING 139.18.16.88 (139.18.16.88) 56(84) bytes of data.
64 bytes from 139.18.16.88: icmp_seq=1 ttl=60 time=53.1 ms
64 bytes from 139.18.16.88: icmp_seq=2 ttl=60 time=26.6 ms
64 bytes from 139.18.16.88: icmp_seq=3 ttl=60 time=31.8 ms
64 bytes from 139.18.16.88: icmp_seq=4 ttl=60 time=49.7 ms
64 bytes from 139.18.16.88: icmp_seq=5 ttl=60 time=33.0 ms

```

pinging through ipfs has a ping of ~90ms

```bash
$ ipfs ping 12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv
PING 12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv.
Pong received: time=132.50 ms
Pong received: time=92.26 ms
Pong received: time=90.62 ms
Pong received: time=91.53 ms
Pong received: time=87.80 ms
Pong received: time=91.57 ms
Pong received: time=91.29 ms

```

and I just cannot get a direct connection:

```auto
$ ipfs swarm connect /ip4/139.18.16.88/tcp/4001/p2p/12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv
connect 12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv success
$ ipfs swarm peers | grep Fv$
/ip4/91.132.178.145/tcp/4001/p2p/12D3KooWFPku6T5TENZYBYziYLoR4kQ4wTQxXWX5ouvLQwVWD2Ga/p2p-circuit/p2p/12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv

```

The firewall blocks some of the connections (invalid TCP sequence) because there seems to be some asymmetric routing going on.

---

<div class="post-metadata">

**Author:** ![danieln](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/danieln/32/6408_2.png) [@danieln](https://discuss.ipfs.tech/u/danieln)\
**Post date:** [February 10, 2025, 1:07pm UTC](https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212/5 "2025-02-10T13:07:41Z")

</div>

For whatever reason, it seems that port 4001 is not actually dialable on that IP address (139.18.16.88).

For example, trying to run libp2p identify with [Vole](https://github.com/ipfs-shipyard/vole) against the TCP multiaddr fails:

```auto
vole libp2p ping "/ip4/139.18.16.88/tcp/4001/p2p/12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv"
panic: failed to dial: failed to dial 12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv: all dials failed
  * [/ip4/139.18.16.88/tcp/4001] dial backoff

goroutine 1 [running]:
main.main()
	/Users/myuser/dev/go/pkg/mod/github.com/ipfs-shipyard/vole@v0.0.0-20240806142935-abb8bd4529f0/main.go:343 +0xd94

```

Are you sure you don’t have a firewall blocking incoming connections on port 4001 on the machine running Kubo?

* * *

Port 4001 isn’t blocked (probably not on the load balancer level, but maybe on the node?)

```auto
$ nmap -p4000-4002 139.18.16.88
Starting Nmap 7.95 ( https://nmap.org ) at 2025-02-10 14:07 CET
Nmap scan report for 139.18.16.88
Host is up (0.040s latency).

PORT STATE SERVICE
4000/tcp closed remoteanything
4001/tcp open newoak
4002/tcp closed mlchat-proxy

Nmap done: 1 IP address (1 host up) scanned in 0.15 seconds

```

---

<div class="post-metadata">

**Author:** ![gkraemer](https://avatars.discourse-cdn.com/v4/letter/g/6de8d8/32.png) [@gkraemer](https://discuss.ipfs.tech/u/gkraemer)\
**Post date:** [February 21, 2025, 4:11pm UTC](https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212/6 "2025-02-21T16:11:53Z")

</div>

I had time to look a bit more into this. I have tried

```bash
nc -l -p 4001

```

on the ipfs host and then send a message via

```bash
nc 139.18.16.88 4001

```

and this works just fine.

Playing around with `vole` I got the following:

```bash
vole libp2p connect "/ip4/139.18.16.88/tcp/4001/p2p/12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv"
panic: failed to dial 12D3KooWQZP1ftDawbTRxNmDmcKGmqii7gmLV8oxXgtTycYCcCFv: all dials failed
	 * [/ip4/139.18.16.88/tcp/4001] failed to negotiate security protocol: read tcp4 172.22.243.169:40721->139.18.16.88:4001: read: connection reset by peer

goroutine 1 [running]:
main.main()
	/home/gkraemer/go/pkg/mod/github.com/ipfs-shipyard/vole@v0.0.0-20250216200225-3e3fc561d9f6/main.go:394 +0x1085

```

Searching for the error I came across [this](https://github.com/ipfs/kubo/issues/8120#issuecomment-864518596), and I can confirm connections come from the loadbalancer IP and not the source IP. I hope our IT can fix it and I’ll report back.

---

<div class="post-metadata">

**Author:** ![danieln](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ipfs.tech/danieln/32/6408_2.png) [@danieln](https://discuss.ipfs.tech/u/danieln)\
**Post date:** [February 24, 2025, 9:18am UTC](https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212/7 "2025-02-24T09:18:39Z")

</div>

Are you running in Kubernetes?

If so, I suspect that it’s indeed due to how external traffic is routed to your IPFS node. Specifically, whether the original source IP for external traffic to the load balancer is preserved when it reaches your IPFS node.

> `Cluster` obscures the client source IP and may cause a second hop to another node, but should have good overall load-spreading. `Local` preserves the client source IP and avoids a second hop for LoadBalancer and NodePort type Services, but risks potentially imbalanced traffic spreading. [Create an External Load Balancer | Kubernetes](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip)

Otherwise, I would look into how the load balancer is configured and whether incoming traffic preserves the source IP.

---

<div class="post-metadata">

**Author:** ![gkraemer](https://avatars.discourse-cdn.com/v4/letter/g/6de8d8/32.png) [@gkraemer](https://discuss.ipfs.tech/u/gkraemer)\
**Post date:** [March 4, 2025, 4:41pm UTC](https://discuss.ipfs.tech/t/getting-a-public-ip-behind-nat/18212/8 "2025-03-04T16:41:18Z")

</div>

I think I solved it, I will let it run for a couple of days and then report back if there are more issues.

IT said it is not possible for the load balancer to maintain its source IP and compared the situation to a home router, where `ipfs` also sits behind NAT and only sees the local address of the router. So this should be very similar to a situation that is actually quite common for `ipfs`.

So I did a test and set up port forwarding on my home router (I am lucky to have a real ipv4 IP at home) and configured my public IP in `Addresses.Announce`. `ipfs id` then gave my local ip but after ~ 2 minutes, I was switched to a relay connection.

Because the ipfs server has both a public IP from the loadbalancer and University NAT, the same always happened to the ipfs server.

I have changed

```bash
$ ipfs --api=/ip4/127.0.0.1/tcp/5001 config Swarm.RelayClient.Enabled
false

```

and voila, no more random relays and things seem to work fine. From prior experience I know that IPFS doesn’t work well through our university NAT and therefore I strongly suspect that `ipfs`’ eagerness to use relays when it is behind NAT together with the NAT issues caused the problem.
