From d57f5b22f40ddf9386a2bac53278051c430633c9 Mon Sep 17 00:00:00 2001 From: Ramzes Date: Sat, 3 Jul 2021 17:42:09 +0300 Subject: [PATCH] Github secrets support --- README.md | 6 ++++-- config.sample.json | 3 ++- main.go | 26 ++++++++++++++++++++++++-- main_test.go | 15 +++++++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 main_test.go diff --git a/README.md b/README.md index a6549df..78fc636 100644 --- a/README.md +++ b/README.md @@ -63,8 +63,8 @@ Edit config **/etc/mini-deployer.json** as you need ### Configuration sample: ```json5 { - "cert": "", - "key": "", + "cert": "/etc/ssl/site.crt", + "key": "/etc/ssl/site.key", "commands": { "micro": "cd /var/www/micro && git pull" }, @@ -76,6 +76,7 @@ Edit config **/etc/mini-deployer.json** as you need "log": "", "disable_autoreload": false, "gitlab_token": "", + "github_secret": "", "timeout": 120 } ``` @@ -85,6 +86,7 @@ Edit config **/etc/mini-deployer.json** as you need * log - path to logfile (if you leave it empty, as described in service file - logs will be in syslog) * disable_autoreload - disable autoreload feature (use curl localhost:7654/reload to do it manually) * gitlab_token - Instead of using whitelist ips you may bypass it using gitlab_token config flag equal to "Secret token" from gitlab webhook configuration +* github_secret - Or use GitHub secret * timeout - how many seconds to wait until process kill (default 10 seconds) diff --git a/config.sample.json b/config.sample.json index 6a623c7..d77f96e 100644 --- a/config.sample.json +++ b/config.sample.json @@ -8,5 +8,6 @@ "::1/128" ], "disable_autoreload": false, - "gitlab_token": "" + "gitlab_token": "", + "github_secret": "" } \ No newline at end of file diff --git a/main.go b/main.go index da5f528..39f9037 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,9 @@ package main import ( "context" + "crypto/hmac" + "crypto/sha256" + "encoding/hex" "encoding/json" "flag" "fmt" @@ -27,6 +30,7 @@ type configFile struct { Timeout int64 `json:"timeout"` DisableAutoreload bool `json:"disable_autoreload"` GitlabToken string `json:"gitlab_token"` + GithubSecret string `json:"github_secret"` } var Cfg configFile @@ -116,7 +120,10 @@ func ReadConfig() error { func RunHttp() { for { port := strings.Split(*listen, ":")[1] - fmt.Printf("Deployer started\n# curl http://localhost:%s/reload\t to manual reload\n\n", port) + fmt.Printf("Deployer started\n") + if Cfg.DisableAutoreload { + fmt.Printf("# curl http://localhost:%s/reload to manual reload\n", port) + } mux := http.NewServeMux() srv := &http.Server{Addr: *listen, Handler: logRequest(mux), ErrorLog: log.Default()} @@ -155,7 +162,7 @@ func registerHandlers(srv *http.Server, mux *http.ServeMux) { writer.WriteHeader(500) wr.Write([]byte(fmt.Sprintf("run err: %s", err))) } - done := make(chan error) + done := make(chan error, 1) go func() { done <- c.Wait() }() // Start a timer @@ -209,10 +216,25 @@ func registerHandlers(srv *http.Server, mux *http.ServeMux) { } } +func checkGithubSig(secret string, header string, body []byte) bool { + s := hmac.New(sha256.New, []byte(secret)) + s.Write(body) + hash := "sha256=" + hex.EncodeToString(s.Sum(nil)) + return hash == header +} + func checkWhitelist(addr string, req *http.Request) bool { if Cfg.GitlabToken != "" && req.Header.Get("X-Gitlab-Token") == Cfg.GitlabToken { return true } + if Cfg.GithubSecret != "" && req.Header.Get("X-Hub-Signature-256") != "" { + post, e := ioutil.ReadAll(req.Body) + if e != nil { + log.Printf("github post read error") + return false + } + return checkGithubSig(Cfg.GithubSecret, req.Header.Get("X-Hub-Signature-256"), post) + } addrParts := strings.Split(addr, ":") addr = strings.Join(addrParts[0:len(addrParts)-1], ":") diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..ce93899 --- /dev/null +++ b/main_test.go @@ -0,0 +1,15 @@ +package main + +import "testing" + +var testBody = `payload` + +func TestGithubSecret(t *testing.T) { + + if checkGithubSig("123", "sha256=5908ccfcc78e69944fd954f569473d5cf65ad2a9dc52056fea7e814b133dbad2", []byte(testBody)) { + t.Logf("Github token check ok") + } else { + t.Fatalf("Github sig check failed") + } + +}