From 43d17ea673f33beaf065143b7f7f72cf7f48d112 Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sat, 1 Oct 2022 14:11:27 +0200 Subject: [PATCH 01/12] bump jellyfin to 10.8.5, restrict some verbose api things --- roles/jellyfin/tasks/jellyfin.yml | 2 +- roles/jellyfin/templates/01-jellyfin.j2 | 27 ++++++++++++++----------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/roles/jellyfin/tasks/jellyfin.yml b/roles/jellyfin/tasks/jellyfin.yml index f89a53f..cc69e30 100644 --- a/roles/jellyfin/tasks/jellyfin.yml +++ b/roles/jellyfin/tasks/jellyfin.yml @@ -87,7 +87,7 @@ - name: start container docker_container: name: jellyfin - image: jellyfin/jellyfin:10.8.4 + image: jellyfin/jellyfin:10.8.5 auto_remove: no detach: yes pull: yes diff --git a/roles/jellyfin/templates/01-jellyfin.j2 b/roles/jellyfin/templates/01-jellyfin.j2 index 89899d8..5b07c76 100644 --- a/roles/jellyfin/templates/01-jellyfin.j2 +++ b/roles/jellyfin/templates/01-jellyfin.j2 @@ -66,18 +66,6 @@ server { return 403; } - location /health { - allow 127.0.0.1; - allow {{ my_public_ips[inventory_hostname] }}/32; - allow {{ my_public_ips[ansible_control_host] }}/32; - allow {{ wireguard_cidr }}; - deny all; - - proxy_pass http://127.0.0.1:{{ jellyfin_port }}; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - # so /web/#!/ works instead of having to go to /web/index.html/#!/ location = /web/ { proxy_pass http://127.0.0.1:{{ jellyfin_port }}/web/index.html; @@ -102,6 +90,20 @@ server { proxy_set_header X-Forwarded-Host $http_host; } + {% for item in ["/health", "/GetUtcTime"] -%} + location {{ item }} { + allow 127.0.0.1; + allow {{ my_public_ips[inventory_hostname] }}/32; + allow {{ my_public_ips[ansible_control_host] }}/32; + allow {{ wireguard_cidr }}; + deny all; + + proxy_pass http://127.0.0.1:{{ jellyfin_port }}; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + {% endfor %} + {# location /videos/ { # # cache video streams: https://jellyfin.org/docs/general/networking/nginx.html#cache-video-streams # proxy_cache cWEB; @@ -116,6 +118,7 @@ server { # proxy_cache_key "{{ jellyfin_url }}$uri?MediaSourceId=$arg_MediaSourceId&VideoCodec=$arg_VideoCodec&AudioCodec=$arg_AudioCodec&AudioStreamIndex=$arg_AudioStreamIndex&VideoBitrate=$arg_VideoBitrate&AudioBitrate=$arg_AudioBitrate&SubtitleMethod=$arg_SubtitleMethod&TranscodingMaxAudioChannels=$arg_TranscodingMaxAudioChannels&RequireAvc=$arg_RequireAvc&SegmentContainer=$arg_SegmentContainer&MinSegments=$arg_MinSegments&BreakOnNonKeyFrames=$arg_BreakOnNonKeyFrames&h264-profile=$h264Profile&h264-level=$h264Level"; # proxy_cache_valid 200 301 302 30d; # } #} + } server { -- 2.40.1 From 529edc03c0143a58659c7dfb44e958086ea3807d Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 10:12:16 +0200 Subject: [PATCH 02/12] nginx reverse proxy in front of hass+zwave, manage hass config files, add dwd_weather+caldav --- roles/hass/defaults/main.yml | 1 + roles/hass/handlers/main.yml | 11 ++++ roles/hass/tasks/hass.yml | 69 +++++++++++++++++++--- roles/hass/templates/01-hass.j2 | 66 +++++++++++++++++++++ roles/hass/templates/configuration.yaml.j2 | 49 +++++++++++++++ roles/hass/templates/secrets.yaml.j2 | 8 +++ 6 files changed, 196 insertions(+), 8 deletions(-) create mode 100644 roles/hass/defaults/main.yml create mode 100644 roles/hass/handlers/main.yml create mode 100644 roles/hass/templates/01-hass.j2 create mode 100644 roles/hass/templates/configuration.yaml.j2 create mode 100644 roles/hass/templates/secrets.yaml.j2 diff --git a/roles/hass/defaults/main.yml b/roles/hass/defaults/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/hass/defaults/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/hass/handlers/main.yml b/roles/hass/handlers/main.yml new file mode 100644 index 0000000..5b98fd6 --- /dev/null +++ b/roles/hass/handlers/main.yml @@ -0,0 +1,11 @@ +--- + +- name: reload nginx + service: + name: nginx + state: reloaded + +- name: restart nginx + service: + name: nginx + state: restarted diff --git a/roles/hass/tasks/hass.yml b/roles/hass/tasks/hass.yml index c6872b0..5bfd88e 100644 --- a/roles/hass/tasks/hass.yml +++ b/roles/hass/tasks/hass.yml @@ -2,6 +2,21 @@ # hass + zwave +- name: install certs + copy: + src: "/usr/local/etc/letsencrypt/live/{{ item }}" + dest: "/usr/local/etc/certs/" + owner: root + group: root + mode: 0755 + tags: + - letsencrypt-certs + notify: reload nginx + vars: + prediff_cmd: echo + with_items: + - "{{ hass_url }}" + - name: create dir structure file: path: "{{ systemuserlist.hass.home }}/{{ item }}" @@ -11,16 +26,39 @@ group: hass with_items: - home-assistant + - home-assistant/config + - home-assistant/.config - zwavejs + - zwavejs/app + - zwavejs/app/store + +- name: home assistant main configuration.yaml + template: + src: configuration.yaml.j2 + dest: "{{ systemuserlist.hass.home }}/home-assistant/config/configuration.yaml" + owner: "{{ systemuserlist.hass.uid }}" + group: "{{ systemuserlist.hass.gid }}" + mode: 0644 + +- name: home assistant secrets file + template: + src: secrets.yaml.j2 + dest: "{{ systemuserlist.hass.home }}/home-assistant/config/secrets.yaml" + owner: "{{ systemuserlist.hass.uid }}" + group: "{{ systemuserlist.hass.gid }}" + mode: 0644 + no_log: true # docker run --run -it -p 8091:8091 -p 3000:3000 --network #bridgewithdns --device /dev/ttyACM0:/dev/zwave -v # /home/ben/zwavejs:/usr/src/app/store zwavejs/zwavejs2mqtt:latest +# the name has changed to zwave-js-ui: +# https://github.com/zwave-js/zwave-js-ui/pull/2650 - name: start zwavejs container docker_container: name: zwavejs - image: zwavejs/zwavejs2mqtt:latest + image: zwavejs/zwave-js-ui:latest detach: true pull: true restart_policy: "unless-stopped" @@ -30,13 +68,12 @@ devices: - "/dev/serial/by-id/usb-0658_0200-if00:/dev/zwave:rwm" ports: - # - "127.0.0.1:3000:3000" - # - "127.0.0.1:8091:8091" - - "3000:3000" - - "8091:8091" + # - "127.0.0.1:1883:1883" # mqtt broker - disabled + # - "127.0.0.1:3000:3000" # ws for hass<->zwavejs + - "127.0.0.1:8091:8091" mounts: - type: bind - source: /var/lib/hass/zwavejs + source: /var/lib/hass/zwavejs/app/store target: /usr/src/app/store networks_cli_compatible: false network_mode: bridgewithdns @@ -65,11 +102,14 @@ env: TZ: "Etc/UTC" ports: - - "8123:8123" + - "127.0.0.1:8123:8123" mounts: - type: bind - source: /var/lib/hass/home-assistant + source: /var/lib/hass/home-assistant/config target: /config + - type: bind + source: /var/lib/hass/home-assistant/.config + target: /.config networks_cli_compatible: false network_mode: bridgewithdns networks: @@ -79,3 +119,16 @@ - home-assistant-container - hass-container - docker-containers + +- name: template nginx vhost + template: + src: 01-hass.j2 + dest: /etc/nginx/sites-enabled/01-hass + owner: root + group: root + mode: 0644 + tags: + - nginx + - hass-nginx + - zwave-nginx + notify: restart nginx diff --git a/roles/hass/templates/01-hass.j2 b/roles/hass/templates/01-hass.j2 new file mode 100644 index 0000000..689f8c8 --- /dev/null +++ b/roles/hass/templates/01-hass.j2 @@ -0,0 +1,66 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 443 ssl http2; + {% if inventory_hostname in wg_clients -%} + listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2; + {% endif -%} + + include /etc/nginx/authelia_internal.conf; + + include listen-proxy-protocol.conf; + include /etc/nginx/sudo-known.conf; + + server_name {{ hass_url }}; + + location / { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_pass http://127.0.0.1:8123; + } + + + location = {{ nginx_zwavejs_path }} { + # zwavejs needs to be accessed with a trailing / to respond. + # + # temporary redirects dont get remembered by the browser + # and redirect issues are no fun + return 302 https://{{ hass_url }}{{ nginx_zwavejs_path }}/; + } + + location {{ nginx_zwavejs_path }}/ { + include /etc/nginx/require_auth.conf; + + proxy_set_header X-External-Path {{ nginx_zwavejs_path }}; + + rewrite ^ $request_uri; + rewrite '^{{ nginx_zwavejs_path }}(/.*)$' $1 break; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_pass http://127.0.0.1:8091$uri; + + # for the special dashboard + # https://zwave-js.github.io/zwave-js-ui/#/usage/reverse-proxy?id=using-an-http-header + # proxy_set_header X-External-Path $http_x_ingress_path; + } + + access_log /var/log/nginx/access_{{ hass_url }}.log main; + error_log /var/log/nginx/error_{{ hass_url }}.log warn; + + ssl_session_timeout 5m; + ssl_certificate /usr/local/etc/certs/{{ hass_url }}/fullchain.pem; + ssl_certificate_key /usr/local/etc/certs/{{ hass_url }}/privkey.pem; + + fastcgi_hide_header X-Powered-By; +} diff --git a/roles/hass/templates/configuration.yaml.j2 b/roles/hass/templates/configuration.yaml.j2 new file mode 100644 index 0000000..8b287cc --- /dev/null +++ b/roles/hass/templates/configuration.yaml.j2 @@ -0,0 +1,49 @@ + +# Loads default set of integrations. Do not remove. +default_config: + +# Text to speech +tts: + - platform: google_translate + +automation: !include automations.yaml +script: !include scripts.yaml +scene: !include scenes.yaml + +calendar: + - platform: caldav + username: !secret caldav_user + password: !secret caldav_passwd + url: !secret caldav_url + +http: + trusted_proxies: + - 127.0.0.1 + - {{ bridgewithdns.host }} + - {{ bridgewithdns_cidr }} + use_x_forwarded_for: true + +sensor: + # https://www.home-assistant.io/integrations/dwd_weather_warnings/ + # https://www.dwd.de/DE/leistungen/opendata/help/warnungen/warning_codes_pdf.pdf?__blob=publicationFile&v=5 + # https://www.dwd.de/DE/leistungen/opendata/help/warnungen/cap_warncellids_csv.html + # 111000000;Berlin;DE300;Berlin;BXX + # 711000002;Berlin - Friedrichshain-Kreuzberg;;B-Friedrh./Kbg.;BXB + # 711000003;Berlin - Pankow;;B-Pankow;BXG + # 711000011;Berlin - Lichtenberg;;B-Lichtenberg;BXC + # 811000000;Stadt Berlin;;Berlin; + # 911000000;Berlin;;Land Berlin;LBE + # 911100000;Berlin;;Berlin;BXZ + # 995000000;Brandenburg/Berlin;;Berlin/Brandenb;DWPD + + - platform: dwd_weather_warnings + # Berlin - Friedrichshain-Kreuzberg + region_name: 711000002 + + - platform: dwd_weather_warnings + # Berlin - Pankow + region_name: 711000003 + + - platform: dwd_weather_warnings + # Stadt Berlin + region_name: 811000000 diff --git a/roles/hass/templates/secrets.yaml.j2 b/roles/hass/templates/secrets.yaml.j2 new file mode 100644 index 0000000..834980a --- /dev/null +++ b/roles/hass/templates/secrets.yaml.j2 @@ -0,0 +1,8 @@ + +# Use this file to store secrets like usernames and passwords. +# Learn more at https://www.home-assistant.io/docs/configuration/secrets/ +some_password: welcome + +caldav_user: "{{ hass_caldav.user }}" +caldav_passwd: "{{ hass_caldav.passwd }}" +caldav_url: https://{{ nextcloud_url }}/remote.php/dav/principals/users/{{ hass_caldav.user }}/ -- 2.40.1 From ec29be56acba0a64d7152861689cd3970cde1133 Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 12:51:46 +0200 Subject: [PATCH 03/12] switching hass container to network_mode=host and adding ufw rules --- roles/hass/handlers/main.yml | 7 +++ roles/hass/tasks/hass.yml | 72 ++++++++++++++++++---- roles/hass/templates/01-hass.j2 | 2 +- roles/hass/templates/configuration.yaml.j2 | 61 +++++++++++++++++- 4 files changed, 128 insertions(+), 14 deletions(-) diff --git a/roles/hass/handlers/main.yml b/roles/hass/handlers/main.yml index 5b98fd6..0f4546e 100644 --- a/roles/hass/handlers/main.yml +++ b/roles/hass/handlers/main.yml @@ -9,3 +9,10 @@ service: name: nginx state: restarted + +- name: restart hass container + docker_container: + name: hass + state: started + restart: true + when: not hass_container.changed diff --git a/roles/hass/tasks/hass.yml b/roles/hass/tasks/hass.yml index 5bfd88e..e463bfd 100644 --- a/roles/hass/tasks/hass.yml +++ b/roles/hass/tasks/hass.yml @@ -1,5 +1,55 @@ --- +- name: allow ssh + ufw: + rule: allow + to_port: "22" + direction: in + state: enabled + tags: + - ufw + +- name: default policy + ufw: + policy: allow + state: enabled + tags: + - ufw + +- name: deny hass cloud port stuff + ufw: + rule: deny + to_port: '42161' + direction: in + state: enabled + tags: + - ufw + +- name: allow zwavejs and hass ports from localhost for nginx + ufw: + rule: allow + to_port: "{{ item }}" + direction: in + src: "127.0.0.1" + state: enabled + with_items: + - '8091' + - '8123' + tags: + - ufw + +- name: reject zwavejs ws and hass ports from tother src + ufw: + rule: deny + to_port: "{{ item }}" + direction: in + state: enabled + with_items: + - "8091" + - "8123" + tags: + - ufw + # hass + zwave - name: install certs @@ -39,6 +89,7 @@ owner: "{{ systemuserlist.hass.uid }}" group: "{{ systemuserlist.hass.gid }}" mode: 0644 + notify: restart hass container - name: home assistant secrets file template: @@ -48,6 +99,7 @@ group: "{{ systemuserlist.hass.gid }}" mode: 0644 no_log: true + notify: restart hass container # docker run --run -it -p 8091:8091 -p 3000:3000 --network #bridgewithdns --device /dev/ttyACM0:/dev/zwave -v @@ -65,20 +117,20 @@ state: "{{ container_state | default('started') }}" container_default_behavior: compatibility user: "{{ systemuserlist.hass.uid }}:dialout" + networks_cli_compatible: false + network_mode: bridgewithdns + networks: + - name: bridgewithdns + ipv4_address: "{{ bridgewithdns.zwavejs }}" devices: - "/dev/serial/by-id/usb-0658_0200-if00:/dev/zwave:rwm" ports: - # - "127.0.0.1:1883:1883" # mqtt broker - disabled - # - "127.0.0.1:3000:3000" # ws for hass<->zwavejs + - "127.0.0.1:3000:3000" # ws for hass<->zwavejs (hass is in host mode, so its not on the bridged network) - "127.0.0.1:8091:8091" mounts: - type: bind source: /var/lib/hass/zwavejs/app/store target: /usr/src/app/store - networks_cli_compatible: false - network_mode: bridgewithdns - networks: - - name: bridgewithdns tags: - zwavejs - zwavejs-container @@ -99,10 +151,9 @@ state: "{{ container_state | default('started') }}" container_default_behavior: compatibility user: "{{ systemuserlist.hass.uid }}:{{ systemuserlist.hass.gid }}" + network_mode: host env: TZ: "Etc/UTC" - ports: - - "127.0.0.1:8123:8123" mounts: - type: bind source: /var/lib/hass/home-assistant/config @@ -110,10 +161,6 @@ - type: bind source: /var/lib/hass/home-assistant/.config target: /.config - networks_cli_compatible: false - network_mode: bridgewithdns - networks: - - name: bridgewithdns tags: - home-assistant - home-assistant-container @@ -132,3 +179,4 @@ - hass-nginx - zwave-nginx notify: restart nginx + register: hass_container diff --git a/roles/hass/templates/01-hass.j2 b/roles/hass/templates/01-hass.j2 index 689f8c8..0e86f0b 100644 --- a/roles/hass/templates/01-hass.j2 +++ b/roles/hass/templates/01-hass.j2 @@ -48,7 +48,7 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; - proxy_pass http://127.0.0.1:8091$uri; + proxy_pass http://{{ bridgewithdns.zwavejs }}:8091$uri; # for the special dashboard # https://zwave-js.github.io/zwave-js-ui/#/usage/reverse-proxy?id=using-an-http-header diff --git a/roles/hass/templates/configuration.yaml.j2 b/roles/hass/templates/configuration.yaml.j2 index 8b287cc..387d839 100644 --- a/roles/hass/templates/configuration.yaml.j2 +++ b/roles/hass/templates/configuration.yaml.j2 @@ -1,6 +1,60 @@ -# Loads default set of integrations. Do not remove. +# Loads default set of integrations. Icluding the cloud crap. Do remove. +# havent gotten it to work wthough, hass doesnt load properly default_config: +# +# the dict contains this: +# https://github.com/home-assistant/core/blob/dev/homeassistant/components/default_config/manifest.json +# +# the cloud thing clistens on (at least) port 42161. +# since we need to run in host mode, and dont have network/port isolation by default +# we'll kill this stuff. +# +# for some reason the settings dialog for it is still at /config/cloud/login, but +# we arent listening on port 42161 anymore (yay!). (but hass doesnt start) +# +# for now we just block the ports with iptables/ufw +# +# config: +# application_credentials: +# automation: +# bluetooth: +# # there is no cloud, just other peoples computers.. +# #cloud: +# counter: +# dhcp: +# energy: +# frontend: +# hardware: +# history: +# homeassistant_alerts: +# input_boolean: +# input_button: +# input_datetime: +# input_number: +# input_select: +# input_text: +# logbook: +# map: +# media_source: +# mobile_app: +# my: +# network: +# person: +# scene: +# schedule: +# script: +# ssdp: +# # kind of undocumented, but didnt help +# stream: +# sun: +# system_health: +# tag: +# timer: +# usb: +# webhook: +# zeroconf: +# zone: # Text to speech tts: @@ -17,6 +71,11 @@ calendar: url: !secret caldav_url http: + # container runs with network_mode=host, so no network isolation. the docs say to not + # do this, and it doesnt work as expected either. + # using ufw/iptables for now.... + # + #server_host: 127.0.0.1 trusted_proxies: - 127.0.0.1 - {{ bridgewithdns.host }} -- 2.40.1 From 2961393af054ada969cd71f7bf073bc1ffc8f5e2 Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 12:59:16 +0200 Subject: [PATCH 04/12] allow loopback with ufw --- roles/hass/tasks/hass.yml | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/roles/hass/tasks/hass.yml b/roles/hass/tasks/hass.yml index e463bfd..abf38d2 100644 --- a/roles/hass/tasks/hass.yml +++ b/roles/hass/tasks/hass.yml @@ -9,6 +9,15 @@ tags: - ufw +- name: allow loopback + ufw: + rule: allow + interface: lo + direction: in + state: enabled + tags: + - ufw + - name: default policy ufw: policy: allow @@ -18,6 +27,7 @@ - name: deny hass cloud port stuff ufw: + # drops packets rule: deny to_port: '42161' direction: in @@ -25,22 +35,10 @@ tags: - ufw -- name: allow zwavejs and hass ports from localhost for nginx +- name: reject zwavejs ws and hass ports (loopback only) ufw: - rule: allow - to_port: "{{ item }}" - direction: in - src: "127.0.0.1" - state: enabled - with_items: - - '8091' - - '8123' - tags: - - ufw - -- name: reject zwavejs ws and hass ports from tother src - ufw: - rule: deny + # connection refused + rule: reject to_port: "{{ item }}" direction: in state: enabled -- 2.40.1 From 7c2ed7419db2a00fe710db46d80f9df9e2b90a9b Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 15:31:57 +0200 Subject: [PATCH 05/12] add a local media dir and set internal/external url, media path and currency/units/tz --- roles/hass/tasks/hass.yml | 10 +++++++--- roles/hass/templates/configuration.yaml.j2 | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/roles/hass/tasks/hass.yml b/roles/hass/tasks/hass.yml index abf38d2..48bbccc 100644 --- a/roles/hass/tasks/hass.yml +++ b/roles/hass/tasks/hass.yml @@ -76,6 +76,7 @@ - home-assistant - home-assistant/config - home-assistant/.config + - home-assistant/media - zwavejs - zwavejs/app - zwavejs/app/store @@ -127,7 +128,7 @@ - "127.0.0.1:8091:8091" mounts: - type: bind - source: /var/lib/hass/zwavejs/app/store + source: "{{ systemuserlist.hass.home }}/zwavejs/app/store" target: /usr/src/app/store tags: - zwavejs @@ -154,11 +155,14 @@ TZ: "Etc/UTC" mounts: - type: bind - source: /var/lib/hass/home-assistant/config + source: "{{ systemuserlist.hass.home }}/home-assistant/config" target: /config - type: bind - source: /var/lib/hass/home-assistant/.config + source: "{{ systemuserlist.hass.home }}/home-assistant/.config" target: /.config + - type: bind + source: "{{ systemuserlist.hass.home }}/home-assistant/media" + target: /usr/var/media tags: - home-assistant - home-assistant-container diff --git a/roles/hass/templates/configuration.yaml.j2 b/roles/hass/templates/configuration.yaml.j2 index 387d839..ead3793 100644 --- a/roles/hass/templates/configuration.yaml.j2 +++ b/roles/hass/templates/configuration.yaml.j2 @@ -82,6 +82,21 @@ http: - {{ bridgewithdns_cidr }} use_x_forwarded_for: true +homeassistant: + name: Home + currency: EUR + unit_system: metric + time_zone: "Europe/Berlin" + external_url: https://{{ hass_url }} + internal_url: https://{{ hass_url }} + allowlist_external_dirs: + - "/usr/var/media" + allowlist_external_urls: + - "https://{{ static_url }}" + - "https://{{ hass_notflix_url }}" + media_dirs: + media: "/usr/var/media" + sensor: # https://www.home-assistant.io/integrations/dwd_weather_warnings/ # https://www.dwd.de/DE/leistungen/opendata/help/warnungen/warning_codes_pdf.pdf?__blob=publicationFile&v=5 -- 2.40.1 From 42e8c67fd1cf89431ab908dac7e7e528f0fbc4d6 Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 15:32:47 +0200 Subject: [PATCH 06/12] set content-security-policy --- roles/monitoring-server/tasks/grafana.yml | 1 + roles/monitoring-server/templates/01-grafana.j2 | 1 + roles/www/templates/01-sudo.is.conf.j2 | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/roles/monitoring-server/tasks/grafana.yml b/roles/monitoring-server/tasks/grafana.yml index ac5421b..90ec5ea 100644 --- a/roles/monitoring-server/tasks/grafana.yml +++ b/roles/monitoring-server/tasks/grafana.yml @@ -22,6 +22,7 @@ dest: /etc/nginx/sites-enabled/01-grafana tags: - grafana-config + - grafana-nginx - nginx-grafana - nginx notify: reload nginx diff --git a/roles/monitoring-server/templates/01-grafana.j2 b/roles/monitoring-server/templates/01-grafana.j2 index 3bc2ce8..3a7bce8 100644 --- a/roles/monitoring-server/templates/01-grafana.j2 +++ b/roles/monitoring-server/templates/01-grafana.j2 @@ -51,6 +51,7 @@ server { add_header Referrer-Policy "no-referrer" always; add_header X-Download-Options "noopen" always; add_header X-Robots-Tag "none" always; + add_header Content-Security-Policy "frame-ancestors 'self' {{ cast_refer }} https://*.{{ domain }};" always; fastcgi_hide_header X-Powered-By; } diff --git a/roles/www/templates/01-sudo.is.conf.j2 b/roles/www/templates/01-sudo.is.conf.j2 index 7448f41..e86ea53 100644 --- a/roles/www/templates/01-sudo.is.conf.j2 +++ b/roles/www/templates/01-sudo.is.conf.j2 @@ -2,7 +2,7 @@ server { - server_name {{ server_names | join(" ") }}; + server_name {%- for d in server_names %} www.{{ d }} {{ d }}{% endfor %}; {% if inventory_hostname in wg_clients -%} listen {{ wg_clients[inventory_hostname].ip }}:443 ssl http2; @@ -53,7 +53,7 @@ server { add_header Referrer-Policy "no-referrer" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Download-Options "noopen" always; - add_header X-Frame-Options "SAMEORIGIN" always; + add_header Content-Security-Policy "frame-ancestors 'self' {{ cast_refer }} {%- for d in server_names %} https://*.{{ d }}{% endfor %};" always; add_header X-Permitted-Cross-Domain-Policies "none" always; # add_header X-Robots-Tag "none" always; add_header X-XSS-Protection "1; mode=block" always; -- 2.40.1 From e053bf911ff0096a6ff729f197b4cb731e9fe74b Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 16:28:27 +0200 Subject: [PATCH 07/12] nginx uses bridge network --- roles/hass/tasks/hass.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/hass/tasks/hass.yml b/roles/hass/tasks/hass.yml index 48bbccc..e3aa9cb 100644 --- a/roles/hass/tasks/hass.yml +++ b/roles/hass/tasks/hass.yml @@ -125,7 +125,6 @@ - "/dev/serial/by-id/usb-0658_0200-if00:/dev/zwave:rwm" ports: - "127.0.0.1:3000:3000" # ws for hass<->zwavejs (hass is in host mode, so its not on the bridged network) - - "127.0.0.1:8091:8091" mounts: - type: bind source: "{{ systemuserlist.hass.home }}/zwavejs/app/store" -- 2.40.1 From d089c5b3133ee6167d024887cfb75107561b090b Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 19:08:18 +0200 Subject: [PATCH 08/12] gafana proxy and cleanup --- roles/hass/tasks/hass.yml | 18 ++++++++++++++++-- roles/hass/templates/01-grafana-proxy.j2 | 23 +++++++++++++++++++++++ roles/hass/templates/01-hass.j2 | 3 +-- 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 roles/hass/templates/01-grafana-proxy.j2 diff --git a/roles/hass/tasks/hass.yml b/roles/hass/tasks/hass.yml index e3aa9cb..1830d04 100644 --- a/roles/hass/tasks/hass.yml +++ b/roles/hass/tasks/hass.yml @@ -125,6 +125,7 @@ - "/dev/serial/by-id/usb-0658_0200-if00:/dev/zwave:rwm" ports: - "127.0.0.1:3000:3000" # ws for hass<->zwavejs (hass is in host mode, so its not on the bridged network) + - "8091:8091" mounts: - type: bind source: "{{ systemuserlist.hass.home }}/zwavejs/app/store" @@ -167,8 +168,9 @@ - home-assistant-container - hass-container - docker-containers + register: hass_container -- name: template nginx vhost +- name: template nginx vhost for hass template: src: 01-hass.j2 dest: /etc/nginx/sites-enabled/01-hass @@ -180,4 +182,16 @@ - hass-nginx - zwave-nginx notify: restart nginx - register: hass_container + +# different task because its better for the hass config to restart nginx +- name: template nginx vhost for grafana-proxy + template: + src: 01-grafana-proxy.j2 + dest: /etc/nginx/sites-enabled/01-grafana + owner: root + group: root + mode: 0644 + tags: + - nginx + - grafana-proxy-nginx + notify: reload nginx diff --git a/roles/hass/templates/01-grafana-proxy.j2 b/roles/hass/templates/01-grafana-proxy.j2 new file mode 100644 index 0000000..25a027c --- /dev/null +++ b/roles/hass/templates/01-grafana-proxy.j2 @@ -0,0 +1,23 @@ +server { + listen 443 ssl http2; + + include /etc/nginx/sudo-known.conf; + + server_name {{ hass_grafana_proxy_url }}; + + location / { + proxy_set_header Host {{ grafana_url }}; + proxy_set_header Authorization "{{ hass_grafana_proxy_auth_header }}"; + + proxy_pass https://{{ hass_grafana_proxy_pass }}; + } + + access_log /var/log/nginx/access_{{ hass_grafana_proxy_url }}.log main; + error_log /var/log/nginx/error_{{ hass_grafana_proxy_url }}.log warn; + + ssl_session_timeout 5m; + ssl_certificate /usr/local/etc/certs/{{ domain }}/fullchain.pem; + ssl_certificate_key /usr/local/etc/certs/{{ domain }}/privkey.pem; + + fastcgi_hide_header X-Powered-By; +} diff --git a/roles/hass/templates/01-hass.j2 b/roles/hass/templates/01-hass.j2 index 0e86f0b..2c26301 100644 --- a/roles/hass/templates/01-hass.j2 +++ b/roles/hass/templates/01-hass.j2 @@ -1,6 +1,6 @@ map $http_upgrade $connection_upgrade { default upgrade; - '' close; + '' upgrade; } server { @@ -27,7 +27,6 @@ server { proxy_pass http://127.0.0.1:8123; } - location = {{ nginx_zwavejs_path }} { # zwavejs needs to be accessed with a trailing / to respond. # -- 2.40.1 From 993d099a9276e72e1f8a39e6c63955728efa71a9 Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 19:11:59 +0200 Subject: [PATCH 09/12] cleanup --- roles/hass/tasks/hass.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/hass/tasks/hass.yml b/roles/hass/tasks/hass.yml index 1830d04..406c3cb 100644 --- a/roles/hass/tasks/hass.yml +++ b/roles/hass/tasks/hass.yml @@ -125,7 +125,6 @@ - "/dev/serial/by-id/usb-0658_0200-if00:/dev/zwave:rwm" ports: - "127.0.0.1:3000:3000" # ws for hass<->zwavejs (hass is in host mode, so its not on the bridged network) - - "8091:8091" mounts: - type: bind source: "{{ systemuserlist.hass.home }}/zwavejs/app/store" -- 2.40.1 From bf6dafbcee36ad8cda5173135af1991eb44c3246 Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 19:18:17 +0200 Subject: [PATCH 10/12] comment explaining something i burned myself on today --- roles/hass/tasks/hass.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/roles/hass/tasks/hass.yml b/roles/hass/tasks/hass.yml index 406c3cb..9939377 100644 --- a/roles/hass/tasks/hass.yml +++ b/roles/hass/tasks/hass.yml @@ -124,7 +124,13 @@ devices: - "/dev/serial/by-id/usb-0658_0200-if00:/dev/zwave:rwm" ports: - - "127.0.0.1:3000:3000" # ws for hass<->zwavejs (hass is in host mode, so its not on the bridged network) + # ws for hass<->zwavejs + # hass is configured to use localhost:3000 to talk to zwavejs, but can + # also use {{ bridgewithdns.zwavejs }}, but hass is very fragile and + # you have to manually work around it if it cant access zwaevjs because the + # ip/dns changed or the container moved networks. it is not configured in a + # config file either. so using localhost is the least fragile strategy. + - "127.0.0.1:3000:3000" mounts: - type: bind source: "{{ systemuserlist.hass.home }}/zwavejs/app/store" -- 2.40.1 From f417e131574eb18472b5975413d598215856b863 Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 22:34:02 +0200 Subject: [PATCH 11/12] not needed --- roles/monitoring-server/templates/01-grafana.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/monitoring-server/templates/01-grafana.j2 b/roles/monitoring-server/templates/01-grafana.j2 index 3a7bce8..da02794 100644 --- a/roles/monitoring-server/templates/01-grafana.j2 +++ b/roles/monitoring-server/templates/01-grafana.j2 @@ -51,7 +51,7 @@ server { add_header Referrer-Policy "no-referrer" always; add_header X-Download-Options "noopen" always; add_header X-Robots-Tag "none" always; - add_header Content-Security-Policy "frame-ancestors 'self' {{ cast_refer }} https://*.{{ domain }};" always; + add_header Content-Security-Policy "frame-ancestors 'self' https://*.{{ domain }};" always; fastcgi_hide_header X-Powered-By; } -- 2.40.1 From c517b925774c26b28d308b90b65ef6dad1ae8d0a Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Sun, 2 Oct 2022 23:34:48 +0200 Subject: [PATCH 12/12] add csp header --- roles/hass/templates/01-grafana-proxy.j2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/roles/hass/templates/01-grafana-proxy.j2 b/roles/hass/templates/01-grafana-proxy.j2 index 25a027c..78db81c 100644 --- a/roles/hass/templates/01-grafana-proxy.j2 +++ b/roles/hass/templates/01-grafana-proxy.j2 @@ -9,6 +9,9 @@ server { proxy_set_header Host {{ grafana_url }}; proxy_set_header Authorization "{{ hass_grafana_proxy_auth_header }}"; + {# strip header from requst #} + {# proxy_set_header Referer ""; #} + proxy_pass https://{{ hass_grafana_proxy_pass }}; } @@ -19,5 +22,7 @@ server { ssl_certificate /usr/local/etc/certs/{{ domain }}/fullchain.pem; ssl_certificate_key /usr/local/etc/certs/{{ domain }}/privkey.pem; + add_header Content-Security-Policy "frame-ancestors 'self' {{ cast_refer }} https://*.{{ domain }};" always; + fastcgi_hide_header X-Powered-By; } -- 2.40.1