# keel-web: the default site of Keel Web (handbook decisions 0030, 0042
# and 0079, the first site of Keel-Linux/tracker#51). Linked from
# sites-enabled/ by the package's postinst in place of Debian's default
# site, whose link it removes and whose file it leaves in sites-available/
# (the postrm puts the link back); taken out by
# /usr/lib/keel/overlays/anubis/state.d/50keel-web while the anubis overlay
# is enabled, when default-anubis stands here, and put back when it is
# disabled. Never edited by hand: it is a conffile, and an operator's own
# default server goes in a file of theirs.
#
# What a simple installation serves: the default server on ports 80 and
# 443, IPv6 first and IPv4 on, and on the loopback addresses of port 80.
# The content is /etc/nginx/snippets/keel-web-site.conf on all of them:
# the placeholder, or the routes of the application layer on top
# (keel-default.d). web.listen.ipv4 of 0042 is keel's to honour when it
# renders the sites; this file is static and listens on both families.
#
# Port 80 (decision 0079): while the machine's certificate is self-signed,
# port 80 serves the site as 443 does, with no redirect. So a site that
# does not control its domain name is seen to work before its name points
# to the machine and ACME gets a certificate. When the certificate is one
# that a certificate authority issued, /usr/lib/keel-web/http-mode links
# /etc/nginx/keel-web/http-redirect.conf, which the public server on port
# 80 includes: port 80 then redirects to HTTPS, except ACME's http-01
# challenges. While the certificate is self-signed the glob matches no
# file, which Nginx accepts.
#
# ACME's http-01 challenges on port 80 (keel-web 0.4.3): a route that
# serves the challenge itself keeps it. http-mode links
# /etc/nginx/keel-web/site-acme.conf to
# /etc/nginx/snippets/keel-web-acme.conf, keel-web's own location for the
# challenges, unless a file of keel-default.d has a prefix location for
# /.well-known/acme-challenge; then the glob matches no file, and the
# route serves the challenges. Two such locations in one server are a
# "duplicate location", and Nginx does not start. The redirect is
# included first, but the order has no effect: its `if` runs at server
# level, before Nginx selects a location, and Nginx selects a prefix
# location by its path, not by its place in the file. The name is not
# http-*.conf, so a copy of this file kept from keel-web 0.4.0 to 0.4.2,
# which includes the snippet by its path, does not include it twice.
#
# The loopback addresses of port 80 are this site's (default_server), not
# those of keel-overlay-nginx's conf.d/keel-health.conf, which listens
# there too and gets only a request with no Host. So http://127.0.0.1/ and
# http://[::1]/ reach the application, whatever the certificate, for the
# checks that run on the machine. Only /keel-health is answered without
# the application: 204, as keel-health.conf does, for the manifest's
# check. The loopback shares the server of port 443, which never
# redirects.
#
# TLS is the machine's certificate as turnkey-make-ssl-cert --default
# writes it, the `default` certificate of 0042: self-signed by
# keel-host-keys.service at the first boot, before Nginx starts, and
# replaced in place by the confconsole Certificate screen through ACME.
# cert.pem is the certificate, the key and the DH parameters in one file,
# the file Webmin and the machine's other services read; Nginx reads the
# certificate chain from it and the other two blocks from their own files.
# Protocols and ciphers are common's conf/turnkey.d/zz-ssl-ciphers
# (Mozilla's "intermediate"): TLS 1.2 and 1.3, forward secret ciphers
# only; no session tickets, whose key Nginx never rotates. No HSTS: over a
# self-signed certificate it locks visitors out. Nginx starts after
# keel-host-keys.service and keel-web-http.service (the package's
# nginx.service.d/keel-web.conf): without the pair it starts on neither
# port.
#
# The pages are /var/www/keel-default, a link the postinst makes to
# /usr/share/keel-web/default-site (Debian policy keeps a package's files
# out of /var/www). An operator who wants something else served while no
# site is configured replaces the link with a directory of theirs; the
# postinst leaves one that is there alone.

server {
	listen [::]:443 ssl default_server;
	listen 0.0.0.0:443 ssl default_server;
	listen [::1]:80 default_server;
	listen 127.0.0.1:80 default_server;
	http2 on;
	server_name _;
	server_tokens off;

	ssl_certificate /etc/ssl/private/cert.pem;
	ssl_certificate_key /etc/ssl/private/cert.key;
	ssl_dhparam /etc/ssl/private/dhparams.pem;
	ssl_protocols TLSv1.2 TLSv1.3;
	ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305';
	ssl_prefer_server_ciphers off;
	ssl_session_tickets off;

	# TODO(Keel-Linux/tracker#51, decision 0042 tls.hsts): add
	# Strict-Transport-Security once the confconsole Certificate screen has
	# issued a CA's certificate through ACME; never over the self-signed one.

	location = /keel-health {
		# try_files, not return, as keel-health.conf has it: return
		# answers in the rewrite phase, before Coraza sees the request.
		# No file has this name, so the answer is always the 204.
		try_files /.keel-health-is-no-file =204;
	}

	include /etc/nginx/snippets/keel-web-site.conf;
}

server {
	listen [::]:80 default_server;
	listen 0.0.0.0:80 default_server;
	server_name _;
	server_tokens off;

	# http-redirect.conf while a CA's certificate is in place, else no file
	include /etc/nginx/keel-web/http-*.conf;
	# site-acme.conf, keel-web's location for ACME's challenges, unless a
	# route of keel-default.d has its own; else no file
	include /etc/nginx/keel-web/site-acme*.conf;

	location = /keel-health {
		try_files /.keel-health-is-no-file =204;
	}

	include /etc/nginx/snippets/keel-web-site.conf;
}
