mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-27 08:00:58 +00:00
586 lines
18 KiB
Go
586 lines
18 KiB
Go
package providers
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/1Panel-dev/1Panel/agent/constant"
|
|
"github.com/1Panel-dev/1Panel/agent/global"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/firewall/forwarding"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/firewall/iptables_helper"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/firewall/lifecycle"
|
|
)
|
|
|
|
type iptablesBackend interface {
|
|
IPv6Available() bool
|
|
Run(table string, args ...string) error
|
|
RunWithStd(table string, args ...string) (string, error)
|
|
RunIPv6(table string, args ...string) error
|
|
RunIPv6WithStd(table string, args ...string) (string, error)
|
|
Restore(family, input string) error
|
|
LoadRulesFromFile(table, chain, fileName string) error
|
|
LoadIPv6RulesFromFile(table, chain, fileName string) error
|
|
}
|
|
|
|
type systemIptablesBackend struct{}
|
|
|
|
func (systemIptablesBackend) IPv6Available() bool {
|
|
commands, err := lifecycle.ResolveIptablesCommands()
|
|
return err == nil && commands.IPv6Available()
|
|
}
|
|
|
|
func (systemIptablesBackend) Run(table string, args ...string) error {
|
|
return iptables_helper.Run(table, args...)
|
|
}
|
|
|
|
func (systemIptablesBackend) RunWithStd(table string, args ...string) (string, error) {
|
|
return iptables_helper.RunWithStd(table, args...)
|
|
}
|
|
|
|
func (systemIptablesBackend) RunIPv6(table string, args ...string) error {
|
|
return iptables_helper.RunIPv6(table, args...)
|
|
}
|
|
|
|
func (systemIptablesBackend) RunIPv6WithStd(table string, args ...string) (string, error) {
|
|
return iptables_helper.RunIPv6WithStd(table, args...)
|
|
}
|
|
|
|
func (systemIptablesBackend) Restore(family, input string) error {
|
|
commands, err := lifecycle.ResolveIptablesCommands()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
executable := commands.Restore4
|
|
if family == forwarding.FamilyIPv6 {
|
|
executable = commands.Restore6
|
|
if executable == "" {
|
|
return fmt.Errorf("ip6tables-restore command family is unavailable")
|
|
}
|
|
}
|
|
manager := cmd.NewCommandMgr(cmd.WithTimeout(60*time.Second), cmd.WithStdin(strings.NewReader(input)))
|
|
return manager.RunWithOptionalSudo(executable, "--noflush", "--wait")
|
|
}
|
|
|
|
func (systemIptablesBackend) LoadRulesFromFile(table, chain, fileName string) error {
|
|
return iptables_helper.LoadRulesFromFile(table, chain, fileName)
|
|
}
|
|
|
|
func (systemIptablesBackend) LoadIPv6RulesFromFile(table, chain, fileName string) error {
|
|
return iptables_helper.LoadIPv6RulesFromFile(table, chain, fileName)
|
|
}
|
|
|
|
type forwardingSystem interface {
|
|
ReadFile(name string) ([]byte, error)
|
|
WriteFile(name string, data []byte, perm os.FileMode) error
|
|
RunWithOptionalSudo(name string, args ...string) error
|
|
}
|
|
|
|
type defaultForwardingSystem struct{}
|
|
|
|
func (defaultForwardingSystem) ReadFile(name string) ([]byte, error) {
|
|
return os.ReadFile(name)
|
|
}
|
|
|
|
func (defaultForwardingSystem) WriteFile(name string, data []byte, perm os.FileMode) error {
|
|
return cmd.WriteFileWithOptionalSudo(name, data, perm)
|
|
}
|
|
|
|
func (defaultForwardingSystem) RunWithOptionalSudo(name string, args ...string) error {
|
|
return cmd.NewCommandMgr().RunWithOptionalSudo(name, args...)
|
|
}
|
|
|
|
type iptablesNATAdapter struct {
|
|
provider string
|
|
backend iptablesBackend
|
|
system forwardingSystem
|
|
}
|
|
|
|
func newIptablesNATAdapter(provider string) *iptablesNATAdapter {
|
|
return &iptablesNATAdapter{
|
|
provider: provider,
|
|
backend: systemIptablesBackend{},
|
|
system: defaultForwardingSystem{},
|
|
}
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) Name() string {
|
|
return l.provider
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) List() ([]forwarding.Rule, error) {
|
|
stdout, err := l.backend.RunWithStd(iptables_helper.NatTab, "-nvL", forwarding.ChainPreRouting, "--line-numbers")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to list NAT rules: %w", err)
|
|
}
|
|
rules := parseIptablesRules(stdout, forwarding.FamilyIPv4)
|
|
if !l.backend.IPv6Available() {
|
|
return rules, nil
|
|
}
|
|
stdout, err = l.backend.RunIPv6WithStd(iptables_helper.NatTab, "-nvL", forwarding.ChainPreRouting, "--line-numbers")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to list IPv6 NAT rules: %w", err)
|
|
}
|
|
return append(rules, parseIptablesRules(stdout, forwarding.FamilyIPv6)...), nil
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) Reconcile(rules []forwarding.Rule) error {
|
|
byFamily := map[string][]forwarding.Rule{
|
|
forwarding.FamilyIPv4: nil,
|
|
forwarding.FamilyIPv6: nil,
|
|
}
|
|
for _, rule := range rules {
|
|
normalized, err := forwarding.NormalizeRule(rule)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if normalized.Family == forwarding.FamilyIPv6 && !l.backend.IPv6Available() {
|
|
return fmt.Errorf("ip6tables command family is unavailable")
|
|
}
|
|
byFamily[normalized.Family] = append(byFamily[normalized.Family], normalized)
|
|
}
|
|
for _, family := range []string{forwarding.FamilyIPv4, forwarding.FamilyIPv6} {
|
|
if family == forwarding.FamilyIPv6 && !l.backend.IPv6Available() {
|
|
continue
|
|
}
|
|
script, err := buildIptablesForwardRestoreScript(byFamily[family])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := l.backend.Restore(family, script); err != nil {
|
|
return fmt.Errorf("restore %s forwarding rules: %w", family, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func buildIptablesForwardRestoreScript(rules []forwarding.Rule) (string, error) {
|
|
natRules := [][]string{{"-F", forwarding.ChainPreRouting}, {"-F", forwarding.ChainPostRouting}}
|
|
filterRules := [][]string{{"-F", forwarding.ChainForward}}
|
|
for _, rule := range rules {
|
|
sourcePort := strings.ReplaceAll(rule.Port, "-", ":")
|
|
targetPort := strings.ReplaceAll(rule.TargetPort, "-", ":")
|
|
preRouting := []string{"-A", forwarding.ChainPreRouting}
|
|
if rule.Interface != "" {
|
|
preRouting = append(preRouting, "-i", rule.Interface)
|
|
}
|
|
preRouting = append(preRouting, "-p", rule.Protocol, "--dport", sourcePort)
|
|
if !isRemoteTarget(rule.Family, rule.TargetIP) {
|
|
natRules = append(natRules, append(preRouting, "-j", "REDIRECT", "--to-port", rule.TargetPort))
|
|
continue
|
|
}
|
|
natRules = append(natRules,
|
|
append(preRouting, "-j", "DNAT", "--to-destination", forwardingTarget(rule)),
|
|
[]string{"-A", forwarding.ChainPostRouting, "-d", rule.TargetIP, "-p", rule.Protocol, "--dport", targetPort, "-j", "MASQUERADE"},
|
|
)
|
|
filterRules = append(filterRules,
|
|
[]string{"-A", forwarding.ChainForward, "-d", rule.TargetIP, "-p", rule.Protocol, "--dport", targetPort, "-j", "ACCEPT"},
|
|
[]string{"-A", forwarding.ChainForward, "-s", rule.TargetIP, "-p", rule.Protocol, "--sport", targetPort, "-j", "ACCEPT"},
|
|
)
|
|
}
|
|
var script strings.Builder
|
|
for _, table := range []struct {
|
|
name string
|
|
rules [][]string
|
|
}{{iptables_helper.NatTab, natRules}, {iptables_helper.FilterTab, filterRules}} {
|
|
script.WriteByte('*')
|
|
script.WriteString(table.name)
|
|
script.WriteByte('\n')
|
|
for _, rule := range table.rules {
|
|
for index, token := range rule {
|
|
if token == "" || strings.ContainsAny(token, " \t\r\n\"'") {
|
|
return "", fmt.Errorf("invalid iptables-restore token %q", token)
|
|
}
|
|
if index > 0 {
|
|
script.WriteByte(' ')
|
|
}
|
|
script.WriteString(token)
|
|
}
|
|
script.WriteByte('\n')
|
|
}
|
|
script.WriteString("COMMIT\n")
|
|
}
|
|
return script.String(), nil
|
|
}
|
|
|
|
func forwardingTarget(rule forwarding.Rule) string {
|
|
if rule.Family == forwarding.FamilyIPv6 {
|
|
return "[" + rule.TargetIP + "]:" + rule.TargetPort
|
|
}
|
|
return rule.TargetIP + ":" + rule.TargetPort
|
|
}
|
|
|
|
func isRemoteTarget(family, target string) bool {
|
|
if family == forwarding.FamilyIPv6 {
|
|
return target != "" && target != "::1" && target != "localhost"
|
|
}
|
|
return target != "" && target != "127.0.0.1" && target != "localhost"
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) Enable() error {
|
|
if err := l.system.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte("1"), constant.FilePerm); err != nil {
|
|
return fmt.Errorf("failed to enable IP forwarding: %w", err)
|
|
}
|
|
if l.backend.IPv6Available() {
|
|
if err := l.system.WriteFile("/proc/sys/net/ipv6/conf/all/forwarding", []byte("1"), constant.FilePerm); err != nil {
|
|
return fmt.Errorf("failed to enable IPv6 forwarding: %w", err)
|
|
}
|
|
}
|
|
data, err := l.system.ReadFile("/etc/sysctl.conf")
|
|
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
|
return fmt.Errorf("failed to read /etc/sysctl.conf: %w", err)
|
|
}
|
|
content := enableForwardingSysctls(string(data), l.backend.IPv6Available())
|
|
if err := l.system.WriteFile("/etc/sysctl.conf", []byte(content), constant.FilePerm); err != nil {
|
|
return fmt.Errorf("failed to persist IP forwarding: %w", err)
|
|
}
|
|
if err := l.system.RunWithOptionalSudo("sysctl", "-p"); err != nil {
|
|
return fmt.Errorf("failed to apply IP forwarding: %w", err)
|
|
}
|
|
|
|
for _, family := range []string{forwarding.FamilyIPv4, forwarding.FamilyIPv6} {
|
|
if family == forwarding.FamilyIPv6 && !l.backend.IPv6Available() {
|
|
continue
|
|
}
|
|
if err := l.batchEnsureChains(family); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) batchEnsureChains(family string) error {
|
|
list := l.backend.RunWithStd
|
|
if family == forwarding.FamilyIPv6 {
|
|
list = l.backend.RunIPv6WithStd
|
|
}
|
|
outputs := make(map[string]string, 2)
|
|
for _, table := range []string{iptables_helper.NatTab, iptables_helper.FilterTab} {
|
|
output, err := list(table, "-S")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
outputs[table] = output
|
|
}
|
|
script := buildIptablesForwardLifecycleScript(outputs, true)
|
|
if script == "" {
|
|
return nil
|
|
}
|
|
if err := l.backend.Restore(family, script); err != nil {
|
|
return fmt.Errorf("batch initialize %s forwarding chains: %w", family, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) Cleanup() error {
|
|
for _, family := range []string{forwarding.FamilyIPv4, forwarding.FamilyIPv6} {
|
|
if family == forwarding.FamilyIPv6 && !l.backend.IPv6Available() {
|
|
continue
|
|
}
|
|
list := l.backend.RunWithStd
|
|
if family == forwarding.FamilyIPv6 {
|
|
list = l.backend.RunIPv6WithStd
|
|
}
|
|
outputs := make(map[string]string, 2)
|
|
for _, table := range []string{iptables_helper.NatTab, iptables_helper.FilterTab} {
|
|
rules, err := list(table, "-S")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
outputs[table] = rules
|
|
}
|
|
script := buildIptablesForwardLifecycleScript(outputs, false)
|
|
if script != "" {
|
|
if err := l.backend.Restore(family, script); err != nil {
|
|
return fmt.Errorf("batch delete %s forwarding chains: %w", family, err)
|
|
}
|
|
}
|
|
}
|
|
for _, file := range []string{forwarding.ForwardFile, forwarding.PreRoutingFile, forwarding.PostRoutingFile,
|
|
iptables_helper.IPv6FileName(forwarding.ForwardFile), iptables_helper.IPv6FileName(forwarding.PreRoutingFile), iptables_helper.IPv6FileName(forwarding.PostRoutingFile)} {
|
|
if err := os.Remove(filepath.Join(global.Dir.FirewallDir, file)); err != nil && !errors.Is(err, os.ErrNotExist) {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func buildIptablesForwardLifecycleScript(outputs map[string]string, create bool) string {
|
|
items := []struct{ table, parent, chain string }{
|
|
{iptables_helper.NatTab, "PREROUTING", forwarding.ChainPreRouting},
|
|
{iptables_helper.NatTab, "POSTROUTING", forwarding.ChainPostRouting},
|
|
{iptables_helper.FilterTab, "FORWARD", forwarding.ChainForward},
|
|
}
|
|
byTable := make(map[string][]string, 2)
|
|
for _, item := range items {
|
|
output := outputs[item.table]
|
|
chainExists := containsExactLine(output, "-N "+item.chain)
|
|
bindingExists := containsExactLine(output, "-A "+item.parent+" -j "+item.chain)
|
|
if create {
|
|
if !chainExists {
|
|
byTable[item.table] = append(byTable[item.table], "-N "+item.chain)
|
|
}
|
|
if !bindingExists {
|
|
byTable[item.table] = append(byTable[item.table], "-A "+item.parent+" -j "+item.chain)
|
|
}
|
|
continue
|
|
}
|
|
if bindingExists {
|
|
byTable[item.table] = append(byTable[item.table], "-D "+item.parent+" -j "+item.chain)
|
|
}
|
|
if chainExists {
|
|
byTable[item.table] = append(byTable[item.table], "-F "+item.chain, "-X "+item.chain)
|
|
}
|
|
}
|
|
var script strings.Builder
|
|
for _, table := range []string{iptables_helper.NatTab, iptables_helper.FilterTab} {
|
|
lines := byTable[table]
|
|
if len(lines) == 0 {
|
|
continue
|
|
}
|
|
script.WriteByte('*')
|
|
script.WriteString(table)
|
|
script.WriteByte('\n')
|
|
script.WriteString(strings.Join(lines, "\n"))
|
|
script.WriteString("\nCOMMIT\n")
|
|
}
|
|
return script.String()
|
|
}
|
|
|
|
func containsExactLine(output, want string) bool {
|
|
for _, line := range strings.Split(output, "\n") {
|
|
if strings.TrimSpace(line) == want {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func enableIPv4Forwarding(content string) string {
|
|
return enableForwardingSysctls(content, false)
|
|
}
|
|
|
|
func enableForwardingSysctls(content string, withIPv6 bool) string {
|
|
lines := strings.Split(strings.TrimRight(content, "\n"), "\n")
|
|
wanted := map[string]string{"net.ipv4.ip_forward": "net.ipv4.ip_forward = 1"}
|
|
if withIPv6 {
|
|
wanted["net.ipv6.conf.all.forwarding"] = "net.ipv6.conf.all.forwarding = 1"
|
|
}
|
|
found := make(map[string]bool, len(wanted))
|
|
for index, line := range lines {
|
|
trimmed := strings.TrimSpace(line)
|
|
if strings.HasPrefix(trimmed, "#") {
|
|
continue
|
|
}
|
|
parts := strings.SplitN(trimmed, "=", 2)
|
|
if len(parts) != 2 {
|
|
continue
|
|
}
|
|
key := strings.TrimSpace(parts[0])
|
|
if replacement, ok := wanted[key]; ok {
|
|
lines[index] = replacement
|
|
found[key] = true
|
|
}
|
|
}
|
|
for _, key := range []string{"net.ipv4.ip_forward", "net.ipv6.conf.all.forwarding"} {
|
|
if replacement, ok := wanted[key]; ok && !found[key] {
|
|
lines = append(lines, replacement)
|
|
}
|
|
}
|
|
if len(lines) > 0 && lines[0] == "" {
|
|
lines = lines[1:]
|
|
}
|
|
return strings.Join(lines, "\n") + "\n"
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) InitStatus() (bool, bool, error) {
|
|
ipv4Init, ipv4Bind, err := l.familyInitStatus(forwarding.FamilyIPv4)
|
|
if err != nil {
|
|
return false, false, err
|
|
}
|
|
if !l.backend.IPv6Available() {
|
|
return ipv4Init, ipv4Bind, nil
|
|
}
|
|
ipv6Init, ipv6Bind, err := l.familyInitStatus(forwarding.FamilyIPv6)
|
|
if err != nil {
|
|
return false, false, err
|
|
}
|
|
return ipv4Init && ipv6Init, ipv4Bind && ipv6Bind, nil
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) familyInitStatus(family string) (bool, bool, error) {
|
|
sysctlPath := "/proc/sys/net/ipv4/ip_forward"
|
|
label := "IPv4"
|
|
list := l.backend.RunWithStd
|
|
if family == forwarding.FamilyIPv6 {
|
|
sysctlPath = "/proc/sys/net/ipv6/conf/all/forwarding"
|
|
label = "IPv6"
|
|
list = l.backend.RunIPv6WithStd
|
|
}
|
|
data, err := l.system.ReadFile(sysctlPath)
|
|
if err != nil {
|
|
return false, false, fmt.Errorf("read %s forwarding status: %w", label, err)
|
|
}
|
|
forwardingEnabled := strings.TrimSpace(string(data)) != "0"
|
|
natRules, err := list(iptables_helper.NatTab, "-S")
|
|
if err != nil {
|
|
return false, false, fmt.Errorf("list %s NAT initialization rules: %w", label, err)
|
|
}
|
|
natInit, natBind := checkInitAndBind(
|
|
[]string{"-N " + forwarding.ChainPreRouting, "-N " + forwarding.ChainPostRouting},
|
|
[]string{"-A PREROUTING -j " + forwarding.ChainPreRouting, "-A POSTROUTING -j " + forwarding.ChainPostRouting},
|
|
strings.Split(natRules, "\n"),
|
|
)
|
|
if !natInit {
|
|
return false, false, nil
|
|
}
|
|
filterRules, err := list(iptables_helper.FilterTab, "-S")
|
|
if err != nil {
|
|
return false, false, fmt.Errorf("list %s filter initialization rules: %w", label, err)
|
|
}
|
|
filterInit, filterBind := checkInitAndBind(
|
|
[]string{"-N " + forwarding.ChainForward},
|
|
[]string{"-A FORWARD -j " + forwarding.ChainForward},
|
|
strings.Split(filterRules, "\n"),
|
|
)
|
|
return natInit && filterInit, forwardingEnabled && natBind && filterBind, nil
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) FamilyStatus(family string) (bool, bool, error) {
|
|
if family == forwarding.FamilyIPv6 && !l.backend.IPv6Available() {
|
|
return false, false, nil
|
|
}
|
|
return l.familyInitStatus(family)
|
|
}
|
|
|
|
func checkInitAndBind(initRules, bindRules, lines []string) (bool, bool) {
|
|
for _, rule := range initRules {
|
|
if !containsExactRule(lines, rule) {
|
|
return false, false
|
|
}
|
|
}
|
|
for _, rule := range bindRules {
|
|
if !containsExactRule(lines, rule) {
|
|
return true, false
|
|
}
|
|
}
|
|
return true, true
|
|
}
|
|
|
|
func containsExactRule(lines []string, rule string) bool {
|
|
for _, line := range lines {
|
|
if strings.TrimSpace(line) == strings.TrimSpace(rule) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (l *iptablesNATAdapter) Replay() error {
|
|
for _, item := range []struct {
|
|
table string
|
|
chain string
|
|
file string
|
|
}{
|
|
{iptables_helper.FilterTab, forwarding.ChainForward, forwarding.ForwardFile},
|
|
{iptables_helper.NatTab, forwarding.ChainPreRouting, forwarding.PreRoutingFile},
|
|
{iptables_helper.NatTab, forwarding.ChainPostRouting, forwarding.PostRoutingFile},
|
|
} {
|
|
if err := l.backend.LoadRulesFromFile(item.table, item.chain, item.file); err != nil {
|
|
return err
|
|
}
|
|
if l.backend.IPv6Available() {
|
|
if err := l.backend.LoadIPv6RulesFromFile(item.table, item.chain, iptables_helper.IPv6FileName(item.file)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func parseIptablesRules(stdout, family string) []forwarding.Rule {
|
|
var rules []forwarding.Rule
|
|
for _, line := range strings.Split(stdout, "\n") {
|
|
fields := strings.Fields(line)
|
|
if len(fields) < 11 {
|
|
continue
|
|
}
|
|
rule := forwarding.Rule{
|
|
Num: fields[0],
|
|
Family: family,
|
|
Protocol: loadProtocol(fields[4]),
|
|
Interface: fields[6],
|
|
}
|
|
for index := 10; index < len(fields); index++ {
|
|
field := fields[index]
|
|
if strings.HasPrefix(field, "dpt:") || strings.HasPrefix(field, "dpts:") {
|
|
rule.Port = loadSourcePort(field)
|
|
}
|
|
if strings.HasPrefix(field, "to:") {
|
|
rule.TargetIP, rule.TargetPort = parseIptablesTarget(strings.TrimPrefix(field, "to:"))
|
|
}
|
|
if field == "redir" && index+2 < len(fields) && fields[index+1] == "ports" {
|
|
rule.TargetPort = fields[index+2]
|
|
}
|
|
}
|
|
if rule.Protocol == "" || rule.Port == "" || rule.TargetPort == "" {
|
|
continue
|
|
}
|
|
if rule.TargetIP == "" {
|
|
if family == forwarding.FamilyIPv6 {
|
|
rule.TargetIP = "::1"
|
|
} else {
|
|
rule.TargetIP = "127.0.0.1"
|
|
}
|
|
}
|
|
rule.TargetPort = strings.TrimPrefix(rule.TargetPort, ":")
|
|
rules = append(rules, rule)
|
|
}
|
|
return rules
|
|
}
|
|
|
|
func parseIptablesTarget(value string) (string, string) {
|
|
if strings.HasPrefix(value, "[") {
|
|
separator := strings.LastIndex(value, "]:")
|
|
if separator > 0 {
|
|
return value[1:separator], value[separator+2:]
|
|
}
|
|
return "", ""
|
|
}
|
|
separator := strings.LastIndex(value, ":")
|
|
if separator <= 0 {
|
|
return "", ""
|
|
}
|
|
return value[:separator], value[separator+1:]
|
|
}
|
|
|
|
func loadProtocol(protocol string) string {
|
|
switch protocol {
|
|
case "0":
|
|
return "all"
|
|
case "1":
|
|
return "icmp"
|
|
case "6":
|
|
return "tcp"
|
|
case "17":
|
|
return "udp"
|
|
default:
|
|
return protocol
|
|
}
|
|
}
|
|
|
|
func loadSourcePort(value string) string {
|
|
port := ""
|
|
if strings.Contains(value, "dpt:") {
|
|
port = strings.ReplaceAll(value, "dpt:", "")
|
|
}
|
|
if strings.Contains(value, "dpts:") {
|
|
port = strings.ReplaceAll(value, "dpts:", "")
|
|
}
|
|
return strings.ReplaceAll(port, ":", "-")
|
|
}
|