go 语言Http服务器远程执行shell命令

背景
想要在服务器上起一个http服务器,用来远程执行shell命令并且返回结果。

基础版

package main

import (
	"io"
	"log"
	"net/http"
)

func main() {
	// Hello world, the web server

	helloHandler := func(w http.ResponseWriter, req *http.Request) {
		io.WriteString(w, "Hello, world!\n")
	}

	http.HandleFunc("/hello", helloHandler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

编译完成之后,执行起一个http服务器,可以在浏览器中使用localhost:8080/hello发送请求。也可以在shell命令行中使用curl命令发送请求。
在这里插入图片描述
在这里插入图片描述
想要远程执行命令,肯定是希望用curl的方式远程执行命令。

上面已经简单的实现了一个http服务器,可以正常响应请求,我们希望的是执行shell命令,应该如何给http服务器传shell命令参数,一起看一下。

实战版

package main

import (
	"bytes"
	"fmt"
	"net/http"
	"os/exec"
)

func execShellCmdBlock(shellCmd string) (string, error) {
	var out bytes.Buffer

	cmd := exec.Command("/bin/bash", "-c", shellCmd)
	cmd.Stdout = &out

	err := cmd.Run()

	return out.String(), err
}

func Register(requestPath string) {
	http.HandleFunc(requestPath, func(writer http.ResponseWriter, request *http.Request) {
		err := request.ParseForm()
		if err != nil {
			return
		}

		cmds := request.Form["cmd"]
		if len(cmds) != 1 {
			return
		}

		ret, err := execShellCmdBlock(cmds[0])
		if err != nil {
			panic(err)
		}

		fmt.Fprintf(writer, "%s", ret)
	})
}

func main() {
	Register("/execute")

	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		panic(err)
	}
}

大概逻辑就是先注册回调,回调解析传入的参数,并且以阻塞的方式运行shell命令。

curtis@curtis-Aspire-E5-471G:~$ curl "http://192.168.0.105:8080/execute?cmd=%20ls%20-l"
total 6244
-rw-rw-r-- 1 curtis curtis      28 1217 12:53 go.mod
-rwxrwxr-x 1 curtis curtis 6383925 1217 13:34 http_server
-rw-rw-r-- 1 curtis curtis     749 1217 13:34 main.go

踩过的坑记录以下:
1、假设要在192.168.0.106上通过curl下发命令,如果http服务器所在的主机没有关闭防火墙的话,会报no route错误。
2、有些服务器可能对某些特定端口有限制,需要使用iptables服务器端口放开,如果端口未放开,会报timeout

有一个疑惑就是如何让http sever可以在后台运行,找到了一个大佬写的库,亲测可用:
https://www.jianshu.com/p/ccf0748d0e6d

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值