From 29a687bd1cc95242b26ef678764c237bf1f8cadb Mon Sep 17 00:00:00 2001
From: Paul Maruhn <paulmaruhn@posteo.de>
Date: Fri, 19 Nov 2021 02:45:43 +0100
Subject: [PATCH] aff nginx task and configs

---
 host_vars/srv02.yml                           | 10 ++++
 .../files/nginx/sites-available/default       | 17 ++++++
 .../files/nginx/sites-available/ffhl-status   | 17 ++++++
 .../files/nginx/sites-available/firmware      | 31 ++++++++++
 .../sites-available/git.luebeck.freifunk.net  | 39 +++++++++++++
 .../files/nginx/sites-available/grafana       | 58 +++++++++++++++++++
 .../files/nginx/sites-available/hopglass-map  | 32 ++++++++++
 .../sites-available/luebeck.freifunk.net      | 52 +++++++++++++++++
 .../files/nginx/sites-available/services      | 24 ++++++++
 .../services/files/nginx/sites-available/wiki | 16 +++++
 roles/services/files/nginx/snippets/acme.conf |  5 ++
 .../files/nginx/snippets/fastcgi-php.conf     | 13 +++++
 .../files/nginx/snippets/geoblock.conf        |  4 ++
 .../files/nginx/snippets/https-redirect.conf  |  4 ++
 .../files/nginx/snippets/snakeoil.conf        |  5 ++
 roles/services/files/nginx/snippets/tls.conf  | 18 ++++++
 roles/services/tasks/main.yml                 |  6 +-
 roles/services/tasks/nginx.yml                | 40 +++++++++++++
 18 files changed, 390 insertions(+), 1 deletion(-)
 create mode 100644 host_vars/srv02.yml
 create mode 100644 roles/services/files/nginx/sites-available/default
 create mode 100644 roles/services/files/nginx/sites-available/ffhl-status
 create mode 100644 roles/services/files/nginx/sites-available/firmware
 create mode 100644 roles/services/files/nginx/sites-available/git.luebeck.freifunk.net
 create mode 100644 roles/services/files/nginx/sites-available/grafana
 create mode 100644 roles/services/files/nginx/sites-available/hopglass-map
 create mode 100644 roles/services/files/nginx/sites-available/luebeck.freifunk.net
 create mode 100644 roles/services/files/nginx/sites-available/services
 create mode 100644 roles/services/files/nginx/sites-available/wiki
 create mode 100644 roles/services/files/nginx/snippets/acme.conf
 create mode 100644 roles/services/files/nginx/snippets/fastcgi-php.conf
 create mode 100644 roles/services/files/nginx/snippets/geoblock.conf
 create mode 100644 roles/services/files/nginx/snippets/https-redirect.conf
 create mode 100644 roles/services/files/nginx/snippets/snakeoil.conf
 create mode 100644 roles/services/files/nginx/snippets/tls.conf
 create mode 100644 roles/services/tasks/nginx.yml

diff --git a/host_vars/srv02.yml b/host_vars/srv02.yml
new file mode 100644
index 0000000..56d017d
--- /dev/null
+++ b/host_vars/srv02.yml
@@ -0,0 +1,10 @@
+nginx:
+  enabled_sites:
+    - default
+    - ffhl-status
+    - firmware
+    - git.luebeck.freifunk.net
+    - grafana
+    - hopglass-map
+    - luebeck.freifunk.net
+    - wiki
diff --git a/roles/services/files/nginx/sites-available/default b/roles/services/files/nginx/sites-available/default
new file mode 100644
index 0000000..93c2bed
--- /dev/null
+++ b/roles/services/files/nginx/sites-available/default
@@ -0,0 +1,17 @@
+server {
+	listen 80 default_server;
+	listen [::]:80 default_server;
+
+	root /var/www/html;
+
+	index index.html index.htm index.nginx-debian.html;
+
+	server_name _;
+	include snippets/acme.conf;
+
+	location / {
+		try_files $uri $uri/ =404;
+	}
+
+}
+
diff --git a/roles/services/files/nginx/sites-available/ffhl-status b/roles/services/files/nginx/sites-available/ffhl-status
new file mode 100644
index 0000000..0d72611
--- /dev/null
+++ b/roles/services/files/nginx/sites-available/ffhl-status
@@ -0,0 +1,17 @@
+server {
+	listen 80;
+	listen [::]:80;
+	listen localhost:443 ssl http2;
+	listen [::]:443 ssl http2;
+
+        server_name status.luebeck.freifunk.net status.ffhl.de status.ffhl;
+	
+	include snippets/acme.conf;
+	include snippets/tls.conf;
+	include snippets/https-redirect.conf;
+
+        ssl_certificate /var/lib/acme/live/luebeck.freifunk.net/fullchain;
+        ssl_certificate_key /var/lib/acme/live/luebeck.freifunk.net/privkey;
+
+	root /var/www/ffhl-status;
+}
diff --git a/roles/services/files/nginx/sites-available/firmware b/roles/services/files/nginx/sites-available/firmware
new file mode 100644
index 0000000..ecb690c
--- /dev/null
+++ b/roles/services/files/nginx/sites-available/firmware
@@ -0,0 +1,31 @@
+server {
+	listen 80;
+	listen [::]:80;
+	listen localhost:443 ssl http2;
+	listen [::]:443 ssl http2;
+	server_name firmware.luebeck.freifunk.net firmware.ffhl.de firmware.ffhl 1.updates.services.ffhl 1.updates.services.ffhl.de 1.updates.services.luebeck.freifunk.net;
+	
+	include snippets/acme.conf;	
+	include snippets/tls.conf;
+	ssl_certificate /var/lib/acme/live/luebeck.freifunk.net/fullchain;
+        ssl_certificate_key /var/lib/acme/live/luebeck.freifunk.net/privkey;
+
+
+ 	client_max_body_size 5m;
+    	client_body_timeout 60;
+	
+	root /var/www/firmware;
+	
+	location / {
+		fancyindex on;
+		fancyindex_css_href /.fancyindex/style.css;
+		# fancyindex_header /.fancyindex/header.html;
+		# fancyindex_footer /.fancyindex/footer.html;
+		fancyindex_exact_size off;
+	}
+
+	location /wizard {
+		alias /var/www/firmware-selector;
+	}
+}
+
diff --git a/roles/services/files/nginx/sites-available/git.luebeck.freifunk.net b/roles/services/files/nginx/sites-available/git.luebeck.freifunk.net
new file mode 100644
index 0000000..24d7ec1
--- /dev/null
+++ b/roles/services/files/nginx/sites-available/git.luebeck.freifunk.net
@@ -0,0 +1,39 @@
+include snippets/geoblock.conf;
+
+server {
+	listen 80;
+        listen [::]:80;
+	listen localhost:443 ssl http2;
+        listen [::]:443 ssl http2;
+        
+	server_name git.ffhl git.luebeck.freifunk.net git.ffhl.de;
+	
+	# TLS
+	include snippets/acme.conf;
+	include snippets/tls.conf;
+	ssl_certificate /var/lib/acme/live/www.luebeck.freifunk.net/fullchain;
+        ssl_certificate_key /var/lib/acme/live/www.luebeck.freifunk.net/privkey;	
+
+	if ($ssl_protocol = "") {
+		# force TLS
+		return 301 https://$host$request_uri;
+	}
+	
+	
+	client_max_body_size 256M;
+	
+	# apply geoblocking
+	if ($allowed_country = no) {
+		return 302 https://luebeck.freifunk.net/;
+	}
+
+        location / {
+                proxy_set_header Host $host;
+                proxy_pass http://localhost:3001/;
+                proxy_connect_timeout       300;
+                proxy_send_timeout          300;
+                proxy_read_timeout          300;
+                send_timeout                300;
+        }
+}
+
diff --git a/roles/services/files/nginx/sites-available/grafana b/roles/services/files/nginx/sites-available/grafana
new file mode 100644
index 0000000..49dabc3
--- /dev/null
+++ b/roles/services/files/nginx/sites-available/grafana
@@ -0,0 +1,58 @@
+proxy_cache_path /var/cache/nginx levels=1:2 inactive=10m max_size=1g keys_zone=grafana:1m;
+
+upstream backend {
+	server 127.0.0.1:3000;
+#	server cranberry.luebeck.freifunk.net:3000 backup;
+}
+
+server {
+	listen 80;
+	listen [::]:80;
+	
+	listen localhost:443 ssl http2;
+	listen [::]:443 ssl http2;
+	
+	server_name monitor.luebeck.freifunk.net monitor.ffhl.de monitor.ffhl;
+	
+	include snippets/acme.conf;	
+	include snippets/tls.conf;
+	ssl_certificate /var/lib/acme/live/luebeck.freifunk.net/fullchain;
+	ssl_certificate_key /var/lib/acme/live/luebeck.freifunk.net/privkey;
+	
+	if ($ssl_protocol = "") {
+		return 301 https://$host$request_uri;
+	}
+
+	location /render/ {
+		more_clear_headers 'Pragma';
+		more_clear_headers 'Cache-Control';
+		more_clear_headers 'Expires';
+		more_clear_headers 'last-modified';
+
+		add_header X-Cache-Status $upstream_cache_status;
+		expires 10m;
+		proxy_cache_key "$host$request_uri";
+		
+		proxy_connect_timeout       300;
+		proxy_send_timeout          300;
+		proxy_read_timeout          300;
+		send_timeout                300;	
+		proxy_cache grafana;
+		proxy_cache_min_uses 5;		
+
+		proxy_hide_header Cache-Control;
+		proxy_hide_header Expires;
+		proxy_hide_header X-Accel-Expires;
+		proxy_cache_methods GET POST;
+		proxy_pass http://127.0.0.1:3000;
+	}
+
+	location / {
+		proxy_connect_timeout       5;
+		proxy_send_timeout          5;
+		proxy_read_timeout          5;
+		send_timeout                5;	
+		proxy_pass http://backend;
+	}
+}
+
diff --git a/roles/services/files/nginx/sites-available/hopglass-map b/roles/services/files/nginx/sites-available/hopglass-map
new file mode 100644
index 0000000..7533c72
--- /dev/null
+++ b/roles/services/files/nginx/sites-available/hopglass-map
@@ -0,0 +1,32 @@
+server {
+	listen 80;
+	listen [::]:80 ;
+	listen localhost:443 ssl http2;
+	listen [::]:443 ssl http2;
+	server_name map2.luebeck.freifunk.net map.luebeck.freifunk.net map.ffhl.de map.ffhl;
+	
+	include snippets/acme.conf;
+	include snippets/tls.conf;
+	ssl_certificate /var/lib/acme/live/www.luebeck.freifunk.net/fullchain;
+	ssl_certificate_key /var/lib/acme/live/www.luebeck.freifunk.net/privkey;
+
+	root /var/www/hopglass;
+	index index.html;
+
+	location / {
+		# First attempt to serve request as file, then
+		# as directory, then fall back to displaying a 404.
+		try_files $uri $uri/ =404;
+	}
+
+	# the hopglass-server is listening on localhost:4000
+	# but the expect it to be at a public url
+	# so we just map /data to localhost:4000
+	location /data/ {
+		proxy_pass http://localhost:4000/;
+	}
+	
+	location /requestd/ {
+		proxy_pass http://localhost:21001/;
+	}
+}
diff --git a/roles/services/files/nginx/sites-available/luebeck.freifunk.net b/roles/services/files/nginx/sites-available/luebeck.freifunk.net
new file mode 100644
index 0000000..323e8bc
--- /dev/null
+++ b/roles/services/files/nginx/sites-available/luebeck.freifunk.net
@@ -0,0 +1,52 @@
+server {
+	listen 80;
+	listen [::]:80;
+	
+	listen localhost:443 ssl http2;
+	listen [::]:443 ssl http2;
+
+        server_name luebeck.freifunk.net ffhl.de ffhl;
+	
+	include snippets/acme.conf;
+	include snippets/tls.conf;
+	include snippets/https-redirect.conf;
+
+        ssl_certificate /var/lib/acme/live/luebeck.freifunk.net/fullchain;
+        ssl_certificate_key /var/lib/acme/live/luebeck.freifunk.net/privkey;
+
+        root /var/www/luebeck.freifunk.net;
+
+        location ~ /map(/?.*) {
+                return 301 $scheme://map.luebeck.freifunk.net$1;
+        }
+
+        location ~ /wiki(/?.*) {
+                return 301 https://wiki.luebeck.freifunk.net$1;
+        }
+
+        location /firmware/ {
+        	return 301 $scheme://firmware.luebeck.freifunk.net/;
+        }
+
+        location /opkg/ {
+        	return 301 $scheme://firmware.luebeck.freifunk.net/;
+        }
+
+        location = /Moelln {
+                return 302 https://wiki.luebeck.freifunk.net/wiki/Moelln;
+        }
+}
+
+server {
+        listen [::]:80;
+        listen [::]:443 ssl;
+        server_name xn--lbeck-kva.freifunk.net www.luebeck.freifunk.net www.ffhl.de;
+	
+	include snippets/acme.conf;
+	include snippets/tls.conf;
+
+        ssl_certificate /var/lib/acme/live/www.luebeck.freifunk.net/fullchain;
+        ssl_certificate_key /var/lib/acme/live/www.luebeck.freifunk.net/privkey;
+
+        return 301 $scheme://luebeck.freifunk.net$request_uri;
+}
diff --git a/roles/services/files/nginx/sites-available/services b/roles/services/files/nginx/sites-available/services
new file mode 100644
index 0000000..bad2efa
--- /dev/null
+++ b/roles/services/files/nginx/sites-available/services
@@ -0,0 +1,24 @@
+server {
+	listen 80;
+	listen [::]:80;
+	
+	listen localhost:443 ssl http2;
+	listen [::]:443 ssl http2;
+
+	server_name services.ffhl.de services.luebeck.freifunk.net;
+	
+	include tls.conf;
+	ssl_certificate /var/lib/acme/live/luebeck.freifunk.net/fullchain;
+        ssl_certificate_key /var/lib/acme/live/luebeck.freifunk.net/privkey;
+	
+	if ($ssl_protocol = "") {
+		return 301 https://$host$request_uri;
+	}
+	
+	location / {
+		proxy_set_header HOST $host;
+		proxy_set_header X-Forwarded-Proto $scheme;
+		proxy_set_header X-Real-IP $remote_addr;
+		proxy_pass https://yunohost.luebeck.freifunk.net;
+	}
+}
diff --git a/roles/services/files/nginx/sites-available/wiki b/roles/services/files/nginx/sites-available/wiki
new file mode 100644
index 0000000..7590be7
--- /dev/null
+++ b/roles/services/files/nginx/sites-available/wiki
@@ -0,0 +1,16 @@
+server {
+	listen 80;
+	listen [::]:80;
+	listen localhost:443 ssl http2;
+	listen [::]:443 ssl http2;
+
+        server_name wiki.luebeck.freifunk.net wiki.ffhl.de wiki.ffhl;
+	
+	include snippets/acme.conf;
+	include snippets/tls.conf;
+
+        ssl_certificate /var/lib/acme/live/luebeck.freifunk.net/fullchain;
+        ssl_certificate_key /var/lib/acme/live/luebeck.freifunk.net/privkey;
+
+	root /var/www/wiki;
+}
diff --git a/roles/services/files/nginx/snippets/acme.conf b/roles/services/files/nginx/snippets/acme.conf
new file mode 100644
index 0000000..b5e9249
--- /dev/null
+++ b/roles/services/files/nginx/snippets/acme.conf
@@ -0,0 +1,5 @@
+location ^~ /.well-known/acme-challenge/ {
+    default_type "text/plain";
+    alias /var/www/acme-challenge/;
+}
+
diff --git a/roles/services/files/nginx/snippets/fastcgi-php.conf b/roles/services/files/nginx/snippets/fastcgi-php.conf
new file mode 100644
index 0000000..467a9e7
--- /dev/null
+++ b/roles/services/files/nginx/snippets/fastcgi-php.conf
@@ -0,0 +1,13 @@
+# regex to split $uri to $fastcgi_script_name and $fastcgi_path
+fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+
+# Check that the PHP script exists before passing it
+try_files $fastcgi_script_name =404;
+
+# Bypass the fact that try_files resets $fastcgi_path_info
+# see: http://trac.nginx.org/nginx/ticket/321
+set $path_info $fastcgi_path_info;
+fastcgi_param PATH_INFO $path_info;
+
+fastcgi_index index.php;
+include fastcgi.conf;
diff --git a/roles/services/files/nginx/snippets/geoblock.conf b/roles/services/files/nginx/snippets/geoblock.conf
new file mode 100644
index 0000000..e886b0b
--- /dev/null
+++ b/roles/services/files/nginx/snippets/geoblock.conf
@@ -0,0 +1,4 @@
+map $geoip_country_code $allowed_country {
+	default yes;
+	IN no; #India
+}
diff --git a/roles/services/files/nginx/snippets/https-redirect.conf b/roles/services/files/nginx/snippets/https-redirect.conf
new file mode 100644
index 0000000..abc0131
--- /dev/null
+++ b/roles/services/files/nginx/snippets/https-redirect.conf
@@ -0,0 +1,4 @@
+# set this in the domain specific config
+if ($ssl_protocol = "") {
+    return 301 https://$server_name$request_uri;
+}
diff --git a/roles/services/files/nginx/snippets/snakeoil.conf b/roles/services/files/nginx/snippets/snakeoil.conf
new file mode 100644
index 0000000..ad26c3e
--- /dev/null
+++ b/roles/services/files/nginx/snippets/snakeoil.conf
@@ -0,0 +1,5 @@
+# Self signed certificates generated by the ssl-cert package
+# Don't use them in a production server!
+
+ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
+ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
diff --git a/roles/services/files/nginx/snippets/tls.conf b/roles/services/files/nginx/snippets/tls.conf
new file mode 100644
index 0000000..03aca34
--- /dev/null
+++ b/roles/services/files/nginx/snippets/tls.conf
@@ -0,0 +1,18 @@
+# only the best ciphers 
+ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ssl_prefer_server_ciphers off;
+ssl_dhparam /etc/nginx/dhparam.pem;
+ssl_protocols TLSv1.2 TLSv1.3;
+ssl_session_timeout 1d;
+ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
+ssl_session_tickets off;
+
+add_header Strict-Transport-Security "max-age=63072000" always;
+
+
+# set this in the domain specific config
+#if ($ssl_protocol = "") {
+#    return 301 https://$server_name$request_uri;
+#}
+
+
diff --git a/roles/services/tasks/main.yml b/roles/services/tasks/main.yml
index 399967c..cd2ed30 100644
--- a/roles/services/tasks/main.yml
+++ b/roles/services/tasks/main.yml
@@ -11,6 +11,10 @@
   include: software.yml
   tags: [base, apt, software]
 
-- name: install packages
+- name: setup monitoring
   include: monitoring.yml
   tags: [base, apt, software]
+
+- name: setup nginx
+  include: nginx.yml
+  tags: [nginx]
diff --git a/roles/services/tasks/nginx.yml b/roles/services/tasks/nginx.yml
new file mode 100644
index 0000000..dc9d90c
--- /dev/null
+++ b/roles/services/tasks/nginx.yml
@@ -0,0 +1,40 @@
+---
+
+- name: install nginx
+  apt:
+    state: present
+    install_recommends: no
+    update_cache: yes
+    name: nginx-full
+
+- name: copy snippets
+  copy:
+    src: nginx/snippets
+    dest: /etc/nginx/
+
+- name: copy available sites
+  copy:
+    src: nginx/sites-available
+    dest: /etc/nginx
+
+
+- name: remove previous enabled sites
+  block:
+    - file: state=absent path="/etc/nginx/sites-enabled/"
+    - file: state=directory path="/etc/nginx/sites-enabled"
+
+
+- name: enable selected sites
+  file:
+    state: link
+    src: "../sites-available/{{item}}"
+    dest: "/etc/nginx/sites-enabled/{{item}}"
+  with_items: "{{ nginx.enabled_sites }}"
+
+- name: restart nginx
+  systemd:
+    enabled: true
+    state: restarted
+    name: "{{item}}"
+  with_items:
+      - nginx
-- 
GitLab