|
|
|
@ -1,4 +1,4 @@ |
|
|
|
// This file copyright 2024, PBX.com LLC
|
|
|
|
// This file copyright 2024-2025, PBX.com LLC
|
|
|
|
|
|
|
|
package main |
|
|
|
|
|
|
|
@ -12,33 +12,37 @@ import ( |
|
|
|
) |
|
|
|
|
|
|
|
func firewall(action, ipaddr string, inputports interface{}) (err error) { |
|
|
|
return firewallWithTimeout(action, ipaddr, inputports, appconf.CacheTimeout) |
|
|
|
} |
|
|
|
|
|
|
|
func firewallWithTimeout(action, ipaddr string, inputports interface{}, timeout int64) (err error) { |
|
|
|
switch p := inputports.(type) { |
|
|
|
case []interface{}: |
|
|
|
for _, porti := range p { |
|
|
|
switch port := porti.(type) { |
|
|
|
case string: |
|
|
|
firewallAction(action, ipaddr, port) |
|
|
|
firewallAction(action, ipaddr, port, timeout) |
|
|
|
case float64: |
|
|
|
firewallAction(action, ipaddr, strconv.Itoa(int(port))) |
|
|
|
firewallAction(action, ipaddr, strconv.Itoa(int(port)), timeout) |
|
|
|
case int64: |
|
|
|
firewallAction(action, ipaddr, strconv.Itoa(int(port))) |
|
|
|
firewallAction(action, ipaddr, strconv.Itoa(int(port)), timeout) |
|
|
|
case int: |
|
|
|
firewallAction(action, ipaddr, strconv.Itoa(port)) |
|
|
|
firewallAction(action, ipaddr, strconv.Itoa(port), timeout) |
|
|
|
} |
|
|
|
} |
|
|
|
case []string: |
|
|
|
for _, port := range p { |
|
|
|
firewallAction(action, ipaddr, port) |
|
|
|
firewallAction(action, ipaddr, port, timeout) |
|
|
|
} |
|
|
|
case float64: |
|
|
|
firewallAction(action, ipaddr, strconv.Itoa(int(p))) |
|
|
|
firewallAction(action, ipaddr, strconv.Itoa(int(p)), timeout) |
|
|
|
case string: |
|
|
|
splitPorts := strings.Split(p, ",") |
|
|
|
for _, port := range splitPorts { |
|
|
|
firewallAction(action, ipaddr, port) |
|
|
|
firewallAction(action, ipaddr, port, timeout) |
|
|
|
} |
|
|
|
case nil: |
|
|
|
firewallAction(action, ipaddr, "") |
|
|
|
firewallAction(action, ipaddr, "", timeout) |
|
|
|
default: |
|
|
|
} |
|
|
|
return nil |
|
|
|
@ -71,10 +75,10 @@ func parsePortProto(p string) PortProto { |
|
|
|
return pp |
|
|
|
} |
|
|
|
|
|
|
|
func firewallAction(action, ipaddr string, portstring string) (err error) { |
|
|
|
func firewallAction(action, ipaddr, portstring string, timeout int64) (err error) { |
|
|
|
switch action { |
|
|
|
case "firewall_add": |
|
|
|
err = firewallAdd(ipaddr, portstring) |
|
|
|
err = firewallAdd(ipaddr, portstring, timeout) |
|
|
|
case "firewall_remove": |
|
|
|
err = firewallDelete(ipaddr, portstring) |
|
|
|
} |
|
|
|
@ -82,12 +86,16 @@ func firewallAction(action, ipaddr string, portstring string) (err error) { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
func firewallAdd(ipaddr, portstring string) error { |
|
|
|
func firewallAdd(ipaddr, portstring string, timeout int64) error { |
|
|
|
var pp PortProto |
|
|
|
pp = parsePortProto(portstring) |
|
|
|
zone := determineZone(ipaddr, pp) |
|
|
|
|
|
|
|
logit(5, "Firewall adding to zone '"+zone+"': "+ipaddr+":"+pp.Port+"/"+pp.Proto) |
|
|
|
if len(pp.Port) > 0 { |
|
|
|
logit(5, "Firewall adding to zone '"+zone+"': "+ipaddr+":"+pp.Port+"/"+pp.Proto) |
|
|
|
} else { |
|
|
|
logit(5, "Firewall adding to zone '"+zone+"': "+ipaddr) |
|
|
|
} |
|
|
|
//ipcache.Set(ipaddr+":"+pp.Port+"/"+pp.Proto, zone, time.Duration(appconf.CacheTimeout) * time.Second)
|
|
|
|
|
|
|
|
if len(pp.Port) > 0 { |
|
|
|
@ -101,20 +109,43 @@ func firewallAdd(ipaddr, portstring string) error { |
|
|
|
//if it's already cached, then don't add it, just refresh the expiry time and return
|
|
|
|
_, alreadyExists := ipcache.Get(ipaddr) |
|
|
|
if alreadyExists { |
|
|
|
ipcache.Set(ipaddr, zone, time.Duration(appconf.CacheTimeout)*time.Second) |
|
|
|
ipcache.Set(ipaddr, zone, time.Duration(timeout)*time.Second) |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
fwOutput, err := exec.Command("firewall-cmd", "--zone="+zone, "--add-source="+ipaddr).CombinedOutput() |
|
|
|
if err != nil { |
|
|
|
logit(3, "Error executing firewall-cmd: "+err.Error()+" OUTPUT: "+string(fwOutput)) |
|
|
|
return errors.New("Error executing firewall-cmd: " + err.Error()) |
|
|
|
return errors.New("Error executing current firewall-cmd: " + err.Error()) |
|
|
|
} |
|
|
|
ipcache.Set(ipaddr, zone, time.Duration(timeout)*time.Second) |
|
|
|
|
|
|
|
// maybe add permanently also
|
|
|
|
if shouldAddPermanently() { |
|
|
|
fwOutput, err = exec.Command("firewall-cmd", "--permanent", "--zone="+zone, "--add-source="+ipaddr).CombinedOutput() |
|
|
|
if err != nil { |
|
|
|
logit(3, "Error executing firewall-cmd --permanent: "+err.Error()+" OUTPUT: "+string(fwOutput)) |
|
|
|
return errors.New("Error executing permanent firewall-cmd: " + err.Error()) |
|
|
|
} |
|
|
|
if len(pp.Port) > 0 { |
|
|
|
err := maybeAddPort(zone, pp, true) |
|
|
|
if err != nil { |
|
|
|
logit(3, err.Error()) |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
ipcache.Set(ipaddr, zone, time.Duration(appconf.CacheTimeout)*time.Second) |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
func shouldAddPermanently() bool { |
|
|
|
if appconf.ServerType == "ephemeral" || appconf.ServerType == "freeswitch" { |
|
|
|
return false |
|
|
|
} |
|
|
|
return true |
|
|
|
} |
|
|
|
|
|
|
|
func firewallDelete(ipaddr, portstring string) error { |
|
|
|
var pp PortProto |
|
|
|
pp = parsePortProto(portstring) |
|
|
|
@ -131,6 +162,27 @@ func firewallDelete(ipaddr, portstring string) error { |
|
|
|
return errors.New("Error executing firewall-cmd: " + err.Error()) |
|
|
|
} |
|
|
|
|
|
|
|
// maybe remove permanently also
|
|
|
|
if shouldAddPermanently() { |
|
|
|
fwOutput, err = exec.Command("firewall-cmd", "--permanent", "--zone="+zone, "--remove-source="+ipaddr).CombinedOutput() |
|
|
|
if err != nil { |
|
|
|
logit(3, "Error executing firewall-cmd --permanent: "+err.Error()+" OUTPUT: "+string(fwOutput)) |
|
|
|
return errors.New("Error executing firewall-cmd --permanent: " + err.Error()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
func firewallDeleteCacheOnly(ipaddr, portstring string) error { |
|
|
|
var pp PortProto |
|
|
|
pp = parsePortProto(portstring) |
|
|
|
zone := determineZone(ipaddr, pp) |
|
|
|
|
|
|
|
logit(5, "removing from cache: '"+zone+"' "+ipaddr) |
|
|
|
|
|
|
|
ipcache.Remove(ipaddr) |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
@ -152,6 +204,7 @@ func maybeAddPort(zone string, pp PortProto, permanent bool) error { |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
func addZonePort(zone, port string, permanent bool) error { |
|
|
|
cmd := exec.Command("firewall-cmd", "--zone="+zone, "--add-port="+port) |
|
|
|
if permanent { |
|
|
|
@ -233,7 +286,7 @@ func reload() error { |
|
|
|
|
|
|
|
func determineZone(ipaddr string, pp PortProto) string { |
|
|
|
var zone string |
|
|
|
logit(7, "Determine zone for ipaddr '"+ipaddr+"'...") |
|
|
|
//logit(7, "Determine zone for ipaddr '"+ipaddr+"'...")
|
|
|
|
|
|
|
|
//do stuff
|
|
|
|
|
|
|
|
|