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:
2025-10-02 00:19:01 +02:00
parent 4d00986273
commit e6a3f3affd
62 changed files with 1517 additions and 99 deletions
@@ -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