├── nginx-dumb-mertics
├── nginx_metrics
│ ├── up
│ └── .style
│ │ └── metrics.xslt
└── nginx.conf
├── lua-ffi
├── lua-qrencode.png
└── nginx.qrencode.conf
├── nginx-AD-auth
├── etc
│ ├── pam.d
│ │ └── nginx
│ └── pam_ldap.conf
└── nginx.conf
├── nginx-yum-repo
├── rebuild-repo.path
├── rebuild-repo.service
├── rebuild_repo.sh
└── yum-repo.conf
├── ssl-certs
├── gen_csr.sh
├── check_expire.sh
├── gen_server.sh
├── gen_client.sh
├── nginx-client-cert.conf
└── host.tld.csr.conf
├── nginx-google-authenticator
├── etc
│ └── pam.d
│ │ └── nginx_google
├── createuser.sh
└── nginx.conf
├── nginx-stream-ssh
├── ssh_config
└── nginx.conf
├── nginx-shell-webhook
├── shell-webhook.service
├── nginx.conf
└── shell-webhook
├── error-code-status
├── lua
│ ├── status_code_log.lua
│ └── status_code_dump.lua
└── nginx.conf
├── metrics-aggregation
└── status.conf
├── http-session
├── rsyslog.local.conf
└── nginx.proxy.conf
├── nginx-extended-limit_rate
└── nginx.conf
├── nginx-autoban
└── server.conf
├── nginx-modules
└── build-modules.sh
└── ReadMe.md
/nginx-dumb-mertics/nginx_metrics/up:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/lua-ffi/lua-qrencode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toxatoor/nginx/HEAD/lua-ffi/lua-qrencode.png
--------------------------------------------------------------------------------
/nginx-AD-auth/etc/pam.d/nginx:
--------------------------------------------------------------------------------
1 | auth required /lib/x86_64-linux-gnu/security/pam_ldap.so
2 | account required /lib/x86_64-linux-gnu/security/pam_ldap.so
3 |
4 |
--------------------------------------------------------------------------------
/nginx-yum-repo/rebuild-repo.path:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description= Rebuild repo
3 |
4 | [Path]
5 | PathModified=/srv/data/repoflags
6 |
7 | [Install]
8 | WantedBy=multi-user.target
9 |
--------------------------------------------------------------------------------
/ssl-certs/gen_csr.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | openssl req -new -newkey rsa:2048 -config $1.csr.conf -nodes -keyout $1.key -out $1.csr
4 |
5 | openssl req -in $1.csr -noout -text
6 |
--------------------------------------------------------------------------------
/nginx-yum-repo/rebuild-repo.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description= Rebuild repo
3 |
4 | [Service]
5 | Type=oneshot
6 | User=nginx
7 | Group=nginx
8 | ExecStart=/opt/bin/rebuild_repo.sh
9 |
--------------------------------------------------------------------------------
/nginx-google-authenticator/etc/pam.d/nginx_google:
--------------------------------------------------------------------------------
1 | auth required pam_google_authenticator.so secret=/etc/nginx/gauth/${USER} user=nginx
2 | account required pam_permit.so
3 |
--------------------------------------------------------------------------------
/nginx-google-authenticator/createuser.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | USER=$1
3 | google-authenticator -t -l "${USER} at my.web.site" -D -f -u -w 10 -s /etc/nginx/gauth/${USER}
4 | chown nginx:nginx /etc/nginx/gauth/${USER}
5 |
--------------------------------------------------------------------------------
/nginx-AD-auth/nginx.conf:
--------------------------------------------------------------------------------
1 |
2 | server {
3 | listen 80 ;
4 |
5 | auth_pam "Secure Zone";
6 | auth_pam_service_name "nginx";
7 |
8 | location / { return 200 "Authorized" ; }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/nginx-stream-ssh/ssh_config:
--------------------------------------------------------------------------------
1 | Host *
2 | ProxyCommand openssl s_client -quiet -connect %h:22 2>/dev/null
3 |
4 | # Host *
5 | # ProxyCommand openssl s_client -quiet -connect %h:22 -cert client.cert -key client.key 2>/dev/null
6 |
--------------------------------------------------------------------------------
/ssl-certs/check_expire.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | domain=$1
4 |
5 | /bin/date --utc --date "$(echo "Q" | openssl s_client -connect ${domain}:443 -servername ${domain} 2>/dev/null | openssl x509 -noout -enddate | awk -F'=' '{print $2}' )"
6 |
--------------------------------------------------------------------------------
/nginx-google-authenticator/nginx.conf:
--------------------------------------------------------------------------------
1 |
2 | load_module modules/ngx_http_auth_pam_module.so ;
3 |
4 | # ...
5 |
6 | location / {
7 | auth_pam "Secure Zone";
8 | auth_pam_service_name "nginx_google";
9 | # ...
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/nginx-shell-webhook/shell-webhook.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=socat-based cmd api
3 | After=network.target
4 |
5 | [Service]
6 | User=nobody
7 | Group=nobody
8 | ExecStart=/usr/bin/socat UDP-LISTEN:50333,fork,bind=127.0.0.1 EXEC:/opt/bin/shell-webhook
9 | Restart=always
10 |
11 | [Install]
12 | WantedBy=multi-user.target
13 |
--------------------------------------------------------------------------------
/error-code-status/lua/status_code_log.lua:
--------------------------------------------------------------------------------
1 | local status_codes = ngx.shared.status_codes
2 |
3 | local resp_code = tonumber(ngx.var.status)
4 |
5 | local newval, err = status_codes:incr(resp_code, 1)
6 | if not newval and err == "not found" then
7 | status_codes:add(resp_code, 0)
8 | status_codes:incr(resp_code, 1)
9 | end
10 |
--------------------------------------------------------------------------------
/nginx-shell-webhook/nginx.conf:
--------------------------------------------------------------------------------
1 | http {
2 |
3 | log_format shellwebhook '$cmd\n' ;
4 |
5 |
6 | server {
7 | location ~* ^/cmd/(\w+)$ {
8 | set $cmd $1 ;
9 | return 200 "$cmd";
10 | access_log syslog:server=127.0.0.1:50333,facility=local7,tag=nginx,severity=info,nohostname shellwebhook ;
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ssl-certs/gen_server.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | openssl req -new -newkey rsa:2048 -text -out cert.req -days 730
4 | openssl rsa -in privkey.pem -out cert.pem
5 | openssl req -x509 -in cert.req -text -key cert.pem -out cert.cert -days 730
6 | openssl dhparam -out dhparams.pem 2048
7 |
8 | cp cert.pem $1.key
9 | cp cert.cert $1.cert
10 |
11 | rm cert.* privkey*
12 |
13 |
--------------------------------------------------------------------------------
/nginx-shell-webhook/shell-webhook:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | LOG=/var/log/shell-webhook.log
4 |
5 | declare -a DATA
6 | read -a DATA
7 | cmd=${DATA[4]}
8 |
9 | case ${cmd} in
10 |
11 | reboot)
12 | echo "Executing reboot" >> ${LOG}
13 | ;;
14 |
15 | update)
16 | echo "Executing update" >> ${LOG}
17 | ;;
18 |
19 | *)
20 | echo "Unknown command" >> ${LOG}
21 | ;;
22 |
23 | esac
24 |
--------------------------------------------------------------------------------
/ssl-certs/gen_client.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | openssl req -new -newkey rsa:2048 -text -out cert.req -days 730
4 | openssl rsa -in privkey.pem -out cert.pem
5 | openssl req -x509 -in cert.req -text -key cert.pem -out cert.cert -days 730
6 | openssl pkcs12 -export -in cert.cert -inkey cert.pem -out cert.p12
7 |
8 | cp cert.cert $1.client.cert
9 | cp cert.p12 $1.client.p12
10 |
11 | rm cert.* privkey*
12 |
13 |
--------------------------------------------------------------------------------
/nginx-yum-repo/rebuild_repo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | FLAGPATH="/srv/data/repoflags"
4 | REPOPATH="/srv/data/repo"
5 | VALID_REPOS=" $(ls -ld ${REPOPATH}/* | xargs -n1 basename | xargs echo ) "
6 |
7 | for flag in ${FLAGPATH}/*
8 | do
9 | repo=$(basename ${flag})
10 |
11 | if [[ ${VALID_REPOS} == *" ${repo} "* ]]; then
12 | /bin/createrepo_c --update ${REPOPATH}/${repo}
13 | fi
14 |
15 | rm -f ${flag}
16 | done
17 |
--------------------------------------------------------------------------------
/error-code-status/lua/status_code_dump.lua:
--------------------------------------------------------------------------------
1 | local status_codes = ngx.shared.status_codes
2 | local notfound = status_codes:get("404") or 0
3 | local badgateway = status_codes:get("502") or 0
4 | local gatewaytimeout = status_codes:get("504") or 0
5 | local clienterr = status_codes:get("499") or 0
6 | local total = badgateway + gatewaytimeout
7 |
8 | ngx.say(notfound, " " , clienterr , " " , badgateway, " " , gatewaytimeout , " = ", total)
9 |
--------------------------------------------------------------------------------
/nginx-dumb-mertics/nginx.conf:
--------------------------------------------------------------------------------
1 | load_module modules/ngx_http_xslt_filter_module.so;
2 |
3 | log_format metrics "" ;
4 |
5 | server {
6 | listen 80 ;
7 | access_log /tmp/nginx_metrics/code_$status metrics ;
8 |
9 | location / {
10 | root html ;
11 | }
12 |
13 | location /nginx_metrics {
14 | alias /tmp/nginx_metrics ;
15 | autoindex on ;
16 | autoindex_format xml ;
17 | xslt_stylesheet /tmp/nginx_metrics/.style/metrics.xslt ;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/nginx-dumb-mertics/nginx_metrics/.style/metrics.xslt:
--------------------------------------------------------------------------------
1 |
\n\n' 51 | 52 | local i = 0 53 | for cur = 1, #data do 54 | local c = data:byte(cur, cur) 55 | char = (bit.band(c,1) == 0) and WHITE or BLACK 56 | out = out .. char 57 | i = i + 1 58 | 59 | if i == width then 60 | out = out .. "\n" 61 | i = 0 62 | end 63 | end 64 | 65 | out = out .. "\n\n" 66 | 67 | ngx.say(out) 68 | 69 | 70 | } 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /nginx-autoban/server.conf: -------------------------------------------------------------------------------- 1 | ### Rate limiting 2 | limit_req_zone $binary_remote_addr zone=api_limit:64m rate=10r/m ; 3 | 4 | ### Lua blocker 5 | lua_shared_dict banned_ips 32m ; 6 | 7 | init_by_lua_block { 8 | 9 | banned_ips = ngx.shared.banned_ips 10 | 11 | } 12 | 13 | ### server.com 14 | 15 | server { 16 | 17 | listen 0.0.0.0:80 ; 18 | 19 | server_name server.com ; 20 | 21 | ### check if client is banned 22 | access_by_lua_block { 23 | 24 | local ip = ngx.var.remote_addr 25 | local ban, flags = banned_ips:get(ip) 26 | if ban then 27 | ngx.exit(ngx.HTTP_FORBIDDEN) 28 | else 29 | return 30 | end 31 | 32 | } 33 | 34 | ### location to ban 35 | 36 | location @ban { 37 | content_by_lua_block { 38 | 39 | local ip = ngx.var.remote_addr 40 | local expire = 300 # time to ban client's ip, in seconds. 41 | local ban, flags = banned_ips:get(ip) 42 | if not ban then 43 | banned_ips:set(ip, 1, expire) 44 | ngx.exit(ngx.HTTP_FORBIDDEN) 45 | end 46 | 47 | } 48 | } 49 | 50 | ### Protected locations 51 | 52 | location /login { 53 | limit_req zone=api_limit burst=2 nodelay; 54 | error_page 503 @ban ; 55 | proxy_pass http://127.0.0.1:8080 ; # backend endpoint 56 | } 57 | 58 | ### Other locations 59 | 60 | location / { 61 | proxy_pass http://127.0.0.1:8080 ; 62 | } 63 | 64 | ### Metrics and statistics 65 | 66 | location /ban_count { 67 | content_by_lua_block { 68 | local ips = banned_ips:get_keys(0) 69 | ngx.say("nginx_lua_blocked_ips " .. table.getn(ips) .. "\n") 70 | } 71 | } 72 | 73 | location /ban_dump { 74 | allow 127.0.0.1/32 ; 75 | deny all ; 76 | content_by_lua_block { 77 | 78 | local ips = banned_ips:get_keys(0) 79 | local output = "" 80 | for k,v in pairs(ips) do 81 | output = output .. v .. "\n" 82 | end 83 | ngx.say(output) 84 | 85 | } 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /http-session/nginx.proxy.conf: -------------------------------------------------------------------------------- 1 | 2 | user nginx; 3 | worker_processes auto; 4 | 5 | error_log /var/log/nginx/error.log warn; 6 | pid /var/run/nginx.pid; 7 | 8 | load_module modules/ngx_http_lua_module.so ; 9 | 10 | worker_rlimit_nofile 32768 ; 11 | 12 | events { 13 | use epoll ; 14 | worker_connections 16384; 15 | } 16 | 17 | 18 | http { 19 | include /etc/nginx/mime.types; 20 | default_type application/octet-stream; 21 | 22 | log_format combined_plus '$remote_addr - $remote_user [$time_local]' 23 | ' "$request" $status $body_bytes_sent "$http_referer"' 24 | ' "$http_user_agent" $request_time $upstream_cache_status' 25 | ' [$upstream_response_time]'; 26 | 27 | access_log /var/log/nginx/access.log combined_plus; 28 | 29 | 30 | lua_need_request_body on ; 31 | 32 | init_worker_by_lua_block { 33 | 34 | socket = require("socket") 35 | tcp = assert(socket.tcp()) 36 | assert(tcp:connect("127.0.0.1", 11515)) 37 | 38 | } 39 | 40 | sendfile on; 41 | #tcp_nopush on; 42 | 43 | #keepalive_timeout 0; 44 | keepalive_timeout 65; 45 | 46 | gzip on; 47 | 48 | client_max_body_size 128m ; 49 | 50 | index index.html index.htm; 51 | 52 | upstream remoteserver { 53 | server 1.2.3.4:80 ; 54 | } 55 | 56 | 57 | server { 58 | 59 | listen 127.0.0.1:8080 default ; 60 | 61 | server_name logging.proxy ; 62 | 63 | access_log /dev/null ; 64 | 65 | location / { 66 | 67 | set $req_headers ""; 68 | set $req_body ""; 69 | set $resp_headers ""; 70 | set $resp_body ""; 71 | 72 | rewrite_by_lua_block { 73 | 74 | local method = ngx.var.request_method 75 | ngx.req.read_body() 76 | ngx.var.req_body = ngx.req.get_body_data() 77 | 78 | } 79 | 80 | body_filter_by_lua_block { 81 | 82 | local resp_body = string.sub(ngx.arg[1], 1, -1) 83 | ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body 84 | if ngx.arg[2] then 85 | ngx.var.resp_body = ngx.ctx.buffered 86 | end 87 | 88 | local req_h = "" 89 | for k,v in pairs (ngx.req.get_headers()) do 90 | req_h = req_h .. k .. ": " .. v .. "\n" 91 | end 92 | ngx.var.req_headers = req_h 93 | 94 | local resp_h = "" 95 | for k,v in pairs (ngx.resp.get_headers()) do 96 | resp_h = resp_h .. k .. ": " .. v .. "\n" 97 | end 98 | ngx.var.resp_headers = resp_h 99 | 100 | } 101 | 102 | log_by_lua_block { 103 | 104 | local out = "===== " .. tostring(ngx.var.time_local) .. " ====\n" 105 | out = out .. tostring(ngx.var.request) .. "\n==\n" .. tostring(ngx.var.req_headers) .. "\n==\n" .. tostring(ngx.var.req_body) .. "\n==\n" 106 | out = out .. "HTTP " .. tostring(ngx.var.status) .. "\n==\n" .. tostring(ngx.var.resp_headers) .. "\n==\n" .. tostring(ngx.var.resp_body) 107 | out = out .. "\n=====================================\n=\n=\n=\n" 108 | assert(tcp:send(out)) 109 | 110 | } 111 | 112 | 113 | 114 | proxy_pass http://remoteserver; 115 | } 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /nginx-modules/build-modules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Build environment 4 | # 5 | # Debian 9: apt-get install curl make gcc g++ uuid-dev libdpkg-perl luajit libluajit-5.1-dev libpcre3-dev libssl-dev libz-dev libpam0g-dev 6 | # 7 | 8 | 9 | function spinner() { 10 | i=1 11 | sp="/-\|" 12 | echo -n ' ' 13 | while read line 14 | do 15 | printf "\b${sp:i++%${#sp}:1}" 16 | done 17 | echo 18 | } 19 | 20 | VER=$(nginx -V 2>&1 ) 21 | TMP=$(mktemp -d) 22 | HOMEDIR=$(pwd) 23 | 24 | 25 | if [ "$(uname -m)" = x86_64 ]; then 26 | BIT_SIZE_NAME=x64 27 | else 28 | BIT_SIZE_NAME=ia32 29 | fi 30 | 31 | VERSION=$(echo "${VER}" | grep "^nginx version: " | awk -F 'nginx version: nginx/' '{print $2}') 32 | CONFIGURE=$(echo "${VER}" | grep "^configure arguments: " | awk -F 'configure arguments: ' '{print $2}' | sed -r ' 33 | s/([^\ ]*=dynamic )/ /g; 34 | s/ --add-dynamic-module=([^\ ]+) / /g; 35 | s/ --add-module=([^\ ]+) / /g;') 36 | 37 | SRC="nginx-${VERSION}" 38 | SRCFILE="nginx-${VERSION}.tar.gz" 39 | 40 | MODULES_PATH="${HOMEDIR}/nginx-${VERSION}-modules" 41 | mkdir -p ${MODULES_PATH} 42 | 43 | pushd ${TMP} 44 | 45 | curl -# http://nginx.org/download/${SRCFILE} > ${SRCFILE} 46 | 47 | ### Clone repos 48 | 49 | git clone https://github.com/vozlt/nginx-module-vts.git nginx-module-vts 50 | git clone https://github.com/sto/ngx_http_auth_pam_module.git ngx_http_auth_pam_module 51 | git clone https://github.com/vkholodkov/nginx-eval-module.git nginx-eval-module 52 | git clone https://github.com/aperezdc/ngx-fancyindex.git ngx-fancyindex 53 | git clone https://github.com/arut/nginx-rtmp-module.git nginx-rtmp-module 54 | git clone https://github.com/vozlt/nginx-module-url.git nginx-module-url 55 | git clone https://github.com/kaltura/nginx-vod-module.git nginx-vod-module 56 | 57 | git clone https://github.com/openresty/lua-nginx-module.git lua-nginx-module 58 | git clone https://github.com/openresty/lua-upstream-nginx-module.git lua-upstream-nginx-module 59 | git clone https://github.com/openresty/stream-lua-nginx-module.git stream-lua-nginx-module 60 | git clone https://github.com/openresty/headers-more-nginx-module.git headers-more-nginx-module 61 | git clone https://github.com/openresty/encrypted-session-nginx-module.git encrypted-session-nginx-module 62 | 63 | git clone https://github.com/yaoweibin/ngx_http_substitutions_filter_module.git ngx_http_substitutions_filter_module 64 | 65 | 66 | ### Openresty's cross-dependencies 67 | git clone https://github.com/openresty/set-misc-nginx-module.git set-misc-nginx-module 68 | git clone https://github.com/vision5/ngx_devel_kit.git ngx_devel_kit 69 | 70 | 71 | ### Modules with extra configuration 72 | git clone https://github.com/pagespeed/ngx_pagespeed.git ngx_pagespeed 73 | git clone https://github.com/google/ngx_brotli.git ngx_brotli 74 | 75 | 76 | ### Prepare repos 77 | 78 | ( cd lua-nginx-module ; git checkout tags/v0.10.15 ; cd .. ) 79 | ( cd stream-lua-nginx-module ; git checkout tags/v0.0.7 ; cd .. ) 80 | ( cd ngx_pagespeed ; git checkout tags/latest-stable ; cd .. ) 81 | # ( cd set-misc-nginx-module ; git checkout tags/v0.32 ; cd .. ) 82 | 83 | ### Prepare dependencies 84 | 85 | ( cd ngx_brotli ; git submodule update --init ; cd .. ) 86 | 87 | ( cd ngx_pagespeed 88 | 89 | _psol=$( cat PSOL_BINARY_URL ) 90 | PSOL_URL=$( eval "echo ${_psol}" ) 91 | curl -# "${PSOL_URL}" > psol.tar.gz 92 | tar zxf psol.tar.gz 93 | 94 | cd .. ) 95 | 96 | tar zxf ${SRCFILE} 97 | cd ${SRC} 98 | CMD="./configure ${CONFIGURE} \ 99 | --add-dynamic-module=../lua-nginx-module \ 100 | --add-dynamic-module=../lua-upstream-nginx-module \ 101 | --add-dynamic-module=../nginx-module-vts \ 102 | --add-dynamic-module=../ngx_http_auth_pam_module \ 103 | --add-dynamic-module=../ngx_brotli \ 104 | --add-dynamic-module=../ngx_pagespeed \ 105 | --add-dynamic-module=../ngx_devel_kit \ 106 | --add-dynamic-module=../set-misc-nginx-module \ 107 | --add-dynamic-module=../encrypted-session-nginx-module \ 108 | --add-dynamic-module=../nginx-eval-module \ 109 | --add-dynamic-module=../ngx-fancyindex \ 110 | --add-dynamic-module=../nginx-rtmp-module \ 111 | --add-dynamic-module=../nginx-module-url \ 112 | --add-dynamic-module=../headers-more-nginx-module \ 113 | --add-dynamic-module=../nginx-vod-module \ 114 | --add-dynamic-module=../ngx_http_substitutions_filter_module \ 115 | --add-dynamic-module=../stream-lua-nginx-module \ 116 | " 117 | 118 | 119 | eval ${CMD} 120 | 121 | ( make | spinner ) && cp objs/*.so ${MODULES_PATH} 122 | #( make | spinner ) && ls -l objs/*.so 123 | 124 | popd 125 | 126 | ls -l ${MODULES_PATH}/ 127 | 128 | # echo ${TMP} 129 | rm -rf ${TMP} 130 | 131 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # Nginx usecases 2 | 3 | ## http-session 4 | 5 | nginx/syslog-based HTTP-sniffer. Prerequisites: 6 | - lua-nginx-module 7 | - luasocket available under builtin luajit 8 | 9 | ## error-code-status 10 | 11 | Simple lua-based extended status, logging errors by http response code - to use with zabbix, etc. Requires lua-nginx-module 12 | 13 | ## metrics-aggregation 14 | 15 | Aggregate prometheus metrics from different exporters in a single endpoint. 16 | 17 | ## nginx-AD-auth 18 | 19 | nginx http-auth against Microsoft Active Directory. 20 | In most cases, foreign soft authenticates against AD using LDAP. So nginx got it's own auth_ldap module - but in some complicated AD schemas it doesn't work at all. 21 | The key point is to use [ngx_auth_pam](https://github.com/sto/ngx_http_auth_pam_module), and set bindings to AD in pam. 22 | 23 | ## nginx-google-authenticator 24 | 25 | nginx with OTP by Google Authenticator. 26 | The key point is also to use [ngx_auth_pam](https://github.com/sto/ngx_http_auth_pam_module). 27 | Install Google Authenticator pam-module: 28 | ``` 29 | apt-get install libpam-google-authenticator 30 | ``` 31 | 32 | Create pam service config (etc/pam.d/nginx_google), and produce GAs files like this: 33 | ``` 34 | createuser.sh johndoe 35 | ``` 36 | ## nginx-dumb-metrics 37 | 38 | Minimalistic prometheus metrics exporter build on top on vanilla nginx with no external modules. Sample output: 39 | ``` 40 | nginx_dumb_requests{metric="code_200"} 14 41 | nginx_dumb_requests{metric="code_404"} 1 42 | nginx_dumb_requests{metric="up"} 1 43 | ``` 44 | 45 | Note: file `up` is required to satisfy xml parser. 46 | 47 | ## ssl-certs 48 | 49 | A bunch of scripts to generate self-signed SSL certs, client .p12 certs, and csr's with SAN. 50 | 51 | gen_server.sh - creates self-signed cert/key and DH-params file. 52 | ``` 53 | ./gen_server.sh host.tld 54 | 55 | ``` 56 | 57 | gen_client.sh - creates client .p12 cert to use with certificate authentication. Usage example shown in nginx-client-cert.conf 58 | ``` 59 | ./gen_client.sh host.tld 60 | 61 | ``` 62 | Note, that it's possible to use self-signed client certs with a host cert, signed by any trusted CA. 63 | Also note, that a file set in ssl_client_certificate may contain several client certificates. Current client can be obtained from ngx_http_ssl_module embedded variables. 64 | 65 | gen_csr.sh - creates CSR with SAN for trusted CA and dumps csr content in readable form. 66 | ``` 67 | ./gen_csr.sh host.tld 68 | 69 | ``` 70 | SAN, for example, is required by several CA's to create a wildcard cert. Alternative namess should be defined in host.tld.csr.conf among pre-defined defautls. 71 | When CA requires csr with SAN for wildcard - in most cases you should define main CN as *.host.tld, and first alternative name set to host.tld. 72 | 73 | check_expire.sh - checks a cert's expiration date on a remote host (using GNU date, so keep in mind). 74 | ``` 75 | $ ./check_expire.sh google.com 76 | Wed May 30 18:50:00 UTC 2018 77 | $ 78 | ``` 79 | 80 | ## nginx-modules 81 | 82 | An automated script to build additional dynamic modules for official nginx package. 83 | The script simply build modules for exact installed nginx version and places results into current directory. 84 | The script requires build environment to be set - including GCC, git, -devel packages for libraries, etc. 85 | 86 | Currently builds modules: 87 | 88 | - Nginx auth_pam module 89 | - Nginx brotli module 90 | - Nginx Lua module 91 | - Nginx Lua stream module (Note: working version of this module does not support dynamic builds) 92 | - Nginx Lua upstream module 93 | - Nginx pagespeed module 94 | - Nginx virtual host traffic status module 95 | - Nginx Development Kit module 96 | - Nginx encrypted sessions module 97 | - Nginx set misc module 98 | - Nginx memcache eval module 99 | - Nginx fancy index module 100 | - Nginx headers_more module 101 | - Nginx rtmp module 102 | - Nginx substitutions filter module 103 | - Nginx VOD module 104 | 105 | ## nginx-yum-repo 106 | 107 | Minimalistic setup to serve yum-repository with nginx. 108 | Requirements: 109 | 110 | - systemd 111 | - nginx 112 | - createrepo (or, for best performance - C implementation [createrepo_c](https://github.com/rpm-software-management/createrepo_c) 113 | 114 | RPM packages are pushed into repository via WebDAV, and, after all packages uploaded, one have to trigger rebuild by http hook. 115 | ``` 116 | curl -T package.rpm http://yum.repo.tld/repo/name/package.rpm 117 | curl http://yum.repo.tld/repoflag/name 118 | ``` 119 | 120 | In general, it's possible to remove hook, and rebuild repodata just on package upload - but, in busy CI environments it will be rebuilding too often. 121 | 122 | ## lua-ffi 123 | 124 | Example how to use luajit-ffi with nginx, based on libqrencode. 125 | First, calling shared library functions requires, that this particular library exists in nginx's process memory space. This could be done with several ways: 126 | 127 | - using native ffi.load() call; 128 | - linking library into nginx binary upon building (either statically or dynamically); 129 | - using LD_PRELOAD env variable; 130 | 131 | As a most complicated way, in this example ffi.load() is used, loading symbols into separate namespace "libqrencode". 132 | 133 | Then, one have to define all necessary symbols from a libqrencode with ffi.cdef() exactly as they're defined in qrencode.h. 134 | The rest is quite obvious except the point that *encode functions returns a pointer to array of chars with meaningful lowest bit - so we have to process this array in lua to draw an "image". 135 | 136 | If everything is ok, you should see something like this: 137 | 138 |  139 | 140 | Note, that you're playing in deep water, and there can be leaks and other issues, causing nginx worker to segfault. 141 | Also note, that init_by_lua_* statements executed upon start master/worker process, and content_by_lua_* - upon accessing to the location, which causes re-reading code when content_by_lua_file is used. So you can run into state when different nginx workers uses different code; therefore in thes example *_by_lua_block is used. 142 | 143 | ## nginx-extended-limit_rate 144 | 145 | Extending limit_rate to any time window. 146 | 147 | ## nginx-autoban 148 | 149 | Lua-based auto blocker. Bans clients exceesing rate limit for arbitrary set time. Supports minimalistic metrics export, could be extended by adding unban option. 150 | Might also be extended to ban clients on any attribute available within HTTP session, e.g: user-agent, args, headers, cookies etc. 151 | 152 | ## nginx-stream-ssh 153 | 154 | Wrapping ssh connection into SSL using nginx-stream module. 155 | The configuration is quite simple: 156 | 157 | - bind sshd to 127.0.0.1:8022 using ListenAddress in sshd_config; 158 | - add stream section into nginx.conf; 159 | - add Host configuration into ssh_config (or ~/.ssh/config); 160 | 161 | This could be used for extra: 162 | 163 | Security 164 | 165 | - most scanning bots expects ssh handshake on 22/tcp, so they will be confused; 166 | - adding a client certificate authentication could add a sort of second factor; 167 | 168 | Flexibility 169 | 170 | - as nginx read SSL session date before proxing, it's possible to proxy a single entry point ssh connections to different upstream by SNI, client certificate DN, issue/expiration date, serial etc using variable mapping. Adding lua scripting allows to use extremaly flexible dynamic mappings. 171 | 172 | ## nginx-shell-webhook 173 | 174 | Minimalistic approach to create shell-based webhooks accessable via nginx 175 | --------------------------------------------------------------------------------