From 4310e46c21fe1c52baf12e89a950fceadf0db38b Mon Sep 17 00:00:00 2001 From: Damian Myrda Date: Sun, 24 Nov 2024 13:46:57 -0600 Subject: [PATCH] Update caddy config and add error pages --- Dockerfile | 8 ++- caddy | 145 +++++++++++++++++++++++++++++++++------ web/templates/404.html | 28 +------- web/templates/429.html | 9 +++ web/templates/500.html | 9 +++ web/templates/error.html | 29 ++++++++ 6 files changed, 181 insertions(+), 47 deletions(-) create mode 100644 web/templates/429.html create mode 100644 web/templates/500.html create mode 100644 web/templates/error.html diff --git a/Dockerfile b/Dockerfile index c9215bc..4019b7d 100644 --- 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 index a3673eb..33f5ff5 100644 --- 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 index ef7ad61..c3f31d0 100644 --- 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 %} not found {% endblock %} -{% block content %} -
-

not found

-
- - +{% block message %} +

not found (404)

{% endblock %} diff --git a/web/templates/429.html b/web/templates/429.html new file mode 100644 index 0000000..a8f037d --- /dev/null +++ b/web/templates/429.html @@ -0,0 +1,9 @@ +{% extends "error.html" %} + +{% block title %} +too many requests +{% endblock %} + +{% block message %} +

too many requests (429)

+{% endblock %} diff --git a/web/templates/500.html b/web/templates/500.html new file mode 100644 index 0000000..4b68968 --- /dev/null +++ b/web/templates/500.html @@ -0,0 +1,9 @@ +{% extends "error.html" %} + +{% block title %} +server error +{% endblock %} + +{% block message %} +

server error (500)

+{% endblock %} diff --git a/web/templates/error.html b/web/templates/error.html new file mode 100644 index 0000000..f8a0172 --- /dev/null +++ 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 %} +
+ {% block message %} + {% endblock %} +
+ + +{% endblock %} -- 2.43.4