From 5a9e8dda437f7ae68113ca91940c1d032880a83e Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Mon, 13 May 2019 17:25:35 +0200
Subject: [PATCH] Multiple fixes after deployment on open.audio

---
 README.md                              | 57 ++++++++++++++++++++++++--
 handlers/main.yml                      |  2 +
 tasks/funkwhale.yml                    | 16 ++++++--
 tasks/main.yml                         |  6 +++
 tasks/services.yml                     |  1 +
 templates/funkwhale-process.service.j2 |  2 +
 templates/nginx.conf.j2                | 56 +++++++++++--------------
 7 files changed, 100 insertions(+), 40 deletions(-)

diff --git a/README.md b/README.md
index 24a2d4c..9c7123a 100644
--- a/README.md
+++ b/README.md
@@ -13,13 +13,44 @@ Using this role, you can install and upgrade a Funkwhale pod, closely matching o
 - Install and configure Funkwhale and it's dependencies
 - Install and configure a SSL certificate with Let's Encrypt (optional)
 
-Usage
------
+Installation and usage
+----------------------
 
-Add the following to your playbook:
+Install ansible:
+
+```
+pip install --user ansible
+```
+
+Create a directory for ansible files:
+
+    mkdir ~/ansible-funkwhale
+    cd ansible-funkwhale
+
+Create a playbook requirements and inventory file:
+
+    touch requirements.yml
+    touch playbook.yml
+    touch inventory.ini
+
+Add the following to `requirements.yml`:
+
+```
+- src: git+https://dev.funkwhale.audio/funkwhale/ansible
+  name: funkwhale
+  version: master
+```
+
+Install the role:
+
+```
+ansible-galaxy install -r requirements.yml
+```
+
+Add the following to `playbook.yml`:
 
 ```yaml
-- hosts: servers
+- hosts: funkwhale-servers
   roles:
     - role: funkwhale
       funkwhale_hostname: yourdomain.funkwhale
@@ -29,6 +60,24 @@ Add the following to your playbook:
 
 See below for a full documentation on available variables.
 
+Add your server to `inventory.ini`:
+
+```ini
+[funkwhale-servers]
+your-server-ip-or-domain
+```
+
+Launch the installation (in check mode, so nothing is applied):
+
+```
+ansible-playbook --ask-become-pass -i inventory.ini playbook.yml --check --diff
+```
+*On some hosts, you may need to install the `python-apt` package for check mode to work*.
+
+This command will show you the changes that would be applied to your system. If you are confortable with them,
+rerun the same command without the `--check` flag.
+
+
 Role Variables
 --------------
 
diff --git a/handlers/main.yml b/handlers/main.yml
index efd098f..d15f22d 100644
--- a/handlers/main.yml
+++ b/handlers/main.yml
@@ -1,10 +1,12 @@
 ---
 - name: restart funkwhale
+  become: true
   service:
     name: funkwhale.target
     state: restarted
 
 - name: reload nginx
+  become: true
   service:
     name: nginx
     state: reloaded
diff --git a/tasks/funkwhale.yml b/tasks/funkwhale.yml
index f67d9ff..0fc178b 100644
--- a/tasks/funkwhale.yml
+++ b/tasks/funkwhale.yml
@@ -1,6 +1,7 @@
 ---
 
 - name: "Create funkwhale user"
+  become: true
   user:
     name: "{{ funkwhale_username }}"
     shell: /bin/false
@@ -33,18 +34,29 @@
   register: result_secret_key_generation
 
 - name: "Create django_secret_key file"
-  when: result_django_secret_key.stat.exists == False
+  when: not ansible_check_mode and result_django_secret_key.stat.exists == False
   become: true
   become_user: "{{ funkwhale_username }}"
   copy:
     content: "{{ result_secret_key_generation.stdout }}"
     dest: "{{ funkwhale_config_path }}/django_secret_key"
 
+- name: "Setup a dummy secret key"
+  when: ansible_check_mode
+  set_fact:
+    django_secret_key: "dummy_secret_key_for_check_mode"
+
 - name: "Retrieve secret key from {{ funkwhale_config_path }}/django_secret_key"
+  when: not ansible_check_mode
   slurp:
     src: "{{ funkwhale_config_path }}/django_secret_key"
   register: secret_key
 
+- name: "Register secret key"
+  when: not ansible_check_mode
+  set_fact:
+    django_secret_key: "{{ secret_key['content'] | b64decode }}"
+
 - name: "Create funkwhale configuration file"
   become: true
   become_user: "{{ funkwhale_username }}"
@@ -53,8 +65,6 @@
     dest: "{{ funkwhale_config_path }}/.env"
     owner: "{{ funkwhale_username }}"
     mode: 0600
-  vars:
-    django_secret_key: "{{ secret_key['content'] | b64decode }}"
   notify:
     - restart funkwhale
 
diff --git a/tasks/main.yml b/tasks/main.yml
index 8e07106..6bafe0b 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,7 +1,13 @@
 ---
 - include: packages.yml
+  tags: [packages]
 - include: db.yml
+  tags: [db]
 - include: redis.yml
+  tags: [redis]
 - include: funkwhale.yml
+  tags: [funkwhale]
 - include: services.yml
+  tags: [services]
 - include: nginx.yml
+  tags: [nginx]
diff --git a/tasks/services.yml b/tasks/services.yml
index b2fd166..e1123d6 100644
--- a/tasks/services.yml
+++ b/tasks/services.yml
@@ -30,6 +30,7 @@
 
 - name: "Start and enable {{ funkwhale_systemd_service_name }}-* services"
   when: funkwhale_nginx_managed
+  become: true
   systemd:
     name: "{{ item }}"
     enabled: true
diff --git a/templates/funkwhale-process.service.j2 b/templates/funkwhale-process.service.j2
index d1c6f45..030c49b 100644
--- a/templates/funkwhale-process.service.j2
+++ b/templates/funkwhale-process.service.j2
@@ -5,6 +5,8 @@ After={{ funkwhale_systemd_after }}
 PartOf={{ funkwhale_systemd_service_name }}.target
 
 [Service]
+Restart=on-failure
+RestartSec=10
 User={{ funkwhale_username }}
 WorkingDirectory={{ funkwhale_install_path }}/api
 EnvironmentFile={{ funkwhale_config_path }}/.env
diff --git a/templates/nginx.conf.j2 b/templates/nginx.conf.j2
index cc12cfb..48893b1 100644
--- a/templates/nginx.conf.j2
+++ b/templates/nginx.conf.j2
@@ -1,20 +1,12 @@
 # {{ ansible_managed }}
-{% if funkwhale_protocol == 'https' %}
+{% if funkwhale_protocol == 'https' -%}
 server {
     listen 80;
+    listen [::]:80;
     server_name {{ funkwhale_hostname }};
-
-    {% if funkwhale_letsencrypt_enabled %}
-    location /.well-known/acme-challenge {
-        root /var/www/letsencrypt;
-        try_files $uri $uri/ =404;
-    }
-    {% endif %}
-    location / {
-        rewrite ^ https://{{ funkwhale_hostname }}$request_uri? permanent;
-    }
+    location / { return 301 https://$host$request_uri; }
 }
-{% endif %}
+{% endif -%}
 
 # required for websocket support
 map $http_upgrade $connection_upgrade {
@@ -23,30 +15,28 @@ map $http_upgrade $connection_upgrade {
 }
 
 server {
-    listen {% if funkwhale_protocol == 'https' %}443 ssl{% else %}80{% endif %};
+    listen {% if funkwhale_protocol == 'https' %}443 ssl{% else %}80{% endif %} http2;
+    listen [::]:{% if funkwhale_protocol == 'https' %}443 ssl{% else -%}80{% endif %} http2;
     server_name {{ funkwhale_hostname }};
-
-    {% if funkwhale_letsencrypt_enabled %}
-    location /.well-known/acme-challenge {
-        root /var/www/letsencrypt;
-        try_files $uri $uri/ =404;
-    }
-    {% endif %}
-    {% if funkwhale_protocol == 'https' %}
-    {% if funkwhale_ssl_key_path %}
+    {% if funkwhale_protocol == 'https' -%}
+    {% if funkwhale_ssl_key_path -%}
     ssl_certificate {{ funkwhale_ssl_cert_path }};
     ssl_certificate_key {{ funkwhale_ssl_key_path }};
-    {% else %}
+    {% else -%}
     ssl_certificate /ect/lectsencrypt/live/{{ funkwhale_hostname }}/fullchain.pem;
     ssl_certificate_key /ect/lectsencrypt/live/{{ funkwhale_hostname }}/privkey.pem;
-    {% endif %}
-    ssl_session_cache shared:le_nginx_SSL:1m;
-    ssl_session_timeout 1440m;
-    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+    {% endif -%}
+    # from https://cipherli.st/
     ssl_prefer_server_ciphers on;
-    ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA";
-    add_header Strict-Transport-Security "max-age=31536000";
-    {% endif %}
+    ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
+    ssl_ecdh_curve secp384r1;
+    ssl_session_timeout  10m;
+    ssl_session_cache shared:SSL:10m;
+    ssl_session_tickets off;
+    ssl_stapling on;
+    ssl_stapling_verify on;
+    add_header Strict-Transport-Security "max-age=63072000; preload";
+    {% endif -%}
 
     root {{ funkwhale_install_path }}/front/dist;
 
@@ -111,14 +101,14 @@ server {
         alias {{ funkwhale_media_path }}/;
     }
 
-    {% if funkwhale_external_storage_enabled %}
+    {% if funkwhale_external_storage_enabled -%}
     # Comment the previous location and uncomment this one if you're storing
     # media files in a S3 bucket
     location ~ /_protected/media/(.+) {
         internal;
         proxy_pass $1;
     }
-    {% else %}
+    {% else -%}
     location /_protected/media {
         # this is an internal location that is used to serve
         # audio files once correct permission / authentication
@@ -126,7 +116,7 @@ server {
         internal;
         alias   {{ funkwhale_media_path }};
     }
-    {% endif %}
+    {% endif -%}
 
     location /_protected/music {
         # this is an internal location that is used to serve
-- 
GitLab