diff --git a/group_vars/all/vars.yml b/group_vars/all/vars.yml index 9b122e5..f84bf28 100644 --- a/group_vars/all/vars.yml +++ b/group_vars/all/vars.yml @@ -9,9 +9,6 @@ ### Misc settings -# Email address for Let's Encrypt and DNS -email: dogeystamp@disroot.org - # Could be sudo instead escalation_method: doas @@ -64,7 +61,12 @@ util_pack: ### Network settings (nameserver, address, etc.) -domain: d.nerdpol.ovh +# Domain to send dynamic DNS updates to +dyndns_domain: d.nerdpol.ovh + +# Domain actually used for the site (this will be set up to forward to dyndns_domain) +# Set this to the same as dyndns_domain if your registrar supports dynamic DNS natively +domain: dogeystamp.com # Forward DNS queries to dns_forward: 1.1.1.1 @@ -86,23 +88,94 @@ gateway: 192.168.0.1 # Connection interface for static IP interface: eth0 -# Email to send renewal notices to -acme_email: "{{ email }}" -# ACME directory to use -# acme_dir: "https://acme-v02.api.letsencrypt.org/directory" -acme_dir: "https://acme.zerossl.com/v2/DV90" - -# Algorithm for ACME External Account Binding -acme_eab_alg: HS256 +# Settings for templates in templates/srv_conf/ and service configs +nginx_services: + wiki: + path: "/" + navidrome: + path: "/" + gitea: + path: "/" + synapse: + # Synapse does not support a prefix path. + max_body_size: 50M + website: + path: "/" +# List of nginx server blocks + +# domain is the domain this server block listens to +# ssl_cert is the name of the SSL certificate and key (see roles/networking/ssl) +# listens sets the ports the block will listen to +# services is a list of services (templates/srv_conf/) to place in this domain + +# Ensure no two services have the same location (domain and path) + +default_listens: + - "443 ssl http2" + - "[::]:443 ssl http2" + +server_blocks: + wiki: + domain: "wiki.{{ domain }}" + ssl_cert: "{{ domain }}" + listens: "{{ default_listens }}" + services: + - wiki + + navidrome: + domain: "mus.{{ domain }}" + ssl_cert: "{{ domain }}" + listens: "{{ default_listens }}" + services: + - navidrome + + gitea: + domain: "git.{{ domain }}" + ssl_cert: "{{ domain }}" + listens: "{{ default_listens }}" + services: + - gitea + + synapse: + domain: "m.{{ domain }}" + ssl_cert: "{{ domain }}" + listens: + - "443 ssl http2" + - "[::]:443 ssl http2" + - "8448 ssl http2 default_server" + - "[::]:8448 ssl http2 default_server" + services: + - synapse + + website: + domain: "www.{{ domain }}" + ssl_cert: "{{ domain }}" + listens: "{{ default_listens }}" + services: + - website + + redirect: + domain: "{{ dyndns_domain }}" + ssl_cert: "{{ dyndns_domain }}" + listens: "{{ default_listens }}" + services: + - redirect + +# Settings for other services not handled by nginx +service_info: + coturn: + domain: "stun.{{ domain }}" + ssl_cert: "stun.{{ domain }}" + ### Mediawiki farm variables # Internal names for the wikis, used for filenames and URLs wiki_names: - - wiki + - bepp - rw @@ -131,8 +204,15 @@ form_secret: "secret" coturn_secret_key: "secret" # SSL ACME External Account Binding secrets (optional: required for some CAs) -acme_eab_kid: "secret" -acme_eab_key: "secret" + +# ZeroSSL +zerossl_acme_eab_kid: "secret" +zerossl_acme_eab_key: "secret" +# If you have a different email for ZeroSSL +zerossl_email: "you@example.com" + +# Email address for ACME and DNS +email: me@example.com diff --git a/roles/networking/ddclient/templates/ddclient.conf.j2 b/roles/networking/ddclient/templates/ddclient.conf.j2 index 669e580..ab84867 100644 --- a/roles/networking/ddclient/templates/ddclient.conf.j2 +++ b/roles/networking/ddclient/templates/ddclient.conf.j2 @@ -7,6 +7,6 @@ protocol=dyndns2 use=web, web=https://ip.me ssl=yes # yes = use https for updates server=ipv4.nsupdate.info -login={{ domain }} +login={{ dyndns_domain }} password='{{ ddclient_pass }}' -{{ domain }} +{{ dyndns_domain }} diff --git a/roles/networking/nameserver/templates/local_zone.j2 b/roles/networking/nameserver/templates/local_zone.j2 index 4494de2..29c0bfa 100644 --- a/roles/networking/nameserver/templates/local_zone.j2 +++ b/roles/networking/nameserver/templates/local_zone.j2 @@ -1,5 +1,5 @@ $TTL 604800 -@ IN SOA {{ domain }}. {{ email }}. ( +@ IN SOA {{ dyndns_domain }}. {{ email }}. ( 3 ; Serial 604800 ; Refresh 86400 ; Retry @@ -10,4 +10,4 @@ ns IN A {{ local_ip }} @ IN NS localhost. @ IN A {{ local_ip }} @ IN AAAA ::1 -{{ domain }} IN A {{ local_ip }} +{{ dyndns_domain }} IN A {{ local_ip }} diff --git a/roles/networking/nameserver/templates/named.conf.j2 b/roles/networking/nameserver/templates/named.conf.j2 index f690a0e..bfb7cf6 100644 --- a/roles/networking/nameserver/templates/named.conf.j2 +++ b/roles/networking/nameserver/templates/named.conf.j2 @@ -27,9 +27,9 @@ zone "0.0.127.in-addr.arpa" IN { file "127.0.0.zone"; }; -zone "{{ domain }}" { +zone "{{ dyndns_domain }}" { type master; - file "/var/named/{{ domain }}"; + file "/var/named/{{ dyndns_domain }}"; }; diff --git a/roles/networking/ssl/defaults/main.yml b/roles/networking/ssl/defaults/main.yml new file mode 100644 index 0000000..a7a6e16 --- /dev/null +++ b/roles/networking/ssl/defaults/main.yml @@ -0,0 +1,30 @@ +# List of domains to get an SSL cert for +# There will be a *single* certificate covering all of these +# Ensure that your CA supports multi-domain certs +ssl_domains: + - "site.dogeystamp.com" + - "d.nerdpol.ovh" + - "{{ wiki_domain }}" + +# File name for the certificate +cert_name: "{{ ssl_domains[0] }}" + +# File name for the private key +key_name: "{{ cert_name }}" + +# Account name for the account key +account_name: "account" + +# Email to send renewal notices to +acme_email: "{{ email }}" + +# ACME directory to use +# (Staging directoy by default.) +acme_dir: "https://acme-staging-v02.api.letsencrypt.org/directory" + +# SSL ACME External Account Binding settings (optional: required for some CAs) +acme_eab: { + alg: HS256, + key: "", + kid: "", +} diff --git a/roles/networking/ssl/tasks/main.yml b/roles/networking/ssl/tasks/main.yml index a09a220..11fdda2 100644 --- a/roles/networking/ssl/tasks/main.yml +++ b/roles/networking/ssl/tasks/main.yml @@ -12,19 +12,13 @@ name: sslr state: present -- name: Add turnserver to SSL read group - user: - name: "turnserver" - append: yes - groups: sslr - - name: Create directories for ACME file: path: "/etc/ssl-acme/{{ item }}" state: directory owner: root group: root - mode: 0711 + mode: 0755 with_items: - account - certs @@ -33,52 +27,52 @@ - name: Generate ACME account key community.crypto.openssl_privatekey: - path: "/etc/ssl-acme/account/account.key" + path: "/etc/ssl-acme/account/{{ account_name }}.key" owner: root group: sslr mode: 0640 - name: Generate ACME private key community.crypto.openssl_privatekey: - path: "/etc/ssl-acme/keys/{{ domain }}.key" + path: "/etc/ssl-acme/keys/{{ key_name }}.key" owner: root group: sslr mode: 0640 -- name: Check if certificate exists +- name: Check if certificate file exists stat: - path: "/etc/ssl-acme/certs/{{ domain }}.crt" + path: "/etc/ssl-acme/certs/{{ cert_name }}.crt" register: cert_file - name: Check if certificate is expired community.crypto.x509_certificate_info: - path: "/etc/ssl-acme/certs/{{ domain }}.crt" + path: "{{ cert_file.stat.path }}" valid_at: now: "+3w" - register: result when: cert_file.stat.exists + register: expired_cert - name: Determine whether the certificate should be regenerated set_fact: - cert_regen: yes - when: not cert_file.stat.exists or result.expired | bool + to_regen: "{{ ssl_domains }}" + when: not cert_file.stat.exists or not expired_cert.valid_at.now - name: Configure nginx for ACME template: src: nginx_bare.conf.j2 dest: /etc/nginx/nginx.conf - when: cert_regen is defined + when: to_regen is defined - name: Restart nginx service service: name: nginx state: restarted enabled: yes - when: cert_regen is defined + when: to_regen is defined - name: Create ACME account community.crypto.acme_account: - account_key_src: /etc/ssl-acme/account/account.key + account_key_src: "/etc/ssl-acme/account/{{ account_name }}.key" state: present allow_creation: yes contact: @@ -86,66 +80,65 @@ acme_directory: "{{ acme_dir }}" terms_agreed: 1 acme_version: 2 - external_account_binding: {alg: "{{ acme_eab_alg }}", key: "{{ acme_eab_key }}", kid: "{{ acme_eab_kid }}"} + external_account_binding: "{{ (acme_eab.key != '') | ternary(acme_eab, omit) }}" register: account - when: cert_regen is defined + when: to_regen is defined - name: Generate ACME CSR community.crypto.openssl_csr: - path: "/etc/ssl-acme/csrs/{{ domain }}.csr" - common_name: "{{ domain }}" - subject_alt_name: "DNS:{{ domain }}" - privatekey_path: "/etc/ssl-acme/keys/{{ domain }}.key" - when: cert_regen is defined + path: "/etc/ssl-acme/csrs/{{ cert_name }}.csr" + subject_alt_name: "{{ to_regen | map('regex_replace', '^', 'DNS:') | join(',') }}" + privatekey_path: "/etc/ssl-acme/keys/{{ key_name }}.key" + when: to_regen is defined - name: Retrieve ACME challenge community.crypto.acme_certificate: acme_directory: "{{ acme_dir }}" acme_version: 2 - account_key_src: /etc/ssl-acme/account/account.key + account_key_src: "/etc/ssl-acme/account/{{ account_name }}.key" account_uri: "{{ account.account_uri }}" account_email: "{{ acme_email }}" terms_agreed: 1 challenge: http-01 - csr: "/etc/ssl-acme/csrs/{{ domain }}.csr" - dest: "/etc/ssl-acme/certs/{{ domain }}.crt" - fullchain_dest: "/etc/ssl-acme/certs/fullchain_{{ domain }}.crt" + csr: "/etc/ssl-acme/csrs/{{ cert_name }}.csr" + dest: "/etc/ssl-acme/certs/{{ cert_name }}.crt" + fullchain_dest: "/etc/ssl-acme/certs/fullchain_{{ cert_name }}.crt" remaining_days: 91 register: acme_challenge - when: cert_regen is defined + when: to_regen is defined - name: Create ACME challenge directory file: - path: "{{ webroot }}/.well-known/acme-challenge" + path: "{{ webroot }}/{{ item }}/.well-known/acme-challenge" state: directory owner: root group: root mode: 0755 - when: cert_regen is defined + with_items: "{{ to_regen }}" + when: to_regen is defined - name: Add ACME challenge files copy: - content: "{{ acme_challenge['challenge_data'][item]['http-01']['resource_value'] }}" - dest: "{{ webroot }}/{{ acme_challenge['challenge_data'][item]['http-01']['resource'] }}" + content: "{{ item.value['http-01']['resource_value'] }}" + dest: "{{ webroot }}/{{ item.key }}/{{ item.value['http-01']['resource'] }}" owner: root group: root mode: 644 - with_items: - - "{{ domain }}" - when: cert_regen is defined + with_items: "{{ acme_challenge['challenge_data'] | dict2items }}" + when: to_regen is defined - name: Complete ACME challenge community.crypto.acme_certificate: acme_directory: "{{ acme_dir }}" acme_version: 2 - account_key_src: /etc/ssl-acme/account/account.key + account_key_src: "/etc/ssl-acme/account/{{ account_name }}.key" account_email: "{{ acme_email }}" account_uri: "{{ account.account_uri }}" challenge: http-01 terms_agreed: 1 - csr: "/etc/ssl-acme/csrs/{{ domain }}.csr" - dest: "/etc/ssl-acme/certs/{{ domain }}.crt" - fullchain_dest: "/etc/ssl-acme/certs/fullchain_{{ domain }}.crt" - chain_dest: "/etc/ssl-acme/certs/chain_{{ domain }}.crt" + csr: "/etc/ssl-acme/csrs/{{ cert_name }}.csr" + dest: "/etc/ssl-acme/certs/{{ cert_name }}.crt" + fullchain_dest: "/etc/ssl-acme/certs/fullchain_{{ cert_name }}.crt" + chain_dest: "/etc/ssl-acme/certs/chain_{{ cert_name }}.crt" data: "{{ acme_challenge }}" - when: cert_regen is defined + when: to_regen is defined diff --git a/roles/networking/ssl/templates/nginx_bare.conf.j2 b/roles/networking/ssl/templates/nginx_bare.conf.j2 index c16b43e..422c6d5 100644 --- a/roles/networking/ssl/templates/nginx_bare.conf.j2 +++ b/roles/networking/ssl/templates/nginx_bare.conf.j2 @@ -6,12 +6,14 @@ events { } http { + {% for item in to_regen %} server { listen 80; - server_name {{ domain }}; - root {{ webroot }}/; + server_name {{ item }}; + root {{ webroot }}/{{ item }}; location / { } } + {% endfor %} } diff --git a/roles/services/coturn/tasks/main.yml b/roles/services/coturn/tasks/main.yml index 02a1a03..c96f526 100644 --- a/roles/services/coturn/tasks/main.yml +++ b/roles/services/coturn/tasks/main.yml @@ -3,6 +3,12 @@ name: coturn state: present +- name: Add turnserver to SSL read group + user: + name: "turnserver" + append: yes + groups: sslr + - name: Get public IP address community.general.ipify_facts: diff --git a/roles/services/coturn/templates/turnserver.conf.j2 b/roles/services/coturn/templates/turnserver.conf.j2 index 03bc7b6..b71e768 100644 --- a/roles/services/coturn/templates/turnserver.conf.j2 +++ b/roles/services/coturn/templates/turnserver.conf.j2 @@ -1,7 +1,7 @@ use-auth-secret static-auth-secret={{ coturn_secret_key }} -realm={{ domain }} +realm={{ service_info.coturn.domain }} server-name=turnserver syslog @@ -34,8 +34,8 @@ user-quota=12 total-quota=1200 # TLS -cert=/etc/ssl-acme/certs/fullchain_{{ domain }}.crt -pkey=/etc/ssl-acme/keys/{{ domain }}.key +cert=/etc/ssl-acme/certs/fullchain_{{ service_info.coturn.ssl_cert }}.crt +pkey=/etc/ssl-acme/keys/{{ service_info.coturn.ssl_cert }}.key # External IP address (automatically managed: do not edit!) external-ip={{ ansible_facts.ipify_public_ip }} diff --git a/roles/services/gitea/templates/gitea_app.ini.j2 b/roles/services/gitea/templates/gitea_app.ini.j2 index ab5031d..76116a1 100644 --- a/roles/services/gitea/templates/gitea_app.ini.j2 +++ b/roles/services/gitea/templates/gitea_app.ini.j2 @@ -267,8 +267,8 @@ FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd [server] ; The protocol the server listens on. One of 'http', 'https', 'unix' or 'fcgi'. PROTOCOL = http -DOMAIN = {{ domain }} -ROOT_URL = http://{{ domain }}/git/ +DOMAIN = {{ server_blocks.gitea.domain }} +ROOT_URL = http://{{ server_blocks.gitea.domain }}{{ nginx_services.gitea.path }} ; when STATIC_URL_PREFIX is empty it will follow ROOT_URL STATIC_URL_PREFIX = ; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket. diff --git a/roles/services/navidrome/templates/navidrome.toml.j2 b/roles/services/navidrome/templates/navidrome.toml.j2 index 47003a1..30c9299 100644 --- a/roles/services/navidrome/templates/navidrome.toml.j2 +++ b/roles/services/navidrome/templates/navidrome.toml.j2 @@ -1,2 +1,2 @@ MusicFolder = "{{ dataroot }}/navidrome/mus/" -BaseUrl = "/mus" +BaseUrl = "{{ nginx_services.navidrome.path }}" diff --git a/roles/services/synapse/templates/homeserver.yaml.j2 b/roles/services/synapse/templates/homeserver.yaml.j2 index 3e9d817..eb9f894 100644 --- a/roles/services/synapse/templates/homeserver.yaml.j2 +++ b/roles/services/synapse/templates/homeserver.yaml.j2 @@ -42,7 +42,7 @@ modules: # lowercase and may contain an explicit port. # Examples: matrix.org, localhost:8080 # -server_name: "{{ domain }}" +server_name: "{{ server_blocks.synapse.domain }}" # When running as a daemon, the file to store the pid in # @@ -1059,7 +1059,7 @@ url_preview_accept_language: # The public URIs of the TURN server to give to clients # -turn_uris: [ "turn:{{ domain }}?transport=udp", "turn:{{ domain }}?transport=tcp" ] +turn_uris: [ "turn:{{ service_info.coturn.domain }}?transport=udp", "turn:{{ service_info.coturn.domain }}?transport=tcp" ] # The shared secret used to compute passwords for the TURN server # diff --git a/roles/services/webserver/tasks/main.yml b/roles/services/webserver/tasks/main.yml index 73c3780..5af956d 100644 --- a/roles/services/webserver/tasks/main.yml +++ b/roles/services/webserver/tasks/main.yml @@ -3,12 +3,30 @@ name: nginx state: present +- name: Create nginx conf.d directory + file: + path: /etc/nginx/conf.d + state: directory + - name: Configure nginx template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: Restart webserver +- name: Create nginx SSL configuration file + template: + src: ssl.conf.j2 + dest: /etc/nginx/ssl.conf + notify: Restart webserver + +- name: Create nginx server blocks + template: + src: server_block.j2 + dest: "/etc/nginx/conf.d/{{ item }}.conf" + with_items: "{{ server_blocks }}" + notify: Restart webserver + - name: Enable nginx service service: name: nginx diff --git a/roles/services/webserver/templates/nginx.conf.j2 b/roles/services/webserver/templates/nginx.conf.j2 index 3d38c3a..cdd24a0 100644 --- a/roles/services/webserver/templates/nginx.conf.j2 +++ b/roles/services/webserver/templates/nginx.conf.j2 @@ -1,95 +1,33 @@ -worker_processes 1; +user http; +worker_processes 1; events { worker_connections 1024; } -http { include mime.types; - - disable_symlinks off; - +http { + include mime.types; default_type application/octet-stream; + sendfile on; + tcp_nodelay on; + tcp_nopush on; keepalive_timeout 65; types_hash_max_size 4096; - root {{ webroot }}/; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log warn; + + gzip on; + gzip_disable "msie6"; + + include /etc/nginx/conf.d/*.conf; server { - if ($host = {{ domain }}) { - return 301 https://$host$request_uri; - } + listen 80 default_server; + + server_name _; + + return 301 https://$host$request_uri; } - - server { - - ssl_certificate /etc/ssl-acme/certs/fullchain_{{ domain }}.crt; - ssl_certificate_key /etc/ssl-acme/keys/{{ domain }}.key; - - ssl_session_cache shared:SSL:1m; - ssl_session_timeout 5m; - - ssl_ciphers HIGH:!aNULL:!MD5; - ssl_prefer_server_ciphers on; - - listen 443 ssl http2; - listen [::]:443 ssl http2; - - listen 8448 ssl http2 default_server; - listen [::]:8448 ssl http2 default_server; - - server_name {{ domain }}; - - location ~* ^(\/_matrix|\/_synapse\/client) { - proxy_pass http://localhost:8008; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $host; - - client_max_body_size 50M; - } - - location = / { - return 301 https://{{ domain }}/site/index.html; - } - - location /site { - index index.html; - } - - location /wiki { - index index.php; - } - - location /rw { - index index.php; - } - - location /git/ { - proxy_pass http://localhost:3000/ ; - } - - location /mus/ { - proxy_pass http://localhost:4533/mus/ ; - } - - location ~ \.php$ { - # 404 - try_files $fastcgi_script_name =404; - - # default fastcgi_params - include fastcgi_params; - - # fastcgi settings - fastcgi_pass unix:/run/php-fpm/php-fpm.sock; - fastcgi_index index.php; - fastcgi_buffers 8 16k; - fastcgi_buffer_size 32k; - - # fastcgi params - fastcgi_param DOCUMENT_ROOT $realpath_root; - fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; - #fastcgi_param PHP_ADMIN_VALUE "open_basedir=$base/:/usr/lib/php/:/tmp/"; - } } -} - diff --git a/roles/services/webserver/templates/server_block.j2 b/roles/services/webserver/templates/server_block.j2 new file mode 100644 index 0000000..4f6ca94 --- /dev/null +++ b/roles/services/webserver/templates/server_block.j2 @@ -0,0 +1,16 @@ +server { + ssl_certificate /etc/ssl-acme/certs/fullchain_{{ server_blocks[item].ssl_cert }}.crt; + ssl_certificate_key /etc/ssl-acme/keys/{{ server_blocks[item].ssl_cert }}.key; + + include ssl.conf; + + server_name {{ server_blocks[item].domain }}; + + {% for listener in server_blocks[item].listens %} + listen {{ listener }}; + {% endfor %} + + {% for srv in server_blocks[item].services %} + {% include "srv_conf/" + srv + ".conf.j2" %} + {% endfor %} +} diff --git a/roles/services/webserver/templates/srv_conf/gitea.conf.j2 b/roles/services/webserver/templates/srv_conf/gitea.conf.j2 new file mode 100644 index 0000000..e93eece --- /dev/null +++ b/roles/services/webserver/templates/srv_conf/gitea.conf.j2 @@ -0,0 +1,3 @@ +location {{ nginx_services[srv].path }} { + proxy_pass http://localhost:3000{{ nginx_services[srv].path }} ; +} diff --git a/roles/services/webserver/templates/srv_conf/navidrome.conf.j2 b/roles/services/webserver/templates/srv_conf/navidrome.conf.j2 new file mode 100644 index 0000000..e4a63b0 --- /dev/null +++ b/roles/services/webserver/templates/srv_conf/navidrome.conf.j2 @@ -0,0 +1,3 @@ +location {{ nginx_services[srv].path }} { + proxy_pass http://localhost:4533{{ nginx_services[srv].path }} ; +} diff --git a/roles/services/webserver/templates/srv_conf/redirect.conf.j2 b/roles/services/webserver/templates/srv_conf/redirect.conf.j2 new file mode 100644 index 0000000..5b714d7 --- /dev/null +++ b/roles/services/webserver/templates/srv_conf/redirect.conf.j2 @@ -0,0 +1 @@ +return 301 https://www.{{ domain }}$request_uri; diff --git a/roles/services/webserver/templates/srv_conf/synapse.conf.j2 b/roles/services/webserver/templates/srv_conf/synapse.conf.j2 new file mode 100644 index 0000000..dbe7319 --- /dev/null +++ b/roles/services/webserver/templates/srv_conf/synapse.conf.j2 @@ -0,0 +1,8 @@ +location ~* ^(\/_matrix|\/_synapse\/client) { + proxy_pass http://localhost:8008; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $host; + + client_max_body_size {{ nginx_services[srv].max_body_size }}; +} diff --git a/roles/services/webserver/templates/srv_conf/website.conf.j2 b/roles/services/webserver/templates/srv_conf/website.conf.j2 new file mode 100644 index 0000000..e4f5fce --- /dev/null +++ b/roles/services/webserver/templates/srv_conf/website.conf.j2 @@ -0,0 +1,4 @@ +location {{ nginx_services[srv].path }} { + root {{ webroot }}/{{ server_blocks.website.domain }}{{ nginx_services[srv].path }}; + index index.html; +} diff --git a/roles/services/webserver/templates/srv_conf/wiki.conf.j2 b/roles/services/webserver/templates/srv_conf/wiki.conf.j2 new file mode 100644 index 0000000..78731f7 --- /dev/null +++ b/roles/services/webserver/templates/srv_conf/wiki.conf.j2 @@ -0,0 +1,17 @@ +location {{ nginx_services[srv].path }} { + index index.php; +} + +location ~ \.php$ { + try_files $fastcgi_script_name = 404; + + include fastcgi_params; + + fastcgi_pass unix:/run/php-fpm/php-fpm.sock; + fastcgi_index index.php; + fastcgi_buffers 8 16k; + fastcgi_buffer_size 32k; + + fastcgi_param DOCUMENT_ROOT $realpath_root; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; +} diff --git a/roles/services/webserver/templates/ssl.conf.j2 b/roles/services/webserver/templates/ssl.conf.j2 new file mode 100644 index 0000000..8d52242 --- /dev/null +++ b/roles/services/webserver/templates/ssl.conf.j2 @@ -0,0 +1,7 @@ +# General SSL settings + +ssl_session_cache shared:SSL:1m; +ssl_session_timeout 5m; + +ssl_ciphers HIGH:!aNULL:!MD5; +ssl_prefer_server_ciphers on; diff --git a/roles/services/website/tasks/main.yml b/roles/services/website/tasks/main.yml index cda0979..e4bb7f4 100644 --- a/roles/services/website/tasks/main.yml +++ b/roles/services/website/tasks/main.yml @@ -1,3 +1,11 @@ +- name: Set site path + set_fact: + path: "{{ server_blocks.website.domain }}{{ nginx_services.website.path }}" + +- name: Set full root + set_fact: + fullroot: "{{ webroot }}/{{ path }}" + - name: Install required packages community.general.pacman: name: @@ -25,13 +33,13 @@ file: group: http owner: http - path: "{{ webroot }}/site/" + path: "{{ fullroot }}" state: directory register: site_folder - name: Deploy source to web root shell: - cmd: "./ssg6 src {{ webroot }}/site/ 'dogeystamp' 'https://{{ domain }}/site'" + cmd: "./ssg6 src {{ fullroot }} '{{ web_name }}' 'https://{{ path }}'" chdir: /srv/web_source when: site_source.changed or site_folder.changed or site_perm.changed become_user: http @@ -42,4 +50,4 @@ name: "Update and deploy website source" minute: 0 hour: "*/12" - job: "git -C /srv/web_source/ pull && /srv/web_source/ssg6 /srv/web_source/src {{ webroot }}/site/ '{{ web_name }}' 'https://{{ domain }}/site'" + job: "git -C /srv/web_source/ pull && /srv/web_source/ssg6 /srv/web_source/src {{ fullroot }} '{{ web_name }}' 'https://{{ path }}'" diff --git a/roles/services/wiki/tasks/main.yml b/roles/services/wiki/tasks/main.yml index 2f627e7..7389216 100644 --- a/roles/services/wiki/tasks/main.yml +++ b/roles/services/wiki/tasks/main.yml @@ -9,23 +9,32 @@ state: present -- name: Symlink wikis into web root +- name: Set wiki root + set_fact: + wiki_root: "{{ webroot }}/{{ server_blocks.wiki.domain }}{{ nginx_services.wiki.path }}" + +- name: Create wiki web root + file: + path: "{{ wiki_root }}" + state: directory + +- name: Symlink wikis into wiki web root file: src: /usr/share/webapps/mediawiki - dest: "{{ webroot }}/{{ item }}" + dest: "{{ wiki_root }}/{{ item }}" state: link with_items: "{{ wiki_names }}" - name: Deploy wiki-farm main configuration file template: src: LocalSettings.php.j2 - dest: "{{ webroot }}/{{ wiki_names[0] }}/LocalSettings.php" + dest: "{{ wiki_root }}/{{ wiki_names[0] }}/LocalSettings.php" mode: u=rwx,g=r,o=r - name: Deploy configuration files for individual wikis template: src: "LocalSettings_{{ item.1 }}.php.j2" - dest: "{{ webroot }}/{{ wiki_names[0] }}/LocalSettings_{{ item.1 }}.php" + dest: "{{ wiki_root }}/{{ wiki_names[0] }}/LocalSettings_{{ item.1 }}.php" with_indexed_items: "{{ wiki_names }}" - name: Ensure correct permissions on data @@ -37,7 +46,7 @@ - name: Copy wiki logo files copy: src: "{{ item }}" - dest: "{{ webroot }}/{{ wiki_names[0] }}/resources/assets/" + dest: "{{ wiki_root }}/{{ wiki_names[0] }}/resources/assets/" with_fileglob: - logos/*.png diff --git a/roles/services/wiki/templates/LocalSettings_wiki.php.j2 b/roles/services/wiki/templates/LocalSettings_bepp.php.j2 similarity index 100% rename from roles/services/wiki/templates/LocalSettings_wiki.php.j2 rename to roles/services/wiki/templates/LocalSettings_bepp.php.j2 diff --git a/run.yml b/run.yml index f1270cd..0c8c017 100644 --- a/run.yml +++ b/run.yml @@ -65,11 +65,47 @@ - mail when: enable_mail + # Main SSL certificate (with Let's Encrypt) - role: networking/ssl tags: - ssl + acme_dir: "https://acme-v02.api.letsencrypt.org/directory" + cert_name: "{{ domain }}" + ssl_domains: + - "{{ server_blocks.wiki.domain }}" + - "{{ server_blocks.synapse.domain }}" + - "{{ server_blocks.website.domain }}" + - "{{ server_blocks.gitea.domain }}" + - "{{ server_blocks.navidrome.domain }}" + account_name: "letsencrypt" when: enable_ssl + # SSL cert for dyndns_domain + - role: networking/ssl + tags: + - ssl + acme_dir: "https://acme-v02.api.letsencrypt.org/directory" + ssl_domains: + - "{{ dyndns_domain }}" + account_name: "letsencrypt" + when: enable_ssl and dyndns_domain != domain + + # ZeroSSL certificate for Coturn (see https://bugs.chromium.org/p/webrtc/issues/detail?id=11710) + - role: networking/ssl + tags: + - ssl + acme_dir: "https://acme.zerossl.com/v2/DV90" + ssl_domains: + - "{{ service_info.coturn.domain }}" + acme_eab: { + alg: HS256, + key: "{{ zerossl_acme_eab_key }}", + kid: "{{ zerossl_acme_eab_kid }}" + } + acme_email: "{{ zerossl_email }}" + account_name: "zerossl" + when: enable_ssl and enable_coturn + - role: services/webserver tags: - webserver