Set up secure JWT-based authentication in OpenResty with OAuth2 provider integration using lua-resty-jwt module. Configure token validation, authentication middleware, and security policies for production web applications.
Prerequisites
- Root or sudo access
- Domain name with DNS configured
- OAuth2 provider (Google, Auth0, Keycloak, etc.)
- SSL certificates
- Basic understanding of JWT and OAuth2 flows
What this solves
OpenResty JWT authentication with OAuth2 integration provides secure, stateless authentication for modern web applications. This implementation eliminates the need for server-side session storage while ensuring secure token validation and OAuth2 provider integration. You'll configure lua-resty-jwt for token handling, implement authentication middleware, and establish security policies that protect your applications from unauthorized access.
Step-by-step configuration
Update system packages
Start by updating your package manager to ensure you get the latest versions of all dependencies.
sudo apt update && sudo apt upgrade -y
sudo dnf update -y
Install OpenResty and required dependencies
Install OpenResty web server with Lua scripting support and additional tools needed for JWT authentication.
sudo apt install -y wget gnupg ca-certificates
wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/openresty.list
sudo apt update
sudo apt install -y openresty luarocks git build-essential libssl-dev
sudo dnf install -y wget
wget https://openresty.org/package/rhel/openresty.repo
sudo mv openresty.repo /etc/yum.repos.d/
sudo dnf install -y openresty luarocks git gcc gcc-c++ openssl-devel
Install lua-resty-jwt module
Install the JWT library for OpenResty that handles token creation, parsing, and validation with cryptographic signatures.
sudo luarocks install lua-resty-jwt
sudo luarocks install lua-resty-http
sudo luarocks install lua-cjson
Create directory structure
Set up the necessary directories for OpenResty configuration, Lua modules, and SSL certificates with proper permissions.
sudo mkdir -p /etc/openresty/conf.d
sudo mkdir -p /etc/openresty/lua
sudo mkdir -p /etc/openresty/ssl
sudo mkdir -p /var/log/openresty
sudo chown -R openresty:openresty /etc/openresty /var/log/openresty
sudo chmod 755 /etc/openresty /var/log/openresty
sudo chmod 750 /etc/openresty/ssl
Generate JWT signing keys
Create RSA key pairs for JWT token signing and verification. The private key signs tokens while the public key validates them.
sudo openssl genrsa -out /etc/openresty/ssl/jwt_private.key 2048
sudo openssl rsa -in /etc/openresty/ssl/jwt_private.key -pubout -out /etc/openresty/ssl/jwt_public.key
sudo chown openresty:openresty /etc/openresty/ssl/jwt_*.key
sudo chmod 600 /etc/openresty/ssl/jwt_private.key
sudo chmod 644 /etc/openresty/ssl/jwt_public.key
Create JWT authentication module
Develop the core Lua module that handles JWT token validation, OAuth2 integration, and authentication logic.
local jwt = require "resty.jwt"
local http = require "resty.http"
local cjson = require "cjson"
local io = require "io"
local _M = {}
-- Configuration
_M.jwt_secret_key = nil
_M.oauth2_introspect_url = "https://oauth.example.com/oauth/introspect"
_M.oauth2_client_id = "your-client-id"
_M.oauth2_client_secret = "your-client-secret"
-- Load JWT public key
function _M.load_jwt_key()
local file = io.open("/etc/openresty/ssl/jwt_public.key", "r")
if not file then
ngx.log(ngx.ERR, "Could not open JWT public key file")
return nil
end
local key = file:read("*all")
file:close()
return key
end
-- Validate JWT token
function _M.validate_jwt(token)
if not _M.jwt_secret_key then
_M.jwt_secret_key = _M.load_jwt_key()
if not _M.jwt_secret_key then
return false, "JWT key not available"
end
end
local jwt_token = jwt:verify(_M.jwt_secret_key, token, {
alg = "RS256"
})
if not jwt_token.verified then
return false, "JWT verification failed"
end
-- Check expiration
if jwt_token.payload.exp and jwt_token.payload.exp < ngx.time() then
return false, "JWT token expired"
end
return true, jwt_token.payload
end
-- OAuth2 token introspection
function _M.introspect_oauth2_token(token)
local httpc = http.new()
httpc:set_timeout(5000)
local res, err = httpc:request_uri(_M.oauth2_introspect_url, {
method = "POST",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
["Authorization"] = "Basic " .. ngx.encode_base64(_M.oauth2_client_id .. ":" .. _M.oauth2_client_secret)
},
body = "token=" .. token
})
if not res then
ngx.log(ngx.ERR, "OAuth2 introspection failed: ", err)
return false, "OAuth2 introspection error"
end
if res.status ~= 200 then
return false, "OAuth2 introspection failed with status: " .. res.status
end
local data = cjson.decode(res.body)
if not data.active then
return false, "OAuth2 token is not active"
end
return true, data
end
-- Extract token from request
function _M.extract_token()
local auth_header = ngx.var.http_authorization
if not auth_header then
return nil, "No authorization header"
end
local token = auth_header:match("Bearer%s+(.+)")
if not token then
return nil, "Invalid authorization header format"
end
return token
end
-- Main authentication function
function _M.authenticate()
local token, err = _M.extract_token()
if not token then
ngx.log(ngx.ERR, "Token extraction failed: ", err)
ngx.status = 401
ngx.header["Content-Type"] = "application/json"
ngx.say(cjson.encode({error = "unauthorized", message = err}))
ngx.exit(401)
end
-- Try JWT validation first
local valid, payload = _M.validate_jwt(token)
if valid then
-- Set user context
ngx.var.auth_user_id = payload.sub or payload.user_id
ngx.var.auth_user_email = payload.email
ngx.var.auth_user_roles = cjson.encode(payload.roles or {})
return
end
-- Fallback to OAuth2 introspection
valid, payload = _M.introspect_oauth2_token(token)
if valid then
-- Set user context from OAuth2 response
ngx.var.auth_user_id = payload.sub or payload.username
ngx.var.auth_user_email = payload.email
ngx.var.auth_user_roles = cjson.encode(payload.scope and {payload.scope} or {})
return
end
-- Authentication failed
ngx.log(ngx.ERR, "Authentication failed: ", payload)
ngx.status = 401
ngx.header["Content-Type"] = "application/json"
ngx.say(cjson.encode({error = "unauthorized", message = "Invalid or expired token"}))
ngx.exit(401)
end
-- Role-based access control
function _M.require_role(required_role)
local user_roles = ngx.var.auth_user_roles
if not user_roles then
ngx.status = 403
ngx.header["Content-Type"] = "application/json"
ngx.say(cjson.encode({error = "forbidden", message = "No roles assigned"}))
ngx.exit(403)
end
local roles = cjson.decode(user_roles)
for _, role in ipairs(roles) do
if role == required_role then
return
end
end
ngx.status = 403
ngx.header["Content-Type"] = "application/json"
ngx.say(cjson.encode({error = "forbidden", message = "Insufficient permissions"}))
ngx.exit(403)
end
return _M
Configure main OpenResty configuration
Set up the primary OpenResty configuration with Lua package paths, security headers, and authentication variables.
user openresty;
worker_processes auto;
error_log /var/log/openresty/error.log;
pid /var/run/openresty.pid;
events {
worker_connections 1024;
use epoll;
}
http {
include /etc/openresty/mime.types;
default_type application/octet-stream;
# Lua package path
lua_package_path "/etc/openresty/lua/?.lua;;";
lua_shared_dict jwt_cache 10m;
# Security headers
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Logging
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'auth_user="$auth_user_id"';
access_log /var/log/openresty/access.log main;
# Performance settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_types text/plain application/json application/javascript text/css;
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/s;
include /etc/openresty/conf.d/*.conf;
}
Create application server configuration
Configure a virtual server with JWT authentication, OAuth2 integration, and protected API endpoints with role-based access control.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
# SSL configuration
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# Authentication variables
set $auth_user_id "";
set $auth_user_email "";
set $auth_user_roles "";
# Health check endpoint (no auth required)
location = /health {
access_log off;
return 200 'healthy';
add_header Content-Type text/plain;
}
# Authentication endpoint for OAuth2 callback
location = /auth/callback {
limit_req zone=auth burst=10 nodelay;
access_by_lua_block {
local jwt_auth = require "jwt_auth"
local cjson = require "cjson"
-- Handle OAuth2 callback and create JWT
local code = ngx.var.arg_code
if not code then
ngx.status = 400
ngx.say(cjson.encode({error = "missing_code"}))
ngx.exit(400)
end
-- Exchange code for token (implement based on your OAuth2 provider)
-- This is a simplified example
ngx.header["Content-Type"] = "application/json"
ngx.say(cjson.encode({message = "OAuth2 callback processed"}))
}
}
# Public API endpoints (no authentication)
location /api/public {
limit_req zone=api burst=20 nodelay;
# Proxy to your application backend
proxy_pass http://127.0.0.1:8080;
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_set_header X-Forwarded-Proto $scheme;
}
# Protected API endpoints (JWT authentication required)
location /api/protected {
limit_req zone=api burst=20 nodelay;
access_by_lua_block {
local jwt_auth = require "jwt_auth"
jwt_auth.authenticate()
}
# Proxy to your application backend with user context
proxy_pass http://127.0.0.1:8080;
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_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Auth-User-ID $auth_user_id;
proxy_set_header X-Auth-User-Email $auth_user_email;
proxy_set_header X-Auth-User-Roles $auth_user_roles;
}
# Admin endpoints (requires admin role)
location /api/admin {
limit_req zone=api burst=10 nodelay;
access_by_lua_block {
local jwt_auth = require "jwt_auth"
jwt_auth.authenticate()
jwt_auth.require_role("admin")
}
proxy_pass http://127.0.0.1:8080;
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_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Auth-User-ID $auth_user_id;
proxy_set_header X-Auth-User-Email $auth_user_email;
proxy_set_header X-Auth-User-Roles $auth_user_roles;
}
# Static files
location / {
root /var/www/html;
index index.html index.htm;
try_files $uri $uri/ =404;
}
}
# HTTP redirect to HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
Create JWT token generation utility
Build a Lua script for generating JWT tokens during development and testing of your authentication system.
local jwt = require "resty.jwt"
local cjson = require "cjson"
local io = require "io"
-- Load private key for signing
local function load_private_key()
local file = io.open("/etc/openresty/ssl/jwt_private.key", "r")
if not file then
error("Could not open JWT private key file")
end
local key = file:read("*all")
file:close()
return key
end
-- Generate JWT token
local function generate_token(payload)
local private_key = load_private_key()
-- Set default expiration (1 hour)
payload.exp = payload.exp or (os.time() + 3600)
payload.iat = payload.iat or os.time()
payload.iss = payload.iss or "openresty-jwt"
local token = jwt:sign(private_key, {
header = {
typ = "JWT",
alg = "RS256"
},
payload = payload
})
return token
end
-- Example usage
if arg and arg[1] then
local payload = {
sub = arg[1] or "user123",
email = arg[2] or "user@example.com",
roles = {arg[3] or "user"}
}
local token = generate_token(payload)
print("JWT Token:")
print(token)
print("\nTest with:")
print("curl -H 'Authorization: Bearer " .. token .. "' https://example.com/api/protected")
else
print("Usage: lua jwt_generator.lua
Configure systemd service
Create a systemd service file to manage OpenResty with proper security settings and automatic restart capabilities.
[Unit]
Description=OpenResty HTTP Server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/var/run/openresty.pid
ExecStartPre=/usr/bin/openresty -t -c /etc/openresty/nginx.conf
ExecStart=/usr/bin/openresty -c /etc/openresty/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
RestartSec=2
Restart=on-failure
User=openresty
Group=openresty
# Security settings
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/openresty /var/run
[Install]
WantedBy=multi-user.target
Create OpenResty user and set permissions
Create a dedicated system user for OpenResty with minimal privileges and proper directory ownership.
sudo useradd --system --no-create-home --shell /bin/false --group openresty openresty
sudo chown -R openresty:openresty /etc/openresty /var/log/openresty
sudo chmod -R 755 /etc/openresty
sudo chmod -R 750 /etc/openresty/ssl /var/log/openresty
sudo chmod 600 /etc/openresty/ssl/jwt_private.key
Enable and start OpenResty service
Enable OpenResty to start automatically on boot and start the service immediately.
sudo systemctl daemon-reload
sudo systemctl enable openresty
sudo systemctl start openresty
Configure firewall rules
Open the necessary ports for HTTP and HTTPS traffic while maintaining security.
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Verify your setup
Test your OpenResty JWT authentication system to ensure all components are working correctly.
# Check OpenResty service status
sudo systemctl status openresty
# Verify configuration syntax
sudo openresty -t -c /etc/openresty/nginx.conf
# Generate a test JWT token
cd /etc/openresty/lua
sudo -u openresty lua jwt_generator.lua testuser user@example.com admin
# Test public endpoint (should work without token)
curl -i https://example.com/api/public
# Test protected endpoint without token (should return 401)
curl -i https://example.com/api/protected
# Test protected endpoint with token (replace TOKEN with generated JWT)
curl -i -H "Authorization: Bearer TOKEN" https://example.com/api/protected
# Check logs for authentication events
sudo tail -f /var/log/openresty/access.log
Configure OAuth2 provider integration
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Global variables
DOMAIN="${1:-localhost}"
OAUTH2_URL="${2:-https://oauth.example.com/oauth/introspect}"
OAUTH2_CLIENT_ID="${3:-your-client-id}"
OAUTH2_CLIENT_SECRET="${4:-your-client-secret}"
usage() {
echo "Usage: $0 [domain] [oauth2_url] [client_id] [client_secret]"
echo "Example: $0 api.example.com https://auth.example.com/oauth/introspect myapp secret123"
exit 1
}
log() {
echo -e "${GREEN}[INFO]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
exit 1
}
cleanup() {
if [ $? -ne 0 ]; then
warn "Installation failed. Cleaning up..."
systemctl stop openresty 2>/dev/null || true
rm -rf /etc/openresty/conf.d/jwt-auth.conf 2>/dev/null || true
fi
}
trap cleanup ERR
check_prerequisites() {
if [ "$EUID" -ne 0 ]; then
error "This script must be run as root or with sudo"
fi
if ! command -v curl &> /dev/null; then
error "curl is required but not installed"
fi
}
detect_distro() {
if [ ! -f /etc/os-release ]; then
error "Cannot detect distribution"
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
OPENRESTY_USER="www-data"
OPENRESTY_GROUP="www-data"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
OPENRESTY_USER="nobody"
OPENRESTY_GROUP="nobody"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
OPENRESTY_USER="nobody"
OPENRESTY_GROUP="nobody"
;;
*)
error "Unsupported distribution: $ID"
;;
esac
}
install_openresty() {
case "$PKG_MGR" in
apt)
$PKG_INSTALL wget gnupg ca-certificates
wget -qO - https://openresty.org/package/pubkey.gpg | apt-key add -
echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/openresty.list
apt update
$PKG_INSTALL openresty luarocks git build-essential libssl-dev
;;
dnf|yum)
$PKG_INSTALL wget
wget -O /etc/yum.repos.d/openresty.repo https://openresty.org/package/rhel/openresty.repo
$PKG_INSTALL openresty luarocks git gcc gcc-c++ openssl-devel
;;
esac
}
install_lua_modules() {
luarocks install lua-resty-jwt
luarocks install lua-resty-http
luarocks install lua-cjson
}
create_directories() {
mkdir -p /etc/openresty/{conf.d,lua,ssl}
mkdir -p /var/log/openresty
chown -R $OPENRESTY_USER:$OPENRESTY_GROUP /etc/openresty /var/log/openresty
chmod 755 /etc/openresty /var/log/openresty
chmod 750 /etc/openresty/ssl
}
generate_jwt_keys() {
openssl genrsa -out /etc/openresty/ssl/jwt_private.key 2048
openssl rsa -in /etc/openresty/ssl/jwt_private.key -pubout -out /etc/openresty/ssl/jwt_public.key
chown $OPENRESTY_USER:$OPENRESTY_GROUP /etc/openresty/ssl/jwt_*.key
chmod 600 /etc/openresty/ssl/jwt_private.key
chmod 644 /etc/openresty/ssl/jwt_public.key
}
create_jwt_module() {
cat > /etc/openresty/lua/jwt_auth.lua << 'EOF'
local jwt = require "resty.jwt"
local http = require "resty.http"
local cjson = require "cjson"
local io = require "io"
local _M = {}
_M.jwt_secret_key = nil
_M.oauth2_introspect_url = os.getenv("OAUTH2_INTROSPECT_URL") or "https://oauth.example.com/oauth/introspect"
_M.oauth2_client_id = os.getenv("OAUTH2_CLIENT_ID") or "your-client-id"
_M.oauth2_client_secret = os.getenv("OAUTH2_CLIENT_SECRET") or "your-client-secret"
function _M.load_jwt_key()
local file = io.open("/etc/openresty/ssl/jwt_public.key", "r")
if not file then
ngx.log(ngx.ERR, "Could not open JWT public key file")
return nil
end
local key = file:read("*all")
file:close()
return key
end
function _M.validate_jwt(token)
if not _M.jwt_secret_key then
_M.jwt_secret_key = _M.load_jwt_key()
if not _M.jwt_secret_key then
return false, "JWT key not available"
end
end
local jwt_token = jwt:verify(_M.jwt_secret_key, token, {
alg = "RS256"
})
if not jwt_token.verified then
return false, "Invalid JWT token"
end
local current_time = ngx.time()
if jwt_token.payload.exp and jwt_token.payload.exp < current_time then
return false, "Token expired"
end
return true, jwt_token.payload
end
function _M.introspect_token(access_token)
local httpc = http.new()
local res, err = httpc:request_uri(_M.oauth2_introspect_url, {
method = "POST",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
["Authorization"] = "Basic " .. ngx.encode_base64(_M.oauth2_client_id .. ":" .. _M.oauth2_client_secret)
},
body = "token=" .. access_token
})
if not res then
return false, "Failed to introspect token: " .. err
end
if res.status ~= 200 then
return false, "Token introspection failed"
end
local result = cjson.decode(res.body)
return result.active == true, result
end
function _M.authenticate()
local auth_header = ngx.var.http_authorization
if not auth_header then
ngx.status = 401
ngx.header["WWW-Authenticate"] = "Bearer"
ngx.say('{"error":"Missing Authorization header"}')
ngx.exit(401)
end
local token = auth_header:match("Bearer%s+(.+)")
if not token then
ngx.status = 401
ngx.say('{"error":"Invalid Authorization header format"}')
ngx.exit(401)
end
local valid, payload = _M.validate_jwt(token)
if valid then
ngx.ctx.user = payload
return
end
valid, payload = _M.introspect_token(token)
if not valid then
ngx.status = 401
ngx.say('{"error":"Invalid or expired token"}')
ngx.exit(401)
end
ngx.ctx.user = payload
end
return _M
EOF
chown $OPENRESTY_USER:$OPENRESTY_GROUP /etc/openresty/lua/jwt_auth.lua
chmod 644 /etc/openresty/lua/jwt_auth.lua
}
create_nginx_config() {
cat > /etc/openresty/conf.d/jwt-auth.conf << EOF
lua_package_path "/etc/openresty/lua/?.lua;;";
server {
listen 80;
server_name $DOMAIN;
location /health {
access_log off;
return 200 "OK";
add_header Content-Type text/plain;
}
location /auth {
access_by_lua_block {
local jwt_auth = require "jwt_auth"
jwt_auth.authenticate()
}
proxy_set_header X-User-ID \$ctx_user_sub;
proxy_set_header X-User-Email \$ctx_user_email;
proxy_pass http://backend;
}
location / {
return 404;
}
}
upstream backend {
server 127.0.0.1:8080;
}
EOF
chown $OPENRESTY_USER:$OPENRESTY_GROUP /etc/openresty/conf.d/jwt-auth.conf
chmod 644 /etc/openresty/conf.d/jwt-auth.conf
}
configure_main_nginx() {
if [ ! -f /etc/openresty/nginx.conf.backup ]; then
cp /usr/local/openresty/nginx/conf/nginx.conf /etc/openresty/nginx.conf.backup
fi
cat > /usr/local/openresty/nginx/conf/nginx.conf << EOF
user $OPENRESTY_USER;
worker_processes auto;
error_log /var/log/openresty/error.log;
pid /var/run/openresty.pid;
events {
worker_connections 1024;
}
http {
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 /var/log/openresty/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /usr/local/openresty/nginx/conf/mime.types;
default_type application/octet-stream;
include /etc/openresty/conf.d/*.conf;
}
EOF
}
setup_systemd_service() {
systemctl enable openresty
systemctl start openresty
}
configure_firewall() {
if command -v ufw &> /dev/null; then
ufw --force enable
ufw allow 80/tcp
ufw allow 443/tcp
elif command -v firewall-cmd &> /dev/null; then
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
fi
}
verify_installation() {
if ! systemctl is-active --quiet openresty; then
error "OpenResty is not running"
fi
if ! curl -s http://localhost/health | grep -q "OK"; then
error "Health check failed"
fi
log "OpenResty JWT authentication is configured and running"
log "Health check: http://$DOMAIN/health"
log "Auth endpoint: http://$DOMAIN/auth"
log "Remember to update OAuth2 credentials in environment variables"
}
main() {
log "[1/11] Checking prerequisites..."
check_prerequisites
log "[2/11] Detecting distribution..."
detect_distro
log "[3/11] Updating system packages..."
$PKG_UPDATE
log "[4/11] Installing OpenResty and dependencies..."
install_openresty
log "[5/11] Installing Lua modules..."
install_lua_modules
log "[6/11] Creating directory structure..."
create_directories
log "[7/11] Generating JWT signing keys..."
generate_jwt_keys
log "[8/11] Creating JWT authentication module..."
create_jwt_module
log "[9/11] Configuring OpenResty..."
configure_main_nginx
create_nginx_config
log "[10/11] Starting services..."
setup_systemd_service
configure_firewall
log "[11/11] Verifying installation..."
verify_installation
log "Installation completed successfully!"
}
if [ $# -gt 4 ]; then
usage
fi
main "$@"
Review the script before running. Execute with: bash install.sh