Skip to content

Instantly share code, notes, and snippets.

@philwinder
Last active February 3, 2022 07:36
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save philwinder/5ec7628c6687794029b3 to your computer and use it in GitHub Desktop.
Save philwinder/5ec7628c6687794029b3 to your computer and use it in GitHub Desktop.
IVZ: Nginx config for using Lua as the authentication module. You must install nginx with lua support. See "openresty" for linux distros or the vagrant bootstrap shell script.
--[[
Provides custom authorization for nginx.
See the `nginx_authorize_by_lua.conf` for the Nginx config. This lua file is referenced in the config
See testWebserverAccess.sh for unit tests.
To Run nginx (make sure you have the lua, config and htpasswd file):
$ /usr/local/openresty/nginx/sbin/nginx -c /etc/nginx/conf/nginx_authorize_by_lua.conf
Logs are available at: /usr/local/openresty/nginx/logs/lua.log
To write to the log:
ngx.log(ngx.DEBUG, user) -- Write user to log
]]--
-- Authorization rules
-- This grants rights to a user
-- Usage: $username = "$group"
local userGroups = {
user = "user",
dev = "dev",
admin = "admin",
bob = "user",
alice = "user",
logAdmin = "adminOfLogs"
}
-- Provides group access rights
-- Usage:
-- $GROUP = { ["$URL_REGEX"] = { "$HTTP_METHOD", "$HTTP_METHOD" } }
local restrictions = {
user = {
["^/monitor*"] = { "HEAD", "GET" },
["^/kibana4*"] = { "HEAD", "GET" }
},
dev = {
["^/monitor*"] = { "HEAD", "GET", "PUT", "POST" },
["^/log*"] = { "HEAD", "GET", "PUT", "POST" },
["^/kibana4*"] = { "HEAD", "GET" }
},
admin = {
["^/*"] = { "HEAD", "GET", "POST", "PUT", "DELETE" },
["^/kibana4*"] = { "HEAD", "GET" }
},
adminOfLogs = {
["^/log*"] = { "HEAD", "GET", "POST", "PUT", "DELETE" }
}
}
-- Write 403 message function
function write403Message ()
ngx.header.content_type = 'text/plain'
ngx.status = 403
ngx.say("403 Forbidden: You don\'t have access to this resource.")
return ngx.exit(403)
end
-- get authenticated user as role
local user = ngx.var.remote_user -- Get user
local role = userGroups[user] -- Get group
-- exit 403 when no matching role has been found
if restrictions[role] == nil then
return write403Message()
end
-- get URL
local uri = ngx.var.uri
-- get method
local method = ngx.req.get_method()
local allowed = false
for path, methods in pairs(restrictions[role]) do
-- path matched rules?
local p = string.match(uri, path)
-- method matched rules?
local m = nil
for _, _method in pairs(methods) do
m = m and m or string.match(method, _method)
end
if p and m then
allowed = true
break
end
end
if not allowed then
return write403Message()
end
admin:8QRvjnvxOmISM
alice:aRoWwFbQFh0ic
bob:qyz8eIFW3uJoo
clare:Lvfja1wClMGnM
dev:CmJO//.L488S2
user:u13.ImIxrC5cU
# Generate passwords:
# You can use an online htpasswd tool, a python script or the openssl package on your distro.
# $ printf "user:$(openssl password -crypt user)\n" >> htpasswd
# $ printf "admin:$(openssl password -crypt admin)\n" >> htpasswd
#
# Install the Nginx with Lua support ("openresty"):
# To Run nginx (make sure you have the lua, config and htpasswd file):
# $ /usr/local/openresty/nginx/sbin/nginx -c /etc/nginx/conf/nginx_authorize_by_lua.conf
worker_processes 1;
error_log logs/lua.log notice;
events {
worker_connections 1024;
}
http {
upstream elasticsearch {
server 127.0.0.1:9200;
keepalive 15;
}
server {
listen 8080;
location / {
auth_basic "Protected Elasticsearch";
auth_basic_user_file "/usr/local/openresty/nginx/auth/htpasswd";
access_by_lua_file '/usr/local/openresty/nginx/conf/authorize.lua';
proxy_pass http://elasticsearch;
proxy_redirect off;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
}
}
}
# Generate passwords:
# You can use an online htpasswd tool, a python script or the openssl package on your distro.
# $ printf "user:$(openssl password -crypt user)\n" >> htpasswd
# $ printf "admin:$(openssl password -crypt admin)\n" >> htpasswd
#
# Install the Nginx with Lua support ("openresty"):
# To Run nginx (make sure you have the lua, config and htpasswd file):
# $ /usr/local/openresty/nginx/sbin/nginx -c /etc/nginx/conf/nginx_authorize_by_lua.conf
#
# This also includes the kibana endpoints
worker_processes 1;
error_log logs/lua.log notice;
events {
worker_connections 1024;
}
http {
upstream elasticsearch {
server 127.0.0.1:9200;
keepalive 15;
}
upstream kibana {
server 127.0.0.1:5601;
}
server {
listen 8080;
# For kibana, re-routes traffic from host:8080/kibana4 to host:5601/
location ~ ^/kibana4/.* {
auth_basic "Protected Elasticsearch";
auth_basic_user_file "/usr/local/openresty/nginx/auth/htpasswd";
access_by_lua_file '/usr/local/openresty/nginx/conf/authorize.lua';
proxy_pass http://kibana;
rewrite ^/kibana4/(.*) /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# To allow host:8080/kibana4 (no trailing slash) to work
location ~ ^/kibana4 {
rewrite ^([^.]*[^/])$ $1/ permanent;
}
location / {
auth_basic "Protected Elasticsearch";
auth_basic_user_file "/usr/local/openresty/nginx/auth/htpasswd";
access_by_lua_file '/usr/local/openresty/nginx/conf/authorize.lua';
proxy_pass http://elasticsearch;
proxy_redirect off;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment