From 2c59ae4a5b27edb351879a68aa7e65afee33710d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E7=A5=A5=E8=B6=85?= Date: Mon, 3 Jul 2023 10:37:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=20executils.LookPath()=20=E4=BB=A3=E6=9B=BF=20exec.LookPath()?= =?UTF-8?q?=20=E9=81=BF=E5=85=8D=E5=9B=A0$PATH=E7=8E=AF=E5=A2=83=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E8=A2=AB=E7=A0=B4=E5=9D=8F=E8=80=8C=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/apps/app_cmd.go | 3 +- internal/firewalls/firewall_firewalld.go | 3 +- internal/firewalls/nftables/conn_test.go | 3 +- internal/firewalls/nftables/installer.go | 9 ++-- internal/iplibrary/action_firewalld.go | 3 +- internal/iplibrary/action_ipset.go | 9 ++-- internal/iplibrary/action_iptables.go | 3 +- internal/nodes/api_stream.go | 5 +- internal/nodes/listener_manager.go | 3 +- internal/nodes/system_services.go | 3 +- internal/utils/clock/manager.go | 7 ++- internal/utils/exec/look_linux.go | 59 ++++++++++++++++++++++++ internal/utils/exec/look_others.go | 10 ++++ internal/utils/service_linux.go | 8 ++-- 14 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 internal/utils/exec/look_linux.go create mode 100644 internal/utils/exec/look_others.go diff --git a/internal/apps/app_cmd.go b/internal/apps/app_cmd.go index c1abe5b..d11f29a 100644 --- a/internal/apps/app_cmd.go +++ b/internal/apps/app_cmd.go @@ -3,6 +3,7 @@ package apps import ( "fmt" teaconst "github.com/TeaOSLab/EdgeNode/internal/const" + executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" "github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/types" @@ -215,7 +216,7 @@ func (this *AppCmd) runStop() { // 从systemd中停止 if runtime.GOOS == "linux" { - systemctl, _ := exec.LookPath("systemctl") + systemctl, _ := executils.LookPath("systemctl") if len(systemctl) > 0 { go func() { // 有可能会长时间执行,这里不阻塞进程 diff --git a/internal/firewalls/firewall_firewalld.go b/internal/firewalls/firewall_firewalld.go index 6fbca5b..0e35ddb 100644 --- a/internal/firewalls/firewall_firewalld.go +++ b/internal/firewalls/firewall_firewalld.go @@ -9,7 +9,6 @@ import ( "github.com/TeaOSLab/EdgeNode/internal/remotelogs" executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" "github.com/iwind/TeaGo/types" - "os/exec" "strings" "time" ) @@ -32,7 +31,7 @@ func NewFirewalld() *Firewalld { cmdQueue: make(chan *firewalldCmd, 4096), } - path, err := exec.LookPath("firewall-cmd") + path, err := executils.LookPath("firewall-cmd") if err == nil && len(path) > 0 { var cmd = executils.NewTimeoutCmd(3*time.Second, path, "--state") err := cmd.Run() diff --git a/internal/firewalls/nftables/conn_test.go b/internal/firewalls/nftables/conn_test.go index 37fa999..8840210 100644 --- a/internal/firewalls/nftables/conn_test.go +++ b/internal/firewalls/nftables/conn_test.go @@ -6,12 +6,13 @@ package nftables_test import ( "github.com/TeaOSLab/EdgeNode/internal/firewalls/nftables" + executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" "os/exec" "testing" ) func TestConn_Test(t *testing.T) { - _, err := exec.LookPath("nft") + _, err := executils.LookPath("nft") if err == nil { t.Log("ok") return diff --git a/internal/firewalls/nftables/installer.go b/internal/firewalls/nftables/installer.go index eb93775..c1aae6d 100644 --- a/internal/firewalls/nftables/installer.go +++ b/internal/firewalls/nftables/installer.go @@ -13,7 +13,6 @@ import ( executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" "github.com/iwind/TeaGo/logs" "os" - "os/exec" "runtime" "time" ) @@ -55,7 +54,7 @@ func init() { // NftExePath 查找nftables可执行文件路径 func NftExePath() string { - path, _ := exec.LookPath("nft") + path, _ := executils.LookPath("nft") if len(path) > 0 { return path } @@ -93,14 +92,14 @@ func (this *Installer) Install() error { var cmd *executils.Cmd // check dnf - dnfExe, err := exec.LookPath("dnf") + dnfExe, err := executils.LookPath("dnf") if err == nil { cmd = executils.NewCmd(dnfExe, "-y", "install", "nftables") } // check apt if cmd == nil { - aptExe, err := exec.LookPath("apt") + aptExe, err := executils.LookPath("apt") if err == nil { cmd = executils.NewCmd(aptExe, "install", "nftables") } @@ -108,7 +107,7 @@ func (this *Installer) Install() error { // check yum if cmd == nil { - yumExe, err := exec.LookPath("yum") + yumExe, err := executils.LookPath("yum") if err == nil { cmd = executils.NewCmd(yumExe, "-y", "install", "nftables") } diff --git a/internal/iplibrary/action_firewalld.go b/internal/iplibrary/action_firewalld.go index 2ad63a1..6dd5156 100644 --- a/internal/iplibrary/action_firewalld.go +++ b/internal/iplibrary/action_firewalld.go @@ -6,7 +6,6 @@ import ( "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" - "os/exec" "runtime" "time" ) @@ -82,7 +81,7 @@ func (this *FirewalldAction) runActionSingleIP(action string, listType IPListTyp path := this.config.Path var err error if len(path) == 0 { - path, err = exec.LookPath("firewall-cmd") + path, err = executils.LookPath("firewall-cmd") if err != nil { if this.firewalldNotFound { return nil diff --git a/internal/iplibrary/action_ipset.go b/internal/iplibrary/action_ipset.go index 6afd46a..4629a48 100644 --- a/internal/iplibrary/action_ipset.go +++ b/internal/iplibrary/action_ipset.go @@ -6,7 +6,6 @@ import ( "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" "github.com/iwind/TeaGo/types" - "os/exec" "runtime" "strconv" "strings" @@ -55,7 +54,7 @@ func (this *IPSetAction) Init(config *firewallconfigs.FirewallActionConfig) erro // 创建ipset { - path, err := exec.LookPath("ipset") + path, err := executils.LookPath("ipset") if err != nil { return err } @@ -99,7 +98,7 @@ func (this *IPSetAction) Init(config *firewallconfigs.FirewallActionConfig) erro // firewalld if this.config.AutoAddToFirewalld { - path, err := exec.LookPath("firewall-cmd") + path, err := executils.LookPath("firewall-cmd") if err != nil { return err } @@ -179,7 +178,7 @@ func (this *IPSetAction) Init(config *firewallconfigs.FirewallActionConfig) erro // iptables if this.config.AutoAddToIPTables { - path, err := exec.LookPath("iptables") + path, err := executils.LookPath("iptables") if err != nil { return err } @@ -311,7 +310,7 @@ func (this *IPSetAction) runActionSingleIP(action string, listType IPListType, i var path = this.config.Path var err error if len(path) == 0 { - path, err = exec.LookPath("ipset") + path, err = executils.LookPath("ipset") if err != nil { // 找不到ipset命令错误只提示一次 if this.ipsetNotfound { diff --git a/internal/iplibrary/action_iptables.go b/internal/iplibrary/action_iptables.go index 2aee19a..8c83309 100644 --- a/internal/iplibrary/action_iptables.go +++ b/internal/iplibrary/action_iptables.go @@ -6,7 +6,6 @@ import ( "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" "github.com/TeaOSLab/EdgeNode/internal/utils" executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" - "os/exec" "runtime" "strings" "time" @@ -87,7 +86,7 @@ func (this *IPTablesAction) runActionSingleIP(action string, listType IPListType var path = this.config.Path var err error if len(path) == 0 { - path, err = exec.LookPath("iptables") + path, err = executils.LookPath("iptables") if err != nil { if this.iptablesNotFound { return nil diff --git a/internal/nodes/api_stream.go b/internal/nodes/api_stream.go index f53df00..cafe288 100644 --- a/internal/nodes/api_stream.go +++ b/internal/nodes/api_stream.go @@ -20,7 +20,6 @@ import ( "github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/maps" "net/url" - "os/exec" "regexp" "runtime" "strconv" @@ -336,7 +335,7 @@ func (this *APIStream) handleNewNodeTask(message *pb.NodeStreamMessage) error { // 检查Systemd服务 func (this *APIStream) handleCheckSystemdService(message *pb.NodeStreamMessage) error { - systemctl, err := exec.LookPath("systemctl") + systemctl, err := executils.LookPath("systemctl") if err != nil { this.replyFail(message.RequestId, "'systemctl' not found") return nil @@ -378,7 +377,7 @@ func (this *APIStream) handleCheckLocalFirewall(message *pb.NodeStreamMessage) e return nil } - nft, err := exec.LookPath("nft") + nft, err := executils.LookPath("nft") if err != nil { this.replyFail(message.RequestId, "'nft' not found: "+err.Error()) return nil diff --git a/internal/nodes/listener_manager.go b/internal/nodes/listener_manager.go index d52d1f6..6c158aa 100644 --- a/internal/nodes/listener_manager.go +++ b/internal/nodes/listener_manager.go @@ -15,7 +15,6 @@ import ( "github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/types" "net/url" - "os/exec" "regexp" "runtime" "sort" @@ -213,7 +212,7 @@ func (this *ListenerManager) findProcessNameWithPort(isUdp bool, port string) st return "" } - path, err := exec.LookPath("ss") + path, err := executils.LookPath("ss") if err != nil { return "" } diff --git a/internal/nodes/system_services.go b/internal/nodes/system_services.go index 1b50349..424187f 100644 --- a/internal/nodes/system_services.go +++ b/internal/nodes/system_services.go @@ -13,7 +13,6 @@ import ( executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" "github.com/iwind/TeaGo/maps" "os" - "os/exec" "runtime" "time" ) @@ -84,7 +83,7 @@ func (this *SystemServiceManager) setupSystemd(params maps.Map) error { } // 检查当前的service - systemctl, err := exec.LookPath("systemctl") + systemctl, err := executils.LookPath("systemctl") if err != nil { return err } diff --git a/internal/utils/clock/manager.go b/internal/utils/clock/manager.go index fc39806..edad01c 100644 --- a/internal/utils/clock/manager.go +++ b/internal/utils/clock/manager.go @@ -13,7 +13,6 @@ import ( executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec" timeutil "github.com/iwind/TeaGo/utils/time" "net" - "os/exec" "runtime" "time" ) @@ -86,7 +85,7 @@ func (this *ClockManager) Sync() error { // check chrony if config.CheckChrony { - chronycExe, err := exec.LookPath("chronyc") + chronycExe, err := executils.LookPath("chronyc") if err == nil && len(chronycExe) > 0 { var chronyCmd = executils.NewTimeoutCmd(3*time.Second, chronycExe, "tracking") err = chronyCmd.Run() @@ -101,11 +100,11 @@ func (this *ClockManager) Sync() error { server = "pool.ntp.org" } - ntpdate, err := exec.LookPath("ntpdate") + ntpdate, err := executils.LookPath("ntpdate") if err != nil { // 使用 date 命令设置 // date --set TIME - dateExe, err := exec.LookPath("date") + dateExe, err := executils.LookPath("date") if err == nil { currentTime, err := this.ReadServer(server) if err != nil { diff --git a/internal/utils/exec/look_linux.go b/internal/utils/exec/look_linux.go new file mode 100644 index 0000000..9b15835 --- /dev/null +++ b/internal/utils/exec/look_linux.go @@ -0,0 +1,59 @@ +// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . +//go:build linux + +package executils + +import ( + "golang.org/x/sys/unix" + "io/fs" + "os" + "os/exec" + "syscall" +) + +// LookPath customize our LookPath() function, to work in broken $PATH environment variable +func LookPath(file string) (string, error) { + result, err := exec.LookPath(file) + if err == nil && len(result) > 0 { + return result, nil + } + + // add common dirs contains executable files these may be excluded in $PATH environment variable + var binPaths = []string{ + "/usr/sbin", + "/usr/bin", + "/usr/local/sbin", + "/usr/local/bin", + } + + for _, binPath := range binPaths { + var fullPath = binPath + string(os.PathSeparator) + file + + stat, err := os.Stat(fullPath) + if err != nil { + continue + } + if stat.IsDir() { + return "", syscall.EISDIR + } + + var mode = stat.Mode() + if mode.IsDir() { + return "", syscall.EISDIR + } + err = syscall.Faccessat(unix.AT_FDCWD, fullPath, unix.X_OK, unix.AT_EACCESS) + if err == nil || (err != syscall.ENOSYS && err != syscall.EPERM) { + return fullPath, err + } + if mode&0111 != 0 { + return fullPath, nil + } + return "", fs.ErrPermission + } + + return "", &exec.Error{ + Name: file, + Err: exec.ErrNotFound, + } +} + diff --git a/internal/utils/exec/look_others.go b/internal/utils/exec/look_others.go new file mode 100644 index 0000000..a759c8e --- /dev/null +++ b/internal/utils/exec/look_others.go @@ -0,0 +1,10 @@ +// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . +//go:build !linux + +package executils + +import "os/exec" + +func LookPath(file string) (string, error) { + return exec.LookPath(file) +} diff --git a/internal/utils/service_linux.go b/internal/utils/service_linux.go index 69cc482..aa1ae90 100644 --- a/internal/utils/service_linux.go +++ b/internal/utils/service_linux.go @@ -24,7 +24,7 @@ func (this *ServiceManager) Install(exePath string, args []string) error { return errors.New("only root users can install the service") } - systemd, err := exec.LookPath("systemctl") + systemd, err := executils.LookPath("systemctl") if err != nil { return this.installInitService(exePath, args) } @@ -39,7 +39,7 @@ func (this *ServiceManager) Start() error { } if files.NewFile(systemdServiceFile).Exists() { - systemd, err := exec.LookPath("systemctl") + systemd, err := executils.LookPath("systemctl") if err != nil { return err } @@ -56,7 +56,7 @@ func (this *ServiceManager) Uninstall() error { } if files.NewFile(systemdServiceFile).Exists() { - systemd, err := exec.LookPath("systemctl") + systemd, err := executils.LookPath("systemctl") if err != nil { return err } @@ -96,7 +96,7 @@ func (this *ServiceManager) installInitService(exePath string, args []string) er return err } - chkCmd, err := exec.LookPath("chkconfig") + chkCmd, err := executils.LookPath("chkconfig") if err != nil { return err }