Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ansible/hosts.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ wiki
srib-radio
azuracast-srib
beszel
kanidm
10 changes: 10 additions & 0 deletions ansible/playbook_infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,13 @@
agent_token: "{{ beszel_agent_token }}"
agent_hub_url: "{{ beszel_agent_hub_url }}"
become: true

- name: Kanidm host config
hosts: kanidm
pre_tasks:
- name: Install nginx
ansible.builtin.include_role:
name: nginxinc.nginx
roles:
- kanidm
become: true
3 changes: 3 additions & 0 deletions ansible/requirements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ collections:
version: "2.2.2"
- name: community.beszel
version: "2.0.0"
roles:
- name: nginxinc.nginx
version: "0.26.0"
3 changes: 3 additions & 0 deletions ansible/roles/common/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@
- nmap
- tmux
- dnsutils
- qemu-guest-agent
- podman
become: true
17 changes: 17 additions & 0 deletions ansible/roles/kanidm/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
- name: Reload Systemd
ansible.builtin.systemd_service:
daemon_reload: true
become: true

- name: Restart kanidm
ansible.builtin.systemd_service:
name: kanidm
state: restarted
become: true

- name: Restart nginx
ansible.builtin.systemd_service:
name: nginx
state: restarted
become: true
35 changes: 35 additions & 0 deletions ansible/roles/kanidm/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
- name: Install common packages
ansible.builtin.apt:
pkg:
- nginx
- nginx-module-acme
state: present
become: true

- name: Write kanidm container file
ansible.builtin.template:
src: templates/kanidm.container
dest: /etc/containers/systemd/
mode: "0644"
notify:
- Reload Systemd
- Restart kanidm
become: true

- name: Write kanidm config file
ansible.builtin.template:
src: templates/server.toml
dest: /var/lib/kanidm/
mode: "0644"
notify: Restart kanidm
become: true

- name: Write kanidm nginx config
ansible.builtin.template:
src: templates/nginx.conf
dest: /etc/nginx/
mode: "0644"
validate: /usr/sbin/nginx -t -c %s
notify: Restart nginx
become: true
21 changes: 21 additions & 0 deletions ansible/roles/kanidm/templates/kanidm.container
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[Container]
Image=docker.io/kanidm/server:1.11.2
ContainerName=kanidm
# Uncomment to enable auto-updates
# AutoUpdate=registry
PublishPort=8443:8443
Volume=/var/lib/kanidm:/data:z

[Unit]
After=default.target

[Install]
# Start by default on boot
WantedBy=default.target

[Service]
# Give the container time to start in case it needs to pull the image
TimeoutStartSec=600
TimeoutStopSec=30
# Creates the state directory of /var/lib/kanidm on the host
StateDirectory=kanidm
70 changes: 70 additions & 0 deletions ansible/roles/kanidm/templates/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
load_module modules/ngx_http_acme_module.so;

user nginx nginx;
worker_processes auto;
worker_rlimit_nofile 2048;

pid /run/nginx.pid;
error_log /var/log/nginx/error.log notice;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
gzip on;
keepalive_timeout 10;
server_tokens off;

resolver 1.1.1.1;

### For ssl cert
acme_issuer letsencrypt {
uri https://acme-v02.api.letsencrypt.org/directory;
# contact admin@example.test;
state_path /var/cache/nginx/acme-letsencrypt;

accept_terms_of_service;
}

### General listener on port 80 is required to process ACME HTTP-01 challenges
server {
listen 80 default_server;
listen [::]:80 default_server;

### Redirect to https
return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
listen [::]:443 ssl;

server_name id.fribyte.no;

### SSL
acme_certificate letsencrypt;
ssl_certificate $acme_certificate;
ssl_certificate_key $acme_certificate_key;
ssl_certificate_cache max=2;

location / {
proxy_pass https://localhost:8443;
proxy_http_version 1.1;
proxy_set_header Host $server_name;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
148 changes: 148 additions & 0 deletions ansible/roles/kanidm/templates/server.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# The server configuration file version.
version = "2"

# The webserver bind address. Requires TLS certificates.
# If the port is set to 443 you may require the
# NET_BIND_SERVICE capability. This accepts a single address
# or an array of addresses to listen on.
# Defaults to "127.0.0.1:8443"
bindaddress = "0.0.0.0:8443"
#
# The read-only ldap server bind address. Requires
# TLS certificates. If set to 636 you may require the
# NET_BIND_SERVICE capability. This accepts a single address
# or an array of addresses to listen on.
# Defaults to "" (disabled)
# ldapbindaddress = "0.0.0.0:3636"
#
# The path to the kanidm database.
db_path = "/data/kanidm.db"
#
# If you have a known filesystem, kanidm can tune the
# database page size to match. Valid choices are:
# [zfs, other]
# If you are unsure about this leave it as the default
# (other). After changing this
# value you must run a vacuum task.
# - zfs:
# * sets database pagesize to 64k. You must set
# recordsize=64k on the zfs filesystem.
# - other:
# * sets database pagesize to 4k, matching most
# filesystems block sizes.
# db_fs_type = "zfs"
#
# The number of entries to store in the in-memory cache.
# Minimum value is 256. If unset
# an automatic heuristic is used to scale this.
# You should only adjust this value if you experience
# memory pressure on your system.
# db_arc_size = 2048
#
# TLS chain and key in pem format. Both must be present.
# If the server receives a SIGHUP, these files will be
# re-read and reloaded if their content is valid.
tls_chain = "/data/chain.pem"
tls_key = "/data/key.pem"

# The path where entry migrations will be read from.
# This path should contain files that match the pattern
# xx-name.json where xx are two number. For example:
# 00-base.json
# 10-groups.json
# Migrations are applied in order. Migrations that fail
# to apply, or have invalid syntax are skipped without
# preventing server start up or reload.
# migration_path = "/data/migrations.d"

#
# The log level of the server. May be one of info, debug, trace
#
# NOTE: this can be overridden by the environment variable
# `KANIDM_LOG_LEVEL` at runtime
# Defaults to "info"
# log_level = "info"
#
# The DNS domain name of the server. This is used in a
# number of security-critical contexts
# such as webauthn, so it *must* match your DNS
# hostname. It is used to create
# security principal names such as `william@idm.example.com`
# so that in a (future) trust configuration it is possible
# to have unique Security Principal Names (spns) throughout
# the topology.
#
# ⚠️ WARNING ⚠️
#
# Changing this value WILL break many types of registered
# credentials for accounts including but not limited to
# webauthn, oauth tokens, and more.
# If you change this value you *must* run
# `kanidmd domain rename` immediately after.
domain = "id.fribyte.no"
#
# The origin for webauthn. This is the url to the server,
# with the port included if it is non-standard (any port
# except 443). This must match or be a descendent of the
# domain name you configure above. If these two items are
# not consistent, the server WILL refuse to start!
# origin = "https://idm.example.com"
# # OR
# origin = "https://idm.example.com:8443"
origin = "https://id.fribyte.no"

# HTTPS requests can be reverse proxied by a loadbalancer.
# To preserve the original IP of the caller, these systems
# will often add a header such as "Forwarded" or
# "X-Forwarded-For". Some other proxies can use the PROXY
# protocol v2 header. While we support the PROXY protocol
# v1 header, we STRONGLY discourage it's use as it has
# significantly greater overheads compared to v2 during
# processing.
# This setting allows configuration of the list of trusted
# IPs or IP ranges which can supply this header information,
# and which format the information is provided in.
# Defaults to "none" (no trusted sources)
# Only one option can be used at a time.
# [http_client_address_info]
# proxy-v2 = ["10.88.0.1", "10.88.0.0/16"]
# # OR
[http_client_address_info]
# x-forward-for = ["127.0.0.1", "127.0.0.0/8"]
x-forward-for = ["10.88.0.1", "10.88.0.0/16"] # Podman network subnet named 'podman'
# # OR
# [http_client_address_info]
# # AVOID IF POSSIBLE!!!
# proxy-v1 = ["127.0.0.1", "127.0.0.0/8"]

# LDAPS requests can be reverse proxied by a loadbalancer.
# To preserve the original IP of the caller, these systems
# can add a header such as the PROXY protocol v2 header.
# While we support the PROXY protocol v1 header, we STRONGLY
# discourage it's use as it has significantly greater
# overheads compared to v2 during processing.
# This setting allows configuration of the list of trusted
# IPs or IP ranges which can supply this header information,
# and which format the information is provided in.
# Defaults to "none" (no trusted sources)
# [ldap_client_address_info]
# proxy-v2 = ["127.0.0.1", "127.0.0.0/8"]
# # OR
# [ldap_client_address_info]
# # AVOID IF POSSIBLE!!!
# proxy-v1 = ["127.0.0.1", "127.0.0.0/8"]

[online_backup]
# The path to the output folder for online backups
path = "/data/kanidm/backups/"
# The schedule to run online backups (see https://crontab.guru/)
# every day at 22:00 UTC (default)
schedule = "00 22 * * *"
# four times a day at 3 minutes past the hour, every 6th hours
# schedule = "03 */6 * * *"
# We also support non standard cron syntax, with the following format:
# sec min hour day of month month day of week year
# (it's very similar to the standard cron syntax, it just allows to specify the seconds
# at the beginning and the year at the end)
# Number of backups to keep (default 7)
# versions = 7
19 changes: 19 additions & 0 deletions local_run_config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#! /usr/bin/bash

cd ansible

echo "Running homelab Ansible local test configuration"

if ! tailscale status > /dev/null; then
echo "Starting tailscale"
tailscale up
fi

tailscale switch headscale.fribyte.no

if [ -e local_config.yml ]
then
ansible-playbook local_config.yml --verbose --become-password-file .ansible_sudo_password --vault-password-file .ansible_vault_key
else
echo "No local config found please create it first."
fi