added simple nginx role
authorChristian Pointner <equinox@realraum.at>
Sat, 6 Jul 2019 01:29:49 +0000 (03:29 +0200)
committerBernhard Tittelbach <bernhard@tittelbach.org>
Wed, 23 Jul 2025 00:23:28 +0000 (02:23 +0200)
ansible/host_playbooks/vex2.yml
ansible/roles/nginx/defaults/main.yml [new file with mode: 0644]
ansible/roles/nginx/handlers/main.yml [new file with mode: 0644]
ansible/roles/nginx/tasks/main.yml [new file with mode: 0644]
ansible/roles/nginx/templates/snippets/hsts.conf.j2 [new file with mode: 0644]
ansible/roles/nginx/templates/snippets/security-headers.conf.j2 [new file with mode: 0644]
ansible/roles/nginx/templates/snippets/ssl.conf.j2 [new file with mode: 0644]
ansible/roles/nginx/templates/vhosts/default.j2 [new file with mode: 0644]

index 8ab2aef..50d1c52 100644 (file)
@@ -4,3 +4,4 @@
   roles:
   - role: base
   - role: acmetool/base
+  - role: nginx
diff --git a/ansible/roles/nginx/defaults/main.yml b/ansible/roles/nginx/defaults/main.yml
new file mode 100644 (file)
index 0000000..cbf13c7
--- /dev/null
@@ -0,0 +1,3 @@
+---
+## nginx-full, nginx-light, ...
+nginx_package_variant: nginx
diff --git a/ansible/roles/nginx/handlers/main.yml b/ansible/roles/nginx/handlers/main.yml
new file mode 100644 (file)
index 0000000..d4e42ca
--- /dev/null
@@ -0,0 +1,5 @@
+---
+- name: reload nginx
+  service:
+    name: nginx
+    state: reloaded
diff --git a/ansible/roles/nginx/tasks/main.yml b/ansible/roles/nginx/tasks/main.yml
new file mode 100644 (file)
index 0000000..a7388c0
--- /dev/null
@@ -0,0 +1,60 @@
+---
+- name: install nginx package
+  apt:
+    name: "{{ nginx_package_variant }}"
+    state: present
+
+- name: install snippets
+  with_fileglob: '../templates/snippets/*.j2'
+  loop_control:
+    label: "{{ item | basename | splitext | first }}"
+  template:
+    src: "snippets/{{ item | basename | splitext | first }}.j2"
+    dest: "/etc/nginx/snippets/{{ item | basename | splitext | first }}"
+  notify: reload nginx
+
+- name: install default vhost
+  template:
+    src: vhosts/default.j2
+    dest: /etc/nginx/sites-enabled/default
+  notify: reload nginx
+
+- name: generate Diffie-Hellman parameters
+  openssl_dhparam:
+    path: /etc/ssl/dhparams.pem
+    size: 2048
+  notify: reload nginx
+
+- name: check if acme certs already exists
+  stat:
+    path: "/var/lib/acme/live/{{ ansible_host }}"
+  register: acme_cert_stat
+
+- name: link nonexistent hostnames to self-signed interim cert
+  when: acme_cert_stat.stat.exists == false
+  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 hostname
+      file:
+        src: "../certs/{{ selfsigned_interim_cert_id }}"
+        dest: "/var/lib/acme/live/{{ ansible_host }}"
+        state: link
+
+- name: make sure nginx config has been loaded
+  meta: flush_handlers
+
+- name: get certificate using acmetool
+  import_role:
+    name: acmetool/cert
+  vars:
+    acmetool_cert_name: "{{ ansible_host }}"
+    acmetool_cert_hostnames: "{{ [ansible_host] }}"
diff --git a/ansible/roles/nginx/templates/snippets/hsts.conf.j2 b/ansible/roles/nginx/templates/snippets/hsts.conf.j2
new file mode 100644 (file)
index 0000000..52d5dd7
--- /dev/null
@@ -0,0 +1,2 @@
+add_header Strict-Transport-Security max-age=15768000;
+
diff --git a/ansible/roles/nginx/templates/snippets/security-headers.conf.j2 b/ansible/roles/nginx/templates/snippets/security-headers.conf.j2
new file mode 100644 (file)
index 0000000..b94d479
--- /dev/null
@@ -0,0 +1,4 @@
+add_header X-Frame-Options DENY;
+add_header X-Content-Type-Options nosniff;
+add_header X-XSS-Protection "1; mode=block";
+# add_header Content-Security-Policy "default-src 'none'; connect-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'";
diff --git a/ansible/roles/nginx/templates/snippets/ssl.conf.j2 b/ansible/roles/nginx/templates/snippets/ssl.conf.j2
new file mode 100644 (file)
index 0000000..7a7da69
--- /dev/null
@@ -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/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/ansible/roles/nginx/templates/vhosts/default.j2 b/ansible/roles/nginx/templates/vhosts/default.j2
new file mode 100644 (file)
index 0000000..91e5956
--- /dev/null
@@ -0,0 +1,32 @@
+server {
+       listen 80 default_server;
+       listen [::]:80 default_server;
+
+  server_name _;
+
+       include snippets/acmetool.conf;
+
+       location / {
+    return 301 https://$host$request_uri;
+       }
+}
+
+server {
+       listen 443 ssl default_server;
+       listen [::]:443 ssl default_server;
+
+       server_name _;
+
+       include snippets/acmetool.conf;
+       include snippets/ssl.conf;
+       ssl_certificate /var/lib/acme/live/{{ ansible_host }}/fullchain;
+       ssl_certificate_key /var/lib/acme/live/{{ ansible_host }}/privkey;
+       include snippets/hsts.conf;
+
+       include snippets/security-headers.conf;
+
+       location / {
+    default_type text/plain;
+    return 200 "Welcome to {{ ansible_host }}!";
+       }
+}