-
-
Save hangj/ce6aabac77e96b010e3b361e18422013 to your computer and use it in GitHub Desktop.
Validating payloads from GitHub webhooks with Nginx + Lua
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- $ sudo opm get jkeys089/lua-resty-hmac | |
local shell = require "resty.shell" | |
local cjson = require "cjson.safe" | |
local hmac = require "resty.hmac" | |
local secret = '<MY SUPER SECRET>' | |
local event = 'push' | |
local branch = 'refs/heads/master' | |
ngx.header.content_type = "text/plain; charset=utf-8" | |
local stdin = "" | |
local timeout = 50 * 1000 -- ms | |
local max_size = 4096*4 -- byte | |
if ngx.req.get_method():upper() ~= "POST" then | |
ngx.log(ngx.ERR, "wrong event request method: ", ngx.req.get_method()) | |
return ngx.exit(ngx.HTTP_NOT_ALLOWED) | |
end | |
local headers = ngx.req.get_headers() | |
if not headers['X-GitHub-Event'] or headers['X-GitHub-Event']:upper() ~= event:upper() then | |
ngx.log(ngx.ERR, "wrong event type: ", headers['X-GitHub-Event']) | |
return ngx.exit(ngx.HTTP_NOT_ACCEPTABLE) | |
end | |
if headers['Content-Type'] ~= 'application/json' then | |
ngx.log(ngx.ERR, "wrong content type header: ", headers['Content-Type']) | |
return ngx.exit (ngx.HTTP_NOT_ACCEPTABLE) | |
end | |
ngx.req.read_body() | |
local data = ngx.req.get_body_data() | |
local args = ngx.req.get_uri_args() | |
if not data then | |
ngx.log(ngx.ERR, "failed to get request body") | |
return ngx.exit (ngx.HTTP_BAD_REQUEST) | |
end | |
local signature = headers['X-Hub-Signature'] | |
local hmac_sha1 = hmac:new(secret, hmac.ALGOS.SHA1) | |
if not hmac_sha1 then | |
ngx.log(ngx.ERR, "falied to create hmac_sha1 object") | |
ngx.say("falied to create hmac_sha1 object") | |
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) | |
end | |
-- local ok = hmac_sha1:update(data) | |
local hex = hmac_sha1:final(data, true) | |
if not hex then | |
ngx.log(ngx.ERR, "failed to add data") | |
ngx.say("failed to add data") | |
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) | |
end | |
hmac_sha1:reset() | |
hex = "sha1=" .. hex | |
if hex ~= signature then | |
ngx.log(ngx.ERR, "wrong webhook signature ", hex, " ", signature) | |
return ngx.exit(ngx.HTTP_FORBIDDEN) | |
end | |
data = cjson.decode(data) | |
if data.ref ~= branch then | |
ngx.say("Skip branch ", data.ref) | |
return ngx.exit(ngx.HTTP_OK) | |
end | |
---- deploy ---- | |
local cmd = "./reload.sh" | |
local ok, stdout, stderr, reason, status = shell.run(cmd, stdin, timeout, max_size) | |
local str = string.format("./reload.sh: \nok=%s\nstdout=%s\nstderr=%s\nreason=%s\nstatus=%s\n", ok, stdout, stderr, reason, status) | |
ngx.log(ngx.ERR, "deploy: ", str) | |
ngx.say(str) | |
if status ~= 0 then | |
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) | |
end | |
local mail = require "resty.mail" | |
local mailer = mail.new({ | |
host = "smtp.qq.com", | |
port = 587, | |
starttls = true, | |
username = "[email protected]", | |
password = "xxxx", -- 邮箱需要设置开启 smtp 服务,这里填写授权码 | |
}) | |
local ok, err = mailer:send({ | |
from = "server <[email protected]>", | |
to = { "[email protected]" }, | |
subject = "deployed " .. (status == 0 and "SUCCESS" or "FAILED"), | |
text = "text", | |
html = "<h1>Header.</h1>", | |
}) | |
if not ok then | |
ngx.log(ngx.ERR, "mailer:send error: ", err) | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
server { | |
# .... | |
location /deploy { | |
client_body_buffer_size 3M; | |
client_max_body_size 3M; | |
content_by_lua_file /path/to/deploy.lua; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
BASEDIR=$(dirname "$0") | |
cd $BASEDIR | |
git pull | |
sudo openresty -p `pwd` -c conf/nginx.conf -t || exit 1 | |
ps -ef | grep openresty | grep -v grep | |
if [ $? -eq 0 ] | |
then | |
sudo openresty -p `pwd` -c conf/nginx.conf -s reload | |
else | |
sudo openresty -p `pwd` -c conf/nginx.conf | |
fi | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment