From: Bernhard Tittelbach Date: Sun, 2 Nov 2025 01:07:51 +0000 (+0100) Subject: vex2: some redirects and stuff X-Git-Url: https://git.realraum.at/?a=commitdiff_plain;h=126025d1ce599aa2d3154090767040a3be6eae50;p=noc.git vex2: some redirects and stuff --- diff --git a/ansible/host_playbooks/vex2.yml b/ansible/host_playbooks/vex2.yml index 91649f6..a053a2d 100644 --- a/ansible/host_playbooks/vex2.yml +++ b/ansible/host_playbooks/vex2.yml @@ -6,5 +6,7 @@ - role: dirty-hacks/vex2-base - role: acmetool/base - role: nginx + - role: web/realraumat + - role: web/r3redirects - role: web/dokuwiki - role: web/r3status diff --git a/ansible/host_vars/vex2/realraumat.yaml b/ansible/host_vars/vex2/realraumat.yaml new file mode 100644 index 0000000..cfc1835 --- /dev/null +++ b/ansible/host_vars/vex2/realraumat.yaml @@ -0,0 +1,9 @@ +--- +r3at_urls: + - r3.at + + +wwwrealraum_urls: + - www.realraum.at + - realraum.at + diff --git a/ansible/roles/acmetool/base/defaults/main.yml b/ansible/roles/acmetool/base/defaults/main.yml index c9a7107..b8c9ca0 100644 --- a/ansible/roles/acmetool/base/defaults/main.yml +++ b/ansible/roles/acmetool/base/defaults/main.yml @@ -1,11 +1,12 @@ --- -acmetool_directory_server_le_live: "https://acme-v01.api.letsencrypt.org/directory" -acmetool_directory_server_le_staging: "https://acme-staging.api.letsencrypt.org/directory" +acmetool_directory_server_le_live: "https://acme-v02.api.letsencrypt.org/directory" +acmetool_directory_server_le_staging: "https://acme-staging-v02.api.letsencrypt.org/directory" ## this can't be changed after the account as been created (aka after the first run) ## and it's not recommended to keep this empty so we don't define it here which will lead to an error # acmetool_account_email: acmetool_directory_server: "{{ acmetool_directory_server_le_staging }}" +# acmetool_directory_server: "{{ acmetool_directory_server_le_live }}" #### optionally set http(s)_proxy # acmetool_http_proxy: diff --git a/ansible/roles/web/r3redirects/defaults/main.yml b/ansible/roles/web/r3redirects/defaults/main.yml new file mode 100644 index 0000000..677b963 --- /dev/null +++ b/ansible/roles/web/r3redirects/defaults/main.yml @@ -0,0 +1,10 @@ +--- +r3at_urls: + - r3.at + +wikirealraum.at_urls: + - wiki.realraum.at + - w.r3.at + +sensors_urls: + - sensors.realraum.at diff --git a/ansible/roles/web/r3redirects/handlers/main.yml b/ansible/roles/web/r3redirects/handlers/main.yml new file mode 100644 index 0000000..d4e42ca --- /dev/null +++ b/ansible/roles/web/r3redirects/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: reload nginx + service: + name: nginx + state: reloaded diff --git a/ansible/roles/web/r3redirects/tasks/main.yml b/ansible/roles/web/r3redirects/tasks/main.yml new file mode 100644 index 0000000..d8e14c3 --- /dev/null +++ b/ansible/roles/web/r3redirects/tasks/main.yml @@ -0,0 +1,3 @@ +--- + +- import_tasks: nginx.yml diff --git a/ansible/roles/web/r3redirects/tasks/nginx.yml b/ansible/roles/web/r3redirects/tasks/nginx.yml new file mode 100644 index 0000000..b1c0605 --- /dev/null +++ b/ansible/roles/web/r3redirects/tasks/nginx.yml @@ -0,0 +1,106 @@ +--- + +- name: install nginx vhost config files + loop: + - r3.at + - w.r3.at + - sensors.realraum.at + template: + src: "{{ item }}.j2" + dest: /etc/nginx/sites-available/{{ item }} + notify: reload nginx + +- name: check if acme certs already exists + stat: + path: /var/lib/acme/live/w.r3.at + register: wr3_acme_cert + +- name: check if acme certs already exists + stat: + path: /var/lib/acme/live/r3.at + register: r3_acme_cert + +- name: check if acme certs already exists + stat: + path: /var/lib/acme/live/sensors.realraum.at + register: sensors_acme_cert + +- name: link nonexistent hostname to self-signed interim cert + when: not wr3_acme_cert.stat.exists + 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 hostnames + file: + src: "../certs/{{ selfsigned_interim_cert_id }}" + dest: /var/lib/acme/live/w.r3.at + state: link + +- name: link nonexistent hostname to self-signed interim cert + when: not r3_acme_cert.stat.exists + 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 hostnames + file: + src: "../certs/{{ selfsigned_interim_cert_id }}" + dest: /var/lib/acme/live/r3.at + state: link + +- name: link nonexistent hostname to self-signed interim cert + when: not sensors_acme_cert.stat.exists + 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 hostnames + file: + src: "../certs/{{ selfsigned_interim_cert_id }}" + dest: /var/lib/acme/live/sensors.realraum.at + state: link + +- name: enable nginx vhost config + loop: + - r3.at + - w.r3.at + - sensors.realraum.at + file: + src: ../sites-available/{{ item }} + dest: /etc/nginx/sites-enabled/{{ item }} + state: link + notify: reload nginx + +- 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: {{ item }} +# loop: +# - r3.at +# - w.r3.at diff --git a/ansible/roles/web/r3redirects/templates/r3.at.j2 b/ansible/roles/web/r3redirects/templates/r3.at.j2 new file mode 100644 index 0000000..147aeda --- /dev/null +++ b/ansible/roles/web/r3redirects/templates/r3.at.j2 @@ -0,0 +1,27 @@ +server { + listen [::]:443 ssl; + listen 443 ssl; + + server_name {{ r3at_urls | join(' ') }}; + + include snippets/acmetool.conf; + include snippets/ssl.conf; + ssl_certificate /var/lib/acme/live/{{ r3at_urls[0] }}/fullchain; + ssl_certificate_key /var/lib/acme/live/{{ r3at_urls[0] }}/privkey; + include snippets/hsts.conf; + + include snippets/security-headers.conf; + + + location = /events.ics { + return 302 https://status.realraum.at/shmcache/grical_realraum.ical; # planned: 301 + } + + location = /events.ical { + return 302 https://status.realraum.at/shmcache/grical_realraum.ical; # planned: 301 + } + + location = / { + return 302 https://realraum.at/; + } +} diff --git a/ansible/roles/web/r3redirects/templates/sensors.realraum.at.j2 b/ansible/roles/web/r3redirects/templates/sensors.realraum.at.j2 new file mode 100644 index 0000000..5afbc99 --- /dev/null +++ b/ansible/roles/web/r3redirects/templates/sensors.realraum.at.j2 @@ -0,0 +1,20 @@ +server { + listen [::]:443 ssl; + listen 443 ssl; + + server_name {{ sensors_urls | join(' ') }}; + + include snippets/acmetool.conf; + include snippets/ssl.conf; + ssl_certificate /var/lib/acme/live/{{ sensors_urls[0] }}/fullchain; + ssl_certificate_key /var/lib/acme/live/{{ sensors_urls[0] }}/privkey; + include snippets/hsts.conf; + + include snippets/security-headers.conf; + + access_log off; + + location / { + return 307 https://status.realraum.at/; + } +} diff --git a/ansible/roles/web/r3redirects/templates/w.r3.at.j2 b/ansible/roles/web/r3redirects/templates/w.r3.at.j2 new file mode 100644 index 0000000..9eb2696 --- /dev/null +++ b/ansible/roles/web/r3redirects/templates/w.r3.at.j2 @@ -0,0 +1,20 @@ +server { + listen [::]:443 ssl; + listen 443 ssl; + + server_name {{ wikirealraum | join(' ') }}; + + include snippets/acmetool.conf; + include snippets/ssl.conf; + ssl_certificate /var/lib/acme/live/{{ wikirealraum[0] }}/fullchain; + ssl_certificate_key /var/lib/acme/live/{{ wikirealraum[0] }}/privkey; + include snippets/hsts.conf; + + include snippets/security-headers.conf; + + access_log off; + + location / { + return 302 https://doku.realraum.at$request_uri; + } +} diff --git a/ansible/roles/web/r3status/defaults/main.yml b/ansible/roles/web/r3status/defaults/main.yml index ed8bd03..29ac966 100644 --- a/ansible/roles/web/r3status/defaults/main.yml +++ b/ansible/roles/web/r3status/defaults/main.yml @@ -1,2 +1,3 @@ --- r3status_spaceapi_path: /dev/shm/spaceapi +r3status_ics_path: /dev/shm/ics diff --git a/ansible/roles/web/r3status/tasks/main.yml b/ansible/roles/web/r3status/tasks/main.yml index af225ed..b4a5a39 100644 --- a/ansible/roles/web/r3status/tasks/main.yml +++ b/ansible/roles/web/r3status/tasks/main.yml @@ -12,6 +12,31 @@ dest: /usr/local/bin/ssh-spaceapi-update.py mode: 0755 +- name: install grical caching script + template: + src: cache_realraum_imported_calendar.sh.j2 + dest: /usr/local/bin/cache_realraum_imported_calendar.sh + mode: 0755 + +- name: copy grical caching services + loop: + - cache_realraum_imported_calendar.timer + - cache_realraum_imported_calendar.service + template: + src: "{{ item }}.j2" + dest: /etc/systemd/system/{{ item }} + mode: 0644 + +- name: install copy grical caching services + loop: + - cache_realraum_imported_calendar.timer + - cache_realraum_imported_calendar.service + ansible.builtin.systemd: + name: "{{ item }}" + state: started + enabled: yes + daemon_reload: yes + - name: create spaceapi user ssh config directory file: path: /srv/r3status/spaceapi/.ssh @@ -29,6 +54,7 @@ content: | no-agent-forwarding,no-port-forwarding,no-pty,no-X11-forwarding,no-user-rc,command="/usr/local/bin/ssh-spaceapi-update.py" {{ r3status_spaceapi_update_user_ssh_key }} +### TODO: grical downloader script - name: create status web-root directory file: diff --git a/ansible/roles/web/r3status/tasks/nginx.yml b/ansible/roles/web/r3status/tasks/nginx.yml index 1c0f7d8..f2302c7 100644 --- a/ansible/roles/web/r3status/tasks/nginx.yml +++ b/ansible/roles/web/r3status/tasks/nginx.yml @@ -39,8 +39,8 @@ - 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: status.realraum.at +# - name: get certificate using acmetool +# import_role: +# name: acmetool/cert +# vars: +# acmetool_cert_name: status.realraum.at diff --git a/ansible/roles/web/r3status/templates/cache_realraum_imported_calendar.service.j2 b/ansible/roles/web/r3status/templates/cache_realraum_imported_calendar.service.j2 new file mode 100644 index 0000000..9712e84 --- /dev/null +++ b/ansible/roles/web/r3status/templates/cache_realraum_imported_calendar.service.j2 @@ -0,0 +1,11 @@ +[Unit] +Description=grical ics caching service + +[Service] +Type=oneshot +WorkingDirectory={{ r3status_ics_path }} +ExecStart=/usr/local/bin/cache_realraum_imported_calendar.sh +User=spaceapi + +[Install] +WantedBy=multi-user.target diff --git a/ansible/roles/web/r3status/templates/cache_realraum_imported_calendar.sh.j2 b/ansible/roles/web/r3status/templates/cache_realraum_imported_calendar.sh.j2 new file mode 100755 index 0000000..5e4d34a --- /dev/null +++ b/ansible/roles/web/r3status/templates/cache_realraum_imported_calendar.sh.j2 @@ -0,0 +1,23 @@ +#!/bin/zsh +DL_PATH=/dev/shm/wget +APACHE_PATH={{ r3status_ics_path }} +ALL_JSON_SRC="https://grical.realraum.at/s/?query=!realraum+|+!r3extern&limit=9&view=json" +ALL_JSON_FILE="grical_realraum.json" +LOCALONLY_JSON_SRC="https://grical.realraum.at/s/?query=!realraum&limit=9&view=json" +LOCALONLY_JSON_FILE="grical_realraum_only.json" +ICAL_DATE_FROM=$(date -d "last month" +"%Y-%m-%d") +ICAL_DATE_TILL=$(date -d "today + 3 months" +"%Y-%m-%d") +ALL_ICAL_SRC="https://grical.realraum.at/s/?query=!realraum+|+!r3extern%20${ICAL_DATE_FROM}%20${ICAL_DATE_TILL}&view=ical" +ALL_ICAL_FILE="grical_realraum.ical" +LOCALONLY_ICAL_SRC="https://grical.realraum.at/s/?query=!realraum%20${ICAL_DATE_FROM}%20${ICAL_DATE_TILL}&view=ical" +LOCALONLY_ICAL_FILE="grical_realraum_only.ical" +mkdir $APACHE_PATH 2>/dev/null +mkdir $DL_PATH 2>/dev/null +### sed makes ical validate according to http://severinghaus.org/projects/icv/?url=https%3A%2F%2Fr3.at%2Fevents.ical +for s d in $ALL_JSON_SRC $ALL_JSON_FILE $ALL_ICAL_SRC $ALL_ICAL_FILE $LOCALONLY_JSON_SRC $LOCALONLY_JSON_FILE $LOCALONLY_ICAL_SRC $LOCALONLY_ICAL_FILE; do + wget --no-check-certificate -o /dev/null --tries=1 "$s" -O "${DL_PATH}/${d}" \ + && sed -i '/^GEO:/d;/^METHOD:PUBLISH/d;s/^\(DTSTAMP:[0-9A-Z]\+\)/\1Z/' "${DL_PATH}/${d}" \ + && [[ -s "${DL_PATH}/${d}" ]] \ + && mv "${DL_PATH}/${d}" "${APACHE_PATH}/${d}" +done + diff --git a/ansible/roles/web/r3status/templates/cache_realraum_imported_calendar.timer.j2 b/ansible/roles/web/r3status/templates/cache_realraum_imported_calendar.timer.j2 new file mode 100644 index 0000000..0e94ff1 --- /dev/null +++ b/ansible/roles/web/r3status/templates/cache_realraum_imported_calendar.timer.j2 @@ -0,0 +1,9 @@ +[Unit] +Description=grical ics caching time + +[Timer] +OnActiveSec=60 +OnUnitActiveSec=60 + +[Install] +WantedBy=multi-user.target diff --git a/ansible/roles/web/r3status/templates/nginx.j2 b/ansible/roles/web/r3status/templates/nginx.j2 index 698b5b1..76fe826 100644 --- a/ansible/roles/web/r3status/templates/nginx.j2 +++ b/ansible/roles/web/r3status/templates/nginx.j2 @@ -16,6 +16,16 @@ server { location = /spaceapi.json { alias {{ r3status_spaceapi_path }}/spaceapi.json; + add_header Access-Control-Allow-Origin "*"; + add_header Pragma "no-cache"; + add_header Cache-Control "no-cache"; + } + + location ^/ics/(.*)$ { + alias {{ r3status_ics_path }}/$1; + add_header Access-Control-Allow-Origin "*"; + add_header Pragma "no-cache"; + add_header Cache-Control "no-cache"; } location /js/ { diff --git a/ansible/roles/web/realraumat/defaults/main.yml b/ansible/roles/web/realraumat/defaults/main.yml new file mode 100644 index 0000000..67c12fe --- /dev/null +++ b/ansible/roles/web/realraumat/defaults/main.yml @@ -0,0 +1,3 @@ +--- +wwwrealraum_urls: + - www.realraum.at \ No newline at end of file diff --git a/ansible/roles/web/realraumat/files/404.html b/ansible/roles/web/realraumat/files/404.html new file mode 100644 index 0000000..c225713 --- /dev/null +++ b/ansible/roles/web/realraumat/files/404.html @@ -0,0 +1,26 @@ + + + + + + 404 - Error ressource not found + + + +


4 ohhh 4

+

In four dimensions we can have a brane.

+

But call it a dimension, then you need to get a brain!

+ + + + + diff --git a/ansible/roles/web/realraumat/handlers/main.yml b/ansible/roles/web/realraumat/handlers/main.yml new file mode 100644 index 0000000..d4e42ca --- /dev/null +++ b/ansible/roles/web/realraumat/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: reload nginx + service: + name: nginx + state: reloaded diff --git a/ansible/roles/web/realraumat/tasks/main.yml b/ansible/roles/web/realraumat/tasks/main.yml new file mode 100644 index 0000000..5b05a88 --- /dev/null +++ b/ansible/roles/web/realraumat/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- name: create webroot path + file: + name: /srv/realraumat/www/ + state: directory + owner: www-data + +- name: Copy files to remote locations + ansible.builtin.copy: + dest: /srv/realraumat/www/404.html + group: www-data + owner: www-data + src: files/404.html + +- import_tasks: nginx.yml + + diff --git a/ansible/roles/web/realraumat/tasks/nginx.yml b/ansible/roles/web/realraumat/tasks/nginx.yml new file mode 100644 index 0000000..db6571d --- /dev/null +++ b/ansible/roles/web/realraumat/tasks/nginx.yml @@ -0,0 +1,53 @@ +--- + +- name: install nginx vhost config files + loop: + - www.realraum.at + template: + src: "{{ item }}.j2" + dest: /etc/nginx/sites-available/{{ item }} + notify: reload nginx + +- name: check if acme certs already exists + stat: + path: /var/lib/acme/live/www.realraum.at + register: wwwrealraum_acme_cert + +- name: link nonexistent hostname to self-signed interim cert + when: not wwwrealraum_acme_cert.stat.exists + 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 hostnames + file: + src: "../certs/{{ selfsigned_interim_cert_id }}" + dest: /var/lib/acme/live/www.realraum.at + state: link + +- name: enable nginx vhost config + loop: + - www.realraum.at + file: + src: ../sites-available/{{ item }} + dest: /etc/nginx/sites-enabled/{{ item }} + state: link + notify: reload nginx + +- 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: {{ item }} +# loop: +# - www.realraum.at diff --git a/ansible/roles/web/realraumat/templates/www.realraum.at.j2 b/ansible/roles/web/realraumat/templates/www.realraum.at.j2 new file mode 100644 index 0000000..fdbf2cf --- /dev/null +++ b/ansible/roles/web/realraumat/templates/www.realraum.at.j2 @@ -0,0 +1,116 @@ +server { + listen [::]:443 ssl; + listen 443 ssl; + + server_name {{ wwwrealraum_urls | join(' ') }}; + + include snippets/acmetool.conf; + include snippets/ssl.conf; + ssl_certificate /var/lib/acme/live/{{ wwwrealraum_urls[0] }}/fullchain; + ssl_certificate_key /var/lib/acme/live/{{ wwwrealraum_urls[0] }}/privkey; + include snippets/hsts.conf; + + include snippets/security-headers.conf; + add_header Content-Security-Policy "upgrade-insecure-requests"; + # Can be used rather than HSTS when it shouldn't be cached + + + root /srv/realraumat/www/; + access_log off; + error_log /var/log/nginx/realraum.at/error.log notice; +# rewrite_log on; + + + # Default redirect to WordPress site + location / { + return 302 https://wp.realraum.at$request_uri; + } + + location ~ ^/wiki/(.*)$ { + return 302 https://doku.realraum.at/$1; + } + + # Specific file redirects to status subdomain + location = /sensors.html { + return 302 https://status.realraum.at/; # planned: 301 + } + + location = /status.json { + return 302 https://status.realraum.at/spaceapi.json; # planned: 301 + } + + location = /shmcache/status.json { + return 302 https://status.realraum.at/spaceapi.json; # planned: 301 + } + + location ~ ^/shmcache/(.*)$ { + return 302 https://status.realraum.at/ics/$1; # planned: 301 + } + + location = /gc_button1.gif { + return 302 https://status.realraum.at/gc_button1.gif; # planned: 301 + } + location = /kiosk1024x768.html { + return 302 https://status.realraum.at/kiosk1024x768.html; # planned: 301 + } + location = /kiosk1050x1680_2.html { + return 302 https://status.realraum.at/kiosk1050x1680_2.html; # planned: 301 + } + location = /kiosk1366x768.html { + return 302 https://status.realraum.at/kiosk1366x768.html; # planned: 301 + } + location = /kiosk1440x900.html { + return 302 https://status.realraum.at/kiosk1440x900.html; # planned: 301 + } + location = /kiosk1680x1050_1.html { + return 302 https://status.realraum.at/kiosk1680x1050_1.html; # planned: 301 + } + location = /kiosk768x1366.html { + return 302 https://status.realraum.at/kiosk768x1366.html; # planned: 301 + } + location = /kiosk768x1366sensors.html { + return 302 https://status.realraum.at/kiosk768x1366sensors.html; # planned: 301 + } + location = /kiosk900x1440.html { + return 302 https://status.realraum.at/kiosk900x1440.html; # planned: 301 + } + location = /kiosk.css { + return 302 https://status.realraum.at/kiosk.css; # planned: 301 + } + location = /kiosk.js { + return 302 https://status.realraum.at/kiosk.js; # planned: 301 + } + location = /logo-red_250x250.png { + return 302 https://status.realraum.at/logo-red_250x250.png; # planned: 301 + } + location = /logo-re_empty_100x100.png { + return 302 https://status.realraum.at/logo-re_empty_100x100.png; # planned: 301 + } + location = /logo-re_open_100x100.png { + return 302 https://status.realraum.at/logo-re_open_100x100.png; # planned: 301 + } + location = /purl.js { + return 302 https://status.realraum.at/purl.js; # planned: 301 + } + location = /vis.css { + return 302 https://status.realraum.at/vis.css; # planned: 301 + } + location = /vis.js { + return 302 https://status.realraum.at/vis.js; # planned: 301 + } + + location = /logo-re_open_100x100.png { + return 302 https://status.realraum.at/logo-re_open_100x100.png; # planned: 301 + } + + location = /logo-re_empty_100x100.png { + return 302 https://status.realraum.at/logo-re_empty_100x100.png; # planned: 301 + } + + location = /logo-red_250x250.png { + return 302 https://status.realraum.at/logo-red_250x250.png; # planned: 301 + } + + error_page 404 /404.html; + +}