summaryrefslogtreecommitdiff
path: root/roles
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2019-01-12 04:25:02 +0100
committerChristian Pointner <equinox@spreadspace.org>2019-01-12 04:25:02 +0100
commitad65b47f83c086096b757cc83b9e49530ed13f70 (patch)
treea2b4cdeb44cf91aa09317d06960970c1e7fbfcd8 /roles
parentadded dyndns client role (diff)
added https for elevate media server
Diffstat (limited to 'roles')
-rw-r--r--roles/acmetool/cert/filter_plugins/acme_certs.py24
-rw-r--r--roles/elevate/media/files/nginx-snippets/hsts.conf1
-rw-r--r--roles/elevate/media/files/nginx-snippets/ssl.conf10
-rw-r--r--roles/elevate/media/tasks/main.yml14
-rw-r--r--roles/elevate/media/tasks/nextcloud-config.yml4
-rw-r--r--roles/elevate/media/tasks/nextcloud.yml2
-rw-r--r--roles/elevate/media/tasks/nginx.yml75
-rw-r--r--roles/elevate/media/templates/nextcloud-nginx.conf.j215
8 files changed, 129 insertions, 16 deletions
diff --git a/roles/acmetool/cert/filter_plugins/acme_certs.py b/roles/acmetool/cert/filter_plugins/acme_certs.py
new file mode 100644
index 00000000..179f71e9
--- /dev/null
+++ b/roles/acmetool/cert/filter_plugins/acme_certs.py
@@ -0,0 +1,24 @@
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from functools import partial
+
+from ansible import errors
+
+
+def acme_cert_nonexistent(data, hostnames):
+ try:
+ return [hostnames[i] for i, d in enumerate(data) if d['stat']['exists'] == False]
+ except Exception as e:
+ raise errors.AnsibleFilterError("acme_cert_nonexistent(): %s" % str(e))
+
+
+class FilterModule(object):
+
+ ''' acme certificate filters '''
+ filter_map = {
+ 'acme_cert_nonexistent': acme_cert_nonexistent,
+ }
+
+ def filters(self):
+ return self.filter_map
diff --git a/roles/elevate/media/files/nginx-snippets/hsts.conf b/roles/elevate/media/files/nginx-snippets/hsts.conf
new file mode 100644
index 00000000..4ca8396e
--- /dev/null
+++ b/roles/elevate/media/files/nginx-snippets/hsts.conf
@@ -0,0 +1 @@
+add_header Strict-Transport-Security max-age=15768000;
diff --git a/roles/elevate/media/files/nginx-snippets/ssl.conf b/roles/elevate/media/files/nginx-snippets/ssl.conf
new file mode 100644
index 00000000..d187a7c0
--- /dev/null
+++ b/roles/elevate/media/files/nginx-snippets/ssl.conf
@@ -0,0 +1,10 @@
+ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AES:!ADH:!AECDH:!MD5;
+ssl_prefer_server_ciphers on;
+
+# openssl dhparam -out /etc/ssl/certs/dhparams.pem 2048
+ssl_dhparam /etc/ssl/dhparams.pem;
+
+ssl_session_cache shared:SSL:10m;
+ssl_session_timeout 10m;
+ssl_session_tickets off;
diff --git a/roles/elevate/media/tasks/main.yml b/roles/elevate/media/tasks/main.yml
index 7b4c6659..9633a0e1 100644
--- a/roles/elevate/media/tasks/main.yml
+++ b/roles/elevate/media/tasks/main.yml
@@ -5,19 +5,11 @@
- nginx
- python-docker
- systemd-docker
+ - python-openssl
state: present
-- name: remove nginx default config
- file:
- name: /etc/nginx/sites-enabled/default
- state: absent
- notify: restart nginx
-
-- name: install nginx config
- template:
- src: nextcloud-nginx.conf.j2
- dest: /etc/nginx/sites-enabled/nextcloud
- notify: restart nginx
+- name: configure nginx
+ import_tasks: nginx.yml
- name: install and configure nextcloud
import_tasks: nextcloud.yml
diff --git a/roles/elevate/media/tasks/nextcloud-config.yml b/roles/elevate/media/tasks/nextcloud-config.yml
index 67bb0cec..2a3c8074 100644
--- a/roles/elevate/media/tasks/nextcloud-config.yml
+++ b/roles/elevate/media/tasks/nextcloud-config.yml
@@ -47,7 +47,3 @@
- name: set up background tasks trigger to cron
command: docker exec -u www-data nextcloud.service /var/www/html/occ background:cron
changed_when: false
-
-### add this until tests have been done
-## 'overwriteprotocol' => 'http', -> /srv/nextcloud/config/nextcloud/config.php
-#
diff --git a/roles/elevate/media/tasks/nextcloud.yml b/roles/elevate/media/tasks/nextcloud.yml
index 44bdfd6d..8531699c 100644
--- a/roles/elevate/media/tasks/nextcloud.yml
+++ b/roles/elevate/media/tasks/nextcloud.yml
@@ -67,7 +67,7 @@
- /srv/ncdata/share:/srv/external
env:
NEXTCLOUD_UPDATE: '1'
- NEXTCLOUD_TRUSTED_DOMAINS: "{{ nextcloud_hostnames | join(' ') }} 89.106.211.61" ## TODO remove ip when tests are done
+ NEXTCLOUD_TRUSTED_DOMAINS: "{{ nextcloud_hostnames | join(' ') }}"
MYSQL_DATABASE: "{{ nextcloud_db.db }}"
MYSQL_HOST: "127.0.0.1:3306"
MYSQL_USER: "{{ nextcloud_db.user }}"
diff --git a/roles/elevate/media/tasks/nginx.yml b/roles/elevate/media/tasks/nginx.yml
new file mode 100644
index 00000000..fd1ed888
--- /dev/null
+++ b/roles/elevate/media/tasks/nginx.yml
@@ -0,0 +1,75 @@
+---
+## TODO: most of these steps could probably be moved to generic role
+
+- name: remove nginx default config
+ file:
+ name: /etc/nginx/sites-enabled/default
+ state: absent
+ notify: restart nginx
+
+- name: install nginx config snippets
+ copy:
+ src: "nginx-snippets/{{ item }}.conf"
+ dest: /etc/nginx/snippets/
+ with_items:
+ - ssl
+ - hsts
+ notify: restart nginx
+
+- name: generate Diffie-Hellman parameters
+ openssl_dhparam:
+ path: /etc/ssl/dhparams.pem
+ size: 2048
+ notify: restart nginx
+
+- name: install nginx config
+ template:
+ src: nextcloud-nginx.conf.j2
+ dest: /etc/nginx/sites-available/nextcloud
+ notify: restart nginx
+
+- name: check if acme certs already exist
+ stat:
+ path: "/var/lib/acme/live/{{ item }}"
+ with_items: "{{ nextcloud_hostnames }}"
+ register: acme_cert_stat
+
+- name: set acmecert_missing_hostnames variable
+ set_fact:
+ acmecert_missing_hostnames: "{{ acme_cert_stat.results | acme_cert_nonexistent(nextcloud_hostnames) }}"
+
+- name: link nonexistent hostnames to self-signed interim cert
+ when: acmecert_missing_hostnames | length > 0
+ block:
+ - name: get id of existing selfsigned interim certificate
+ command: cat /var/lib/acme/.selfsigned-interim-cert
+ changed_when: false
+ check_mode: false
+ register: selfsigned_interim_cert_id
+
+ - name: set selfsigned_interim_cert_id variable
+ set_fact:
+ selfsigned_interim_cert_id: "{{ selfsigned_interim_cert_id.stdout }}"
+
+ - name: link to snakeoil cert for nonexistent hostnames
+ file:
+ src: "../certs/{{ selfsigned_interim_cert_id }}"
+ dest: "/var/lib/acme/live/{{ item }}"
+ state: link
+ with_items: "{{ acmecert_missing_hostnames }}"
+
+- name: enable vhost config using acme cert
+ file:
+ src: ../sites-available/nextcloud
+ dest: /etc/nginx/sites-enabled/nextcloud
+ state: link
+
+- name: make sure nginx config has been (re)loaded
+ meta: flush_handlers
+
+- name: get certificate using acmetool
+ import_role:
+ name: acmetool/cert
+ vars:
+ acmetool_cert_name: "{{ nextcloud_hostnames[0] }}"
+ acmetool_cert_hostnames: "{{ nextcloud_hostnames }}"
diff --git a/roles/elevate/media/templates/nextcloud-nginx.conf.j2 b/roles/elevate/media/templates/nextcloud-nginx.conf.j2
index 0c39b4a1..50a0cdc5 100644
--- a/roles/elevate/media/templates/nextcloud-nginx.conf.j2
+++ b/roles/elevate/media/templates/nextcloud-nginx.conf.j2
@@ -6,6 +6,19 @@ server {
listen 80;
listen [::]:80;
server_name {{ nextcloud_hostnames | join(' ') }};
+ return 301 https://$host$request_uri;
+}
+
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name cloud.example.com;
+
+ include snippets/acmetool.conf;
+ include snippets/ssl.conf;
+ ssl_certificate /var/lib/acme/live/{{ nextcloud_hostnames[0] }}/fullchain;
+ ssl_certificate_key /var/lib/acme/live/{{ nextcloud_hostnames[0] }}/privkey;
+ include snippets/hsts.conf;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
@@ -78,6 +91,8 @@ server {
location ~ \.(?:css|js|woff2?|svg|gif)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
+ ## It is intended to have hsts duplicated to the one above
+ include snippets/hsts.conf;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;