major cleanup
All checks were successful
Ansible Lint / build (push) Successful in 1m24s
Ansible Galaxy / deploy (push) Successful in 2m8s

This commit is contained in:
s3lph 2024-08-11 03:39:26 +02:00
parent 76f918111a
commit aeef456223
26 changed files with 240 additions and 323 deletions

8
.ansible-lint Normal file
View file

@ -0,0 +1,8 @@
---
skip_list:
- meta-runtime[unsupported-version]
- galaxy[no-changelog]
- galaxy[version-incorrect]
- name[casing]
- var-naming[no-role-prefix]

View file

@ -0,0 +1,29 @@
---
name: Ansible Galaxy
on: # noqa yaml[truthy]
push:
tags:
- 'v*'
jobs:
deploy:
runs-on: docker
steps:
- uses: actions/checkout@v4
- name: Set version in galaxy.yml
run: |
VERSION=${GITHUB_REF#refs/tags/v}
sed -re "s/^version:.*$/version: ${VERSION}/" -i galaxy.yml
- name: Upload collection to Ansible Galaxy
env:
GALAXY_API_KEY: ${{ secrets.GALAXY_API_KEY }}
run: |
apt update; apt install --yes python3-pip
pip3 install --break-system-packages ansible
ansible-galaxy collection build
ansible-galaxy collection publish --api-key=${GALAXY_API_KEY} s3lph-webserver*tar.gz

View file

@ -0,0 +1,17 @@
---
name: Ansible Lint
on: [push, pull_request] # noqa yaml[truthy]
jobs:
build:
runs-on: docker
steps:
- uses: actions/checkout@v4
- run: |
apt update; apt install --yes python3-pip
pip3 install --break-system-packages ansible-lint
ansible-lint

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
s3lph-webserver*.tar.gz

View file

@ -1,3 +1,73 @@
# Ansible Collection - s3lph.webserver
WIP
Configure Apache2 and Certbot, with an auto-bootstrap mechanism.
## Usage Examples
### Multi-VHost Setup with Let's Encrypt Certificates
We start with the following playbook:
```yaml
- hosts: webserver
roles:
- s3lph.webserver.apache2
- s3lph.webserver.certbot
```
To configure our VHosts, we create a hostvars file, e.g. `host_vas/web01.example.org/apache2.yml`:
```yaml
apache2_sites:
# This simply serves /var/www/foo.example.org/html under the vhost foo.example.org.
foo.example.org:
documentroot: /var/www/foo.example.org/html
tls_certfile: /etc/letsencrypt/live/foo.example.org/fullchain.pem
tls_keyfile: /etc/letsencrypt/live/foo.example.org/privkey.pem
# A simple reverse-proxy example
bar.example.org:
aliases:
- baz.example.org
documentroot: /var/www/bar.example.org/html
tls_certfile: /etc/letsencrypt/live/bar.example.org/fullchain.pem
tls_keyfile: /etc/letsencrypt/live/bar.example.org/privkey.pem
# You can add any Apache2 config to the VHost config
additional_config: |
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
```
To tell the certbot role which certificates to issue, create another hostvars file such as `host_vas/web01.example.org/certbot.yml`:
```yaml
certbot_certificates:
foo.example.org:
webroot_map:
foo.example.org: /var/www/foo.example.org/html
bar.example.org:
webroot_map:
bar.example.org: /var/www/bar.example.org/html
baz.example.org: /var/www/bar.example.org/html
```
### Bootstrap
The bootstrap mechanism works in two steps:
- When the configured certificate files do not exist yet, the apache2 role instead uses Debian's default "snakeoil" certificate, resulting in a valid configuration, but using self-signed certificates.
- After the ACME challenge has been completed - which can be done with invalid certs - and the Apache2 role is applied a second time, it now configures the certificates issued by Let's Encrypt.
This can either be achieved by running the playbook from the previous example twice, or by invoking the Apache2 role twice in the same playbook (but in a second play):
```yaml
- hosts: webserver
roles:
- s3lph.webserver.apache2
- s3lph.webserver.certbot
- hosts: webserver
roles:
- s3lph.webserver.apache2
```

View file

@ -16,7 +16,7 @@ readme: README.md
# A list of the collection's content authors. Can be just the name or in the format 'Full Name <email> (url)
# @nicks:irc/im.site#channel'
authors:
- s3lph <account-gitlab-ideynizv@kernelpanic.lol>
- s3lph <s3lph@kabelsalat.ch>
### OPTIONAL but strongly recommended
@ -26,14 +26,14 @@ description: Webserver, Apache, Nginx, Lets Encrypt, ACME, Certbot
# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only
# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file'
license:
- MIT
- MIT
# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character
# requirements as 'namespace' and 'name'
tags:
- application
- webserver
- apache2
- nginx
- letsencrypt
- certbot
@ -45,20 +45,19 @@ dependencies:
community.general: ">=2.2.0"
# The URL of the originating SCM repository
repository: https://gitlab.com/s3lph/ansible-collection-webserver
repository: https://git.kabelsalat.ch/s3lph/ansible-collection-webserver
# The URL to any online docs
documentation: https://gitlab.com/s3lph/ansible-collection-webserver
documentation: https://git.kabelsalat.ch/s3lph/ansible-collection-webserver
# The URL to the homepage of the collection/project
homepage: https://gitlab.com/s3lph/ansible-collection-webserver
homepage: https://git.kabelsalat.ch/s3lph/ansible-collection-webserver
# The URL to the collection issue tracker
issues: https://gitlab.com/s3lph/ansible-collection-webserver/-/issues
issues: https://git.kabelsalat.ch/s3lph/ansible-collection-webserver/issues
# A list of file glob-like patterns used to filter any files or directories that should not be included in the build
# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This
# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry',
# and '.git' are always filtered
build_ignore: []

52
meta/runtime.yml Normal file
View file

@ -0,0 +1,52 @@
---
# Collections must specify a minimum required ansible version to upload
# to galaxy
requires_ansible: '>=2.15'
# Content that Ansible needs to load from another location or that has
# been deprecated/removed
# plugin_routing:
# action:
# redirected_plugin_name:
# redirect: ns.col.new_location
# deprecated_plugin_name:
# deprecation:
# removal_version: "4.0.0"
# warning_text: |
# See the porting guide on how to update your playbook to
# use ns.col.another_plugin instead.
# removed_plugin_name:
# tombstone:
# removal_version: "2.0.0"
# warning_text: |
# See the porting guide on how to update your playbook to
# use ns.col.another_plugin instead.
# become:
# cache:
# callback:
# cliconf:
# connection:
# doc_fragments:
# filter:
# httpapi:
# inventory:
# lookup:
# module_utils:
# modules:
# netconf:
# shell:
# strategy:
# terminal:
# test:
# vars:
# Python import statements that Ansible needs to load from another location
# import_redirection:
# ansible_collections.ns.col.plugins.module_utils.old_location:
# redirect: ansible_collections.ns.col.plugins.module_utils.new_location
# Groups of actions/modules that take a common set of options
# action_groups:
# group_name:
# - module1
# - module2

3
roles/apache2/README.md Normal file
View file

@ -0,0 +1,3 @@
# s3lph.webserver.apache2
See collection readme for usage info.

View file

@ -20,7 +20,7 @@ apache2_tls_noacme_fallback_keyfile: /etc/ssl/private/ssl-cert-snakeoil.key
# generated 2024-08-10, Mozilla Guideline v5.7, Apache 2.4.61, OpenSSL 3.0.13, intermediate configuration, no OCSP
# https://ssl-config.mozilla.org/#server=apache&version=2.4.61&config=intermediate&openssl=3.0.13&ocsp=false&guideline=5.7
apache2_tls_protocols: "all -SSLv3 -TLSv1 -TLSv1.1"
apache2_tls_ciphersuite: "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"
apache2_tls_ciphersuite: "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" # noqa yaml[line-length]
apache2_tls_honor_cipher_order: false
apache2_tls_session_tickets: false

View file

@ -1,11 +1,11 @@
---
- name: restart apache2
service:
- name: Restart Apache2
ansible.builtin.service:
name: apache2
state: restarted
- name: reload apache2
service:
- name: Reload Apache2
ansible.builtin.service:
name: apache2
state: reloaded

View file

@ -1,17 +1,18 @@
---
- name: enable apache2 modules
- name: Enable Apache2 modules
community.general.apache2_module:
name: "{{ item }}"
loop: "{{ apache2_modules }}"
notify: restart apache2
notify: Restart Apache2
- meta: flush_handlers
- name: Flush handlers
ansible.builtin.meta: flush_handlers
- name: check for tls keypair existence
- name: Check for TLS keypair existence
ansible.builtin.stat:
path: "{{ item }}"
follow: yes
path: "{{ item }}"
follow: true
loop: |
{%- set files = [] -%}
{%- for name, site in apache2_sites.items() -%}
@ -23,31 +24,33 @@
{{- files | unique | list -}}
register: apache2_register_stat_tls_keypairs
- name: create apache document roots
- name: Create Apache2 document roots
ansible.builtin.file:
path: "{{ item.documentroot | default(apache2_vhost_documentroot) }}"
state: directory
owner: "{{ item.documentroot_owner | default(apache2_vhost_documentroot_owner) }}"
group: "{{ item.documentroot_group | default(apache2_vhost_documentroot_group) }}"
mode: 0755
mode: "0755"
loop: "{{ apache2_sites.values() }}"
- name: render apache site configs
- name: Render Apache2 site configs
ansible.builtin.template:
src: etc/apache2/sites-available/site.conf.j2
dest: "/etc/apache2/sites-available/{{ item.key }}.conf"
owner: root
group: root
mode: 0644
mode: "0644"
vars:
name: "{{ item.key }}"
site_name: "{{ item.key }}"
site: "{{ item.value }}"
certfile_exists: "{{ (apache2_register_stat_tls_keypairs.results | selectattr('item', 'equalto', (item.value.tls_certfile | default(apache2_tls_certfile)) ))[0].stat.exists }}"
keyfile_exists: "{{ (apache2_register_stat_tls_keypairs.results | selectattr('item', 'equalto', (item.value.tls_certfile | default(apache2_tls_keyfile)) ))[0].stat.exists }}"
certfile_name: "{{ item.value.tls_certfile | default(apache2_tls_certfile) }}"
keyfile_name: "{{ item.value.tls_certfile | default(apache2_tls_keyfile) }}"
certfile_exists: "{{ (apache2_register_stat_tls_keypairs.results | selectattr('item', 'equalto', certfile_name))[0].stat.exists }}"
keyfile_exists: "{{ (apache2_register_stat_tls_keypairs.results | selectattr('item', 'equalto', keyfile_name))[0].stat.exists }}"
loop: "{{ apache2_sites | dict2items }}"
notify: reload apache2
notify: Reload Apache2
- name: enable apache2 sites
- name: Enable Apache2 sites
ansible.builtin.file:
path: "/etc/apache2/sites-enabled/{{ item }}.conf"
state: link
@ -55,4 +58,4 @@
owner: root
group: root
loop: "{{ apache2_sites.keys() }}"
notify: reload apache2
notify: Reload apache2

View file

@ -1,17 +1,17 @@
---
- name: install apache2 and related packages
- name: Install Apache2 and related packages
ansible.builtin.apt:
name:
- apache2
- ssl-cert # snakeoil cert used for optional tls bootstrapping
- name: install apache2 and related packages
- name: Install Apache2 and related packages
ansible.builtin.apt:
name: "{{ apache2_module_packages }}"
- name: start and enable apache2
- name: Start and enable Apache2
ansible.builtin.service:
name: apache2
state: started
enabled: yes
enabled: true

View file

@ -1,11 +1,13 @@
---
- ansible.builtin.import_tasks: install.yml
- name: Install Apache2
ansible.builtin.import_tasks: install.yml
tags:
- "role::apache2"
- "role::apache2:install"
- ansible.builtin.import_tasks: config.yml
- name: Configure Apache2
ansible.builtin.import_tasks: config.yml
tags:
- "role::apache2"
- "role::apache2:config"

View file

@ -4,7 +4,7 @@
<VirtualHost *:80>
ServerAdmin {{ site.serveradmin | default(apache2_vhost_serveradmin) }}
ServerName {{ name }}
ServerName {{ site_name }}
{% for alias in site.aliases | default(apache2_vhost_serveraliases) %}
ServerAlias {{ alias }}
{% endfor %}
@ -14,7 +14,7 @@
CustomLog {{ site.accesslog | default(apache2_vhost_accesslog) }}
{% if site.http_redirect_to_https | default(apache2_vhost_http_redirect_to_https) %}
Redirect permanent / https://{{ name }}/
Redirect permanent / https://{{ site_name }}/
{% else %}
DocumentRoot {{ site.documentroot | default(apache2_vhost_documentroot) }}
@ -31,7 +31,7 @@
<VirtualHost *:443>
ServerAdmin {{ site.serveradmin | default(apache2_vhost_serveradmin) }}
ServerName {{ name }}
ServerName {{ site_name }}
{% for alias in site.aliases | default(apache2_vhost_serveraliases) %}
ServerAlias {{ alias }}
{% endfor %}

3
roles/certbot/README.md Normal file
View file

@ -0,0 +1,3 @@
# s3lph.webserver.certbot
See collection readme for usage info.

View file

@ -1,7 +1,6 @@
---
- name: install certbot
- name: Install certbot
ansible.builtin.apt:
name:
- certbot

View file

@ -1,6 +1,6 @@
---
- name: issue certificates
- name: Issue certificates
ansible.builtin.command: >-
/usr/bin/certbot certonly
--server {{ cert.server | default(certbot_acme_server) }}
@ -10,7 +10,7 @@
{% else %}
--email {{ cert.email | default(certbot_email) }}
{% endif %}
--cert-name {{ name }}
--cert-name {{ cert_name }}
--rsa-key-size {{ cert.rsa_key_size | default(certbot_rsa_key_size) }}
{% if cert.challenge | default(certbot_challenge) == 'webroot' %}
@ -20,20 +20,20 @@
--webroot-map '{{ cert.webroot_map | to_json }}'
{% else %}
--webroot {{ cert.webroot }}
{% for domain in cert.domains | default([name]) %}
{% for domain in cert.domains | default([cert_name]) %}
--domain {{ domain }}
{% endfor %}
{% endif %}
{% else %}
--{{ cert.challenge | default(certbot_challenge) }}
{{ cert.challenge_freeform_arguments }}
{% endif %}
args:
creates: "/etc/letsencrypt/live/{{ name }}/fullchain.pem"
creates: "/etc/letsencrypt/live/{{ cert_name }}/fullchain.pem"
vars:
name: "{{ item.key }}"
cert_name: "{{ item.key }}"
cert: "{{ item.value }}"
loop: "{{ certbot_certificates | dict2items }}"

View file

@ -1,11 +1,13 @@
---
- ansible.builtin.import_tasks: install.yml
- name: Install certbot
ansible.builtin.import_tasks: install.yml
tags:
- "role::certbot"
- "role::certbot:install"
- ansible.builtin.import_tasks: issue.yml
- name: Issue certificates
ansible.builtin.import_tasks: issue.yml
tags:
- "role::certbot"
- "role::certbot:issue"

View file

@ -1,25 +0,0 @@
---
nginx_vhost_serveraliases: []
nginx_vhost_documentroot: /var/www/html
nginx_vhost_documentroot_owner: www-data
nginx_vhost_documentroot_group: www-data
nginx_vhost_http_enabled: true
nginx_vhost_https_enabled: true
nginx_vhost_http_redirect_to_https: true
nginx_tls_certfile: "/etc/letsencrypt/live/{{ inventory_hostname }}/fullchain.pem"
nginx_tls_keyfile: "/etc/letsencrypt/live/{{ inventory_hostname }}/privkey.pem"
nginx_tls_noacme_fallback_certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem
nginx_tls_noacme_fallback_keyfile: /etc/ssl/private/ssl-cert-snakeoil.key
# generated 2022-02-26, Mozilla Guideline v5.6, nginx 1.18.0, OpenSSL 1.1.1k, intermediate configuration, no OCSP
# https://ssl-config.mozilla.org/#server=nginx&version=1.18.0&config=intermediate&openssl=1.1.1k&ocsp=false&guideline=5.6
nginx_ssl_protocols: "TLSv1.2 TLSv1.3"
nginx_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"
nginx_ssl_prefer_server_ciphers: false
nginx_ssl_session_tickets: false
nginx_modules: []
nginx_sites: {}

View file

@ -1,11 +0,0 @@
---
- name: restart nginx
service:
name: nginx
state: restarted
- name: reload nginx
service:
name: nginx
state: reloaded

View file

@ -1,62 +0,0 @@
---
- name: enable nginx modules
ansible.builtin.file:
path: "/etc/nginx/modules-enabled/50-mod-{{ item }}.conf"
state: link
src: "/usr/share/nginx/modules-available/mod-{{ item }}.conf"
owner: root
group: root
loop: "{{ nginx_modules }}"
notify: restart nginx
- ansible.builtin.meta: flush_handlers
- name: check for tls keypair existence
ansible.builtin.stat:
path: "{{ item }}"
follow: yes
loop: |
{%- set files = [] -%}
{%- for name, site in nginx_sites.items() -%}
{%- if site.https_enabled | default(nginx_vhost_https_enabled) -%}
{%- set _x = files.append(site.tls_certfile | default(nginx_tls_certfile)) -%}
{%- set _x = files.append(site.tls_keyfile | default(nginx_tls_keyfile)) -%}
{%- endif -%}
{%- endfor -%}
{{- files | unique | list -}}
register: nginx_register_stat_tls_keypairs
- name: create nginx document roots
ansible.builtin.file:
path: "{{ item.documentroot | default(nginx_vhost_documentroot) }}"
state: directory
owner: "{{ item.documentroot_owner | default(nginx_vhost_documentroot_owner) }}"
group: "{{ item.documentroot_group | default(nginx_vhost_documentroot_group) }}"
mode: 0755
loop: "{{ nginx_sites.values() }}"
- name: render nginx site configs
ansible.builtin.template:
src: etc/nginx/sites-available/site.conf.j2
dest: "/etc/nginx/sites-available/{{ item.key }}.conf"
owner: root
group: root
mode: 0644
vars:
name: "{{ item.key }}"
site: "{{ item.value }}"
certfile_exists: "{{ (nginx_register_stat_tls_keypairs.results | selectattr('item', 'equalto', (item.value.tls_certfile | default(nginx_tls_certfile)) ))[0].stat.exists }}"
keyfile_exists: "{{ (nginx_register_stat_tls_keypairs.results | selectattr('item', 'equalto', (item.value.tls_certfile | default(nginx_tls_keyfile)) ))[0].stat.exists }}"
loop: "{{ nginx_sites | dict2items }}"
notify: reload nginx
- name: enable nginx sites
ansible.builtin.file:
path: "/etc/nginx/sites-enabled/{{ item }}.conf"
state: link
src: "/etc/nginx/sites-available/{{ item }}.conf"
owner: root
group: root
loop: "{{ nginx_sites.keys() }}"
notify: reload nginx

View file

@ -1,22 +0,0 @@
---
- name: install nginx and related packages
ansible.builtin.apt:
name:
- nginx
- ssl-cert # snakeoil cert used for optional tls bootstrapping
- name: deploy ffdhe2048 dhparams
ansible.builtin.template:
src: etc/nginx/dh_param
dest: /etc/nginx/dh_param
owner: root
group: root
mode: 0644
notify: reload nginx
- name: start and enable nginx
ansible.builtin.service:
name: nginx
state: started
enabled: yes

View file

@ -1,11 +0,0 @@
---
- ansible.builtin.import_tasks: install.yml
tags:
- "role::nginx"
- "role::nginx:install"
- ansible.builtin.import_tasks: config.yml
tags:
- "role::nginx"
- "role::nginx:config"

View file

@ -1,8 +0,0 @@
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----

View file

@ -1,65 +0,0 @@
{{ ansible_managed | comment }}
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_dhparam /etc/nginx/dh_param;
ssl_protocols {{ nginx_ssl_protocols }};
ssl_ciphers {{ nginx_ssl_ciphers }};
ssl_prefer_server_ciphers {{ nginx_ssl_prefer_server_ciphers }};
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

View file

@ -1,67 +0,0 @@
{{ ansible_managed | comment }}
{% if site.http_enabled | default(nginx_vhost_http_enabled) %}
server {
listen 80{% if site.default_server | default(false) %} default_server{% endif %};
listen [::]:80{% if site.default_server | default(false) %} default_server{% endif %};
server_name {{ name }}{% for alias in site.aliases | default(nginx_vhost_serveraliases) %} {{ alias }}{% endfor %};
{% if site.http_redirect_to_https | default(nginx_vhost_http_redirect_to_https) %}
location / {
return 301 https://$host$request_uri;
}
{% else %}
root {{ site.documentroot | default(nginx_vhost_documentroot) }};
{% if site.php_proxy is defined %}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass {{ site.php_proxy }};
fastcgi_index index.php;
include fastcgi_params;
}
{% endif %}
{{ site.additional_config | indent(4) }}
{% endif %}
}
{% endif %}
{% if site.https_enabled | default(nginx_vhost_https_enabled) %}
server {
listen 443 ssl http2{% if site.default_server | default(false) %} default_server{% endif %};
listen [::]:443 ssl http2{% if site.default_server | default(false) %} default_server{% endif %};
server_name {{ name }}{% for alias in site.aliases | default(nginx_vhost_serveraliases) %} {{ alias }}{% endfor %};
{% if certfile_exists and keyfile_exists %}
ssl_certificate {{ site.tls_certfile | default(nginx_tls_certfile) }};
ssl_certificate_key {{ site.tls_keyfile | default(nginx_tls_keyfile) }};
{% else %}
ssl_certificate {{ nginx_tls_noacme_fallback_certfile }};
ssl_certificate_key {{ nginx_tls_noacme_fallback_keyfile }};
{% endif %}
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
root {{ site.documentroot | default(nginx_vhost_documentroot) }};
{% if site.php_proxy is defined %}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass {{ site.php_proxy }};
fastcgi_index index.php;
include fastcgi_params;
}
{% endif %}
{{ site.additional_config | indent(4) }}
}
{% endif %}