Technitium working

This commit is contained in:
2026-09-11 18:25:20 -04:00
parent 16ae125e1f
commit f4e770f569
15 changed files with 224 additions and 53 deletions
@@ -1 +1,2 @@
ha_pair_value: '01'
subnet_suffix_value: '1'
@@ -0,0 +1 @@
unprivileged_user: quadlet
@@ -1 +1,2 @@
ha_pair_value: '02'
subnet_suffix_value: '2'
@@ -0,0 +1 @@
unprivileged_user: quadlet
@@ -0,0 +1 @@
unprivileged_user: download
+1 -1
View File
@@ -3,7 +3,7 @@
- name: Configure ssh and firewall
hosts:
# - archlinux_servers
- ch01.balsillie.house
- ch02.balsillie.house
gather_facts: false
become: true
pre_tasks:
+5 -1
View File
@@ -1,6 +1,10 @@
[storage]
driver = "overlay"
graphroot="$HOME/.local/share/containers/storage"
[storage.options]
ignore_chown_errors = "true"
additionalimagestores = [
"/var/containers/images"
]
]
[storage.options.overlay]
mount_program = "/usr/bin/fuse-overlayfs"
+13
View File
@@ -0,0 +1,13 @@
# code: language=ansible
- name: Quadlet daemon-reload # noqa: command-instead-of-module
ansible.builtin.command:
cmd: systemctl --user --machine=quadlet@.host daemon-reload
changed_when: false
# - name: Quadlet daemon-reload # noqa: command-instead-of-module
# become: true
# become_user: quadlet
# ansible.builtin.systemd_service:
# daemon_reload: true
# scope: user
+88 -10
View File
@@ -8,6 +8,7 @@
- passt
- podlet
- podman-compose
- fuse-overlayfs
state: present
update_cache: true
@@ -22,28 +23,50 @@
- name: Create an unprivileged user to run quadlet files as
ansible.builtin.user:
comment: Quadlet services user
create_home: false
home: /
create_home: true
home: /home/quadlet
name: quadlet
password: '!'
password_lock: true
shell: /usr/bin/nologin
shell: /usr/bin/bash
state: present
system: true
system: false # Can't be a system user or subuid/subgid entries don't get created
- name: Ensure quadlet user parent directory exists
- name: Ensure graphroot location exists for unprivileged user
ansible.builtin.file:
group: root
mode: '0755'
owner: root
path: /etc/containers/systemd/users
group: quadlet
mode: '0750'
owner: quadlet
path: "/home/quadlet/.local/share/containers/storage"
state: directory
- name: Create quadlet user directory
- name: Enable linger for unprivileged user
ansible.builtin.command:
cmd: loginctl enable-linger quadlet
creates: /var/lib/systemd/linger/quadlet
register: podman_enable_linger_result
- name: Reboot if enabling lingering caused a change # noqa: no-handler
when:
- podman_enable_linger_result is changed
ansible.builtin.reboot:
post_reboot_delay: 10
test_command: whoami
- name: Create directories for quadlet volumes
ansible.builtin.file:
group: quadlet
mode: '0775'
owner: quadlet
path: /quadlet/{{ item }}
state: directory
loop: "{{ podman_containers }}"
- name: Create quadlet systemd user directory
ansible.builtin.file:
group: root
mode: '0775'
owner: root
path: /etc/containers/systemd/users/quadlet
state: directory
@@ -79,3 +102,58 @@
mode: '0644'
owner: root
src: "{{ role_path }}/files/storage.conf"
- name: Template out volume unit files
ansible.builtin.template:
dest: /etc/containers/systemd/users/quadlet/{{ item }}.volume
group: root
mode: '0644'
owner: root
src: "{{ role_path }}/templates/quadlet.volume.j2"
loop: "{{ podman_containers }}"
notify:
- Quadlet daemon-reload
- name: Template out network unit file
ansible.builtin.template:
dest: /etc/containers/systemd/users/quadlet/dual-stack.network
group: root
mode: '0644'
owner: root
src: "{{ role_path }}/templates/dual-stack.network.j2"
notify:
- Quadlet daemon-reload
- name: Template out container unit files
ansible.builtin.template:
dest: /etc/containers/systemd/users/quadlet/{{ item }}.container
group: root
mode: '0644'
owner: root
src: "{{ role_path }}/templates/{{ item }}.container.j2"
loop:
- technitium
notify:
- Quadlet daemon-reload
- name: Flush handlers to trigger daemon-reload
ansible.builtin.meta: flush_handlers
- name: Enable IP forwarding
ansible.posix.sysctl:
name: "{{ item }}"
reload: true
state: present
sysctl_set: true
value: 1
loop:
- net.ipv4.ip_forward
- net.ipv6.conf.all.forwarding
# Enable forwarding rules in UFW
# Enable/start user service
# Add to containers.conf
# [network]
# rootless_port_forwarder="pasta"
@@ -0,0 +1,12 @@
[Network]
NetworkDeleteOnStop=true
DisableDNS=no
Driver=bridge
Internal=no
IPv6=yes
Subnet={{ podman_subnet_prefix_ipv4 }}{{ subnet_suffix_value }}.0/24
Subnet={{ podman_subnet_prefix_ipv6 }}{{ subnet_suffix_value }}::/64
IPRange={{ podman_subnet_prefix_ipv4 }}{{ subnet_suffix_value }}.128/26
IPRange={{ podman_subnet_prefix_ipv6 }}{{ subnet_suffix_value }}::0100/120
Gateway={{ podman_subnet_prefix_ipv4 }}{{ subnet_suffix_value }}.254
Gateway={{ podman_subnet_prefix_ipv6 }}{{ subnet_suffix_value }}::254
+5
View File
@@ -0,0 +1,5 @@
[Volume]
Device=/quadlet/{{ item }}
Group=quadlet
Type=bind
User=quadlet
@@ -0,0 +1,56 @@
[Unit]
Description=Technitium DNS Server
After=network-online.target
[Service]
Restart=on-failure
[Install]
WantedBy=default.target
[Container]
# Ref: https://manpages.opensuse.org/Tumbleweed/podman/quadlet.5.en.html#Container_units_%5BContainer%5D
ContainerName=technitium
Image={{ podman_technitium_registry }}/{{ podman_technitium_repository }}:{{ podman_technitium_version }}
HostName=ns{{ ha_pair_value }}
AutoUpdate=local
# Do not try to pull the image, use pre-populated local image store only
Pull=never
# Set timezone inside container
Timezone=America/New_York
# Volume mappings
Volume=technitium.volume:/etc/dns
# Specify custom podman network to use
Network=dual-stack.network
# Set container addresses
IP={{ podman_subnet_prefix_ipv4 }}{{ subnet_suffix_value }}.153
IP6={{ podman_subnet_prefix_ipv6 }}{{ subnet_suffix_value }}::0153
# Port mappings
# HTTP Web UI IPv4/6
PublishPort={{ ipv4_address }}:5380:5380/tcp
PublishPort=[{{ ipv6_address }}]:5380:5380/tcp
# DNS TCP/UDP IPv4/6
#PublishPort={{ ipv4_address }}:5353:53/tcp
#PublishPort=[{{ ipv6_address }}]:5353:53/udp
#PublishPort={{ ipv4_address }}:5353:53/udp
#PublishPort=[{{ ipv6_address }}]:5353:53/tcp
# Environment Variables
Environment=DNS_SERVER_DOMAIN=ns{{ ha_pair_value }}.{{ podman_local_domain }}
# UID/GID Mappings
UIDMap=0:0:1
@@ -1,37 +0,0 @@
[Unit]
Description=Technitium DNS Server
[Container]
ContainerName=technitium
Image={{ podman_technitium_registry }}/{{ podman_technitium_repository }}:{{ podman_technitium_version }}
# Enable auto-update container
AutoUpdate=registry
Volume=/path/to/syncthing/config:/config
Volume=/path/to/data1:/data1
HostName=technitium{{ ha_pair_value }}
PublishPort=127.0.0.1:8384:8384/tcp
PublishPort=22000:22000/tcp
Environment=PUID=1000
Environment=PGID=1000
Environment=TZ=Etc/UTC
# UID mapping is needed to run linuxserver.io container as rootless podman.
# This will map UID=1000 inside the container to intermediate UID=0.
# For rootless podman intermediate UID=0 will be mapped to the UID of current user.
UIDMap=1000:0:1
UIDMap=0:1:1000
UIDMap=1001:1001:64536
[Service]
Restart=on-failure
# Extend Timeout to allow time to pull the image
TimeoutStartSec=300
# The [Install] section allows enabling the generated service.
[Install]
WantedBy=default.target
+28
View File
@@ -1,5 +1,12 @@
# code: language=ansible
podman_containers:
- technitium
- git-server
- distribution
podman_local_domain: "balsillie.house"
podman_technitium_registry: "docker.io"
podman_technitium_repository: "technitium/dns-server"
podman_technitium_version: "15.4.0"
@@ -11,3 +18,24 @@ podman_distribution_version: "3"
podman_git_server_registry: "docker.io"
podman_git_server_repository: "rockstorm/git-server"
podman_git_server_version: "2.54"
podman_subnet_prefix_ipv4: '10.96.1'
podman_subnet_prefix_ipv6: '2600:4040:593d:8b1'
podman_ufw_rules:
- source: '10.96.30.0/24'
port: '5380'
proto: tcp
comment: 'Technitium Web UI LAN IPv4'
- source: '10.96.10.0/24'
port: '5380'
proto: tcp
comment: 'Technitium Web UI Servers IPv4'
- source: '2600:4040:593d:8b30::/64'
port: '5380'
proto: tcp
comment: 'Technitium Web UI LAN IPv6'
- source: '2600:4040:593d:8b10::/64'
port: '5380'
proto: tcp
comment: 'Technitium Web UI Servers IPv6'
+11 -4
View File
@@ -46,7 +46,7 @@
name: "{{ sudoers_user }}"
state: present
- name: Add sudoers entry
- name: Add sudoers entries
community.general.sudoers:
commands:
- ALL
@@ -54,12 +54,19 @@
- '!fqdn' # Ensures using shortname only when assessing hostname in sudo rule
group: sudo
host: "{{ inventory_hostname_short }}"
name: sudo_group
nopassword: false
runas: root
name: sudo_{{ item.name }}
nopassword: "{{ item.nopassword }}"
runas: "{{ item.name }}"
state: present
sudoers_path: "/etc/sudoers.d"
validation: required
loop:
- name: root
nopassword: false
- name: "{{ unprivileged_user }}"
nopassword: true
loop_control:
label: "{{ item.name }}"
- name: Remove default sudoers file
ansible.builtin.file: