Files
1Panel/agent/utils/firewall/iptables_helper/inspect.go
T
ssongliu e119239d3d refactor: manage firewall rules through runtime state and file backups (#13998)
Replace database rule synchronization with native rule operations and file-based backup, import, and recovery. Update firewall management views, descriptions, whitelist handling, and translations.

Include terminal reconnect fixes and xpack build tags for Darwin build targets. Remove temporary regression test files before committing.
2026-10-08 18:19:30 +08:00

130 lines
3.4 KiB
Go

package iptables_helper
import (
"fmt"
"strings"
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
)
func LoadInitStatus(tab string) (bool, bool, error) {
return loadInitStatus(tab, RunWithStd)
}
func LoadFamilyInitStatus(family, tab string) (bool, bool, error) {
initialized, bound, _, err := LoadFamilyState(family, tab)
return initialized, bound, err
}
func LoadFamilyState(family, tab string) (bool, bool, bool, error) {
runner := RunWithStd
switch family {
case constant.FirewallFamilyIPv4:
case constant.FirewallFamilyIPv6:
runner = RunIPv6WithStd
default:
return false, false, false, fmt.Errorf("unsupported iptables family %q", family)
}
if tab != "base" {
return false, false, false, nil
}
output, err := runner(FilterTab, "-S")
if err != nil {
return false, false, false, err
}
count := 0
for _, chain := range BasicChains() {
if containsIptablesRule(output, "-N "+chain) {
count++
}
}
initialized := count == len(BasicChains())
_, bound := checkWithInitAndBind([]string{"-N " + BasicBeforeChain, "-N " + BasicChain, "-N " + BasicAfterChain}, []string{"-A INPUT -j " + BasicBeforeChain, "-A INPUT -j " + BasicChain, "-A INPUT -j " + BasicAfterChain}, strings.Split(output, "\n"))
return initialized, bound, count > 0 && !initialized, nil
}
func LoadFamilyBindStatus(family string) (bool, error) {
var (
output string
err error
)
switch family {
case constant.FirewallFamilyIPv4:
output, err = RunWithStd(FilterTab, "-S", InputChain)
case constant.FirewallFamilyIPv6:
output, err = RunIPv6WithStd(FilterTab, "-S", InputChain)
default:
return false, fmt.Errorf("unsupported iptables family %q", family)
}
if err != nil {
return false, err
}
return hasBaseChainBinding(output), nil
}
func hasBaseChainBinding(output string) bool {
for _, line := range strings.Split(output, "\n") {
line = strings.TrimSpace(line)
for _, chain := range BasicChains() {
if line == fmt.Sprintf("-A %s -j %s", InputChain, chain) {
return true
}
}
}
return false
}
func loadInitStatus(tab string, runner func(string, ...string) (string, error)) (bool, bool, error) {
switch tab {
case "base":
filterRules, err := runner(FilterTab, "-S")
if err != nil {
return false, false, fmt.Errorf("load iptables initialization status: %w", err)
}
lines := strings.Split(filterRules, "\n")
initRules := []string{
"-N " + BasicBeforeChain,
"-N " + BasicChain,
"-N " + BasicAfterChain,
}
bindRules := []string{
fmt.Sprintf("-A %s -j %s", InputChain, BasicBeforeChain),
fmt.Sprintf("-A %s -j %s", InputChain, BasicChain),
fmt.Sprintf("-A %s -j %s", InputChain, BasicAfterChain),
}
isInit, isBind := checkWithInitAndBind(initRules, bindRules, lines)
return isInit, isBind, nil
default:
return false, false, nil
}
}
func checkWithInitAndBind(initRules, bindRules []string, lines []string) (bool, bool) {
output := strings.Join(lines, "\n")
for _, rule := range initRules {
if !containsIptablesRule(output, rule) {
if global.LOG != nil {
global.LOG.Debugf("not found init rule: %s", rule)
}
return false, false
}
}
for _, rule := range bindRules {
found := false
for _, line := range lines {
if strings.TrimSpace(line) == strings.TrimSpace(rule) {
found = true
break
}
}
if !found {
if global.LOG != nil {
global.LOG.Debugf("not found bind rule: %s", rule)
}
return true, false
}
}
return true, true
}