1Panel-dev / 1Panel-dev/1Panel
[Bug] Enabling container port guard (nftables) locks out SSH: nftables initialization ignores existing "Host Firewall" rules and stale FirewallPortWhiteList takes precedence
Open
@wanghe-fit2cloud is already working on this.
Since Sep 14, 2026.
type: question
- Dominant language
- Go
- Stars
- 37k
- Forks
- 3.4k
- Avg merge
- 9h 16m
- Merged PRs (30d)
- 105
Description
Contact Information
No response
1Panel Version
v2.3.0
Steps to Reproduce
- On a Linux server (e.g., Ubuntu 24.04 / 26.04), configure SSH to use a custom port (e.g.,
54321). - In 1Panel web console, navigate to System -> Firewall -> Host Firewall.
- Verify or add an ALLOW rule for port
54321under the host firewall (e.g., UFW backend). The rule clearly shows status "Allowed" for port54321in the 1Panel UI. - Now, navigate to System -> Firewall -> Settings.
- Under Container Port Guard , select nftables as the backend and click apply/initialize.
- Result: The active SSH session on port
54321is immediately dropped, and all subsequent SSH connections are rejected/timed out, completely locking the administrator out.
Problem Description
Tracing 1Panel v2.3.0 reveals a severe design flaw where Host Firewall rules and Container Port Guard (nftables) operate as completely isolated silos:
A. Host Firewall Rules Are Completely Ignored by nftables
- In the 1Panel UI, users manage firewall rules under Host Firewall (
firewall_rules/ system UFW). Here, port54321is clearly listed as Allowed. - However, when enabling Container Port Guard with
nftables, 1Panel's initialization logic (nftables_helper/manager.go) never reads or migrates existing Host Firewall rules. - Because
nftableshooks directly into the Linux netfilter pipeline, it bypasses UFW entirely.
B. The Stale Database Cache (FirewallPortWhiteList) Overrides Everything
- Instead of checking active host firewall rules or active listening sockets,
initPreRules()strictly pulls from the static database settingFirewallPortWhiteList(inagent.db):SELECT value FROM settings WHERE key = 'FirewallPortWhiteList'; -- Permanently stuck at installation default: "22/tcp\n80/tcp\n443/tcp\n443/udp" - Even though
54321was explicitly allowed in the UI's Host Firewall tab, it was never automatically synced into the separateFirewallPortWhiteListconfiguration key.
C. The Fatal Lockout Sequence (initPreRules)
In agent/utils/firewall/nftables_helper/manager.go:
func (m *Manager) initPreRules() error {
// Only ports from the stale database whitelist (22, 80, 443) are accepted here
for _, port := range ports {
commands = append(commands, requiredPortCommand(tableFamily, port))
}
// Followed immediately by a catch-all drop
commands = append(commands,
[]string{"flush", "chain", tableFamily, TableName, BasicAfterChain},
[]string{"add", "rule", tableFamily, TableName, BasicAfterChain, "meta", "l4proto", "tcp", "drop"},
[]string{"add", "rule", tableFamily, TableName, BasicAfterChain, "meta", "l4proto", "udp", "drop"},
)
return runBatch(commands...)
}
- Port
22(where nothing is listening) is allowed, while the real SSH port54321(despite being allowed under Host Firewall) is missing from the nftables chain. - The chain immediately executes
meta l4proto tcp drop, severing admin access instantly.
The expected correct result
- Rule Inheritance / Migration: When initializing the
nftablesbackend, 1Panel MUST inherit or migrate the active rules already explicitly allowed in Host Firewall , especially the SSH port. - Dynamic Sync: 1Panel must ensure the actual active SSH listening port is included in the nftables whitelist before applying any packet drop policy.
- The administrator should never be locked out when enabling container protection on a server where the port was already marked as "Allowed" in the same panel.
Related log output
Additional Information
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.