vincentmli / BPFire

BPFire development tree
36 stars 3 forks source link

loxilb UI: loxicmd save -a -c /var/ipfire/loxilb/ result in "Can't create dump file" #30

Closed vincentmli closed 1 month ago

vincentmli commented 3 months ago

attempted to add loxicmd save -l -c /var/ipfire/loxilb/ loxilb LB UI loxilbconfig.cgi below:

sub SaveLB {
    my @save_options;
    my $command = 'loxicmd';
    my $dir="/var/ipfire/loxilb/";
    push(@save_options, "save", "-l", "-c", $dir);
    my @output = &General::system_output($command, @save_options);
    $errormessage = join('', @output);
}

$errormessage get "Can't create dump file"

vincentmli commented 2 months ago

opensnoop

PID    COMM              FD ERR PATH

23188  loxicmd           -1   2 /etc/ld.so.cache
23188  loxicmd           -1   2 /lib64/glibc-hwcaps/x86-64-v2/libresolv.so.2
23188  loxicmd            3   0 /lib64/libresolv.so.2
23188  loxicmd            3   0 /lib64/libc.so.6
23188  loxicmd            3   0 /proc/self/maps
23188  loxicmd            3   0 /sys/kernel/mm/transparent_hugepage/hpage_pmd_size
1814   unbound           12   0 /etc/unbound/root.hints
23194  loxicmd           -1   2 /etc/ld.so.cache
23194  loxicmd           -1   2 /lib64/glibc-hwcaps/x86-64-v2/libresolv.so.2
23194  loxicmd            3   0 /lib64/libresolv.so.2
23194  loxicmd            3   0 /lib64/libc.so.6
23194  loxicmd            3   0 /proc/self/maps
23194  loxicmd            3   0 /sys/kernel/mm/transparent_hugepage/hpage_pmd_size
23194  loxicmd            3   0 /etc/localtime
23194  loxicmd           -1  13 ipconfig_2024-08-21_20:44:49.txt <====
vincentmli commented 2 months ago

diff below to loxicmd fixed the problem:

root@r210:/home/vincent/go/src/github.com/vincentmli/BPFire/cache/loxicmd-0.9.6# git diff
diff --git a/cmd/dump/save.go b/cmd/dump/save.go
index 0b14d36..fd6b9d3 100644
--- a/cmd/dump/save.go
+++ b/cmd/dump/save.go
@@ -80,6 +80,10 @@ func SaveCmd(saveOpts *SaveOptions, restOptions *api.RESTOptions) *cobra.Command
                                        return
                                }
                                fmt.Println("LB Configuration saved in", lbfile)
+                               err = os.Remove(lbfile)
+                               if err != nil {
+                                       fmt.Println(err.Error())
+                               }
                        }
                        if saveOpts.SaveSessionConfig || saveOpts.SaveAllConfig {
                                sessionFile, err := get.Sessiondump(restOptions, dpath)
diff --git a/cmd/get/get_loadbalancer.go b/cmd/get/get_loadbalancer.go
index 173e4a9..9ad29b8 100644
--- a/cmd/get/get_loadbalancer.go
+++ b/cmd/get/get_loadbalancer.go
@@ -226,6 +226,7 @@ func Lbdump(restOptions *api.RESTOptions, path string) (string, error) {
        fileP := []string{"lbconfig_", ".txt"}
        t := time.Now()
        file := strings.Join(fileP, t.Local().Format("2006-01-02_15:04:05"))
+       file = path + file
        f, err := os.Create(file)
        if err != nil {
                fmt.Printf("Can't create dump file\n")

opensnoop:

PID    COMM              FD ERR PATH
4419   loxicmd            3   0 /etc/localtime
4419   loxicmd            3   0 /var/ipfire/loxilb/lbconfig_2024-08-23_19:00:35.txt <=====
4419   loxicmd            8   0 /dev/null

it looks when loxicmd save -l -c /var/ipfire/loxilb/ to save LB config and invoked from web interface with user nobody permission, the file variable requires explicit directory path /var/ipfire/loxilb/ since /var/ipfire/loxilb is owned by user nobody, without explicit directory path, user nobody has no permission to create file lbconfig_2024-08-23_19:00:35.txt which does not have explicit path that is owned by user nobody.

vincentmli commented 2 months ago

since BPFire only deal with loxilb IP/LB/FW for now, diff below could work around the issue

diff --git a/cmd/dump/save.go b/cmd/dump/save.go
index 0b14d36..372c761 100644
--- a/cmd/dump/save.go
+++ b/cmd/dump/save.go
@@ -72,6 +72,10 @@ func SaveCmd(saveOpts *SaveOptions, restOptions *api.RESTOptions) *cobra.Command
                                        return
                                }
                                fmt.Println("IP Configuration saved in", file)
+                               err = os.Remove(file)
+                               if err != nil {
+                                       fmt.Println(err.Error())
+                               }
                        }
                        if saveOpts.SaveLBConfig || saveOpts.SaveAllConfig {
                                lbfile, err := get.Lbdump(restOptions, dpath)
@@ -80,6 +84,10 @@ func SaveCmd(saveOpts *SaveOptions, restOptions *api.RESTOptions) *cobra.Command
                                        return
                                }
                                fmt.Println("LB Configuration saved in", lbfile)
+                               err = os.Remove(lbfile)
+                               if err != nil {
+                                       fmt.Println(err.Error())
+                               }
                        }
                        if saveOpts.SaveSessionConfig || saveOpts.SaveAllConfig {
                                sessionFile, err := get.Sessiondump(restOptions, dpath)
@@ -104,6 +112,10 @@ func SaveCmd(saveOpts *SaveOptions, restOptions *api.RESTOptions) *cobra.Command
                                        return
                                }
                                fmt.Println("Firewall Configuration saved in", FWFile)
+                               err = os.Remove(FWFile)
+                               if err != nil {
+                                       fmt.Println(err.Error())
+                               }
                        }
                        if saveOpts.SaveEPConfig || saveOpts.SaveAllConfig {
                                EPFile, err := get.EPdump(restOptions, dpath)
diff --git a/cmd/get/get_firewall.go b/cmd/get/get_firewall.go
index bd80a4c..c45ce57 100644
--- a/cmd/get/get_firewall.go
+++ b/cmd/get/get_firewall.go
@@ -144,6 +144,7 @@ func FWdump(restOptions *api.RESTOptions, path string) (string, error) {
        fileP := []string{"FWconfig_", ".txt"}
        t := time.Now()
        file := strings.Join(fileP, t.Local().Format("2006-01-02_15:04:05"))
+       file = path + file
        f, err := os.Create(file)
        if err != nil {
                fmt.Printf("Can't create dump file\n")
diff --git a/cmd/get/get_loadbalancer.go b/cmd/get/get_loadbalancer.go
index 173e4a9..9ad29b8 100644
--- a/cmd/get/get_loadbalancer.go
+++ b/cmd/get/get_loadbalancer.go
@@ -226,6 +226,7 @@ func Lbdump(restOptions *api.RESTOptions, path string) (string, error) {
        fileP := []string{"lbconfig_", ".txt"}
        t := time.Now()
        file := strings.Join(fileP, t.Local().Format("2006-01-02_15:04:05"))
+       file = path + file
        f, err := os.Create(file)
        if err != nil {
                fmt.Printf("Can't create dump file\n")
diff --git a/cmd/get/get_netlink.go b/cmd/get/get_netlink.go
index a9c8747..e4da735 100644
--- a/cmd/get/get_netlink.go
+++ b/cmd/get/get_netlink.go
@@ -517,6 +517,7 @@ func Nlpdump(dpath string) (string, error) {
        fileP := []string{"ipconfig_", ".txt"}
        t := time.Now()
        file := strings.Join(fileP, t.Local().Format("2006-01-02_15:04:05"))
+       file = dpath + file
        f, err = os.Create(file)
        if err != nil {
                fmt.Printf("Can't create dump file\n")
@@ -525,7 +526,7 @@ func Nlpdump(dpath string) (string, error) {

        defer f.Close()

-       path = "ipconfig_" + t.Local().Format("2006-01-02_15:04:05") + "/"
+       path = dpath + "ipconfig_" + t.Local().Format("2006-01-02_15:04:05") + "/"
        //fmt.Printf("Creating intf config dir : %s\n", path)
        if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
                err := os.Mkdir(path, os.ModePerm)
vincentmli commented 2 months ago

better diff to create the file under /tmp directory and cleaned up after loxicmd exit

diff --git a/cmd/get/get_firewall.go b/cmd/get/get_firewall.go
index bd80a4c..296f711 100644
--- a/cmd/get/get_firewall.go
+++ b/cmd/get/get_firewall.go
@@ -141,7 +141,7 @@ func FWAPICall(restOptions *api.RESTOptions) (*http.Response, error) {

 func FWdump(restOptions *api.RESTOptions, path string) (string, error) {
        // File Open
-       fileP := []string{"FWconfig_", ".txt"}
+       fileP := []string{"/tmp/FWconfig_", ".txt"}
        t := time.Now()
        file := strings.Join(fileP, t.Local().Format("2006-01-02_15:04:05"))
        f, err := os.Create(file)
@@ -149,7 +149,7 @@ func FWdump(restOptions *api.RESTOptions, path string) (string, error) {
                fmt.Printf("Can't create dump file\n")
                os.Exit(1)
        }
-       defer f.Close()
+       defer os.Remove(f.Name())

        // API Call
        client := api.NewLoxiClient(restOptions)
diff --git a/cmd/get/get_loadbalancer.go b/cmd/get/get_loadbalancer.go
index 173e4a9..1aa08b8 100644
--- a/cmd/get/get_loadbalancer.go
+++ b/cmd/get/get_loadbalancer.go
@@ -223,7 +223,7 @@ func Lbdump(restOptions *api.RESTOptions, path string) (string, error) {
        lbresp := api.LbRuleModGet{}
        dresp := api.LbRuleModGet{}
        // File Open
-       fileP := []string{"lbconfig_", ".txt"}
+       fileP := []string{"/tmp/lbconfig_", ".txt"}
        t := time.Now()
        file := strings.Join(fileP, t.Local().Format("2006-01-02_15:04:05"))
        f, err := os.Create(file)
@@ -231,7 +231,7 @@ func Lbdump(restOptions *api.RESTOptions, path string) (string, error) {
                fmt.Printf("Can't create dump file\n")
                os.Exit(1)
        }
-       defer f.Close()
+       defer os.Remove(f.Name())

        // API Call
        client := api.NewLoxiClient(restOptions)
diff --git a/cmd/get/get_netlink.go b/cmd/get/get_netlink.go
index a9c8747..e58a75a 100644
--- a/cmd/get/get_netlink.go
+++ b/cmd/get/get_netlink.go
@@ -514,7 +514,7 @@ func GetBonds() {
 func Nlpdump(dpath string) (string, error) {
        var ret int
        var err error
-       fileP := []string{"ipconfig_", ".txt"}
+       fileP := []string{"/tmp/ipconfig_", ".txt"}
        t := time.Now()
        file := strings.Join(fileP, t.Local().Format("2006-01-02_15:04:05"))
        f, err = os.Create(file)
@@ -523,9 +523,9 @@ func Nlpdump(dpath string) (string, error) {
                os.Exit(1)
        }

-       defer f.Close()
+       defer os.Remove(f.Name())

-       path = "ipconfig_" + t.Local().Format("2006-01-02_15:04:05") + "/"
+       path = "/tmp/" + "ipconfig_" + t.Local().Format("2006-01-02_15:04:05") + "/"
        //fmt.Printf("Creating intf config dir : %s\n", path)
        if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
                err := os.Mkdir(path, os.ModePerm)
@@ -534,6 +534,8 @@ func Nlpdump(dpath string) (string, error) {
                }
        }

+       defer os.RemoveAll(path)
+
        /*Get bridge info first */
        GetBridges()
        GetBonds()