制作Openresty镜像
下载Dockerfile
git地址:https://github.com/openresty/docker-openresty/tree/1.27.1.1-1/alpine
需要把Dockerfile、nginx.conf、nginx.vh.default.conf下载下来
修改Dockerfile
# Dockerfile - alpine
# https://github.com/openresty/docker-openresty
# 这儿修改成自己的alpine arm镜像
# 可从docker hub上拉取
# docker pull alpine:3.21@sha256:757d680068d77be46fd1ea20fb21db16f150468c5e7079a08a2e4705aec096ac
# 推送到自己的docker仓库
ARG RESTY_IMAGE_BASE="alpine"
ARG RESTY_IMAGE_TAG="3.21"
FROM ${RESTY_IMAGE_BASE}:${RESTY_IMAGE_TAG}
LABEL maintainer="Eugene <925718725@qq.com>"
# Docker Build Arguments
# 这儿同上
ARG RESTY_IMAGE_BASE="alpine"
ARG RESTY_IMAGE_TAG="3.21"
ARG RESTY_VERSION="1.27.1.1"
# https://github.com/openresty/openresty-packaging/blob/master/alpine/openresty-openssl3/APKBUILD
ARG RESTY_OPENSSL_VERSION="3.0.15"
ARG RESTY_OPENSSL_PATCH_VERSION="3.0.15"
# 这儿如果是内网安装可下载下来上传到本地的文件服务中,如果没有文件服务则看下面,直接把文件下载后拷贝到容器中
#ARG RESTY_OPENSSL_URL_BASE="https://github.com/openssl/openssl/releases/download/openssl-${RESTY_OPENSSL_VERSION}"
ARG RESTY_OPENSSL_URL_BASE="https://xxx.cn/group1/M00/4A/73/FDCYBWe1RdWAAazPAOm-abGvJDc8291.gz?filename=openssl-3.0.15.tar.gz"
# LEGACY: "https://www.openssl.org/source/old/1.1.1"
ARG RESTY_OPENSSL_BUILD_OPTIONS="enable-camellia enable-seed enable-rfc3779 enable-cms enable-md2 enable-rc5 \
enable-weak-ssl-ciphers enable-ssl3 enable-ssl3-method enable-md2 enable-ktls enable-fips \
"
# https://github.com/openresty/openresty-packaging/blob/master/alpine/openresty-pcre2/APKBUILD
ARG RESTY_PCRE_VERSION="10.44"
ARG RESTY_PCRE_SHA256="86b9cb0aa3bcb7994faa88018292bc704cdbb708e785f7c74352ff6ea7d3175b"
ARG RESTY_PCRE_BUILD_OPTIONS="--enable-jit --enable-pcre2grep-jit --disable-bsr-anycrlf --disable-coverage --disable-ebcdic --disable-fuzz-support \
--disable-jit-sealloc --disable-never-backslash-C --enable-newline-is-lf --enable-pcre2-8 --enable-pcre2-16 --enable-pcre2-32 \
--enable-pcre2grep-callout --enable-pcre2grep-callout-fork --disable-pcre2grep-libbz2 --disable-pcre2grep-libz --disable-pcre2test-libedit \
--enable-percent-zt --disable-rebuild-chartables --enable-shared --disable-static --disable-silent-rules --enable-unicode --disable-valgrind \
"
# 根据自己的机器来定义
ARG RESTY_J="4"
# https://github.com/openresty/openresty-packaging/blob/master/alpine/openresty/APKBUILD
# 可禁用或启用nginx的组件
ARG RESTY_CONFIG_OPTIONS="\
--with-compat \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_geoip_module=dynamic \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_image_filter_module=dynamic \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_v2_module \
--with-http_v3_module \
--with-http_xslt_module=dynamic \
--with-ipv6 \
--with-mail \
--with-mail_ssl_module \
--with-md5-asm \
--with-sha1-asm \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-threads \
"
ARG RESTY_CONFIG_OPTIONS_MORE=""
ARG RESTY_LUAJIT_OPTIONS="--with-luajit-xcflags='-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT'"
ARG RESTY_PCRE_OPTIONS="--with-pcre-jit"
ARG RESTY_ADD_PACKAGE_BUILDDEPS=""
ARG RESTY_ADD_PACKAGE_RUNDEPS=""
ARG RESTY_EVAL_PRE_CONFIGURE=""
ARG RESTY_EVAL_POST_DOWNLOAD_PRE_CONFIGURE=""
ARG RESTY_EVAL_POST_MAKE=""
# These are not intended to be user-specified
ARG _RESTY_CONFIG_DEPS="--with-pcre \
--with-cc-opt='-DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/pcre2/include -I/usr/local/openresty/openssl3/include' \
--with-ld-opt='-L/usr/local/openresty/pcre2/lib -L/usr/local/openresty/openssl3/lib -Wl,-rpath,/usr/local/openresty/pcre2/lib:/usr/local/openresty/openssl3/lib' \
"
LABEL resty_image_base="${RESTY_IMAGE_BASE}"
LABEL resty_image_tag="${RESTY_IMAGE_TAG}"
LABEL resty_version="${RESTY_VERSION}"
LABEL resty_openssl_version="${RESTY_OPENSSL_VERSION}"
LABEL resty_openssl_patch_version="${RESTY_OPENSSL_PATCH_VERSION}"
LABEL resty_openssl_url_base="${RESTY_OPENSSL_URL_BASE}"
LABEL resty_openssl_build_options="${RESTY_OPENSSL_BUILD_OPTIONS}"
LABEL resty_pcre_version="${RESTY_PCRE_VERSION}"
LABEL resty_pcre_build_options="${RESTY_PCRE_BUILD_OPTIONS}"
LABEL resty_pcre_sha256="${RESTY_PCRE_SHA256}"
LABEL resty_config_options="${RESTY_CONFIG_OPTIONS}"
LABEL resty_config_options_more="${RESTY_CONFIG_OPTIONS_MORE}"
LABEL resty_config_deps="${_RESTY_CONFIG_DEPS}"
LABEL resty_add_package_builddeps="${RESTY_ADD_PACKAGE_BUILDDEPS}"
LABEL resty_add_package_rundeps="${RESTY_ADD_PACKAGE_RUNDEPS}"
LABEL resty_eval_pre_configure="${RESTY_EVAL_PRE_CONFIGURE}"
LABEL resty_eval_post_download_pre_configure="${RESTY_EVAL_POST_DOWNLOAD_PRE_CONFIGURE}"
LABEL resty_eval_post_make="${RESTY_EVAL_POST_MAKE}"
LABEL resty_luajit_options="${RESTY_LUAJIT_OPTIONS}"
LABEL resty_pcre_options="${RESTY_PCRE_OPTIONS}"
# 这儿拷贝一些需要用到的文件到容器内,如果没有文件服务,也可从这儿直接下载拷贝到容器中
COPY hosts /etc/hosts
COPY openresty-1.27.1.1.tar.gz /openresty-1.27.1.1.tar.gz
COPY openssl-3.0.15.tar.gz /openssl-3.0.15.tar.gz
COPY pcre2-10.44.tar.gz /pcre2-10.44.tar.gz
RUN apk add --no-cache --virtual .build-deps \
build-base \
coreutils \
curl \
gd-dev \
geoip-dev \
libxslt-dev \
linux-headers \
make \
perl-dev \
readline-dev \
zlib-dev \
${RESTY_ADD_PACKAGE_BUILDDEPS} \
&& apk add --no-cache \
gd \
geoip \
libgcc \
libxslt \
tzdata \
zlib \
${RESTY_ADD_PACKAGE_RUNDEPS} \
&& cd /tmp \
&& if [ -n "${RESTY_EVAL_PRE_CONFIGURE}" ]; then eval $(echo ${RESTY_EVAL_PRE_CONFIGURE}); fi \
&& cd /tmp \
# 没有文件服务则使用下面的把文件拷贝到/tmp中
#&& curl -fSL "${RESTY_OPENSSL_URL_BASE}" -o openssl-${RESTY_OPENSSL_VERSION}.tar.gz \
&& mv /openssl-${RESTY_OPENSSL_VERSION}.tar.gz /tmp/openssl-${RESTY_OPENSSL_VERSION}.tar.gz \
&& tar xzf openssl-${RESTY_OPENSSL_VERSION}.tar.gz \
&& cd openssl-${RESTY_OPENSSL_VERSION} \
&& if [ $(echo ${RESTY_OPENSSL_VERSION} | cut -c 1-5) = "3.0.15" ] ; then \
echo 'patching OpenSSL 3.0.15 for OpenResty' \
# 这儿使用了国内代理加速,前面加上https://hub.gitmirror.com/
&& curl -s https://hub.gitmirror.com/https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-${RESTY_OPENSSL_PATCH_VERSION}-sess_set_get_cb_yield.patch | patch -p1 ; \
fi \
&& if [ $(echo ${RESTY_OPENSSL_VERSION} | cut -c 1-5) = "1.1.1" ] ; then \
echo 'patching OpenSSL 1.1.1 for OpenResty' \
# 这儿使用了国内代理加速,前面加上https://hub.gitmirror.com/
&& curl -s https://hub.gitmirror.com/https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-${RESTY_OPENSSL_PATCH_VERSION}-sess_set_get_cb_yield.patch | patch -p1 ; \
fi \
&& if [ $(echo ${RESTY_OPENSSL_VERSION} | cut -c 1-5) = "1.1.0" ] ; then \
echo 'patching OpenSSL 1.1.0 for OpenResty' \
# 这儿使用了国内代理加速,前面加上https://hub.gitmirror.com/
&& curl -s https://hub.gitmirror.com/https://raw.githubusercontent.com/openresty/openresty/ed328977028c3ec3033bc25873ee360056e247cd/patches/openssl-1.1.0j-parallel_build_fix.patch | patch -p1 \
# 这儿使用了国内代理加速,前面加上https://hub.gitmirror.com/
&& curl -s https://hub.gitmirror.com/https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-${RESTY_OPENSSL_PATCH_VERSION}-sess_set_get_cb_yield.patch | patch -p1 ; \
fi \
&& ./config \
shared zlib -g \
--prefix=/usr/local/openresty/openssl3 \
--libdir=lib \
-Wl,-rpath,/usr/local/openresty/openssl3/lib \
${RESTY_OPENSSL_BUILD_OPTIONS} \
&& make -j${RESTY_J} \
&& make -j${RESTY_J} install_sw \
&& cd /tmp \
# 没有文件服务则使用下面的把文件拷贝到/tmp中
#&& curl -fSL "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-${RESTY_PCRE_VERSION}/pcre2-${RESTY_PCRE_VERSION}.tar.gz" -o pcre2-${RESTY_PCRE_VERSION}.tar.gz \
#&& curl -fSL "https://xxx.cn/group1/M00/4A/73/FDCYBWe1RkyAFxyPACbz2DejUDQ2905.gz?filename=pcre2-10.44.tar.gz" -o pcre2-${RESTY_PCRE_VERSION}.tar.gz \
&& mv /pcre2-${RESTY_PCRE_VERSION}.tar.gz /tmp/pcre2-${RESTY_PCRE_VERSION}.tar.gz \
&& echo "${RESTY_PCRE_SHA256} pcre2-${RESTY_PCRE_VERSION}.tar.gz" | shasum -a 256 --check \
&& tar xzf pcre2-${RESTY_PCRE_VERSION}.tar.gz \
&& cd /tmp/pcre2-${RESTY_PCRE_VERSION} \
&& CFLAGS="-g -O3" ./configure \
--prefix=/usr/local/openresty/pcre2 \
--libdir=/usr/local/openresty/pcre2/lib \
${RESTY_PCRE_BUILD_OPTIONS} \
&& CFLAGS="-g -O3" make -j${RESTY_J} \
&& CFLAGS="-g -O3" make -j${RESTY_J} install \
&& cd /tmp \
# 没有文件服务则使用下面的把文件拷贝到/tmp中
#&& curl -fSL https://openresty.org/download/openresty-${RESTY_VERSION}.tar.gz -o openresty-${RESTY_VERSION}.tar.gz \
#&& curl -fSL https://xxx.cn/group1/M00/4A/73/FDCYBWe1SgyAF70MAFrqvT8TigE1077.gz?filename=openresty-1.27.1.1.tar.gz -o openresty-${RESTY_VERSION}.tar.gz \
&& mv /openresty-${RESTY_VERSION}.tar.gz /tmp/openresty-${RESTY_VERSION}.tar.gz \
&& tar xzf openresty-${RESTY_VERSION}.tar.gz \
&& cd /tmp/openresty-${RESTY_VERSION} \
&& if [ -n "${RESTY_EVAL_POST_DOWNLOAD_PRE_CONFIGURE}" ]; then eval $(echo ${RESTY_EVAL_POST_DOWNLOAD_PRE_CONFIGURE}); fi \
&& eval ./configure -j${RESTY_J} ${_RESTY_CONFIG_DEPS} ${RESTY_CONFIG_OPTIONS} ${RESTY_CONFIG_OPTIONS_MORE} ${RESTY_LUAJIT_OPTIONS} ${RESTY_PCRE_OPTIONS} \
&& make -j${RESTY_J} \
&& make -j${RESTY_J} install \
&& cd /tmp \
&& if [ -n "${RESTY_EVAL_POST_MAKE}" ]; then eval $(echo ${RESTY_EVAL_POST_MAKE}); fi \
&& rm -rf \
openssl-${RESTY_OPENSSL_VERSION}.tar.gz openssl-${RESTY_OPENSSL_VERSION} \
pcre2-${RESTY_PCRE_VERSION}.tar.gz pcre2-${RESTY_PCRE_VERSION} \
openresty-${RESTY_VERSION}.tar.gz openresty-${RESTY_VERSION} \
&& apk del .build-deps \
&& mkdir -p /var/run/openresty \
&& ln -sf /dev/stdout /usr/local/openresty/nginx/logs/access.log \
&& ln -sf /dev/stderr /usr/local/openresty/nginx/logs/error.log
# Add additional binaries into PATH for convenience
ENV PATH=$PATH:/usr/local/openresty/luajit/bin:/usr/local/openresty/nginx/sbin:/usr/local/openresty/bin
# Copy nginx configuration files
COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
COPY nginx.vh.default.conf /etc/nginx/conf.d/default.conf
CMD ["/usr/local/openresty/bin/openresty", "-g", "daemon off;"]
# Use SIGQUIT instead of default SIGTERM to cleanly drain requests
# See https://github.com/openresty/docker-openresty/blob/master/README.md#tips--pitfalls
STOPSIGNAL SIGQUIT
制作openresty镜像
docker build -t openresty:alpine-aarch64-eugene .
鉴权
运行openresty
docker run --privileged -u root -d --name openresty --restart=always --network=host -v /data/openresty/conf:/usr/local/openresty/nginx/conf -v /data/openresty/logs:/usr/local/openresty/nginx/logs -v /data/openresty/ssl:/usr/local/openresty/nginx/ssl -v /usr/local/openresty/nginx/html -v /data/openresty/lua:/usr/local/openresty/nginx/lua -v /etc/localtime:/etc/localtime openresty:alpine-aarch64-eugene
编写lua脚本
nginx-jwt.lua
-- nginx-jwt.lua
local cjson = require "cjson"
local jwt = require "resty.jwt"
--your secret
local public_key = [[
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmpsshjCcEKvc+J3HQcO2
i+cu8blV6T9Lh8YhKGuYOevu3Tqj/Yc9G2UrxC/xFLmj5zYAYtKfy1KB7lGhpZRM
47GnPm/RoP4ozXaaFxjDCmqM+Y345eeusQtbbPXvUHCVLMSTgpEBYI9T5Atg90bm
5uBZgDSsn2rXoJCijsuqXUoE3Glmt/SacVY7yNigG9X+e1zd/C/nveBQdI+QY5A4
fyXCJcw1sdLe+nc27Sh86PtX8J4s3+mG4ElQkwHzMSTE4cf8ffRR/jwrFT+NVUii
gavJG/mF4v8XU8yN1LvoSnak8lc+LS6nHmnI1vSZdYKD3u9i3RAW5lTIpCCrsf7G
yQIDAQAB
-----END PUBLIC KEY-----
]]
--无需鉴权api清单
local no_need_token_api_list = {'/api/register', '/api/login'}
local no_need_ip = {'127.0.0.1'}
local function ignore_url (val)
for index, value in ipairs(no_need_token_api_list) do
if (value == val) then
return true
end
end
return false
end
local function ignore_ip (val)
for index,value in ipairs(no_need_ip) do
if(value == val) then
return true
end
end
return false
end
local M = {}
function M.auth()
if ignore_url(ngx.var.request_uri) then
return
else
end
if ignore_ip(ngx.var.remote_addr) then
return
else
end
-- require Authorization request header
local auth_header = ngx.var.http_Authorization
local headers = ngx.req.get_headers()
local reqUri = ngx.var.request_uri
local reqList = {}
string.gsub(reqUri,'[^/]+',function (w)
table.insert(reqList,w)
end)
local urlSiteId = reqList[2]
if headers["xtenant"] == nil then
ngx.log(ngx.WARN, "No xtenant header")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
if urlSiteId ~= headers["xtenant"] then
ngx.log(ngx.WARN, "No Authorization header")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
if auth_header == nil then
ngx.log(ngx.WARN, "No Authorization header")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- require Bearer token
local _, _, token = string.find(auth_header, "Bearer%s+(.+)")
if token == nil then
ngx.log(ngx.ERR, "Missing token")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
--jwt:set_alg_whitelist({ RS256 = 1 })
local jwt_obj = jwt:verify(public_key,token)
if ""..jwt_obj.payload.site_id ~= ""..headers["xtenant"] then
ngx.log(ngx.ERR, "No Authorization header"..jwt_obj.payload.site_id)
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
local httpc = require("resty.http").new()
-- 改成自己的鉴权接口
local res, err = httpc:request_uri("https://xxx.cn/gateway/service/api/v1/file/auth", {
ssl_verify = ssl_verify or false,
method = "GET",
headers = {
["Authorization"] = "Bearer "..token,
},
})
if not res then
ngx.log(ngx.ERR, "request failed: "..err)
ngx.exit(ngx.HTTP_UNAUTHORIZED)
return
end
if res.body ~= "true" then
ngx.log(ngx.ERR, "Invalid token2: ".. res.body)
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say("Invalid token22: ".. res.body)
ngx.header.content_type = "application/json; charset=utf-8"
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
end
return M
nginx-jwt-src.lua
-- nginx-jwt.lua
local cjson = require "cjson"
local jwt = require "resty.jwt"
local redis = require "resty.redis"
--your secret
local public_key = [[
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmpsshjCcEKvc+J3HQcO2
i+cu8blV6T9Lh8YhKGuYOevu3Tqj/Yc9G2UrxC/xFLmj5zYAYtKfy1KB7lGhpZRM
47GnPm/RoP4ozXaaFxjDCmqM+Y345eeusQtbbPXvUHCVLMSTgpEBYI9T5Atg90bm
5uBZgDSsn2rXoJCijsuqXUoE3Glmt/SacVY7yNigG9X+e1zd/C/nveBQdI+QY5A4
fyXCJcw1sdLe+nc27Sh86PtX8J4s3+mG4ElQkwHzMSTE4cf8ffRR/jwrFT+NVUii
gavJG/mF4v8XU8yN1LvoSnak8lc+LS6nHmnI1vSZdYKD3u9i3RAW5lTIpCCrsf7G
yQIDAQAB
-----END PUBLIC KEY-----
]]
--无需鉴权api清单
local no_need_token_api_list = {'/api/register', '/api/login',}
local function ignore_url (val)
for index, value in ipairs(no_need_token_api_list) do
if (value == val) then
return true
end
end
if (string.sub(val,1,17)=="/group1/100/medal") then
return true
end
return false
end
local M = {}
function M.auth()
if ignore_url(ngx.var.request_uri) then
return
else
end
-- require Authorization request header
local auth_header = ngx.var.http_Authorization
local headers = ngx.req.get_headers()
local reqUri = ngx.var.request_uri
local reqArgs = ngx.req.get_uri_args()
local reqList = {}
string.gsub(reqUri,'[^/]+',function (w)
table.insert(reqList,w)
end)
local urlSiteId = reqList[2]
local red = redis:new()
-- 自己的redis
local redisok,err = red:connect("127.0.0.1",6379)
if not redisok then
ngx.log(ngx.ERR,"redis Cannot connect, host: ")
--return nil, err
end
red:auth("Qwer1234")
local acckey = ngx.var.arg_accessKey
if acckey == nil then
ngx.log(ngx.ERR, "Missing acckey error: ")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
local redisToken,rediserror = red:get(acckey)
if not redisToken or type(redisToken) == "userdata" then
ngx.log(ngx.ERR, "redis error: ")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
local token = redisToken
local jwt_obj = jwt:verify(public_key,token)
if ""..jwt_obj.payload.client_id == "platform-manage" then
return
end
if ""..jwt_obj.payload.site_id ~= urlSiteId then
ngx.log(ngx.ERR, "No Authorization header"..jwt_obj.payload.site_id)
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
local httpc = require("resty.http").new()
-- 改成自己的鉴权接口
local res, err = httpc:request_uri("https://xxx.cn/gateway/service/api/v1/file/auth", {
ssl_verify = ssl_verify or false,
method = "GET",
headers = {
["Authorization"] = "Bearer "..token,
},
})
if not res then
ngx.log(ngx.ERR, "request failed: "..err)
ngx.exit(ngx.HTTP_UNAUTHORIZED)
return
end
if res.body ~= "true" then
ngx.log(ngx.ERR, "Invalid token2: ".. res.body)
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say("Invalid token22: ".. res.body)
ngx.header.content_type = "application/json; charset=utf-8"
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
end
return M
nginx-upload-auth.lua
-- nginx-jwt.lua
local cjson = require "cjson"
local jwt = require "resty.jwt"
--your secret
local public_key = [[
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmpsshjCcEKvc+J3HQcO2
i+cu8blV6T9Lh8YhKGuYOevu3Tqj/Yc9G2UrxC/xFLmj5zYAYtKfy1KB7lGhpZRM
47GnPm/RoP4ozXaaFxjDCmqM+Y345eeusQtbbPXvUHCVLMSTgpEBYI9T5Atg90bm
5uBZgDSsn2rXoJCijsuqXUoE3Glmt/SacVY7yNigG9X+e1zd/C/nveBQdI+QY5A4
fyXCJcw1sdLe+nc27Sh86PtX8J4s3+mG4ElQkwHzMSTE4cf8ffRR/jwrFT+NVUii
gavJG/mF4v8XU8yN1LvoSnak8lc+LS6nHmnI1vSZdYKD3u9i3RAW5lTIpCCrsf7G
yQIDAQAB
-----END PUBLIC KEY-----
]]
--无需鉴权api清单
local no_need_token_api_list = {'/api/register', '/api/login'}
local function ignore_url (val)
for index, value in ipairs(no_need_token_api_list) do
if (value == val) then
return true
end
end
return false
end
local M = {}
function M.auth()
if ignore_url(ngx.var.request_uri) then
return
else
end
-- require Authorization request header
local auth_header = ngx.var.http_Authorization
local headers = ngx.req.get_headers()
local reqUri = ngx.var.request_uri
local reqList = {}
string.gsub(reqUri,'[^/]+',function (w)
table.insert(reqList,w)
end)
local urlSiteId = reqList[2]
if headers["xtenant"] == nil then
ngx.log(ngx.WARN, "No xtenant header")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
if auth_header == nil then
ngx.log(ngx.WARN, "No Authorization header")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- require Bearer token
local _, _, token = string.find(auth_header, "Bearer%s+(.+)")
if token == nil then
ngx.log(ngx.ERR, "Missing token")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
--jwt:set_alg_whitelist({ RS256 = 1 })
local jwt_obj = jwt:verify(public_key,token)
if ""..jwt_obj.payload.client_id == "platform-manage" then
return;
end
if ""..jwt_obj.payload.site_id ~= ""..headers["xtenant"] then
ngx.log(ngx.ERR, "No Authorization header"..jwt_obj.payload.site_id)
ngx.say("Invalid token: ".. cjson.encode(jwt_obj).."headSiteId:"..headers["xtenant"].."tokenSiteId:"..jwt_obj.payload.site_id)
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
local httpc = require("resty.http").new()
-- 改成自己的鉴权接口
local res, err = httpc:request_uri("https://xxx.cn/gateway/service/api/v1/file/auth", {
ssl_verify = ssl_verify or false,
method = "GET",
headers = {
["Authorization"] = "Bearer "..token,
},
})
if not res then
ngx.log(ngx.ERR, "request failed: "..err)
ngx.exit(ngx.HTTP_UNAUTHORIZED)
return
end
if res.body ~= "true" then
ngx.log(ngx.ERR, "Invalid token2: ".. res.body)
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say("Invalid token22: ".. res.body)
ngx.header.content_type = "application/json; charset=utf-8"
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
end
return M
下载lua插件并安装
下载 lua-resty-jwt 、 lua-resty-hmac 、lua-resty-http插件:
lua-resty-jwt: https://github.com/SkyLothar/lua-resty-jwt
lua-resty-hmac: https://github.com/jkeys089/lua-resty-hmac
lua-resty-http:https://github.com/ledgetech/lua-resty-http
拷贝三个插件的 lib/resty 下的文件拷贝到一个文件夹中
找到 evp.lua,进入 evp.lua 文件,将 EVP_MD_CTX_create () 全部替换为 EVP_MD_CTX_new,将 EVP_MD_CTX_destroy 全部替换为 EVP_MD_CTX_free
注意:报错module ‘resty.http‘ not found是因为没有lua-resty-http插件
报这个错是因为上面这个函数名没有替换
evp.lua:216: dlsym(RTLD_DEFAULT, EVP_MD_CTX_create): symbol not found
进入容器
docker exec -it openresty bash
创建文件夹
mkdir -p /usr/local/openresty/lualib-extend/resty
然后把刚刚的插件和之前写的lua脚本拷贝到容器中,结构如下
配置nginx
nginx.conf
# nginx.conf -- docker-openresty
#
# This file is installed to:
# `/usr/local/openresty/nginx/conf/nginx.conf`
# and is the file loaded by nginx at startup,
# unless the user specifies otherwise.
#
# It tracks the upstream OpenResty's `nginx.conf`, but removes the `server`
# section and adds this directive:
# `include /etc/nginx/conf.d/*.conf;`
#
# The `docker-openresty` file `nginx.vh.default.conf` is copied to
# `/etc/nginx/conf.d/default.conf`. It contains the `server section
# of the upstream `nginx.conf`.
#
# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
#
#user nobody;
#worker_processes 1;
# Enables the use of JIT for regular expressions to speed-up their processing.
pcre_jit on;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 65535;
}
http {
limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;
#注意在这儿配置的是刚刚插件的路径
lua_package_path "usr/local/openresty/lualib-extend/?.lua;;";
#include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /usr/local/openresty/nginx/logs/access.log main;
error_log /usr/local/openresty/nginx/logs/error.log error;
sendfile on;
server_tokens off;
keepalive_timeout 600s;
client_header_timeout 600s;
client_body_timeout 600s;
send_timeout 600s;
client_max_body_size 1024m;
#指定nginx与后端fastcgi server连接超时时间
fastcgi_connect_timeout 600s;
#指定nginx向后端传送请求超时时间(指已完成两次握手后向fastcgi传送请求超时时间)
fastcgi_send_timeout 600s;
#指定nginx向后端传送响应超时时间(指已完成两次握手后向fastcgi传送响应超时时间)
fastcgi_read_timeout 600s;
proxy_redirect ~/big/upload/(.*) /big/upload/$1; #继点续传一定要设置(注意)
# Enables or disables the use of underscores in client request header fields.
# When the use of underscores is disabled, request header fields whose names contain underscores are marked as invalid and become subject to the ignore_invalid_headers directive.
# underscores_in_headers off;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
# Log in JSON Format
# log_format nginxlog_json escape=json '{ "timestamp": "$time_iso8601", '
# '"remote_addr": "$remote_addr", '
# '"body_bytes_sent": $body_bytes_sent, '
# '"request_time": $request_time, '
# '"response_status": $status, '
# '"request": "$request", '
# '"request_method": "$request_method", '
# '"host": "$host",'
# '"upstream_addr": "$upstream_addr",'
# '"http_x_forwarded_for": "$http_x_forwarded_for",'
# '"http_referrer": "$http_referer", '
# '"http_user_agent": "$http_user_agent", '
# '"http_version": "$server_protocol", '
# '"nginx_access": true }';
# access_log /dev/stdout nginxlog_json;
# See Move default writable paths to a dedicated directory (#119)
# https://github.com/openresty/docker-openresty/issues/119
client_body_temp_path /var/run/openresty/nginx-client-body;
proxy_temp_path /var/run/openresty/nginx-proxy;
fastcgi_temp_path /var/run/openresty/nginx-fastcgi;
uwsgi_temp_path /var/run/openresty/nginx-uwsgi;
scgi_temp_path /var/run/openresty/nginx-scgi;
#sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
#keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
include /usr/local/openresty/nginx/conf/conf.d/*.conf;
# Don't reveal OpenResty version to clients.
# server_tokens off;
}
include /etc/nginx/conf.d/*.main;
conf/conf.d/file.conf
upstream file
{
server 127.0.0.1:8080;
ip_hash;
}
access_log /usr/local/openresty/nginx/logs/nginx_access.log;
error_log /usr/local/openresty/nginx/logs/nginx_error.log;
resolver 114.114.114.114;
server
{
listen 80;
listen 443 ssl ;
server_name xxx.cn;
ssl_certificate /usr/local/openresty/nginx/ssl/xxx.cn.pem;
ssl_certificate_key /usr/local/openresty/nginx/ssl/xxx.cn.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:!ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:!RC4-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;
ssl_prefer_server_ciphers on;
client_header_buffer_size 16k;
large_client_header_buffers 4 16k;
#proxy_ssl_session_reuse off;
location /group1 {
#ssl_preread on;
limit_req zone=allips burst=5 nodelay;
add_header Access-Control-Expose-Headers Content-Disposition;
add_header Cache-Control max-age=360000;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Headers "access_token, Content-Type, X-Client-Id, Authorization, X-Domain, xtenant, clientid" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, PATCH, DELETE, HEAD" always;
add_header Access-Control-Max-Age 86400 always;
return 204;
}
## 这儿就可以使用lua脚本进行鉴权了。
access_by_lua_block {
local obj = require('nginx-jwt')
obj.auth()
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_ssl_session_reuse off;
#proxy_ssl_server_name off;
proxy_pass http://file;
}
location ~*\.(doc|docx|xls|xlsx|ppt|pptx|pdf)$ {
add_header Access-Control-Expose-Headers "Content-Disposition";
if ($arg_accesskey != "") {
access_by_lua_block {
local obj = require('nginx-jwt-src')
obj.auth()
}
}
if ($arg_accesskey = "") {
access_by_lua_block
{
local obj = require('nginx-jwt')
obj.auth()
}
}
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Headers "access_token, Content-Type, X-Client-Id, Authorization, X-Domain, xtenant, clientid" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, PATCH, DELETE, HEAD" always;
add_header Access-Control-Max-Age 86400 always;
return 204;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_ssl_session_reuse off;
#proxy_ssl_server_name off;
proxy_pass http://file;
}
location ~*\.(apk|jpg|png|gif|jpeg|heic)$ {
access_by_lua_block {
local obj = require('nginx-jwt-src')
obj.auth()
}
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Headers "access_token, Content-Type, X-Client-Id, Authorization, X-Domain, xtenant, clientid" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, PATCH, DELETE, HEAD" always;
add_header Access-Control-Max-Age 86400 always;
return 204;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://file;
}
location ~*\.(mp3|mp4)$ {
limit_req zone=allips burst=5 nodelay;
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Headers "access_token, Content-Type, X-Client-Id, Authorization, X-Domain, xtenant, clientid" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, PATCH, DELETE, HEAD" always;
add_header Access-Control-Max-Age 86400 always;
limit_rate_after 20m;
limit_rate 100k;
access_by_lua_block {
local obj = require('nginx-jwt-src')
obj.auth()
}
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://file;
}
}
重启openresty
文件服务
略