Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Docker published ports on host unreachable from ipvlan container on another VLAN, Unraid 7.3.4

Featured Replies

Hi all. I hope this is the correct forum for this question. While I reference container names, I don't think my issue is container specific.

I've been attempting to get a DMZ vlan running on my home network, but have running into a problem where a container on the DMZ vlan cannot communicate with a port published by docker to my server's ip on my main vlan. After coming up empty searching the internet, I tried turning to an ai agent. The ai had me run some diagnostics, but was not able to provide a solid conclusion about why this issue could be happening. I've asked it to generate a short summary that I could post here in hopes a real person might be able to help me understand my flaw (other than trusting a computer). The summary is below:


Setup

  • Unraid 7.3.4, host IP 10.1.1.2 on br0 (UniFi gateway at 10.1.1.1).

  • VLAN 30 with IPv4 address assignment None. Docker network type: ipvlan. “Host access to custom networks”: off. (Author note: It seems like a commonly suggested solution to other issues is to enable this. I don't think it should need to be enabled for my case based on my understanding of the setting, but I tried enabling it just in case and did not experience any change in behavior.)

  • Seerr on the br0.30 ipvlan network (10.1.30.14). Radarr is on a user-defined bridge with published port 7878. A firewall rule allows 10.1.30.14 → 10.1.1.2:7878, and the flow log shows it allowed.

Problem
From Seerr’s network namespace, curl http://10.1.1.2:7878/ times out with 0 bytes received. The TCP handshake completes, but no data is ever accepted afterward.

What works from the same container

  • Internet access.

  • Home Assistant VM at 10.1.1.20:8123 (also reached from a second ipvlan container).

  • A native host service (Unraid web UI, port 80).

  • A native listener on the host (busybox httpd -p 8099, --net=host).

What fails

  • A fresh test container (nginx:alpine, -p 8099:80 on the user-defined bridge), with a firewall rule for the port. So Docker-published ports fail while native host ports work.

Diagnostics

  • Host capture: the SYN arrives, and the SYN-ACK and reply leave on br0 and return on br0.30.

  • Capture inside the container’s namespace: the replies arrive on eth0 with valid checksums, but the container keeps retransmitting as if it received nothing. ss -tin shows segs_in:1, bytes_acked:1.

  • Inside the container: rp_filter = 0, all drop and checksum counters = 0, only the nat iptables table present.

  • On the host: rp_filter = 0, no route for 10.1.30.0/24, no address on br0.30.

Questions

  1. Is there a known reason a Docker-published (DNAT’d) port would fail for an ipvlan container on a VLAN while native host listeners work?

  2. Does Unraid 7.x treat this traffic differently (VLAN set to None, br0.30 as the ipvlan parent, Docker’s published-port rules)?


I apologize for the wall of ai, but I'm pretty out of my depth here trying to diagnose this issue. Any help is much appreciated!

Edited by the_capn
Removed link that was added automatically

  • Community Expert
22 minutes ago, the_capn said:

I apologize for the wall of ai, but I'm pretty out of my depth here trying to diagnose this issue.

No worries, here's an AI-assisted reply, since this is also out of my wellhouse, but AI is, in my experience, typically pretty good at resolving this kind of issue.

The most important result is that a host-network listener on port 8099 works from Seerr, but a Docker-published port 8099 does not. That rules out the VLAN routing, the UniFi firewall rule and the inter-VLAN path. The traffic takes the same route in both tests. The only difference is that the published port goes through Docker's NAT on the host before it reaches the bridge container. Host access to custom networks is not relevant for this path, so leaving it off is fine.

As a workaround that avoids the published port completely, give Radarr its own IP on your main LAN. Set its network to the custom br0 network (Custom: br0) with a fixed address, for example 10.1.1.30. Then point Seerr at that IP on port 7878 and adjust the firewall rule. This is the same kind of path as your working Home Assistant VM, so it should work. Note that any containers on your user-defined bridge that reach Radarr by its container name will need to use the new IP. If you prefer, Host network mode for Radarr also avoids the NAT, as your busybox test showed.

If you want to help us find out why the published port fails, please run these and post the output:

1. From a physical device on VLAN 30 (a laptop or phone), try http://10.1.1.2:8099 with the nginx test container. This tells us whether the problem only affects ipvlan containers on the same server.

2. On the server, save the current counters, repeat the failing curl from Seerr, then save them again:

cat /proc/net/stat/nf_conntrack > /tmp/ct-before.txt

nsenter -t $(docker inspect -f '{{.State.Pid}}' seerr) -n nstat -az > /tmp/ns-before.txt

# run the failing curl from Seerr now

cat /proc/net/stat/nf_conntrack > /tmp/ct-after.txt

nsenter -t $(docker inspect -f '{{.State.Pid}}' seerr) -n nstat -az > /tmp/ns-after.txt

Please post the four files. The counters that change show where the replies are dropped.

3. Please also attach your diagnostics (Tools > Diagnostics), taken after a failed test.

  • Author

Thank you for the quick response. I connected my phone to my dmz vlan, and validated I could connect to both the temporary nginx at 8099 and radarr at 7878. I did my best to run the scripts you provided, hopefully everything is correct.
As to putting radarr on my main network via ipvlan/br0, my hope was to keep my docker containers separated from my internal network where possible. But then again, my understanding of netsec is pretty shoddy, so I might be chasing down a goal that doesn't even provide a real benefit.

Oh, one other thing. curl isn't included in the Seerr container, so I have been using wget --tries=1 --timeout=5 http://10.1.1.2:7878 to attempt to connect instead. Not sure if that makes a difference.

ct-after.txt ct-before.txt ns-after.txt ns-before.txt merlin-diagnostics-20261029-1506.zip

Edited by the_capn
added extra info

  • Community Expert

That was very helpful. The phone test shows that the router, the firewall rule and the published port all work. The problem only happens when the client is an ipvlan container on the same server.

I believe this is what happens. On Unraid, VLAN 30 is a separate bridge (br0.30), and Seerr's ipvlan interface sits on it. Docker loads br_netfilter, so packets that enter that bridge also go through the host's connection tracking. When your phone connects, Radarr's replies go to the router and out over Wi-Fi, and they never touch the server again. When Seerr connects, the replies come back from the router into br0.30, and the host checks them a second time. The host already has a NAT entry for the connection, which translates 10.1.1.2:7878 to Radarr's internal 172.18.0.x address. The returning reply doesn't match that entry, so the host treats it as a new connection that clashes with the existing one, and NAT changes the port. The SYN-ACK isn't affected, which is why the handshake completes. Every packet after it arrives at Seerr with the wrong port, so Seerr doesn't recognize it and sends a reset. Your counters match this: about 20 TCP segments reached Seerr's network namespace during the test, but they never reached the connection, and Seerr's reset counter went up by 18. With the busybox listener there is no NAT, so the returning replies match the existing entry and nothing is changed.

To test this, please run the following on the server. It tells the host not to track packets that arrive on the VLAN 30 bridge. The host has no IP on VLAN 30, so it doesn't need to track them:

iptables -t raw -I PREROUTING -i br0.30 -j NOTRACK

Then repeat the wget from Seerr. To remove the rule, run:

iptables -t raw -D PREROUTING -i br0.30 -j NOTRACK

The rule is also removed when you reboot.

If it works, you can keep your current setup. To make the rule permanent, add the same iptables line to the end of /boot/config/go. If you add more VLANs later with ipvlan containers that need to reach published ports, add one line for each VLAN bridge, for example br0.20.

About keeping Radarr off the main LAN: a published port on 10.1.1.2 is already reachable from your main LAN. So giving Radarr its own br0 IP would not reduce separation. But if the rule above works, you don't need to change anything. You can also turn "Host access to custom networks" back off, because it doesn't affect this path.

Please let us know the result.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.