commit c54680e004e50c2ae9a0aa13e5ee1eec7cb3091c
parent ea069d2110cb2ed9359f988f1a465b8b6a8ae9fe
Author: Damian Myrda <damian@prime8.dev>
Date: Sun, 24 Nov 2024 13:46:57 -0600
Update caddy config and add error pages
Diffstat:
6 files changed, 181 insertions(+), 47 deletions(-)
diff --git a/Dockerfile b/Dockerfile
@@ -5,10 +5,14 @@ RUN ["zola", "build"]
FROM caddy:builder AS caddy
RUN xcaddy build \
- --with github.com/caddyserver/cache-handler
+ --with github.com/caddyserver/cache-handler \
+ --with github.com/mholt/caddy-ratelimit
FROM caddy:latest
COPY --from=caddy /usr/bin/caddy /usr/bin/caddy
COPY ./caddy /etc/caddy/Caddyfile
COPY --from=web /src/public/ /web/
-EXPOSE 80 443
+EXPOSE 80 443 443/udp
+
+HEALTHCHECK --interval=60s --timeout=5s --start-period=5s \
+ CMD curl -f http://localhost/ || exit 1
diff --git a/caddy b/caddy
@@ -1,46 +1,151 @@
{
- cache
+ cache
}
+# Root
prime8.dev {
- redir https://www.prime8.dev{uri} 301
+ redir https://www.prime8.dev{uri} 301
+
+ # Rate Limiting
+ rate_limit {
+ burst 20 # Allow an initial burst of 20 requests
+ limit 10 # After the burst, allow 10 requests per minute
+ }
+
+ # Security
+ header {
+ Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year
+ X-Frame-Options "DENY" # Prevent embedding
+ -Server # Remove the Server header
+ Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions
+ X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing
+ Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior
+ }
+ tls damian@prime8.dev
}
+# Main Site
www.prime8.dev {
root * /web/
file_server
try_files {path} {path}.html
- cache
- handle_errors {
- @404 {
- expression {http.error.status_code} == 404
- }
- rewrite @404 /404.html
- file_server
- }
+ # 404 Page Handling
+ handle_errors {
+ @404 {
+ expression {http.error.status_code} == 404
+ }
+ rewrite @404 /404.html
+
+ @429 {
+ expression {http.error.status_code} == 429
+ }
+ rewrite @429 /429.html
+
+ @500 {
+ expression {http.error.status_code} == 500
+ }
+ rewrite @500 /500.html
+
+ file_server
+ }
+
+ # Caching
+ cache
+ header /static/* {
+ Cache-Control "public, max-age=86400; immutable" # Cache for 1 day
+ }
+
+ # Rate Limiting
+ rate_limit {
+ burst 20 # Allow an initial burst of 20 requests
+ limit 10 # After the burst, allow 10 requests per minute
+ }
- tls damian@prime8.dev
+ # Security
+ header {
+ Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year
+ X-Frame-Options "DENY" # Prevent embedding
+ -Server # Remove the Server header
+ Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions
+ X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing
+ Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior
+ }
+ tls damian@prime8.dev
}
+# Mail Server
mail.prime8.dev {
- tls damian@prime8.dev
+ header {
+ X-Robots-Tag "noindex, nofollow" # Prevent search engine indexing
+
+ # Security
+ Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year
+ X-Frame-Options "DENY" # Prevent embedding
+ -Server # Remove the Server header
+ Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions
+ X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing
+ Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior
+ }
+ tls damian@prime8.dev
}
+# Git Server
git.prime8.dev {
- reverse_proxy http://gitweb:80
- cache
+ reverse_proxy http://gitweb:80
- header {
- X-Robots-Tag "index, nofollow"
+ # Caching
+ cache
+ header /static/* {
+ Cache-Control "public, max-age=86400; immutable" # Cache for 1 day
+ }
+
+ # Rate Limiting
+ rate_limit {
+ burst 20 # Allow an initial burst of 20 requests
+ limit 10 # After the burst, allow 10 requests per minute
}
- tls damian@prime8.dev
+ header {
+ X-Robots-Tag "noindex, nofollow" # Prevent search engine indexing
+
+ # Security
+ Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year
+ X-Frame-Options "DENY" # Prevent embedding
+ -Server # Remove the Server header
+ Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions
+ X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing
+ Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior
+ }
+ tls damian@prime8.dev
}
+# CSC Website
csc.prime8.dev {
- reverse_proxy http://csc:80
- cache
+ reverse_proxy http://csc:80
- tls damian@prime8.dev
+ # Caching
+ cache
+ header /static/* {
+ Cache-Control "public, max-age=86400; immutable" # Cache for 1 day
+ }
+
+ # Rate Limiting
+ rate_limit {
+ burst 20 # Allow an initial burst of 20 requests
+ limit 10 # After the burst, allow 10 requests per minute
+ }
+
+ header {
+ X-Robots-Tag "noindex, nofollow" # Prevent search engine indexing
+
+ # Security
+ Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Enforce HTTPS for 1 year
+ X-Frame-Options "DENY" # Prevent embedding
+ -Server # Remove the Server header
+ Permissions-Policy "geolocation=(), microphone=(), camera=()" # No permissions
+ X-Content-Type-Options "nosniff" # Prevent MIME-type sniffing
+ Referrer-Policy "no-referrer-when-downgrade" # Control referrer behavior
+ }
+ tls damian@prime8.dev
}
diff --git a/web/templates/404.html b/web/templates/404.html
@@ -1,31 +1,9 @@
-{% extends "base.html" %}
-
-{% import "nav.html" as nav %}
-{% block navbar %}
-{{ nav::bar(active="") }}
-{% endblock %}
+{% extends "error.html" %}
{% block title %}
<title>not found</title>
{% endblock %}
-{% block content %}
-<div id="message">
- <h1>not found</h1>
-</div>
-<style>
- #content {
- padding: 0px !important;
- }
-
- #message {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
- }
-</style>
-<script>
- _386 = { fastLoad: true };
-</script>
+{% block message %}
+<h1 id="message">not found (404)</h1>
{% endblock %}
diff --git a/web/templates/429.html b/web/templates/429.html
@@ -0,0 +1,9 @@
+{% extends "error.html" %}
+
+{% block title %}
+<title>too many requests</title>
+{% endblock %}
+
+{% block message %}
+<h1 id="message">too many requests (429)</h1>
+{% endblock %}
diff --git a/web/templates/500.html b/web/templates/500.html
@@ -0,0 +1,9 @@
+{% extends "error.html" %}
+
+{% block title %}
+<title>server error</title>
+{% endblock %}
+
+{% block message %}
+<h1 id="message">server error (500)</h1>
+{% endblock %}
diff --git a/web/templates/error.html b/web/templates/error.html
@@ -0,0 +1,29 @@
+{% extends "base.html" %}
+
+{% import "nav.html" as nav %}
+{% block navbar %}
+{{ nav::bar(active="") }}
+{% endblock %}
+
+{% block content %}
+<div>
+ {% block message %}
+ {% endblock %}
+</div>
+<style>
+ #content {
+ padding: 0px !important;
+ }
+
+ #message {
+ color: #ff5555;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ }
+</style>
+<script>
+ _386 = { fastLoad: true };
+</script>
+{% endblock %}