nginx: Update configuration, remove static serve

Services will now have an additional set of security-oriented response
headers attached, and cache times re-jigged.

In addition, the `nginx-serve-static@` service has been removed in
favour of `nginx-serve-volume@`, which is simpler to set up and use.
This commit is contained in:
Alex Palaistras 2023-03-25 13:21:47 +00:00
parent 6ab280592e
commit efff72baa8
5 changed files with 189 additions and 143 deletions

View File

@ -68,8 +68,15 @@ systemd:
[Service]
Environment=SSL_CERT_NAME=localhost
- name: nginx-serve-static@static.localhost.service
- name: nginx-serve-volume@static.localhost.service
enabled: true
dropins:
- name: populate-volume.conf
contents: |
[Service]
ExecStartPre=/bin/podman volume create static.localhost
ExecStartPre=/bin/sh -c "V=$(podman volume mount static.localhost) && echo 'Hello World!' > $V/index.html"
ExecStartPost=/bin/podman volume unmount static.localhost
- name: nginx-proxy-http@static.localhost.service
enabled: true
@ -166,14 +173,7 @@ storage:
inline: |
export SYSTEMD_PAGER=cat
# Example sites for static and PHP setups.
- path: /etc/coreos-home-server/static.localhost/Containerfile
mode: 0644
contents:
inline: |
FROM localhost/nginx:latest
RUN /bin/echo "Hello Static World!" > /srv/index.html
# Example sites for Nginx-PHP setup.
- path: /etc/coreos-home-server/php.localhost/Containerfile
mode: 0644
contents:

View File

@ -4,6 +4,7 @@
# Run as a unique, less privileged user for security reasons.
# Default: nobody nobody
# https://nginx.org/en/docs/ngx_core_module.html#user
# https://en.wikipedia.org/wiki/Principle_of_least_privilege
user nginx nginx;
# Sets the worker threads to the number of CPU cores available in the system for
@ -167,6 +168,8 @@ http {
font/ttf
image/bmp
image/svg+xml
image/vnd.microsoft.icon
image/x-icon
text/cache-manifest
text/calendar
text/css
@ -182,112 +185,110 @@ http {
# Serve resources with a far-future expiration date.
#
# (!) If you don't control versioning with filename-based cache busting, you
# should consider lowering the cache times to something like one week.
#
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires
# https://nginx.org/en/docs/http/ngx_http_headers_module.html#expires
map $sent_http_content_type $expires {
default 1M;
# Default: Fallback
default 1y;
# No content
# Default: No content
"" off;
# CSS
~*text/css 1y;
# Specific: Assets
~*image/svg\+xml 1y;
~*image/vnd.microsoft.icon 1w;
~*image/x-icon 1w;
# Data interchange
# Specific: Manifests
~*application/manifest\+json 1w;
~*text/cache-manifest epoch;
# Specific: Data interchange
~*application/atom\+xml 1h;
~*application/rdf\+xml 1h;
~*application/rss\+xml 1h;
~*application/json 0;
~*application/ld\+json 0;
~*application/schema\+json 0;
~*application/geo\+json 0;
~*application/xml 0;
~*text/calendar 0;
~*text/xml 0;
# Specific: Documents
~*text/html epoch;
~*text/markdown epoch;
~*text/calendar epoch;
# Favicon (cannot be renamed!) and cursor images
~*image/vnd.microsoft.icon 1w;
~*image/x-icon 1w;
# HTML
~*text/html 0;
# JavaScript
~*application/javascript 1y;
~*application/x-javascript 1y;
~*text/javascript 1y;
# Manifest files
~*application/manifest\+json 1w;
~*application/x-web-app-manifest\+json 0;
~*text/cache-manifest 0;
# Markdown
~*text/markdown 0;
# Media files
~*audio/ 1M;
~*image/ 1M;
~*video/ 1M;
# WebAssembly
~*application/wasm 1y;
# Web fonts
~*font/ 1M;
~*application/vnd.ms-fontobject 1M;
~*application/x-font-ttf 1M;
~*application/x-font-woff 1M;
~*application/font-woff 1M;
~*application/font-woff2 1M;
# Other
# Specific: Other
~*text/x-cross-domain-policy 1w;
# Generic: Data
~*json epoch;
~*xml epoch;
}
expires $expires;
# Add X-XSS-Protection for HTML documents.
# conf/security/x-xss-protection.conf
map $sent_http_content_type $x_xss_protection {
~*text/html "1; mode=block";
# Add Cache-Control.
map $sent_http_content_type $cache_control {
default "public, immutable, stale-while-revalidate";
# No content
"" "no-store";
# Manifest files
~*application/manifest\+json "public";
~*text/cache-manifest ""; # `no-cache` (*)
# Assets
~*image/svg\+xml "public, immutable, stale-while-revalidate";
# Data interchange
~*application/(atom|rdf|rss)\+xml "public, stale-while-revalidate";
# Documents
~*text/html "private, must-revalidate";
~*text/markdown "private, must-revalidate";
~*text/calendar "private, must-revalidate";
# Data
~*json ""; # `no-cache` (*)
~*xml ""; # `no-cache` (*)
}
# Add X-Frame-Options for HTML documents.
# conf/security/x-frame-options.conf
map $sent_http_content_type $x_frame_options {
~*text/html SAMEORIGIN;
}
# Add Content-Security-Policy for HTML documents.
# conf/security/content-security-policy.conf
map $sent_http_content_type $content_security_policy {
~*text/(html|javascript)|application/pdf|xml "default-src 'self'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests";
~*text/(html|javascript)|application/pdf|xml "default-src 'self'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'; upgrade-insecure-requests";
}
# Add Permissions-Policy for HTML documents.
map $sent_http_content_type $permissions_policy {
~*text/(html|javascript)|application/pdf|xml "accelerometer=(),autoplay=(),camera=(),display-capture=(),document-domain=(),encrypted-media=(),fullscreen=(),geolocation=(),gyroscope=(),magnetometer=(),microphone=(),midi=(),payment=(),picture-in-picture=(),publickey-credentials-get=(),screen-wake-lock=(),sync-xhr=(self),usb=(),web-share=(),xr-spatial-tracking=()";
}
# Add Referrer-Policy for HTML documents.
# conf/security/referrer-policy.conf.conf
map $sent_http_content_type $referrer_policy {
~*text/(css|html|javascript)|application\/pdf|xml "strict-origin-when-cross-origin";
}
# Add X-UA-Compatible for HTML documents.
# conf/internet_explorer/x-ua-compatible.conf
map $sent_http_content_type $x_ua_compatible {
~*text/html "IE=edge";
# Add Cross-Origin-Policies for HTML documents.
# Cross-Origin-Embedder-Policy
map $sent_http_content_type $coep_policy {
~*text/(html|javascript)|application/pdf|xml "require-corp";
}
# Cross-Origin-Opener-Policy
map $sent_http_content_type $coop_policy {
~*text/(html|javascript)|application/pdf|xml "same-origin";
}
# Cross-Origin-Resource-Policy
map $sent_http_content_type $corp_policy {
~*text/(html|javascript)|application/pdf|xml "same-origin";
}
# Add Access-Control-Allow-Origin.
# conf/cross-origin/requests.conf
map $sent_http_content_type $cors {
# Images
~*image/ "*";
~*image/ "*";
# Web fonts
~*font/ "*";

View File

@ -3,12 +3,6 @@
# Set a strict Referrer Policy to mitigate information leakage.
#
# (1) The `Referrer-Policy` header is included in responses for resources that are able to request
# (or navigate to) other resources.
#
# This includes the commonly used resource types: HTML, CSS, XML/SVG, PDF documents, scripts and
# workers.
#
# To prevent referrer leakage entirely, specify the `no-referrer` value instead. Note that the effect
# could impact analytics metrics negatively.
#
@ -66,29 +60,6 @@ add_header X-Frame-Options $x_frame_options always;
# Protect website reflected Cross-Site Scripting (XSS) attacks.
#
# (1) Try to re-enable the cross-site scripting (XSS) filter built into most web browsers.
#
# The filter is usually enabled by default, but in some cases, it may be disabled by the user.
# However, in Internet Explorer, for example, it can be re-enabled just by sending the
# `X-XSS-Protection` header with the value of `1`.
#
# (2) Prevent web browsers from rendering the web page if a potential reflected (a.k.a
# non-persistent) XSS attack is detected by the filter.
#
# By default, if the filter is enabled and browsers detect a reflected XSS attack, they will
# attempt to block the attack by making the smallest possible modifications to the returned web
# page.
#
# Unfortunately, in some browsers (e.g.: Internet Explorer), this default behavior may allow the
# XSS filter to be exploited. Therefore, it's better to inform browsers to prevent the rendering
# of the page altogether, instead of attempting to modify it.
#
# https://hackademix.net/2009/11/21/ies-xss-filter-creates-xss-vulnerabilities
#
# (!) Do not rely on the XSS filter to prevent XSS attacks! Ensure that you are taking all possible
# measures to prevent XSS attacks, the most obvious being: validating and sanitizing your
# website's inputs.
#
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
# https://blogs.msdn.microsoft.com/ie/2008/07/02/ie8-security-part-iv-the-xss-filter/
# https://blogs.msdn.microsoft.com/ieinternals/2011/01/31/controlling-the-xss-filter/
@ -99,12 +70,14 @@ add_header X-XSS-Protection $x_xss_protection always;
# Block access to all hidden files and directories except for the
# visible content from within the `/.well-known/` hidden directory.
#
# These types of files usually contain user preferences or the preserved state of a utility, and can
# include rather private places like, for example, the `.git` or `.svn` directories.
# These types of files usually contain user preferences or the preserved state
# of a utility, and can include rather private places like, for example, the
# `.git` or `.svn` directories.
#
# The `/.well-known/` directory represents the standard (RFC 5785) path prefix for "well-known
# locations" (e.g.: `/.well-known/manifest.json`, `/.well-known/keybase.txt`), and therefore, access
# to its visible content should not be blocked.
# The `/.well-known/` directory represents the standard (RFC 5785) path prefix
# for "well-known locations" (e.g.: `/.well-known/manifest.json`,
# `/.well-known/keybase.txt`), and therefore, access to its visible content
# should not be blocked.
#
# https://www.mnot.net/blog/2010/04/07/well-known
# https://tools.ietf.org/html/rfc5785
@ -115,11 +88,114 @@ location ~* /\.(?!well-known\/) {
# Block access to files that can expose sensitive information.
#
# By default, block access to backup and source files that may be left by some text editors and can
# pose a security risk when anyone has access to them.
# By default, block access to backup and source files that may be left by some
# text editors and can pose a security risk when anyone has access to them.
#
# https://feross.org/cmsploit/
location ~* (?:#.*#|\.(?:bak|conf|dist|fla|in[ci]|log|orig|psd|sh|sql|sw[op])|~)$ {
deny all;
}
# Mitigate the risk of cross-site scripting and other content-injection
# attacks.
#
# This can be done by setting a Content Security Policy which permits
# trusted sources of content for your website.
#
# There is no policy that fits all websites, you will have to modify the
# `Content-Security-Policy` directives in the example depending on your needs.
#
# To make your CSP implementation easier, you can use an online CSP header
# generator such as:
# https://report-uri.com/home/generate/
#
# It is encouraged that you validate your CSP header using a CSP validator
# such as: https://csp-evaluator.withgoogle.com
#
# https://www.w3.org/TR/CSP/
# https://owasp.org/www-project-secure-headers/#content-security-policy
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
# https://developers.google.com/web/fundamentals/security/csp
# https://content-security-policy.com/
add_header Content-Security-Policy $content_security_policy always;
# Set a strict Permissions Policy to mitigate access to browser features.
#
# The header uses a structured syntax, and allows sites to more tightly
# restrict which origins can be granted access to features.
# The list of available features:
# https://github.com/w3c/webappsec-permissions-policy/blob/main/features.md
#
# The example policy below aims to disable all features expect synchronous
# `XMLHttpRequest` requests on the same origin.
#
# To check your Permissions Policy, you can use an online service, such as:
# https://securityheaders.com/
# https://observatory.mozilla.org/
#
# https://www.w3.org/TR/permissions-policy-1/
# https://owasp.org/www-project-secure-headers/#permissions-policy
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
# https://scotthelme.co.uk/a-new-security-header-feature-policy/
add_header Permissions-Policy $permissions_policy always;
# Set strict a Cross Origin Policy to mitigate information leakage.
#
# (1) Cross-Origin-Embedder-Policy prevents a document from loading any
# cross-origin resources that dont explicitly grant the document
# permission.
# https://html.spec.whatwg.org/multipage/origin.html#coep
# https://owasp.org/www-project-secure-headers/#cross-origin-embedder-policy
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy
#
# (2) Cross-Origin-Opener-Policy allows you to ensure a top-level document does
# not share a browsing context group with cross-origin documents.
# https://html.spec.whatwg.org/multipage/origin.html#cross-origin-opener-policies
# https://owasp.org/www-project-secure-headers/#cross-origin-opener-policy
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy
#
# (3) Cross-Origin-Resource-Policy allows to define a policy that lets web
# sites and applications opt in to protection against certain requests from
# other origins, to mitigate speculative side-channel attacks.
# https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header
# https://owasp.org/www-project-secure-headers/#cross-origin-resource-policy
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy
# https://resourcepolicy.fyi/
#
# To check your Cross Origin Policy, you can use an online service, such as:
# https://securityheaders.com/
# https://observatory.mozilla.org/
#
# https://web.dev/coop-coep/
# https://web.dev/why-coop-coep/
# https://web.dev/cross-origin-isolation-guide/
# https://scotthelme.co.uk/coop-and-coep/
add_header Cross-Origin-Embedder-Policy $coep_policy always;
add_header Cross-Origin-Opener-Policy $coop_policy always;
add_header Cross-Origin-Resource-Policy $corp_policy always;
# Serve resources with appropriate cache control directives.
#
# The `Cache-Control` header field holds directives (instructions) that control
# caching in browsers and shared caches (e.g. Proxies, CDNs).
# Its use targets web performances improvement by specifying the expected
# client and network caches behaviors.
#
# The usable cache directives are listed here:
# https://www.iana.org/assignments/http-cache-directives/http-cache-directives.xml
#
# The cache directives are documented here:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#response_directives
#
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
# https://www.rfc-editor.org/rfc/rfc9111.html
# https://www.rfc-editor.org/rfc/rfc8246.html
# https://www.rfc-editor.org/rfc/rfc5861.html
# https://www.iana.org/assignments/http-cache-directives/http-cache-directives.xml
# https://cache-tests.fyi/
add_header Cache-Control $cache_control;

View File

@ -1,7 +0,0 @@
server {
listen 8080;
server_name ${SERVER_NAME};
root /srv;
include server.conf;
}

View File

@ -1,24 +0,0 @@
[Unit]
Description=NGINX Static Web Service for %I
Wants=container-build@%i.service nginx.service nginx-proxy-http@%i.service
After=container-build@%i.service nginx.service
Before=nginx-proxy-http@%i.service
[Service]
Type=notify
NotifyAccess=all
SyslogIdentifier=%N
Restart=on-failure
Environment=PODMAN_SYSTEMD_UNIT=%n
Environment=SERVER_NAME=%i SERVICE_DATA_DIRECTORY=/data
Environment=NGINX_CONF=%E/coreos-home-server/nginx/service/%p.conf.template
ExecStartPre=/bin/podman create --replace --name %i --net internal --sdnotify=conmon --volume %i:${SERVICE_DATA_DIRECTORY}:z,ro localhost/%i:latest
ExecStartPre=/bin/sh -c "envsubst '$SERVER_NAME' < ${NGINX_CONF} > /tmp/%i.conf"
ExecStartPre=/bin/sh -c 'podman cp /tmp/%i.conf %i:/etc/nginx/conf.d/%i.conf && rm -f /tmp/%i.conf'
ExecStart=/bin/podman start --attach %i
ExecStop=/bin/podman stop --ignore --time 10 %i
ExecStopPost=/bin/podman rm --ignore --force %i
[Install]
Alias=%i.service
WantedBy=multi-user.target