Skip to content

Commit dd4cd30

Browse files
committed
Fix: I discovered an issue after last Ubuntu updates at the moment of allocating port forwarding rules.
1 parent dd11d1b commit dd4cd30

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

src/aleph/vm/network/firewall.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,25 @@ def get_base_chains_for_hook(hook: str, family: str = "ip") -> list:
9090

9191
def get_table_for_hook(hook: str, family: str = "ip") -> str:
9292
chains = get_base_chains_for_hook(hook, family)
93-
table = chains.pop()["chain"]["table"]
93+
if not chains:
94+
raise Exception(f"Could not find any base chain for hook '{hook}'")
95+
96+
# Sort by priority, lowest-to-highest
97+
chains.sort(key=lambda x: x["chain"].get("prio", 0))
98+
99+
if hook == "prerouting":
100+
# For prerouting (DNAT), we MUST use the 'nat' type hook.
101+
# Filter for 'nat' type chains and pick the one with the highest priority (last in list).
102+
nat_chains = [c for c in chains if c["chain"].get("type") == "nat"]
103+
if not nat_chains:
104+
# Fallback: maybe only the 'raw' chain exists. This will fail, but it's what the log shows.
105+
logger.warning(f"No 'nat' type prerouting chain found. Falling back to highest prio chain.")
106+
table = chains[-1]["chain"]["table"]
107+
else:
108+
table = nat_chains[-1]["chain"]["table"] # Pick highest prio 'nat' chain
109+
else:
110+
# For forward/postrouting, use the lowest priority (earliest)
111+
table = chains[0]["chain"]["table"]
94112
return table
95113

96114

@@ -230,9 +248,21 @@ def initialize_nftables() -> None:
230248
new_chain = {"chain": chain}
231249
commands.append({"add": new_chain})
232250
chains.append(new_chain)
233-
# If multiple base chain for the hook, use the less priority one
251+
252+
# Sort by priority, lowest-to-highest
234253
chains.sort(key=lambda x: x["chain"]["prio"])
235-
base_chains[hook] = chains[0]["chain"]
254+
255+
if hook == "prerouting":
256+
# For prerouting, we MUST use the 'nat' type hook which has a higher priority than the 'raw' hook,
257+
# We filter for 'nat' type, and if multiple, pick the one with highest priority (last in list).
258+
nat_chains = [c for c in chains if c["chain"].get("type") == "nat"]
259+
if not nat_chains:
260+
raise Exception("Failed to find or create a 'nat' type prerouting chain")
261+
base_chains[hook] = nat_chains[-1]["chain"] # Pick highest prio 'nat' chain
262+
else:
263+
# For other hooks (forward, postrouting), use the original logic:
264+
# the one with the lowest priority (earliest).
265+
base_chains[hook] = chains[0]["chain"]
236266

237267
# Add chain aleph-supervisor-nat
238268
commands += add_entity_if_not_present(

0 commit comments

Comments
 (0)