Add custom error pages and Nginx configuration for proxy module
- Introduced custom HTML error pages for various HTTP status codes (400, 401, 403, 404, 408, 429, 500, 502, 503, 504) in the proxy module. - Created a .gitignore file to exclude non-HTML files in the error resources directory. - Updated Nginx configuration to serve custom error pages for upstream errors. - Added new Nginx configuration templates for handling HTTP and stream protocols. - Implemented Wireguard configuration templates and associated variables for secure connections. - Established Kubernetes resources for Stunnel and Wireguard, including deployment, service accounts, and config maps. - Defined variables for the Stunnel and Wireguard modules to facilitate configuration. - Created a new Wol Proxy module with Kubernetes resources for deployment and service management.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
import logging
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s [%(levelname)s] %(message)s"
|
||||
)
|
||||
|
||||
EXPECTED_TOKEN = os.getenv("AUTH_TOKEN", "")
|
||||
|
||||
class AuthHandler(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
auth = self.headers.get('Authorization')
|
||||
|
||||
# Log request info
|
||||
client_ip = self.client_address[0]
|
||||
logging.info(f"Auth request from {client_ip}")
|
||||
|
||||
if auth == f"Bearer {EXPECTED_TOKEN}":
|
||||
logging.info("Authentication successful")
|
||||
self.send_response(200)
|
||||
else:
|
||||
logging.warning("Authentication failed")
|
||||
self.send_response(401)
|
||||
self.end_headers()
|
||||
|
||||
def log_message(self, format, *args):
|
||||
# Suppress default BaseHTTPRequestHandler logging
|
||||
return
|
||||
|
||||
if __name__ == '__main__':
|
||||
if not EXPECTED_TOKEN:
|
||||
logging.error("AUTH_TOKEN environment variable not set. Exiting.")
|
||||
exit(1)
|
||||
|
||||
server = HTTPServer(('', 5000), AuthHandler)
|
||||
logging.info("Auth server running on port 5000...")
|
||||
server.serve_forever()
|
||||
@@ -0,0 +1 @@
|
||||
!*.html
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>400 - Bad Request</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">❌</div>
|
||||
<h1>400 - Bad Request</h1>
|
||||
<p>Oops! The server couldn't understand your request.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>401 - Unauthorized</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">🔒</div>
|
||||
<h1>401 - Unauthorized</h1>
|
||||
<p>You need to log in to access this resource.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>403 - Forbidden</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">🚫</div>
|
||||
<h1>403 - Forbidden</h1>
|
||||
<p>You don't have permission to view this page.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>404 - Page Not Found</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">🔍</div>
|
||||
<h1>404 - Page Not Found</h1>
|
||||
<p>We couldn't find the page you're looking for.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>408 - Request Timeout</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">⏳</div>
|
||||
<h1>408 - Request Timeout</h1>
|
||||
<p>The server took too long to respond. Try again later.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>429 - Too Many Requests</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">🚦</div>
|
||||
<h1>429 - Too Many Requests</h1>
|
||||
<p>You're making too many requests. Please slow down.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>500 - Internal Server Error</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">⚠️</div>
|
||||
<h1>500 - Internal Server Error</h1>
|
||||
<p>Something went wrong on our end. We're working on it.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>502 - Bad Gateway</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">🔌</div>
|
||||
<h1>502 - Bad Gateway</h1>
|
||||
<p>The server received an invalid response from upstream.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>503 - Service Unavailable</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">🛠️</div>
|
||||
<h1>503 - Service Unavailable</h1>
|
||||
<p>We're doing some maintenance. Please check back soon.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>504 - Gateway Timeout</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #121212;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
max-width: 500px;
|
||||
}
|
||||
.icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
color: #f39c12;
|
||||
}
|
||||
h1 { font-size: 2rem; margin-bottom: 10px; }
|
||||
p { font-size: 1rem; color: #cccccc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="icon">📡</div>
|
||||
<h1>504 - Gateway Timeout</h1>
|
||||
<p>The upstream server didn't respond in time.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,54 @@
|
||||
server {
|
||||
listen ${http_port};
|
||||
%{ if tls ~}
|
||||
listen ${https_port} ssl;
|
||||
ssl_certificate /etc/ssl/certs/private/tls.crt;
|
||||
ssl_certificate_key /etc/ssl/certs/private/tls.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
%{ endif ~}
|
||||
server_name ${fqdn};
|
||||
# Custom error page for upstream errors
|
||||
%{ for e in errors ~}
|
||||
error_page ${e} /errors/${e}.html;
|
||||
location = /errors/${e}.html {
|
||||
root /usr/share/nginx/html;
|
||||
internal;
|
||||
}
|
||||
%{ endfor ~}
|
||||
%{ if custom_snippet != "" ~}
|
||||
${custom_snippet}
|
||||
%{ endif ~}
|
||||
%{ if auth ~}
|
||||
location = /auth {
|
||||
internal;
|
||||
proxy_pass http://localhost:5000/;
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header Authorization $http_authorization;
|
||||
}
|
||||
%{ endif }
|
||||
%{ for l in locations ~}
|
||||
location ${l.path} {
|
||||
%{ if l.resolver == "" ~}
|
||||
%{ if resolver != "" ~}
|
||||
resolver ${resolver};
|
||||
%{ endif ~}
|
||||
%{ else ~}
|
||||
resolver ${l.resolver};
|
||||
%{ endif ~}
|
||||
%{ if l.private ~}
|
||||
auth_request /auth<;
|
||||
%{ endif ~}
|
||||
set $upstream "%{ if l.upstream != "" ~}${l.upstream}%{ else ~}${upstream}%{ endif ~}";
|
||||
%{ if l.rewrite != "" ~}
|
||||
rewrite ${l.rewrite};
|
||||
%{ endif ~}
|
||||
proxy_pass $upstream;
|
||||
proxy_http_version 1.1;
|
||||
%{ for k,v in l.headers ~}
|
||||
proxy_set_header ${k} ${v};
|
||||
%{ endfor ~}
|
||||
proxy_intercept_errors on;
|
||||
}
|
||||
%{ endfor ~}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
worker_processes auto;
|
||||
|
||||
error_log /dev/stderr warn;
|
||||
pid /tmp/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
proxy_temp_path /tmp/proxy_temp;
|
||||
client_body_temp_path /tmp/client_temp;
|
||||
fastcgi_temp_path /tmp/fastcgi_temp;
|
||||
uwsgi_temp_path /tmp/uwsgi_temp;
|
||||
scgi_temp_path /tmp/scgi_temp;
|
||||
|
||||
client_max_body_size 10M;
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
include /etc/nginx/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 /dev/stdout main;
|
||||
|
||||
sendfile on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
server {
|
||||
listen 8888;
|
||||
server_name _;
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "OK";
|
||||
}
|
||||
}
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
|
||||
stream {
|
||||
include /etc/nginx/streams.d/*.conf;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
upstream ${name} {
|
||||
%{ if resolver != "" ~}
|
||||
resolver ${resolver};
|
||||
%{ endif ~}
|
||||
server ${upstream}:${upstream_port};
|
||||
}
|
||||
server {
|
||||
listen %{ if protocol == "UDP" ~}${port} udp;%{ else ~}${port};%{ endif }
|
||||
%{ if custom_snippet != "" ~}
|
||||
${custom_snippet}
|
||||
%{ endif ~}
|
||||
proxy_pass ${name};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
[Interface]
|
||||
PrivateKey = ${wireguard_private_key}
|
||||
Address = ${wireguard_address}
|
||||
|
||||
[Peer]
|
||||
PublicKey = ${wireguard_public_key}
|
||||
PresharedKey = ${wireguard_pre_shared_key}
|
||||
AllowedIPs = ${wireguard_allowed_ips}
|
||||
Endpoint = ${wireguard_endpoint}
|
||||
PersistentKeepalive = 25
|
||||
Reference in New Issue
Block a user