Import nginx types from e-Durable's cdist repositories

This commit is contained in:
fnux 2021-06-22 13:46:32 +02:00
parent af66c7e753
commit 41cf480b25
No known key found for this signature in database
GPG key ID: 4502C902C00A1E12
17 changed files with 495 additions and 0 deletions

View file

@ -0,0 +1,40 @@
cdist-type__recycledcloud_nginx(7)
===================================
NAME
----
cdist-type__recycledcloud_nginx - Serve web content with NGINX
DESCRIPTION
-----------
Leverages `__recycledcloud_nginx_vhost` to serve web content.
REQUIRED PARAMETERS
-------------------
domain
Domain name to be served.
OPTIONAL PARAMETERS
-------------------
config
Custom NGINX logic, templated within a standard `server` section with
`server_name` and TLS parameters set. Defaults to simple static hosting.
altdomains
Alternative domain names for this vhost and related TLS certificate.
uacme-hookscript
Custom hook passed to the __uacme_obtain type: useful to integrate the
dns-01 challenge with third-party DNS providers.
AUTHORS
-------
Timothée Floure <timothee.floure@posteo.net>
COPYING
-------
Copyright \(C) 2020 Joachim Desroches. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

View file

@ -0,0 +1,76 @@
#!/bin/sh
os="$(cat "${__global:?}"/explorer/os)"
case "$os" in
alpine)
nginx_user=nginx
nginx_certdir=/etc/nginx/ssl
;;
debian|ubuntu)
nginx_user=www-data
nginx_certdir=/etc/nginx/ssl
;;
*)
echo "This type does not support $os yet. Aborting." >&2;
exit 1;
;;
esac
if [ -f "${__object:?}/parameter/domain" ];
then
domain="$(cat "${__object:?}/parameter/domain")"
else
domain="${__object_id:?}"
fi
altdomains=
if [ -f "${__object:?}/parameter/altdomains" ];
then
altdomains="$(cat "${__object:?}/parameter/altdomains")"
fi
set_custom_uacme_hookscript=
if [ -f "${__object:?}/parameter/uacme-hookscript" ];
then
uacme_hookscript="$(cat "${__object:?}/parameter/uacme-hookscript")"
set_custom_uacme_hookscript="--hookscript $uacme_hookscript"
fi
# Deploy simple HTTP vhost, allowing to serve ACME challenges.
__recycledcloud_nginx_vhost "301-to-https-$domain" \
--domain "$domain" --altdomains "$altdomains" --to-https
# Obtaining TLS cert.
cert_ownership=$nginx_user
if [ -f "${__object:?}/parameter/force-cert-ownership-to" ]; then
cert_ownership=$(cat "${__object:?}/parameter/force-cert-ownership-to")
fi
__uacme_account
# shellcheck disable=SC2086
require="__recycledcloud_nginx_vhost/301-to-https-$domain __uacme_account" \
__uacme_obtain "$domain" \
--altdomains "$altdomains" \
$set_custom_uacme_hookscript \
--owner "$cert_ownership" \
--install-key-to "$nginx_certdir/$domain/privkey.pem" \
--install-cert-to "/$nginx_certdir/$domain/fullchain.pem" \
--renew-hook "service nginx reload"
# Deploy HTTPS nginx vhost.
if [ -f "${__object:?}/parameter/config" ]; then
if [ "$(cat "${__object:?}/parameter/config")" = "-" ]; then
nginx_logic="${__object:?}/stdin"
else
nginx_logic="${__object:?}/parameter/config"
fi
mkdir -p "${__object:?}/files"
cat "$nginx_logic" > "${__object:?}/files/config"
require="__uacme_obtain/$domain" __recycledcloud_nginx_vhost "$domain" \
--altdomains "$altdomains" --config "${__object:?}/files/config"
else
require="__uacme_obtain/$domain" __recycledcloud_nginx_vhost "$domain" \
--altdomains "$altdomains"
fi

View file

@ -0,0 +1 @@
80

View file

@ -0,0 +1 @@
443

View file

@ -0,0 +1,5 @@
config
domain
altdomains
uacme-hookscript
force-cert-ownership-to

View file

@ -0,0 +1,4 @@
# Redirect request to this page in HTTPS.
location / {
return 301 https://$host$request_uri;
}

View file

@ -0,0 +1,37 @@
#!/bin/sh
# Template for static NGINX hosting.
echo 'server {'
# Listen
cat <<- EOF
listen ${LPORT:?} $TLS;
listen [::]:${LPORT:?} $TLS;
EOF
# Name
echo "server_name ${DOMAIN:?} $ALTDOMAINS;"
# ACME challenges.
cat << EOF
location /.well-known/acme-challenge/ {
alias ${ACME_CHALLENGE_DIR:?};
}
EOF
if [ -n "$TLS" ];
then
if [ -n "$HSTS" ];
then
echo 'include snippets/hsts;'
fi
cat <<- EOF
ssl_certificate ${NGINX_CERTDIR:?}/${DOMAIN:?}/fullchain.pem;
ssl_certificate_key ${NGINX_CERTDIR:?}/${DOMAIN:?}/privkey.pem;
EOF
fi
echo "${NGINX_LOGIC:?}"
echo '}'

View file

@ -0,0 +1 @@
add_header Strict-Transport-Security "max-age=31536000" always;

View file

@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>cdist configured!</title>
</head>
<body>
You have successfully configured a vhost with
<a href="https://cdi.st">cdist</a>. You can now upload content!
</body>
</html>

View file

@ -0,0 +1,13 @@
#!/bin/sh
# Template for static NGINX hosting.
NGINX_LOGIC="$(cat << EOF
location / {
root ${NGINX_WEBROOT:?}/${DOMAIN:?};
index index.html;
}
EOF
)"
export NGINX_LOGIC
"${__type:?}/files/generic.conf.sh"

View file

@ -0,0 +1,25 @@
#!/bin/sh
# Template for HTTPS redirection.
echo 'server {'
# Listen
cat <<- EOF
listen ${LPORT:?};
listen [::]:${LPORT:?};
EOF
# Name
echo "server_name ${DOMAIN:?} $ALTDOMAINS;"
# ACME challenges.
cat << EOF
location /.well-known/acme-challenge/ {
alias ${ACME_CHALLENGE_DIR:?};
}
EOF
# HTTPS redirection.
echo 'include snippets/301-to-https;'
echo '}'

View file

@ -0,0 +1,26 @@
#!/bin/sh
os="$(cat "${__global:?}"/explorer/os)"
case "$os" in
alpine)
reload_hook="service nginx --ifstopped start;\
service nginx --ifstarted reload"
;;
debian|ubuntu|*)
reload_hook="systemctl reload-or-restart nginx"
;;
esac
# Check configuration and reload if valid.
# TODO: only check if configuration was changed (= listen for __file's
# messages).
cat << EOF
if nginx -t; then
$reload_hook
else
echo "NGINX configuration is invalid. Exiting." >2&
nginx -t >2&
exit 1
fi
EOF

View file

@ -0,0 +1,83 @@
cdist-type__nginx_vhost(7)
===================================
NAME
----
cdist-type__nginx_vhost - Have nginx serve content for a virtual host
DESCRIPTION
-----------
This type setups up nginx with reasonable defaults and creates a vhost to be
served, optionally with TLS certificates obtained from the Let's Encrypt CA
through the ACME HTTP-01 challenge-response mechanism.
By default, if no rules are specified, then the vhost will serve as-is the
contents of the `WEBROOT/foo.com` directory, where WEBROOT is
determined depending on the OS, adhering as close to `hier(7)` as possible.
NGINX expects files in the vhost to be served to be at least readable by the
`USER` group, that it creates if it does not exist. It is recommended to have
the user owning the files to be someone else, and the files beeing
group-readable but not writeable.
Finally, if TLS is not disabled, then this type makes nginx expect the
fullchain certificate and the private key in
`CERTDIR/domain/{fullchain,privkey}.pem`.
+------------------+---------+-------------------+-----------------------------+
| Operating System | USER | WEBROOT | CERTDIR |
+==================+=========+===================+=============================+
| Alpine Linux | `nginx` | `/srv/www/` | `/etc/nginx/ssl/` |
+------------------+---------+-------------------+-----------------------------+
| Arch Linux | `www` | `/srv/www/` | `/etc/nginx/ssl/` |
+------------------+---------+-------------------+-----------------------------+
| FreeBSD | `www` | `/usr/local/www/` | `/usr/local/etc/nginx/ssl/` |
+------------------+---------+-------------------+-----------------------------+
OPTIONAL PARAMETERS
-------------------
config
A custom configuration file for the vhost, inserted in a server section
populated with `server_name` and TLS parameters unless `--standalone-config`
is specified. Can be specified either as a file path, or if the value of this
flag is '-', then the configuration is read from stdin.
domain
The domain this server will respond to. If this is omitted, then the
`__object_id` is used.
lport
The port to which we listen. If this is omitted, the defaults of `80` for
HTTP and `443` for HTTPS are used.
altdomains
Alternative domain names for this vhost.
BOOLEAN PARAMETERS
------------------
no-hsts
Do not use HSTS pinning.
no-tls
Do not serve over HTTPS.
to-https
Ignore --config flag and redirect to HTTPS. Implies --no-tls.
standalone-config
Insert the content of
AUTHORS
-------
Joachim Desroches <joachim.desroches@epfl.ch>
Timothée Floure <timothee.floure@posteo.net>
COPYING
-------
Copyright \(C) 2020 Joachim Desroches. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

View file

@ -0,0 +1,162 @@
#!/bin/sh
#
# 2020 Joachim Desroches <joachim.desroches@epfl.ch>
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
# Create NGINX vhosts
os="$(cat "${__global:?}"/explorer/os)"
mkdir -p "${__object:?}/files"
case "$os" in
alpine)
__package nginx
nginx_confdir="/etc/nginx"
install_reqs="__package/nginx"
require="$install_reqs" __start_on_boot nginx
export NGINX_SITEDIR="$nginx_confdir/conf.d"
export NGINX_CERTDIR="$nginx_confdir/ssl"
export NGINX_SNIPPETSDIR="$nginx_confdir/snippets"
export NGINX_WEBROOT="/var/www"
export ACME_CHALLENGE_DIR="$NGINX_WEBROOT/.well-known/acme-challenge/"
;;
debian|ubuntu)
__package nginx
nginx_confdir="/etc/nginx"
install_reqs="__package/nginx"
export NGINX_SITEDIR="$nginx_confdir/sites-enabled"
export NGINX_CERTDIR="$nginx_confdir/ssl"
export NGINX_SNIPPETSDIR="$nginx_confdir/snippets"
export NGINX_WEBROOT="/var/www"
export ACME_CHALLENGE_DIR="$NGINX_WEBROOT/.well-known/acme-challenge/"
;;
*)
echo "This type does not support $os yet. Aborting." >&2;
exit 1;
esac
# Domain
if [ -f "${__object:?}/parameter/domain" ];
then
DOMAIN="$(cat "${__object:?}/parameter/domain")"
else
DOMAIN="${__object_id:?}"
fi
export DOMAIN
ALTDOMAINS=
if [ -f "${__object:?}/parameter/altdomains" ];
then
ALTDOMAINS="$(cat "${__object:?}/parameter/altdomains")"
fi
export ALTDOMAINS
# Use TLS ?
if [ -f "${__object:?}/parameter/no-tls" ];
then
TLS=
echo "WARNING: you have disabled TLS for vhost $DOMAIN" >&2
else
TLS=ssl
fi
export TLS
# Use HSTS ?
if [ -f "${__object:?}/parameter/no-hsts" ];
then
HSTS=
else
HSTS=true
fi
export HSTS
# Redirect to HTTPS ?
if [ -f "${__object:?}/parameter/to-https" ];
then
TO_HTTPS=true
else
TO_HTTPS=
fi
export HSTS
# Port to listen on
if [ -f "${__object:?}/parameter/lport" ];
then
LPORT="$(cat "${__object:?}/parameter/lport")"
else
if [ -n "$TLS" ] && [ -z "$TO_HTTPS" ];
then
LPORT=443
else
LPORT=80
fi
fi
export LPORT
# Server definition
if [ -n "$TO_HTTPS" ];
then
# Ignore configuration, simply serve ACME challenge and redirect to HTTPS.
"${__type:?}/files/to-https.conf.sh" > "${__object:?}/files/vhost.conf"
vhost_conf="${__object:?}/files/vhost.conf"
elif [ -f "${__object:?}/parameter/config" ];
then
# Extract nginx config from type parameter.
if [ "$(cat "${__object:?}/parameter/config")" = "-" ];
then
vhost_partial="${__object:?}/stdin"
else
vhost_partial=$(cat "${__object:?}/parameter/config")
fi
# Either use config as-in or template it in generic vhost structure.
if [ -f "${__object:?}/parameter/standalone-config" ]; then
vhost_conf=$vhost_partial
else
NGINX_LOGIC=$(cat "$vhost_partial") "${__type:?}/files/generic.conf.sh" \
> "${__object:?}/files/vhost.conf"
vhost_conf="${__object:?}/files/vhost.conf"
fi
else
# Default to simple static configuration.
"${__type:?}/files/static.conf.sh" > "${__object:?}/files/vhost.conf"
vhost_conf="${__object:?}/files/vhost.conf"
require="$install_reqs" __directory "$NGINX_WEBROOT/$DOMAIN"
require="__directory$NGINX_WEBROOT/$DOMAIN" \
__file "$NGINX_WEBROOT/$DOMAIN/index.html" --state exists \
--source "${__type:?}/files/index.html" \
--mode 0644
fi
# Install snippets.
require="$install_reqs" __directory "$NGINX_SNIPPETSDIR"
for snippet in hsts 301-to-https; do
require="__directory/$NGINX_SNIPPETSDIR" __file \
"$NGINX_SNIPPETSDIR/$snippet" --source "${__type:?}/files/$snippet"
done
# Install vhost.
require="$install_reqs" __file "$NGINX_SITEDIR/$__object_id.conf" \
--source "$vhost_conf" \
--mode 0644

View file

@ -0,0 +1,4 @@
no-tls
no-hsts
to-https
standalone-config

View file

@ -0,0 +1 @@
index.html index.htm

View file

@ -0,0 +1,4 @@
domain
config
altdomains
lport