Browse Source

Support both temporary and permanent firewall, depending on server type.

master
Ruel Tmeizeh - RuhNet 1 week ago
parent
commit
fbe05cff39
2 changed files with 77 additions and 20 deletions
  1. +70
    -17
      firewall.go
  2. +7
    -3
      main.go

+ 70
- 17
firewall.go View File

@ -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


+ 7
- 3
main.go View File

@ -1,8 +1,8 @@
////////////////////////////////////////////////////////////////////////
// KazooFirewallAgent (c) 2024, RuhNet, All Rights Reserved, except
// KazooFirewallAgent (c) 2024-2025, RuhNet, All Rights Reserved, except
// for firewall.go, which is copyright PBX.com LLC
// Author: Ruel Tmeizeh, RuhNet www.ruhnet.co
// Dual-Licensed to PBX.com LLC under a non-exclusive unlimited
// Dual-Licensed to PBX.com LLC under a non-exclusive nearly-unlimited
// most-rights-granted use/deployment/transfer/modification license.
////////////////////////////////////////////////////////////////////////
package main
@ -114,7 +114,11 @@ func main() {
//fmt.Println()
//create the IP address cache with expiry and function to run when cached entry expires
ipcache = NewTTL(appconf.CacheTimeout, firewallDelete)
if shouldAddPermanently() {
ipcache = NewTTL(appconf.CacheTimeout, firewallDeleteCacheOnly)
} else {
ipcache = NewTTL(appconf.CacheTimeout, firewallDelete)
}
if appconf.FirewallType == "firewalld" {
logit(5, "reloading FirewallD...")


Loading…
Cancel
Save