summaryrefslogtreecommitdiff
path: root/roles/whawty/auth
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2024-01-28 02:11:05 +0100
committerChristian Pointner <equinox@spreadspace.org>2024-01-28 02:11:05 +0100
commit24b4917d8186551bcf987b72d1c3588e4705096a (patch)
tree4cba19d0999095ac27edafc9f88513fdaa80ab16 /roles/whawty/auth
parentmove ch-auth-legacy to _graveyard_ (diff)
finalize whawty/auth roles for now
Diffstat (limited to 'roles/whawty/auth')
-rw-r--r--roles/whawty/auth/app/defaults/main.yml18
-rw-r--r--roles/whawty/auth/app/tasks/listeners.yml18
-rw-r--r--roles/whawty/auth/app/tasks/main.yml18
-rw-r--r--roles/whawty/auth/app/templates/systemd.service.j232
-rw-r--r--roles/whawty/auth/app/templates/systemd.socket.j222
-rw-r--r--roles/whawty/auth/store/defaults/main.yml52
-rw-r--r--roles/whawty/auth/store/tasks/main.yml37
-rw-r--r--roles/whawty/auth/store/tasks/sync-client.yml49
-rw-r--r--roles/whawty/auth/store/templates/systemd.service.j26
9 files changed, 183 insertions, 69 deletions
diff --git a/roles/whawty/auth/app/defaults/main.yml b/roles/whawty/auth/app/defaults/main.yml
index fa188349..d1423a61 100644
--- a/roles/whawty/auth/app/defaults/main.yml
+++ b/roles/whawty/auth/app/defaults/main.yml
@@ -1,2 +1,18 @@
---
-whawty_install_pam_module: no
+whawty_auth_app_install_pam_module: no
+
+## TODO: add support for web config (including TLS)
+
+# whawty_auth_app_instances:
+# blub:
+# store: foo
+# listeners:
+# saslauthd:
+# sockets:
+# - /var/run/whawty/auth.sock
+# user: foo
+# group: bar
+# mode: 0600
+# web:
+# sockets:
+# - 127.0.0.1:1234
diff --git a/roles/whawty/auth/app/tasks/listeners.yml b/roles/whawty/auth/app/tasks/listeners.yml
new file mode 100644
index 00000000..82944222
--- /dev/null
+++ b/roles/whawty/auth/app/tasks/listeners.yml
@@ -0,0 +1,18 @@
+---
+- name: generate systemd socket units
+ loop: "{{ whawty_auth_app.config.listeners | dict2items }}"
+ loop_control:
+ label: "{{ item.key }}"
+ template:
+ src: systemd.socket.j2
+ dest: "/etc/systemd/system/whawty-auth-{{ whawty_auth_app.name }}_{{ item.key }}.socket"
+
+- name: make sure systemd socket units are enabled and started
+ loop: "{{ whawty_auth_app.config.listeners | dict2items }}"
+ loop_control:
+ label: "{{ item.key }}"
+ systemd:
+ daemon_reload: yes
+ name: "whawty-auth-{{ whawty_auth_app.name }}_{{ item.key }}.socket"
+ state: started
+ enabled: yes
diff --git a/roles/whawty/auth/app/tasks/main.yml b/roles/whawty/auth/app/tasks/main.yml
index 00a02c7e..cc19fd2e 100644
--- a/roles/whawty/auth/app/tasks/main.yml
+++ b/roles/whawty/auth/app/tasks/main.yml
@@ -1,5 +1,21 @@
---
- name: install whawty app
apt:
- name: "{{ ['whawty-auth'] | union(whawty_auth_install_pam_module | ternary(['libpam-whawty'], [])) }}"
+ name: "{{ ['whawty-auth'] | union(whawty_auth_app_install_pam_module | ternary(['libpam-whawty'], [])) }}"
state: present
+
+- name: generate systemd service units
+ loop: "{{ whawty_auth_app_instances | dict2items(key_name='name', value_name='config') }}"
+ loop_control:
+ loop_var: whawty_auth_app
+ label: "{{ whawty_auth_app.name }}"
+ template:
+ src: systemd.service.j2
+ dest: "/etc/systemd/system/whawty-auth-{{ whawty_auth_app.name }}.service"
+
+- name: generate, start and enable systemd socket units
+ loop: "{{ whawty_auth_app_instances | dict2items(key_name='name', value_name='config') }}"
+ loop_control:
+ loop_var: whawty_auth_app
+ label: "{{ whawty_auth_app.name }}"
+ include_tasks: listeners.yml
diff --git a/roles/whawty/auth/app/templates/systemd.service.j2 b/roles/whawty/auth/app/templates/systemd.service.j2
new file mode 100644
index 00000000..875d692e
--- /dev/null
+++ b/roles/whawty/auth/app/templates/systemd.service.j2
@@ -0,0 +1,32 @@
+{% set whawty_auth_store = whawty_auth_store_instances[whawty_auth_app.config.store] %}
+[Unit]
+Description=whawty.auth authentication agent for {{ whawty_auth_app.name }}
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/whawty-auth --store "/etc/whawty/auth/store-{{ whawty_auth_app.config.store }}.yml" runsa
+ExecReload=/bin/kill -HUP $MAINPID
+Restart=always
+RestartSec=3
+
+AmbientCapabilities=
+CapabilityBoundingSet=
+DeviceAllow=/dev/null rw
+DevicePolicy=strict
+LockPersonality=true
+MemoryDenyWriteExecute=true
+NoNewPrivileges=true
+PrivateDevices=true
+PrivateTmp=true
+ProtectControlGroups=true
+ProtectHome=true
+ProtectKernelModules=true
+ProtectKernelTunables=true
+ProtectSystem=strict
+{% if 'sync' not in whawty_auth_store or whawty_auth_store.sync.type != 'client' %}
+ReadWritePaths={{ whawty_auth_store.config.basedir }}
+{% endif %}
+RemoveIPC=true
+RestrictNamespaces=true
+RestrictRealtime=true
+SystemCallArchitectures=native
diff --git a/roles/whawty/auth/app/templates/systemd.socket.j2 b/roles/whawty/auth/app/templates/systemd.socket.j2
new file mode 100644
index 00000000..f0432e3b
--- /dev/null
+++ b/roles/whawty/auth/app/templates/systemd.socket.j2
@@ -0,0 +1,22 @@
+[Unit]
+Description=whawty.auth authentication agent for {{ whawty_auth_app.name }}/{{ item.key }}
+
+[Socket]
+Service=whawty-auth-{{ whawty_auth_app.name }}.service
+FileDescriptorName={{ item.key }}
+{% for socket in item.value.sockets %}
+ListenStream={{ socket }}
+{% endfor %}
+RemoveOnStop=true
+{% if 'user' in item.value %}
+SocketUser={{ item.value.user }}
+{% endif %}
+{% if 'group' in item.value %}
+SocketGroup={{ item.value.group }}
+{% endif %}
+{% if 'mode' in item.value %}
+SocketMode={{ item.value.mode }}
+{% endif %}
+
+[Install]
+WantedBy=sockets.target
diff --git a/roles/whawty/auth/store/defaults/main.yml b/roles/whawty/auth/store/defaults/main.yml
index b8cb08b7..c479c600 100644
--- a/roles/whawty/auth/store/defaults/main.yml
+++ b/roles/whawty/auth/store/defaults/main.yml
@@ -1,27 +1,27 @@
---
-# whawty_auth_store:
-# name: foo
-# config:
-# basedir: "/var/lib/whawty/auth/foo"
-# default: 2
-# params:
-# - id: 1
-# scryptauth:
-# hmackey: "<32bytes random secret data base64-encoded>"
-# cost: 12
-# - id: 2
-# argon2id:
-# time: 1
-# memory: 65536 ## 64 MB
-# threads: 4
-# length: 32
-# permissions:
-# owner: root
-# group: foo
-# file-mode: "0640"
-# dir-mode: "0750"
-# sync:
-# type: client
-# hostname: passwd.example.com
-# port: 3022
-# user: sync
+# whawty_auth_store_instances:
+# foo:
+# config:
+# basedir: "/var/lib/whawty/auth/foo"
+# default: 2
+# params:
+# - id: 1
+# scryptauth:
+# hmackey: "<32bytes random secret data base64-encoded>"
+# cost: 12
+# - id: 2
+# argon2id:
+# time: 1
+# memory: 65536 ## 64 MB
+# threads: 4
+# length: 32
+# permissions:
+# owner: root
+# group: foo
+# file-mode: "0640"
+# dir-mode: "0750"
+# sync:
+# type: client
+# hostname: passwd.example.com
+# port: 3022
+# user: sync
diff --git a/roles/whawty/auth/store/tasks/main.yml b/roles/whawty/auth/store/tasks/main.yml
index 86f2691b..9a0ea26b 100644
--- a/roles/whawty/auth/store/tasks/main.yml
+++ b/roles/whawty/auth/store/tasks/main.yml
@@ -5,21 +5,36 @@
state: directory
- name: create store base directory
+ loop: "{{ whawty_auth_store_instances | dict2items }}"
+ loop_control:
+ label: "{{ item.key }}"
file:
- path: "{{ whawty_auth_store.config.basedir }}"
+ path: "{{ item.value.config.basedir }}"
state: directory
- mode: "{{ whawty_auth_store.permissions['dir-mode'] | default(omit) }}"
- owner: "{{ whawty_auth_store.permissions.owner | default(omit) }}"
- group: "{{ whawty_auth_store.permissions.group | default(omit) }}"
+ mode: "{{ item.value.permissions['dir-mode'] | default(omit) }}"
+ owner: "{{ item.value.permissions.owner | default(omit) }}"
+ group: "{{ item.value.permissions.group | default(omit) }}"
- name: generate store config file
+ loop: "{{ whawty_auth_store_instances | dict2items }}"
+ loop_control:
+ label: "{{ item.key }}"
copy:
- content: "{{ whawty_auth_store.config | to_nice_yaml(indent=2) }}"
- dest: "/etc/whawty/auth/store-{{ whawty_auth_store.name }}.yml"
- mode: "{{ whawty_auth_store.permissions['file-mode'] | default(omit) }}"
- owner: "{{ whawty_auth_store.permissions.owner | default(omit) }}"
- group: "{{ whawty_auth_store.permissions.group | default(omit) }}"
+ content: "{{ item.value.config | to_nice_yaml(indent=2) }}"
+ dest: "/etc/whawty/auth/store-{{ item.key }}.yml"
+ mode: "{{ item.value.permissions['file-mode'] | default(omit) }}"
+ owner: "{{ item.value.permissions.owner | default(omit) }}"
+ group: "{{ item.value.permissions.group | default(omit) }}"
+
+- name: install rsync
+ when: "(whawty_auth_store_instances | dict2items | selectattr('value.sync', 'defined') | length) > 0"
+ apt:
+ name: rsync
+ state: present
- name: configure sync
- when: "'sync' in whawty_auth_store"
- include_tasks: "sync-{{ whawty_auth_store.sync.type }}.yml"
+ loop: "{{ whawty_auth_store_instances | dict2items }}"
+ loop_control:
+ label: "{{ item.key }}"
+ when: "'sync' in item.value"
+ include_tasks: "sync-{{ item.value.sync.type }}.yml"
diff --git a/roles/whawty/auth/store/tasks/sync-client.yml b/roles/whawty/auth/store/tasks/sync-client.yml
index 77dce1d1..a45e4727 100644
--- a/roles/whawty/auth/store/tasks/sync-client.yml
+++ b/roles/whawty/auth/store/tasks/sync-client.yml
@@ -1,70 +1,65 @@
---
-- name: install rsync
- apt:
- name: rsync
- state: present
-
- name: make sure sync client config directory exists
file:
- path: "/etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync"
+ path: "/etc/whawty/auth/.store-{{ item.key }}-sync"
state: directory
- name: generate ssh config for whawty-auth store sync client
copy:
content: |
Host whawty-auth-server
- Hostname {{ whawty_auth_store.sync.hostname }}
- {% if 'port' in whawty_auth_store.sync %}
- Port {{ whawty_auth_store.sync.port }}
+ Hostname {{ item.value.sync.hostname }}
+ {% if 'port' in item.value.sync %}
+ Port {{ item.value.sync.port }}
{% endif %}
- User {{ whawty_auth_store.sync.user }}
- IdentityFile /etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync/id_ed25519
+ User {{ item.value.sync.user }}
+ IdentityFile /etc/whawty/auth/.store-{{ item.key }}-sync/id_ed25519
IdentitiesOnly yes
- UserKnownHostsFile /etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync/known_hosts
+ UserKnownHostsFile /etc/whawty/auth/.store-{{ item.key }}-sync/known_hosts
ControlMaster auto
- ControlPath /run/ssh-master.whawty-auth-store-sync-{{ whawty_auth_store.name }}
+ ControlPath /run/ssh-master.whawty-auth-store-sync-{{ item.key }}
ControlPersist 300
- dest: "/etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync/ssh_config"
+ dest: "/etc/whawty/auth/.store-{{ item.key }}-sync/ssh_config"
- name: generate ssh keypair for sync client
openssh_keypair:
- path: /etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync/id_ed25519
+ path: /etc/whawty/auth/.store-{{ item.key }}-sync/id_ed25519
type: ed25519
- comment: "whawty-auth-sync-{{ whawty_auth_store.name }}@{{ inventory_hostname }}"
+ comment: "whawty-auth-sync-{{ item.key }}@{{ inventory_hostname }}"
- name: generate sync script
copy:
content: |
#!/bin/bash
{% set rsync_args = [] %}
- {% if 'permissions' in whawty_auth_store %}
- {% if 'file-mode' in whawty_auth_store.permissions %}
- {% set _dummy = rsync_args.append(" --chmod=F"~whawty_auth_store.permissions['file-mode']) %}
+ {% if 'permissions' in item.value %}
+ {% if 'file-mode' in item.value.permissions %}
+ {% set _dummy = rsync_args.append(" --chmod=F"~item.value.permissions['file-mode']) %}
{% endif %}
- {% if 'owner' in whawty_auth_store.permissions %}
- {% set _dummy = rsync_args.append(" --chown="~whawty_auth_store.permissions.owner~":"~whawty_auth_store.permissions.group) %}
+ {% if 'owner' in item.value.permissions %}
+ {% set _dummy = rsync_args.append(" --chown="~item.value.permissions.owner~":"~item.value.permissions.group) %}
{% endif %}
{% endif %}
while true; do
- /usr/bin/rsync -rtW --delete --delete-delay --delay-updates --partial-dir=.tmp{{ rsync_args | join('') }} -e 'ssh -F "/etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync/ssh_config"' 'rsync://whawty-auth-server/store' '{{ whawty_auth_store.config.basedir }}'
+ /usr/bin/rsync -rtW --delete --delete-delay --delay-updates --partial-dir=.tmp{{ rsync_args | join('') }} -e 'ssh -F "/etc/whawty/auth/.store-{{ item.key }}-sync/ssh_config"' 'rsync://whawty-auth-server/store' '{{ item.value.config.basedir }}'
sleep 60
done
- dest: /etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync/run.sh
+ dest: /etc/whawty/auth/.store-{{ item.key }}-sync/run.sh
mode: 0755
- name: generate known_hosts file
- shell: "ssh-keyscan{% if 'port' in whawty_auth_store.sync %} -p {{ whawty_auth_store.sync.port }}{% endif %} {{ whawty_auth_store.sync.hostname }} > /etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync/known_hosts"
+ shell: "ssh-keyscan{% if 'port' in item.value.sync %} -p {{ item.value.sync.port }}{% endif %} {{ item.value.sync.hostname }} > /etc/whawty/auth/.store-{{ item.key }}-sync/known_hosts"
args:
- creates: "/etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync/known_hosts"
+ creates: "/etc/whawty/auth/.store-{{ item.key }}-sync/known_hosts"
- name: install systemd units for whawty-auth store sync client
template:
src: "systemd.service.j2"
- dest: "/etc/systemd/system/whawty-auth-store-sync-{{ whawty_auth_store.name }}.service"
+ dest: "/etc/systemd/system/whawty-auth-store-sync-{{ item.key }}.service"
- name: make sure whawty-auth store sync client is enabled and started
systemd:
daemon_reload: yes
- name: "whawty-auth-store-sync-{{ whawty_auth_store.name }}.service"
+ name: "whawty-auth-store-sync-{{ item.key }}.service"
state: started
enabled: yes
diff --git a/roles/whawty/auth/store/templates/systemd.service.j2 b/roles/whawty/auth/store/templates/systemd.service.j2
index 2fe45642..7e066901 100644
--- a/roles/whawty/auth/store/templates/systemd.service.j2
+++ b/roles/whawty/auth/store/templates/systemd.service.j2
@@ -1,9 +1,9 @@
[Unit]
-Description=sync for whawty-auth store {{ whawty_auth_store.name }}
+Description=sync for whawty-auth store {{ item.key }}
[Service]
Type=simple
-ExecStart=/etc/whawty/auth/.store-{{ whawty_auth_store.name }}-sync/run.sh
+ExecStart=/etc/whawty/auth/.store-{{ item.key }}-sync/run.sh
# systemd hardening-options
AmbientCapabilities=CAP_CHOWN CAP_FOWNER
@@ -20,7 +20,7 @@ ProtectHome=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=strict
-ReadWritePaths={{ whawty_auth_store.config.basedir }}
+ReadWritePaths={{ item.value.config.basedir }}
RemoveIPC=true
RestrictNamespaces=true
RestrictRealtime=true