Initial commit
This commit is contained in:
commit
d8ec69086d
12 changed files with 306 additions and 0 deletions
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Ansible Collection - s3lph.webserver
|
||||||
|
|
||||||
|
WIP
|
65
galaxy.yml
Normal file
65
galaxy.yml
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
### REQUIRED
|
||||||
|
# The namespace of the collection. This can be a company/brand/organization or product namespace under which all
|
||||||
|
# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with
|
||||||
|
# underscores or numbers and cannot contain consecutive underscores
|
||||||
|
namespace: s3lph
|
||||||
|
|
||||||
|
# The name of the collection. Has the same character restrictions as 'namespace'
|
||||||
|
name: webserver
|
||||||
|
|
||||||
|
# The version of the collection. Must be compatible with semantic versioning
|
||||||
|
version: 0.1
|
||||||
|
|
||||||
|
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
|
||||||
|
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>
|
||||||
|
|
||||||
|
|
||||||
|
### OPTIONAL but strongly recommended
|
||||||
|
# A short summary description of the collection
|
||||||
|
description: Webserver, Apache, 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
|
||||||
|
|
||||||
|
# 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:
|
||||||
|
- email
|
||||||
|
- mailserver
|
||||||
|
- postfix
|
||||||
|
- dovecot
|
||||||
|
- postfixadmin
|
||||||
|
- postsrsd
|
||||||
|
|
||||||
|
# Collections that this collection requires to be installed for it to be usable. The key of the dict is the
|
||||||
|
# collection label 'namespace.name'. The value is a version range
|
||||||
|
# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version
|
||||||
|
# range specifiers can be set and are separated by ','
|
||||||
|
dependencies:
|
||||||
|
community.general: "2.2.0"
|
||||||
|
|
||||||
|
# The URL of the originating SCM repository
|
||||||
|
repository: https://gitlab.com/s3lph/ansible-collection-webserver
|
||||||
|
|
||||||
|
# The URL to any online docs
|
||||||
|
documentation: https://gitlab.com/s3lph/ansible-collection-webserver
|
||||||
|
|
||||||
|
# The URL to the homepage of the collection/project
|
||||||
|
homepage: https://gitlab.com/s3lph/ansible-collection-webserver
|
||||||
|
|
||||||
|
# The URL to the collection issue tracker
|
||||||
|
issues: https://gitlab.com/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: []
|
||||||
|
|
31
roles/apache2/defaults/main.yml
Normal file
31
roles/apache2/defaults/main.yml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
apache2_vhost_serveradmin: root@localhost
|
||||||
|
apache2_vhost_serveraliases: []
|
||||||
|
apache2_vhost_documentroot: /var/www/html
|
||||||
|
apache2_vhost_loglevel: warn
|
||||||
|
apache2_vhost_errorlog: "${APACHE_LOG_DIR}/error.log"
|
||||||
|
apache2_vhost_accesslog: "${APACHE_LOG_DIR}/access.log combined"
|
||||||
|
|
||||||
|
apache2_vhost_http_enabled: true
|
||||||
|
apache2_vhost_https_enabled: true
|
||||||
|
apache2_vhost_http_redirect_to_https: true
|
||||||
|
|
||||||
|
apache2_tls_certfile: "/etc/letsencrypt/live/{{ inventory_hostname }}/fullchain.pem"
|
||||||
|
apache2_tls_keyfile: "/etc/letsencrypt/live/{{ inventory_hostname }}/privkey.pem"
|
||||||
|
apache2_tls_noacme_fallback_certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||||
|
apache2_tls_noacme_fallback_keyfile: /etc/ssl/private/ssl-cert-snakeoil.key
|
||||||
|
# generated 2021-04-22, Mozilla Guideline v5.6, Apache 2.4.41, OpenSSL 1.1.1d, intermediate configuration, no OCSP
|
||||||
|
# https://ssl-config.mozilla.org/#server=apache&version=2.4.41&config=intermediate&openssl=1.1.1d&ocsp=false&guideline=5.6
|
||||||
|
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"
|
||||||
|
apache2_tls_honor_cipher_order: false
|
||||||
|
apache2_tls_session_tickets: false
|
||||||
|
|
||||||
|
apache2_modules:
|
||||||
|
- ssl
|
||||||
|
- proxy_http
|
||||||
|
- headers
|
||||||
|
- rewrite
|
||||||
|
|
||||||
|
apache2_sites: {}
|
11
roles/apache2/handlers/main.yml
Normal file
11
roles/apache2/handlers/main.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: restart apache2
|
||||||
|
service:
|
||||||
|
name: apache2
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: reload apache2
|
||||||
|
service:
|
||||||
|
name: apache2
|
||||||
|
state: reloaded
|
52
roles/apache2/tasks/config.yml
Normal file
52
roles/apache2/tasks/config.yml
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: enable apache2 modules
|
||||||
|
community.general.apache2_module:
|
||||||
|
name: "{{ item }}"
|
||||||
|
loop: "{{ apache2_modules }}"
|
||||||
|
notify: restart apache2
|
||||||
|
|
||||||
|
- name: flush handlers
|
||||||
|
meta:
|
||||||
|
flush_handlers: {}
|
||||||
|
|
||||||
|
- name: check for tls keypair existence
|
||||||
|
stat:
|
||||||
|
path: "{{ item }}"
|
||||||
|
follow: yes
|
||||||
|
loop: |
|
||||||
|
{%- set files = [] -%}
|
||||||
|
{%- for name, site in apache2_sites | dict2items -%}
|
||||||
|
{%- if site.https_enabled | default(apache2_vhost_https_enabled) -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- set _x = files.append(site.tls_certfile | default(apache2_tls_certfile)) -%}
|
||||||
|
{%- set _x = files.append(site.tls_keytfile | default(apache2_tls_keyfile)) -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{{- files | unique | list -}}
|
||||||
|
register: apache2_register_stat_tls_keypairs
|
||||||
|
|
||||||
|
- name: render apache site configs
|
||||||
|
template:
|
||||||
|
src: etc/apache2/sites-available/site.conf.j2
|
||||||
|
dest: "/etc/apache2/sites-available/{{ item.key }}.conf"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
vars:
|
||||||
|
name: "{{ item.key }}"
|
||||||
|
site: "{{ item.value }}"
|
||||||
|
certfile_exists: "{{ apache2_register_stat_tls_keypairs[item.value.tls_certfile | default(apache2_tls_certfile)].stat.exists }}"
|
||||||
|
keyfile_exists: "{{ apache2_register_stat_tls_keypairs[item.value.tls_keyfile | default(apache2_tls_keyfile)].stat.exists }}"
|
||||||
|
loop: "{{ apache2_sites | dict2items }}"
|
||||||
|
notify: reload apache2
|
||||||
|
|
||||||
|
- name: enable apache2 sites
|
||||||
|
file:
|
||||||
|
path: "/etc/apache2/sites-enabled/{{ item }}.conf"
|
||||||
|
state: link
|
||||||
|
src: "../sites-available/{{ item }}.conf"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0777
|
||||||
|
loop: "{{ apache2_sites }}"
|
||||||
|
notify: reload apache2
|
13
roles/apache2/tasks/install.yml
Normal file
13
roles/apache2/tasks/install.yml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: install apache2 and related packages
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- apache2
|
||||||
|
- ssl-cert # snakeoil cert used for optional tls bootstrapping
|
||||||
|
|
||||||
|
- name: start and enable apache2
|
||||||
|
service:
|
||||||
|
name: apache2
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
11
roles/apache2/tasks/main.yml
Normal file
11
roles/apache2/tasks/main.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- import_tasks: install.yml
|
||||||
|
tags:
|
||||||
|
- "role::apache2"
|
||||||
|
- "role::apache2:install"
|
||||||
|
|
||||||
|
- import_tasks: config.yml
|
||||||
|
tags:
|
||||||
|
- "role::apache2"
|
||||||
|
- "role::apache2:config"
|
|
@ -0,0 +1,55 @@
|
||||||
|
{{ ansible_managed | comment }}
|
||||||
|
|
||||||
|
{% if site.http_enabled | default(apache2_vhost_http_enabled) %}
|
||||||
|
<VirtualHost *:80>
|
||||||
|
|
||||||
|
ServerAdmin {{ site.serveradmin | default(apache2_vhost_serveradmin) }}
|
||||||
|
ServerName {{ name }}
|
||||||
|
{% for alias in site.aliases %}
|
||||||
|
ServerAlias {{ alias }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
LogLevel {{ site.loglevel | default(apache2_vhost_loglevel) }}
|
||||||
|
ErrorLog {{ site.errorlog | default(apache2_vhost_errorlog) }}
|
||||||
|
CustomLog {{ site.accesslog | default(apache2_vhost_accesslog) }}
|
||||||
|
|
||||||
|
{% if site.http_redirect_to_https | default(apache2_vhost_http_redirect_to_https) %}
|
||||||
|
Redirect permanent / https://{{ name }}/
|
||||||
|
{% else %}
|
||||||
|
DocumentRoot {{ site.documentroot | default(apache2_vhost_documentroot) }}
|
||||||
|
|
||||||
|
{{ site.additional_config | indent(8) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</VirtualHost>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if site.https_enabled | default(apache2_vhost_https_enabled) %}
|
||||||
|
<VirtualHost *:443>
|
||||||
|
|
||||||
|
ServerAdmin {{ site.serveradmin | default(apache2_vhost_serveradmin) }}
|
||||||
|
ServerName {{ name }}
|
||||||
|
{% for alias in site.aliases %}
|
||||||
|
ServerAlias {{ alias }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
LogLevel {{ site.loglevel | default(apache2_vhost_loglevel) }}
|
||||||
|
ErrorLog {{ site.errorlog | default(apache2_vhost_errorlog) }}
|
||||||
|
CustomLog {{ site.accesslog | default(apache2_vhost_accesslog) }}
|
||||||
|
|
||||||
|
SSLEngine on
|
||||||
|
{% if certfile_exists and keyfile_exists %}
|
||||||
|
SSLCertificateFile {{ site.tls_certfile | default(apache2_tls_certfile) }}
|
||||||
|
SSLCertificateKeyFile {{ site.tls_keyfile | default(apache2_tls_keyfile) }}
|
||||||
|
{% else %}
|
||||||
|
SSLCertificateFile {{ apache2_tls_noacme_fallback_certfile }}
|
||||||
|
SSLCertificateKeyFile {{ apache2_tls_noacme_fallback_keyfile }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
DocumentRoot {{ site.documentroot | default(apache2_vhost_documentroot) }}
|
||||||
|
|
||||||
|
{{ site.additional_config | indent(8) }}
|
||||||
|
|
||||||
|
</VirtualHost>
|
||||||
|
{% endif %}
|
9
roles/certbot/defaults/main.yml
Normal file
9
roles/certbot/defaults/main.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
certbot_webroot: /var/www/html
|
||||||
|
certbot_rsa_key_size: 4096
|
||||||
|
certbot_email: null
|
||||||
|
certbot_acme_server: "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
|
certbot_challenge: webroot
|
||||||
|
|
||||||
|
certbot_certificates: {}
|
7
roles/certbot/tasks/install.yml
Normal file
7
roles/certbot/tasks/install.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: install certbot
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- certbot
|
||||||
|
|
38
roles/certbot/tasks/issue.yml
Normal file
38
roles/certbot/tasks/issue.yml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: issue certificates
|
||||||
|
command: >-
|
||||||
|
/usr/bin/certbot certonly
|
||||||
|
--server {{ cert.server | default(certbot_acme_server) }}
|
||||||
|
--agree-tos
|
||||||
|
{% if cert.email | default(certbot_email) is none %}
|
||||||
|
--register-unsafely-without-email
|
||||||
|
{% else %}
|
||||||
|
--email {{ cert.email | default(certbot_email) }}
|
||||||
|
{% endif %}
|
||||||
|
--cert-name {{ name }}
|
||||||
|
--rsa-key-size {{ cert.rsa_key_size | default(certbot_rsa_key_size) }}
|
||||||
|
|
||||||
|
{% if cert.challenge | default(certbot_challenge) == 'webroot' %}
|
||||||
|
|
||||||
|
--webroot
|
||||||
|
{% if cert.webroot_map is defined %}
|
||||||
|
--webroot-map '{{ cert.webroot_map | to_json(width=99999) }}'
|
||||||
|
{% else %}
|
||||||
|
--webroot {{ cert.webroot }}
|
||||||
|
{% for domain in cert.domains | default([name]) %}
|
||||||
|
--domain {{ domain }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
--{{ cert.challenge | default(certbot_challenge) }}
|
||||||
|
{{ cert.challenge_freeform_arguments }}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
creates: "/etc/letsencrypt/live/{{ name }}/fullchain.pem"
|
||||||
|
vars:
|
||||||
|
name: "{{ item.key }}"
|
||||||
|
cert: "{{ item.value }}"
|
||||||
|
loop: "{{ certbot_certificates | dict2items }}"
|
11
roles/certbot/tasks/main.yml
Normal file
11
roles/certbot/tasks/main.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- import_tasks: install.yml
|
||||||
|
tags:
|
||||||
|
- "role::certbot"
|
||||||
|
- "role::certbot:install"
|
||||||
|
|
||||||
|
- import_tasks: issue.yml
|
||||||
|
tags:
|
||||||
|
- "role::certbot"
|
||||||
|
- "role::certbot:issue"
|
Loading…
Reference in a new issue