北京 通过 golang 更新 nginx 配置文件

zhejie · 2019年11月08日 · 最后由 lework 回复于 2019年11月08日 · 411 次阅读

应用场景:公司项目对外面公司出售,到期了就在 web 页面把以 xxx 为结尾的 url 屏蔽掉,但是开发写的前端只是个标记,没有实现这个功能,通过这个程序,对方在 web 页面操作后会访问此程序 url 发送两个字段 id,name,通过这两个字段实现修改 nginx 配置文件完成屏蔽
目录结构:
├── main.go //主程序入口
├── nginxconf
│   └── nginxconf.go //修改 nginx 配置文件
├── nginx_reload
│   └── nginx_reload.go //重启 nginx
└── web
└── web.go //传入参数入口
注:nginx 配置文件命名,如果不一样安需求修改:
如果域名为 dscp.super.com,那么 url 里 id 就为 dscp,配置文件名字为 dscp.super.com_vhost.conf
文件内容:
nginx_reload.go

package nginx_reload

import (
    "bytes"
    "os/exec"
)

func Reload() (string, string, error) {
    var outMsg, errMsg bytes.Buffer
    cmd := exec.Command("/bin/bash", "-c", `nginx -s reload`)  //如果nginx没有环境变量或者bin目录下软连接的话要写绝对路径
    cmd.Stdout = &outMsg
    cmd.Stderr = &errMsg
    err := cmd.Run()    //如果命令成功执行,返回值为nil
    return outMsg.String(), errMsg.String(), err
}

web.go

package web

import (
    "fmt"
    "log"
    "net/http"
    "nginxconf"
)

func AddUser(w http.ResponseWriter, req *http.Request) {
    //配置文件目录,根据自己需求配置
    var path string = ("/opt/nginx-1.13.7-prod/conf/vhosts/")
        //通过访问http://$IP:8989/user?&id=wh&name=test获取参数,id为子域名前缀,name为要屏蔽的字段
    id, name := req.FormValue("id"), req.FormValue("name")
    if id == "wh"{  //通过判断确定是否有这个域名,这里得手动按照下面else if id == "xx"添加
        path2 := fmt.Sprintf("%s%s.super.com_vhost.conf", path, id)
        nginxconf.Nginxconf(path2,name)
    }else if id == "yh"{ 
        path2 := fmt.Sprintf("%s%s.super.com_vhost.conf", path, id)
        nginxconf.Nginxconf(path2,name)      //如果有就调用nginxconf.Nginxconf函数进行修改
    }else {
        fmt.Println("错误的子域名:", id)
    }
    out := fmt.Sprintf("子域名为: %s, 禁用字段为: %s", id, name)  
    log.Println(out)   //打印日志
    fmt.Fprintf(w, out)  //返回结果
}

nginxconf.go

package nginxconf

import (
    "bytes"
    "fmt"
    "os/exec"
)
func Nginxconf(path, name string) (string, string, error) {
    var outMsg, errMsg bytes.Buffer
    cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf(`sed -i 's/404.html;/&\nif \
 (\$request_uri  ~* "%s") {return 403;}/' %s`, name, path))  //这里通过web函数传过来的参数使用sed命令进行替换
    cmd.Stdout = &outMsg
    cmd.Stderr = &errMsg
    err := cmd.Run()    //如果命令成功执行,返回值为nil
    return outMsg.String(), errMsg.String(), err

    nginx_reload.Reload()  //重启nginx
}

main.go

package main

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

func main() {
    http.HandleFunc("/", web.AddUser)
    err := http.ListenAndServe(":8989", nil)  //8989为端口号,可以自定义
    if err != nil {
        log.Fatal("ListenAndServe: ", err.Error())
    }
}

注:通过浏览器访问的话后台会执行两次,所以会报错:"错误的子域名:",用 curl 访问没任何问题.

通过 api 接口来管理应用程序,非常棒👍 ,后续如果在加个 web 操作界面。那就更加棒了👍 👍 👍

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册