github.com/TeaOSLab/EdgeNode@v1.3.8/internal/firewalls/nftables/installer.go (about)

     1  // Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
     2  //go:build linux
     3  
     4  package nftables
     5  
     6  import (
     7  	"fmt"
     8  	"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
     9  	teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
    10  	"github.com/TeaOSLab/EdgeNode/internal/events"
    11  	"github.com/TeaOSLab/EdgeNode/internal/goman"
    12  	"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
    13  	executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec"
    14  	"github.com/iwind/TeaGo/logs"
    15  	"os"
    16  	"runtime"
    17  	"time"
    18  )
    19  
    20  func init() {
    21  	if !teaconst.IsMain {
    22  		return
    23  	}
    24  
    25  	events.On(events.EventReload, func() {
    26  		// linux only
    27  		if runtime.GOOS != "linux" {
    28  			return
    29  		}
    30  
    31  		nodeConfig, err := nodeconfigs.SharedNodeConfig()
    32  		if err != nil {
    33  			return
    34  		}
    35  
    36  		if nodeConfig == nil || !nodeConfig.AutoInstallNftables {
    37  			return
    38  		}
    39  
    40  		if os.Getgid() == 0 { // root user only
    41  			if len(NftExePath()) > 0 {
    42  				return
    43  			}
    44  			goman.New(func() {
    45  				err := NewInstaller().Install()
    46  				if err != nil {
    47  					// 不需要传到API节点
    48  					logs.Println("[NFTABLES]install nftables failed: " + err.Error())
    49  				}
    50  			})
    51  		}
    52  	})
    53  }
    54  
    55  // NftExePath 查找nftables可执行文件路径
    56  func NftExePath() string {
    57  	path, _ := executils.LookPath("nft")
    58  	if len(path) > 0 {
    59  		return path
    60  	}
    61  
    62  	for _, possiblePath := range []string{
    63  		"/usr/sbin/nft",
    64  	} {
    65  		_, err := os.Stat(possiblePath)
    66  		if err == nil {
    67  			return possiblePath
    68  		}
    69  	}
    70  
    71  	return ""
    72  }
    73  
    74  type Installer struct {
    75  }
    76  
    77  func NewInstaller() *Installer {
    78  	return &Installer{}
    79  }
    80  
    81  func (this *Installer) Install() error {
    82  	// linux only
    83  	if runtime.GOOS != "linux" {
    84  		return nil
    85  	}
    86  
    87  	// 检查是否已经存在
    88  	if len(NftExePath()) > 0 {
    89  		return nil
    90  	}
    91  
    92  	var cmd *executils.Cmd
    93  
    94  	// check dnf
    95  	dnfExe, err := executils.LookPath("dnf")
    96  	if err == nil {
    97  		cmd = executils.NewCmd(dnfExe, "-y", "install", "nftables")
    98  	}
    99  
   100  	// check apt
   101  	if cmd == nil {
   102  		aptExe, err := executils.LookPath("apt")
   103  		if err == nil {
   104  			cmd = executils.NewCmd(aptExe, "install", "nftables")
   105  		}
   106  	}
   107  
   108  	// check yum
   109  	if cmd == nil {
   110  		yumExe, err := executils.LookPath("yum")
   111  		if err == nil {
   112  			cmd = executils.NewCmd(yumExe, "-y", "install", "nftables")
   113  		}
   114  	}
   115  
   116  	if cmd == nil {
   117  		return nil
   118  	}
   119  
   120  	cmd.WithTimeout(10 * time.Minute)
   121  	cmd.WithStderr()
   122  	err = cmd.Run()
   123  	if err != nil {
   124  		return fmt.Errorf("%w: %s", err, cmd.Stderr())
   125  	}
   126  
   127  	remotelogs.Println("NFTABLES", "installed nftables with command '"+cmd.String()+"' successfully")
   128  
   129  	return nil
   130  }