前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用golang写一个简单的agent

使用golang写一个简单的agent

原创
作者头像
保持热爱奔赴山海
发布2024-09-05 14:10:51
1320
发布2024-09-05 14:10:51
举报
文章被收录于专栏:DevOps

agent的好处:在不便于ssh打通的环境下,可以通过agent来接受待执行的命令(例如数据采集、脚本执行)

代码如下:

代码语言:txt
复制
package main

import (
    "flag"
    "fmt"
    "log"
    "net/http"
    "os/exec"
    "strings"
    "time"
)

const expectedParams = 4

func handler(password, scriptPath string) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Println("Received HTTP request!")
        query := r.URL.RawQuery
        parts := strings.Split(query, "?")
        if len(parts) != expectedParams+1 { // 1 for password, 4 for parameters
            http.Error(w, fmt.Sprintf("Expected exactly %d parameters", expectedParams), http.StatusBadRequest)
            return
        }

        passwd := parts[0]
        cmdParts := parts[1:]


        if passwd != password {
            http.Error(w, "Incorrect password!", http.StatusUnauthorized)
            return
        }

        cmd := exec.Command("bash", "-c", fmt.Sprintf("cd %s && ./%s %s %s %s", scriptPath, cmdParts[0], cmdParts[1], cmdParts[2], cmdParts[3]))

        out, err := cmd.CombinedOutput()
        if err != nil {
            http.Error(w, fmt.Sprintf("Command execution error: %v", err), http.StatusInternalServerError)
            return
        }

        w.WriteHeader(http.StatusOK)
        w.Write(out)
    }
}

func main() {
    // 定义命令行参数
    port := flag.String("port", "8888", "The port to listen on")
    pass := flag.String("password", "", "The password for authentication")
    scriptPath := flag.String("scriptPath", "/opt/dba_scripts/", "The path to the script directory")
    flag.Parse()

    if *pass == "" {
        log.Fatal("Password must be provided")
    }

    http.HandleFunc("/", handler(*pass, *scriptPath))
    serverAddr := fmt.Sprintf("0.0.0.0:%s", *port)
    s := &http.Server{
        Addr:           serverAddr,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }

    log.Println(time.Now().Format(time.RFC1123), "Server Starts -", serverAddr)
    err := s.ListenAndServe()
    if err != nil {
        log.Fatal(err)
    }
    log.Println(time.Now().Format(time.RFC1123), "Server Stops -", serverAddr)
}

编译和运行

代码语言:txt
复制
go build 
./main -port=8888 -password=123456 -scriptPath=/opt/

调用

代码语言:txt
复制
1、编写测试python脚本
    # 注意:
    # 如果是python脚本的话,需要在第一行定义python的版本。
    # 如果是shell脚本,需要在第一行定义#!/bin/bash字样。
    
    cat aaa.py   内容如下:
    #!/usr/bin/python3
    print("aaaaaaaaaaaaa")


2、需要先确保文件是可执行权限的
     chmod +x aaa.py 


3、 调用
    curl '127.0.0.1:8888/?123456?aaa.py?arg1?arg2?arg3'
    直接在屏幕上输出了 aaaaaaaaaaaaa


其它例子:
    带参数的例子
        curl '127.0.0.1:8888/?123456?test2.sh?db1?tb1?size'
        curl '127.0.0.1:8888/?123456?test2.sh?db1?tb1?' 
    
    不带参数的例子(注意确保参数是4个即可,不足的补齐):
        curl '127.0.0.1:8888/?123456?test2.sh???'

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档