diff --git a/webapps/hedgedoc/defaults/main.yml b/webapps/hedgedoc/defaults/main.yml index f49ce18f..cff858b3 100644 --- a/webapps/hedgedoc/defaults/main.yml +++ b/webapps/hedgedoc/defaults/main.yml @@ -2,11 +2,12 @@ # defaults file for mastodon system_dep: "['apt-transport-https', 'postgresql', 'python3-psycopg2', 'nginx', 'git', 'wget', 'certbot']" git_url: 'https://github.com/hedgedoc/hedgedoc.git' -git_version: '1.9.6' -node_version: 'node_16.x' +git_version: '1.9.7' +node_version: 'node_16.x' # Node 18 is NOT supported as of May 2023; See https://docs.hedgedoc.org/setup/manual-setup/ node_port: '3000' service: 'example' domains: ['example.domain.org'] +certbot_admin_email: 'mgauthier@evolix.ca' db_host: 'localhost' db_user: "{{ service }}" diff --git a/webapps/hedgedoc/tasks/main.yml b/webapps/hedgedoc/tasks/main.yml index 700bf9d7..cf2a9864 100644 --- a/webapps/hedgedoc/tasks/main.yml +++ b/webapps/hedgedoc/tasks/main.yml @@ -4,10 +4,14 @@ - name: Install main system dependencies apt: name: "{{ system_dep }}" + update_cache: yes -- name: Install node-gyp from yarn +- name: Install node-gyp from npm shell: npm install --global node-gyp +- name: Enable yarn (via corepack) + shell: "corepack enable; yarn set version classic" + - name: Add UNIX account user: name: "{{ service }}" @@ -34,6 +38,10 @@ version: "{{ git_version | default(omit) }}" update: yes umask: '0022' +# - name: Set cache dir for yarn +# shell: yarn config set cache-folder /var/tmp/cache/yarn +# args: +# chdir: "~/" - name: Run setup shell: "bin/setup" args: @@ -70,7 +78,12 @@ - name: Start service service: name: "{{ service }}.service" - state: started + state: restarted + +- name: Template nginx snippet for Let's Encrypt/Certbot + template: + src: "letsencrypt.conf.j2" + dest: "/etc/nginx/snippets/letsencrypt.conf" - name: Check if SSL certificate is present and register result stat: @@ -81,7 +94,7 @@ block: - name: Template vhost without SSL for successfull LE challengce template: - src: "vhost.j2" + src: "vhost.conf.j2" dest: "/etc/nginx/sites-available/{{ service }}" - name: Enable temporary nginx vhost for LE file: @@ -97,9 +110,18 @@ path: /var/lib/letsencrypt state: directory mode: '0755' -# - name: Generate certificate with certbot -# shell: certbot certonly --webroot --webroot-path /var/lib/letsencrypt -d {{ domains |first }} - when: ssl.stat.exists == false + - name: Generate certificate with certbot + shell: certbot certonly --webroot --webroot-path /var/lib/letsencrypt --non-interactive --agree-tos --email {{ certbot_admin_email }} -d {{ domains |first }} + - name: Create the ssl dir if needed + file: + path: /etc/nginx/ssl + state: directory + mode: '0750' + - name: Template ssl bloc for nginx vhost + template: + src: "ssl.conf.j2" + dest: "/etc/nginx/ssl/{{ domains |first }}.conf" + when: ssl.stat.exists != true - name: (Re)check if SSL certificate is present and register result stat: @@ -108,7 +130,7 @@ - name: (Re)template conf file for nginx vhost with SSL template: - src: "vhost.j2" + src: "vhost.conf.j2" dest: "/etc/nginx/sites-available/{{ service }}" - name: Enable nginx vhost for hedgedoc diff --git a/webapps/hedgedoc/templates/letsencrypt.conf.j2 b/webapps/hedgedoc/templates/letsencrypt.conf.j2 new file mode 100644 index 00000000..6b33847e --- /dev/null +++ b/webapps/hedgedoc/templates/letsencrypt.conf.j2 @@ -0,0 +1,5 @@ +location ~ /.well-known/acme-challenge { + alias /var/lib/letsencrypt/; + try_files $uri =404; + allow all; +} diff --git a/webapps/hedgedoc/templates/ssl.conf.j2 b/webapps/hedgedoc/templates/ssl.conf.j2 new file mode 100644 index 00000000..86194389 --- /dev/null +++ b/webapps/hedgedoc/templates/ssl.conf.j2 @@ -0,0 +1,22 @@ +## +# Certificates +# you need a certificate to run in production. see https://letsencrypt.org/ +## +ssl_certificate /etc/letsencrypt/live/{{ domains | first }}/fullchain.pem; +ssl_certificate_key /etc/letsencrypt/live/{{ domains | first }}/privkey.pem; + +## +# Security hardening (as of Nov 15, 2020) +# based on Mozilla Guideline v5.6 +## + +ssl_protocols TLSv1.2 TLSv1.3; +ssl_prefer_server_ciphers on; +ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; # add ECDHE-RSA-AES256-SHA if you want compatibility with Android 4 +ssl_session_timeout 1d; # defaults to 5m +ssl_session_cache shared:SSL:10m; # estimated to 40k sessions +ssl_session_tickets off; +ssl_stapling on; +ssl_stapling_verify on; +# HSTS (https://hstspreload.org), requires to be copied in 'location' sections that have add_header directives +#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; diff --git a/webapps/hedgedoc/templates/vhost.j2 b/webapps/hedgedoc/templates/vhost.conf.j2 similarity index 73% rename from webapps/hedgedoc/templates/vhost.j2 rename to webapps/hedgedoc/templates/vhost.conf.j2 index 177416c3..ecd89214 100644 --- a/webapps/hedgedoc/templates/vhost.j2 +++ b/webapps/hedgedoc/templates/vhost.conf.j2 @@ -8,8 +8,8 @@ server { listen [::]:80; server_name {{ domains |first }}; - # For Let's Encrypt - location /.well-known/acme-challenge/ { allow all; } + # For certbot + include /etc/nginx/snippets/letsencrypt.conf; {% if ssl.stat.exists %} location / { return 301 https://$host$request_uri; } @@ -20,13 +20,14 @@ server { server { listen 443 ssl http2; listen [::]:443 ssl http2; + server_name {{ domains |first }}; - # For Let's Encrypt - location /.well-known/acme-challenge/ { allow all; } - ssl_certificate /etc/letsencrypt/live/{{ domains |first }}/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/{{ domains |first }}/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/{{ domains |first }}/chain.pem; + access_log /var/log/nginx/{{ service }}.access.log; + error_log /var/log/nginx/{{ service }}.error.log; + + include /etc/nginx/snippets/letsencrypt.conf; + include /etc/nginx/ssl/{{ domains | first }}.conf; location / { proxy_pass http://127.0.0.1:{{ node_port }};