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