From 6b2c70f5da7e45e5b2ed662a3d85763aebab13ea Mon Sep 17 00:00:00 2001 From: Sonny Bakker Date: Sun, 6 Apr 2025 19:30:16 +0200 Subject: [PATCH 1/2] Add radicale to vpn config & use RouteTable directive --- host_vars/desktop/vpn.yml | 50 +++++++++---------- host_vars/xps/vpn.yml | 40 +++++++-------- .../personal/desktop/network/wg0.netdev.j2 | 3 +- .../personal/desktop/network/wg0.network.j2 | 10 ---- .../personal/desktop/network/wg1.netdev.j2 | 3 +- templates/personal/xps/network/wg0.netdev.j2 | 3 +- templates/personal/xps/network/wg0.network.j2 | 10 ---- templates/personal/xps/network/wg1.netdev.j2 | 3 +- 8 files changed, 51 insertions(+), 71 deletions(-) diff --git a/host_vars/desktop/vpn.yml b/host_vars/desktop/vpn.yml index 887ccdf..ffcd439 100644 --- a/host_vars/desktop/vpn.yml +++ b/host_vars/desktop/vpn.yml @@ -1,49 +1,47 @@ # TODO: scope variables to their destination file vpn_default: - ip: '10.0.0.3' - prefix: '24' - interface: 'wg0' - dns: '10.0.0.1' + ip: 10.0.0.3 + prefix: 24 + interface: wg0 + dns: 10.0.0.1 domains: - - ~vpn.{{ server_domain }} - - ~transmission.{{ server_domain }} - - ~syncthing.{{ server_domain }} + - '~vpn.{{ server_domain }}' + - '~transmission.{{ server_domain }}' + - '~syncthing.{{ server_domain }}' + - '~radicale.{{ server_domain }}' public_key_path: '{{ vpn_config_dir }}/keys/public/default/desktop.pub' private_key_path: '{{ vpn_config_dir }}/keys/private/default/desktop.key' peers: - - name: 'fudiggity' + - name: fudiggity allowed_ips: - - address: '10.0.0.0/24' - create_route: false - - address: '172.16.238.0/24' - create_route: true - - address: '172.32.238.0/24' - create_route: true + - 10.0.0.0/24 + - 172.16.238.0/24 + - 172.32.238.0/24 + - 172.64.238.0/24 endpoint: '{{ server_domain }}:51902' - public_key: 'CeybSMpJiicXmndIuhe89Bay3z3PEdYNyAwIFsacBEo=' + public_key: CeybSMpJiicXmndIuhe89Bay3z3PEdYNyAwIFsacBEo= preshared_key_path: '{{ vpn_config_dir }}/keys/private/default/preshared-zeus.psk' - preshared_key_source_path: 'files/personal/desktop/wireguard/default/preshared.psk' + preshared_key_source_path: files/personal/desktop/wireguard/default/preshared.psk vpn_media: - ip: '10.0.1.3' - prefix: '24' - interface: 'wg1' - dns: '10.0.1.1' + ip: 10.0.1.3 + prefix: 24 + interface: wg1 + dns: 10.0.1.1 domains: - '~media-vpn.{{ server_domain }}' public_key_path: '{{ vpn_config_dir }}/keys/public/media/desktop.pub' private_key_path: '{{ vpn_config_dir }}/keys/private/media/desktop.key' - private_key_source_path: 'files/personal/desktop/wireguard/media/desktop.key' + private_key_source_path: files/personal/desktop/wireguard/media/desktop.key peers: - - name: 'zeus-media' + - name: zeus-media allowed_ips: - - address: '10.0.1.0/24' - create_route: false + - 10.0.1.0/24 endpoint: '{{ server_domain }}:51903' - public_key: 'EugKeo63C5N5kz9ShMHtYswO9Qh6mE00MtfLSFmqqjg=' + public_key: EugKeo63C5N5kz9ShMHtYswO9Qh6mE00MtfLSFmqqjg= preshared_key_path: '{{ vpn_config_dir }}/keys/private/media/preshared-zeus.psk' - preshared_key_source_path: 'files/personal/desktop/wireguard/media/preshared.psk' + preshared_key_source_path: files/personal/desktop/wireguard/media/preshared.psk diff --git a/host_vars/xps/vpn.yml b/host_vars/xps/vpn.yml index 1a2eab2..5d4c0ac 100644 --- a/host_vars/xps/vpn.yml +++ b/host_vars/xps/vpn.yml @@ -1,35 +1,34 @@ vpn_default: - ip: '10.0.0.2' - prefix: '24' - interface: 'wg0' - dns: '10.0.0.1' + ip: 10.0.0.2 + prefix: 24 + interface: wg0 + dns: 10.0.0.1 domains: - '~vpn.{{ server_domain }}' - '~transmission.{{ server_domain }}' - '~syncthing.{{ server_domain }}' + - '~radicale.{{ server_domain }}' public_key_path: '{{ vpn_config_dir }}/keys/public/default/laptop.pub' private_key_path: '{{ vpn_config_dir }}/keys/private/default/laptop.key' peers: - - name: 'fudiggity' + - name: fudiggity allowed_ips: - - address: '10.0.0.0/24' - create_route: false - - address: '172.16.238.0/24' - create_route: true - - address: '172.32.238.0/24' - create_route: true + - 10.0.0.0/24 + - 172.16.238.0/24 + - 172.32.238.0/24 + - 172.64.238.0/24 endpoint: '{{ server_domain }}:51902' public_key: 'CeybSMpJiicXmndIuhe89Bay3z3PEdYNyAwIFsacBEo=' preshared_key_path: '{{ vpn_config_dir }}/keys/private/default/preshared-zeus.psk' - preshared_key_source_path: 'files/personal/xps/wireguard/default/preshared.psk' + preshared_key_source_path: files/personal/xps/wireguard/default/preshared.psk vpn_media: - ip: '10.0.1.2' - prefix: '24' - interface: 'wg1' - dns: '10.0.1.1' + ip: 10.0.1.2 + prefix: 24 + interface: wg1 + dns: 10.0.1.1 domains: - '~media-vpn.{{ server_domain }}' @@ -37,11 +36,10 @@ vpn_media: private_key_path: '{{ vpn_config_dir }}/keys/private/media/laptop.key' peers: - - name: 'fudiggity-media' + - name: fudiggity-media allowed_ips: - - address: '10.0.1.0/24' - create_route: false + - 10.0.1.0/24 endpoint: '{{ server_domain }}:51903' - public_key: 'EugKeo63C5N5kz9ShMHtYswO9Qh6mE00MtfLSFmqqjg=' + public_key: EugKeo63C5N5kz9ShMHtYswO9Qh6mE00MtfLSFmqqjg= preshared_key_path: '{{ vpn_config_dir }}/keys/private/media/preshared-zeus.psk' - preshared_key_source_path: 'files/personal/xps/wireguard/media/preshared.psk' + preshared_key_source_path: files/personal/xps/wireguard/media/preshared.psk diff --git a/templates/personal/desktop/network/wg0.netdev.j2 b/templates/personal/desktop/network/wg0.netdev.j2 index ffceef7..db08b4e 100644 --- a/templates/personal/desktop/network/wg0.netdev.j2 +++ b/templates/personal/desktop/network/wg0.netdev.j2 @@ -7,13 +7,14 @@ Description=WireGuard tunnel {{ vpn_default.interface }} [WireGuard] PrivateKeyFile={{ vpn_default.private_key_path }} +RouteTable=main {% for peer in vpn_default.peers %} [WireGuardPeer] PublicKey={{ peer.public_key }} PresharedKeyFile={{ peer.preshared_key_path }} {% for ip in peer.allowed_ips %} -AllowedIPs={{ ip.address }} +AllowedIPs={{ ip }} {% endfor %} {% if peer.endpoint %} Endpoint={{ peer.endpoint }} diff --git a/templates/personal/desktop/network/wg0.network.j2 b/templates/personal/desktop/network/wg0.network.j2 index 515a71a..36beed3 100644 --- a/templates/personal/desktop/network/wg0.network.j2 +++ b/templates/personal/desktop/network/wg0.network.j2 @@ -7,13 +7,3 @@ Name={{ vpn_default.interface }} Address={{ vpn_default.ip }}/{{ vpn_default.prefix }} DNS={{ vpn_default.dns }} Domains={{ vpn_default.domains | join(' ') }} - -{% for peer in vpn_default.peers %} -{% for ip in peer.allowed_ips %} -{% if ip.create_route %} -[Route] -Destination={{ ip.address }} -Scope=link -{% endif %} -{% endfor %} -{% endfor %} diff --git a/templates/personal/desktop/network/wg1.netdev.j2 b/templates/personal/desktop/network/wg1.netdev.j2 index 13d86df..5fbc9f9 100644 --- a/templates/personal/desktop/network/wg1.netdev.j2 +++ b/templates/personal/desktop/network/wg1.netdev.j2 @@ -7,13 +7,14 @@ Description=WireGuard tunnel {{ vpn_media.interface }} [WireGuard] PrivateKeyFile={{ vpn_media.private_key_path }} +RouteTable=main {% for peer in vpn_media.peers %} [WireGuardPeer] PublicKey={{ peer.public_key }} PresharedKeyFile={{ peer.preshared_key_path }} {% for ip in peer.allowed_ips %} -AllowedIPs={{ ip.address }} +AllowedIPs={{ ip }} {% endfor %} {% if peer.endpoint %} Endpoint={{ peer.endpoint }} diff --git a/templates/personal/xps/network/wg0.netdev.j2 b/templates/personal/xps/network/wg0.netdev.j2 index ffceef7..db08b4e 100644 --- a/templates/personal/xps/network/wg0.netdev.j2 +++ b/templates/personal/xps/network/wg0.netdev.j2 @@ -7,13 +7,14 @@ Description=WireGuard tunnel {{ vpn_default.interface }} [WireGuard] PrivateKeyFile={{ vpn_default.private_key_path }} +RouteTable=main {% for peer in vpn_default.peers %} [WireGuardPeer] PublicKey={{ peer.public_key }} PresharedKeyFile={{ peer.preshared_key_path }} {% for ip in peer.allowed_ips %} -AllowedIPs={{ ip.address }} +AllowedIPs={{ ip }} {% endfor %} {% if peer.endpoint %} Endpoint={{ peer.endpoint }} diff --git a/templates/personal/xps/network/wg0.network.j2 b/templates/personal/xps/network/wg0.network.j2 index 515a71a..36beed3 100644 --- a/templates/personal/xps/network/wg0.network.j2 +++ b/templates/personal/xps/network/wg0.network.j2 @@ -7,13 +7,3 @@ Name={{ vpn_default.interface }} Address={{ vpn_default.ip }}/{{ vpn_default.prefix }} DNS={{ vpn_default.dns }} Domains={{ vpn_default.domains | join(' ') }} - -{% for peer in vpn_default.peers %} -{% for ip in peer.allowed_ips %} -{% if ip.create_route %} -[Route] -Destination={{ ip.address }} -Scope=link -{% endif %} -{% endfor %} -{% endfor %} diff --git a/templates/personal/xps/network/wg1.netdev.j2 b/templates/personal/xps/network/wg1.netdev.j2 index 13d86df..5fbc9f9 100644 --- a/templates/personal/xps/network/wg1.netdev.j2 +++ b/templates/personal/xps/network/wg1.netdev.j2 @@ -7,13 +7,14 @@ Description=WireGuard tunnel {{ vpn_media.interface }} [WireGuard] PrivateKeyFile={{ vpn_media.private_key_path }} +RouteTable=main {% for peer in vpn_media.peers %} [WireGuardPeer] PublicKey={{ peer.public_key }} PresharedKeyFile={{ peer.preshared_key_path }} {% for ip in peer.allowed_ips %} -AllowedIPs={{ ip.address }} +AllowedIPs={{ ip }} {% endfor %} {% if peer.endpoint %} Endpoint={{ peer.endpoint }} From 20bf21baa2e934d6979e512347679313275e5d41 Mon Sep 17 00:00:00 2001 From: Sonny Bakker Date: Sun, 6 Apr 2025 21:16:57 +0200 Subject: [PATCH 2/2] Add pa-dlna setup for xps --- host_vars/xps/vpn.yml | 3 ++ tasks/personal/xps.yml | 45 ++++++++++++++++++++++- templates/personal/xps/nftables.j2 | 3 ++ templates/personal/xps/pa-dlna/config.j2 | 26 +++++++++++++ templates/personal/xps/pa-dlna/service.j2 | 40 ++++++++++++++++++++ 5 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 templates/personal/xps/pa-dlna/config.j2 create mode 100644 templates/personal/xps/pa-dlna/service.j2 diff --git a/host_vars/xps/vpn.yml b/host_vars/xps/vpn.yml index 5d4c0ac..22822fd 100644 --- a/host_vars/xps/vpn.yml +++ b/host_vars/xps/vpn.yml @@ -1,3 +1,6 @@ +pa_dlna_version: 0.16 +pa_dlna_systemd_version: 0.0.9 + vpn_default: ip: 10.0.0.2 prefix: 24 diff --git a/tasks/personal/xps.yml b/tasks/personal/xps.yml index 10b48b2..b1eb784 100644 --- a/tasks/personal/xps.yml +++ b/tasks/personal/xps.yml @@ -1,9 +1,50 @@ - name: Provision powertop systemd service become: true ansible.builtin.template: - src: 'templates/personal/xps/powertop.service.j2' - dest: '/etc/systemd/system/powertop.service' + src: templates/personal/xps/powertop.service.j2 + dest: /etc/systemd/system/powertop.service owner: root group: root mode: '0644' notify: restart powertop + +- name: Provision python pa-dlna + block: + - name: Create configuration directory + ansible.builtin.file: + path: '{{ xdg_config_dir }}/pa-dlna' + state: directory + mode: '0755' + + - name: Copy configuration file + ansible.builtin.template: + src: templates/personal/xps/pa-dlna/config.j2 + dest: '{{ xdg_config_dir }}/pa-dlna/pa-dlna.conf' + mode: '0755' + + - name: Copy systemd service + ansible.builtin.template: + src: templates/personal/xps/pa-dlna/service.j2 + dest: '{{ xdg_config_dir }}/systemd/user/pa-dlna.service' + mode: '0755' + + - name: Create virtualenv directory + become: true + ansible.builtin.file: + path: /opt/virtualenv/pa-dlna + state: directory + owner: sonny + group: sonny + mode: '0755' + + - name: Install pa-dlna + ansible.builtin.pip: + name: 'pa-dlna=={{ pa_dlna_version }}' + virtualenv: /opt/virtualenv/pa-dlna + virtualenv_command: python3.13 -m venv + + - name: Install python-systemd + ansible.builtin.pip: + name: 'python-systemd=={{ pa_dlna_systemd_version }}' + virtualenv: /opt/virtualenv/pa-dlna + virtualenv_command: python3.13 -m venv diff --git a/templates/personal/xps/nftables.j2 b/templates/personal/xps/nftables.j2 index b54a534..5140777 100644 --- a/templates/personal/xps/nftables.j2 +++ b/templates/personal/xps/nftables.j2 @@ -23,6 +23,9 @@ table inet filter { # allow ssh tcp dport ssh accept + ip saddr 192.168.2.11 tcp dport 8080 accept comment "HTTP pa-dlna server" + ip saddr 192.168.2.11 udp dport 1900 accept comment "UPnP" + # syncthing ip saddr 10.0.0.1 tcp dport 22000 accept } diff --git a/templates/personal/xps/pa-dlna/config.j2 b/templates/personal/xps/pa-dlna/config.j2 new file mode 100644 index 0000000..865a203 --- /dev/null +++ b/templates/personal/xps/pa-dlna/config.j2 @@ -0,0 +1,26 @@ +# {{ ansible_managed }} +# +# This is the built-in pa-dlna configuration written as text. It can be +# parsed by a Python Configuration parser and consists of sections, each led +# by a [section] header, followed by option/value entries separated by +# '='. See https://docs.python.org/3/library/configparser.html. +# +# The 'selection' option is written as a multi-line in which case all the +# lines after the first line start with a white space. +# +# The default value of 'selection' lists the encoders in this order: +# - mp3 encoders first as mp3 is the most common encoding +# - lossless encoders +# - then lossy encoders +# See https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio. + +[DEFAULT] +selection = + FFMpegFlacEncoder, + FFMpegOpusEncoder, +sample_format = s24be +rate = 96000 +channels = 2 +track_metadata = yes +soap_minimum_interval = 5 +args = None diff --git a/templates/personal/xps/pa-dlna/service.j2 b/templates/personal/xps/pa-dlna/service.j2 new file mode 100644 index 0000000..feef6f1 --- /dev/null +++ b/templates/personal/xps/pa-dlna/service.j2 @@ -0,0 +1,40 @@ +# {{ ansible_managed }} +# +# When enabled, the pa-dlna service unit is started automatically after the +# pulseaudio or pipewire service unit is started. It will also stop when the +# pulseaudio or pipewire service unit stops. However it will stop when the +# pulseaudio or pipewire service unit is restarted but it will not start. +# +# Both pa-dlna and pulseaudio service units are of 'Type=notify'. This means +# that pa-dlna will only start after pulseaudio has notified systemd that it +# is ready and pa-dlna may connect successfully to libpulse. +# +# However the pipewire service unit is of 'Type=simple'. In that case and if +# pa-dlna fails to start with the error: +# LibPulseStateError(('PA_CONTEXT_FAILED', 'Connection refused')) +# add a delay to the pa-dlna start up sequence with the directive: +# ExecStartPre=/bin/sleep 1 +# +# Any pa-dlna option may be added to the 'ExecStart' directive, for example to +# restrict the allowed NICs or IP addresses (recommended) or to change the +# log level. +# The '--systemd' option is required. +# +# The 'python-systemd' package is required. + +[Unit] +Description=Pa-dlna Service +Documentation=https://pa-dlna.readthedocs.io/en/stable/ + +After=pipewire-session-manager.service + +[Service] +Type=simple +ExecStart=/opt/virtualenv/pa-dlna/bin/pa-dlna +Slice=session.slice + +NoNewPrivileges=yes +UMask=0077 + +[Install] +WantedBy=pipewire-session-manager.service