aboutsummaryrefslogtreecommitdiffstats
path: root/templates
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2026-05-13 00:13:57 +0300
committerJan Tuomi <jan@jantuomi.fi>2026-05-16 18:42:27 +0300
commitb5860daf11ac353049cb1654b9414a129e5cfb96 (patch)
tree87ed89711e4f0e85ace0a97fa123199152c67302 /templates
parent4715a28fdcd87440400d17154bfa361d99db29cc (diff)
Rework
Diffstat (limited to 'templates')
-rw-r--r--templates/diddle/root_diddle_env.j29
-rw-r--r--templates/diddle/usr_local_bin_diddle17
-rw-r--r--templates/diddle/usr_local_etc_rc.d_diddle43
-rw-r--r--templates/etc_aliases.j21
-rw-r--r--templates/etc_crontab.j232
-rw-r--r--templates/etc_devfs.rules.j291
-rw-r--r--templates/etc_dma_auth.conf.j21
-rw-r--r--templates/etc_dma_dma.conf.j28
-rw-r--r--templates/etc_fstab.j27
-rw-r--r--templates/etc_jail.conf.d_[jailname].conf.j243
-rw-r--r--templates/etc_jail.conf.j26
-rw-r--r--templates/etc_periodic.conf.j24
-rw-r--r--templates/etc_rc.conf.j248
-rw-r--r--templates/etc_resolv.conf.j22
-rw-r--r--templates/etc_ssh_sshd_config.j2121
-rw-r--r--templates/homepage/etc_crontab.j29
-rw-r--r--templates/homepage/usr_local_etc_nginx_nginx.conf.j255
-rw-r--r--templates/hommabot/etc_crontab.j210
-rw-r--r--templates/hommabot/root_hommabot_deps.sh14
-rw-r--r--templates/hommabot/root_hommabot_env.j24
-rwxr-xr-xtemplates/ingress/acme-dns-auth.py170
-rw-r--r--templates/ingress/etc_crontab.j218
-rw-r--r--templates/ingress/etc_pf.conf.j227
-rw-r--r--templates/ingress/nginx_snippet_ban.inc17
-rw-r--r--templates/ingress/pf-ban-socket.py72
-rw-r--r--templates/ingress/usr_local_bin_gen_goaccess.sh.j28
-rw-r--r--templates/ingress/usr_local_bin_hetzner_ddns.sh.j2130
-rw-r--r--templates/ingress/usr_local_etc_hetzner_auth.j21
-rw-r--r--templates/ingress/usr_local_etc_nginx_nginx.conf.j2141
-rw-r--r--templates/ingress/usr_local_etc_rc.d_pf_ban_socket43
-rw-r--r--templates/jail_confs/_default.j25
-rw-r--r--templates/jail_confs/_epl_network.j218
-rw-r--r--templates/jail_confs/dl.j26
-rw-r--r--templates/jail_confs/ingress.j222
-rw-r--r--templates/jail_confs/komga.j24
-rw-r--r--templates/jail_confs/plex.j24
-rw-r--r--templates/jail_confs/postgres.j24
-rw-r--r--templates/jail_confs/samba.j24
-rw-r--r--templates/jail_confs/syncthing.j211
-rw-r--r--templates/root_bashrc7
-rw-r--r--templates/root_clone.sh21
-rw-r--r--templates/root_ssh_config.j24
-rw-r--r--templates/usr_local_bin_backup.sh.j2365
-rw-r--r--templates/usr_local_bin_logto.sh.j247
-rw-r--r--templates/usr_local_bin_pylogsentinel-batch-email.sh.j214
-rw-r--r--templates/usr_local_bin_safepf.sh36
-rw-r--r--templates/usr_local_etc_pylogsentinel.conf.j222
-rw-r--r--templates/usr_local_etc_rc.d_zpool_gpt_labels.j233
-rw-r--r--templates/usr_local_etc_smartd.conf.j24
49 files changed, 0 insertions, 1783 deletions
diff --git a/templates/diddle/root_diddle_env.j2 b/templates/diddle/root_diddle_env.j2
deleted file mode 100644
index ca7db78..0000000
--- a/templates/diddle/root_diddle_env.j2
+++ /dev/null
@@ -1,9 +0,0 @@
-PYTHONUNBUFFERED="1"
-BASE_URL="https://diddle.jan.systems"
-DB_PATH="db.sqlite3"
-EMAIL_HOST="smtp.postmarkapp.com"
-EMAIL_PORT="587"
-EMAIL_HOST_USER="{{ diddle_email_host_user }}"
-EMAIL_HOST_PASSWORD="{{ diddle_email_host_password }}"
-EMAIL_USE_TLS="true"
-EMAIL_MESSAGE_FROM="diddle@jan.systems"
diff --git a/templates/diddle/usr_local_bin_diddle b/templates/diddle/usr_local_bin_diddle
deleted file mode 100644
index d07cd5e..0000000
--- a/templates/diddle/usr_local_bin_diddle
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-set -eux
-
-PATH=$PATH:/usr/local/bin
-
-cd /root/diddle
-
-if [ ! -f venv ]; then
- python3.11 -m venv venv
-fi
-
-PATH=$PATH:/root/diddle/venv/bin
-
-pip install -r requirements.txt
-python apply_migrations.py
-gunicorn --bind "0.0.0.0:80" -w 4 app:app
diff --git a/templates/diddle/usr_local_etc_rc.d_diddle b/templates/diddle/usr_local_etc_rc.d_diddle
deleted file mode 100644
index 01deaad..0000000
--- a/templates/diddle/usr_local_etc_rc.d_diddle
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-#
-# PROVIDE: diddle
-# REQUIRE: NETWORKING
-# KEYWORD: shutdown
-#
-# Enable in /etc/rc.conf:
-# diddle_enable="YES"
-#
-. /etc/rc.subr
-
-name="diddle"
-rcvar=diddle_enable
-
-load_rc_config $name
-
-: ${diddle_command:=/usr/local/bin/diddle}
-: ${diddle_log:=/var/log/${name}.log}
-
-start_cmd="${name}_start"
-stop_cmd="${name}_stop"
-status_cmd="${name}_status"
-
-extra_commands="status"
-
-diddle_start() {
- /usr/local/bin/logto ${diddle_log} ${diddle_command} &
-}
-
-diddle_status() {
- if ps aux | grep diddle | grep -v grep | grep -v rc.d/diddle; then
- echo "diddle is running"
- else
- echo "diddle is not running"
- exit 1
- fi
-}
-
-diddle_stop() {
- ps aux | grep diddle | grep -v grep | grep -v rc.d/diddle | awk '{print $2}' | xargs kill -TERM
-}
-
-run_rc_command "$1"
diff --git a/templates/etc_aliases.j2 b/templates/etc_aliases.j2
deleted file mode 100644
index 4fe3e7f..0000000
--- a/templates/etc_aliases.j2
+++ /dev/null
@@ -1 +0,0 @@
-*: {{ dma_to_address }}
diff --git a/templates/etc_crontab.j2 b/templates/etc_crontab.j2
deleted file mode 100644
index de1f3c6..0000000
--- a/templates/etc_crontab.j2
+++ /dev/null
@@ -1,32 +0,0 @@
-# /etc/crontab - root's crontab for FreeBSD
-#
-#
-SHELL=/bin/sh
-PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
-#
-#minute hour mday month wday who command
-#
-# Save some entropy so that /dev/random can re-seed on boot.
-*/11 * * * * operator /usr/libexec/save-entropy
-#
-# Rotate log files every hour, if necessary.
-0 * * * * root newsyslog
-#
-# Perform daily/weekly/monthly maintenance.
-1 3 * * * root periodic daily
-15 4 * * 6 root periodic weekly
-30 5 1 * * root periodic monthly
-#
-# Adjust the time zone if the CMOS clock keeps local time, as opposed to
-# UTC time. See adjkerntz(8) for details.
-1,31 0-5 * * * root adjkerntz -a
-
-# Take snapshots every day at 3:05 AM
-5 3 * * * root logto /var/log/backup /usr/local/bin/backup snapshot prune-local
-# Send backup snapshots to remote every third day at 4:05 AM
-5 4 */3 * * root logto /var/log/backup /usr/local/bin/backup send-to-remote prune-remote notify
-
-# Run pylogmonitor
-*/10 * * * * root python -m pylogsentinel
-# Run pylogsentinel batch job once a day
-5 6 * * * root /usr/local/bin/pylogsentinel-batch-email.sh
diff --git a/templates/etc_devfs.rules.j2 b/templates/etc_devfs.rules.j2
deleted file mode 100644
index 531b767..0000000
--- a/templates/etc_devfs.rules.j2
+++ /dev/null
@@ -1,91 +0,0 @@
-# "as-is" to the devfs(8) command with the exception that
-# any references to other rulesets will be expanded first. These
-# references must include a dollar sign '$' in front of the
-# name to be expanded properly.
-#
-#
-
-# Very basic and secure ruleset: Hide everything.
-# Used as a basis for other rules.
-#
-[devfsrules_hide_all=1]
-add hide
-
-# Basic devices typically necessary.
-# Requires: devfsrules_hide_all
-#
-[devfsrules_unhide_basic=2]
-add path null unhide
-add path zero unhide
-add path crypto unhide
-add path random unhide
-add path urandom unhide
-
-# Devices typically needed to support logged-in users.
-# Requires: devfsrules_hide_all
-#
-[devfsrules_unhide_login=3]
-add path 'ptyp*' unhide
-add path 'ptyq*' unhide
-add path 'ptyr*' unhide
-add path 'ptys*' unhide
-add path 'ptyP*' unhide
-add path 'ptyQ*' unhide
-add path 'ptyR*' unhide
-add path 'ptyS*' unhide
-add path 'ptyl*' unhide
-add path 'ptym*' unhide
-add path 'ptyn*' unhide
-add path 'ptyo*' unhide
-add path 'ptyL*' unhide
-add path 'ptyM*' unhide
-add path 'ptyN*' unhide
-add path 'ptyO*' unhide
-add path 'ttyp*' unhide
-add path 'ttyq*' unhide
-add path 'ttyr*' unhide
-add path 'ttys*' unhide
-add path 'ttyP*' unhide
-add path 'ttyQ*' unhide
-add path 'ttyR*' unhide
-add path 'ttyS*' unhide
-add path 'ttyl*' unhide
-add path 'ttym*' unhide
-add path 'ttyn*' unhide
-add path 'ttyo*' unhide
-add path 'ttyL*' unhide
-add path 'ttyM*' unhide
-add path 'ttyN*' unhide
-add path 'ttyO*' unhide
-add path ptmx unhide
-add path pts unhide
-add path 'pts/*' unhide
-add path fd unhide
-add path 'fd/*' unhide
-add path stdin unhide
-add path stdout unhide
-add path stderr unhide
-add path 'drm' unhide
-add path 'drm/*' unhide
-add path 'dri' unhide
-add path 'dri/*' unhide
-
-[devfsrules_jail=4]
-add include $devfsrules_hide_all
-add include $devfsrules_unhide_basic
-add include $devfsrules_unhide_login
-
-[devfsrules_jail_postgres=5]
-add include $devfsrules_hide_all
-add include $devfsrules_unhide_basic
-add include $devfsrules_unhide_login
-add include $devfsrules_jail
-add path 'bpf*' unhide
-
-[devfsrules_jail_ingress=5]
-add include $devfsrules_hide_all
-add include $devfsrules_unhide_basic
-add include $devfsrules_unhide_login
-add include $devfsrules_jail
-add path 'bpf*' unhide
-add path 'pf*' unhide
diff --git a/templates/etc_dma_auth.conf.j2 b/templates/etc_dma_auth.conf.j2
deleted file mode 100644
index a1000ea..0000000
--- a/templates/etc_dma_auth.conf.j2
+++ /dev/null
@@ -1 +0,0 @@
-{{ smtp_user }}|{{ smtp_host }}:{{ smtp_password }}
diff --git a/templates/etc_dma_dma.conf.j2 b/templates/etc_dma_dma.conf.j2
deleted file mode 100644
index dfaa04f..0000000
--- a/templates/etc_dma_dma.conf.j2
+++ /dev/null
@@ -1,8 +0,0 @@
-SMARTHOST {{ smtp_host }}
-PORT {{ smtp_port }}
-AUTHPATH /etc/dma/auth.conf
-SECURETRANSFER
-STARTTLS
-MAILNAME {{ dma_mail_hostname }}
-MASQUERADE {{ ansible_hostname }}@{{ dma_mail_hostname }}
-#NULLCLIENT
diff --git a/templates/etc_fstab.j2 b/templates/etc_fstab.j2
deleted file mode 100644
index 95d3fa0..0000000
--- a/templates/etc_fstab.j2
+++ /dev/null
@@ -1,7 +0,0 @@
-# Device Mountpoint FStype Options Dump Pass#
-/dev/gpt/efiboot0 /boot/efi msdosfs rw 2 2
-/dev/nda0p3.eli none swap sw 0 0
-/dev/nda1p3.eli none swap sw 0 0
-/dev/nda2p3.eli none swap sw 0 0
-/dev/nda3p3.eli none swap sw 0 0
-tmpfs /tmp tmpfs rw,mode=777,size=2g 0 0
diff --git a/templates/etc_jail.conf.d_[jailname].conf.j2 b/templates/etc_jail.conf.d_[jailname].conf.j2
deleted file mode 100644
index df10f47..0000000
--- a/templates/etc_jail.conf.d_[jailname].conf.j2
+++ /dev/null
@@ -1,43 +0,0 @@
-# eplXa is host end (local network bridge), eplXb is jail end.
-# The corresponding pubnet interface is epwX, but that's not created for all jails.
-{{ jail.name }} {
- # STARTUP/LOGGING/VNET
- vnet;
- persist;
- exec.clean;
-
- exec.prestart = "";
- exec.start = "/bin/sh /etc/rc";
- exec.poststart = "";
- exec.prestop = "";
- exec.stop = "/bin/sh /etc/rc.shutdown";
- exec.poststop = "";
-
- exec.consolelog = "/var/log/jail_console_${name}.log";
-
- # PERMISSIONS
- allow.raw_sockets;
- exec.clean;
- mount.devfs;
-
- # HOSTNAME/PATH
- host.hostname = "${name}";
- path = "/usr/local/jails/containers/${name}";
-
- # JAIL-SPECIFIC CONFIGURATION
-{% set t = lookup(
- 'ansible.builtin.first_found',
- {
- 'files': [
- 'jail_confs/' ~ jail.name ~ '.j2',
- 'jail_confs/_default.j2',
- ],
- 'paths': [ playbook_dir ~ '/templates' ]
- },
- errors='ignore'
-) %}
-
-{% if t %}
-{{ lookup('ansible.builtin.template', t) | indent(2, true) }}
-{% endif %}
-}
diff --git a/templates/etc_jail.conf.j2 b/templates/etc_jail.conf.j2
deleted file mode 100644
index 7190816..0000000
--- a/templates/etc_jail.conf.j2
+++ /dev/null
@@ -1,6 +0,0 @@
-# Include configurations from standard locations.
-.include "/etc/jail.conf.d/*.conf";
-.include "/etc/jail.*.conf";
-.include "/usr/local/etc/jail[.]conf";
-.include "/usr/local/etc/jail.conf.d/*.conf";
-.include "/usr/local/etc/jail.*.conf";
diff --git a/templates/etc_periodic.conf.j2 b/templates/etc_periodic.conf.j2
deleted file mode 100644
index 176b55d..0000000
--- a/templates/etc_periodic.conf.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-daily_status_smart_enable="YES"
-daily_status_security_inline="YES"
-daily_status_zfs_enable="YES"
-weekly_certbot_enable="YES"
diff --git a/templates/etc_rc.conf.j2 b/templates/etc_rc.conf.j2
deleted file mode 100644
index 5380056..0000000
--- a/templates/etc_rc.conf.j2
+++ /dev/null
@@ -1,48 +0,0 @@
-hostname="pursotin"
-keymap="fi.kbd"
-sshd_enable="YES"
-ntpd_enable="YES"
-ntpd_sync_on_start="YES"
-powerd_enable="YES"
-moused_nondefault_enable="NO"
-# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
-dumpdev="AUTO"
-zfs_enable="YES"
-{% if is_test_vm %}
-defaultrouter="10.0.20.1"
-{% else %}
-defaultrouter="{{ lan_ipv4_gateway }}"
-{% endif %}
-cloned_interfaces="bridge0 bridge1"
-ifconfig_{{ nic_lan }}_name="lan0"
-ifconfig_{{ nic_wan }}_name="wan0"
-ifconfig_bridge0_name="brlan0"
-ifconfig_bridge1_name="brwan0"
-{% if is_test_vm %}
-ifconfig_lan0="inet 10.0.20.2/24"
-{% else %}
-ifconfig_lan0="inet {{ lan_ipv4_cidr }}"
-{% endif %}
-ifconfig_lan0_ipv6="inet6 accept_rtadv"
-ifconfig_wan0="up"
-ifconfig_brlan0="addm lan0 up"
-ifconfig_brwan0="addm wan0 up"
-zpool_gpt_labels_enable="YES"
-smartd_enable="YES"
-pf_enable="YES"
-syslogd_enable="YES"
-syslogd_flags="-s"
-jail_enable="YES"
-jail_parallel_start="YES"
-jail_reverse_stop="YES"
-clear_tmp_enable="YES"
-cleanvar_enable="YES"
-auditd_enable="YES"
-devd_enable="YES"
-{% if not is_test_vm %}
-vm_enable="YES"
-vm_dir="zfs:zroot/vm"
-vm_list="alpine0"
-vm_delay="5"
-kld_list="if_wg i915kms"
-{% endif %}
diff --git a/templates/etc_resolv.conf.j2 b/templates/etc_resolv.conf.j2
deleted file mode 100644
index b382ecf..0000000
--- a/templates/etc_resolv.conf.j2
+++ /dev/null
@@ -1,2 +0,0 @@
-search {{ lan_search_domain }}
-nameserver {{ dns_nameserver | default(lan_ipv4_gateway) }}
diff --git a/templates/etc_ssh_sshd_config.j2 b/templates/etc_ssh_sshd_config.j2
deleted file mode 100644
index 06179ce..0000000
--- a/templates/etc_ssh_sshd_config.j2
+++ /dev/null
@@ -1,121 +0,0 @@
-# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $
-
-# This is the sshd server system-wide configuration file. See
-# sshd_config(5) for more information.
-
-# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
-
-# The strategy used for options in the default sshd_config shipped with
-# OpenSSH is to specify options with their default value where
-# possible, but leave them commented. Uncommented options override the
-# default value.
-
-# Note that some of FreeBSD's defaults differ from OpenBSD's, and
-# FreeBSD has a few additional options.
-
-#Port 22
-#AddressFamily any
-#ListenAddress 0.0.0.0
-#ListenAddress ::
-
-#HostKey /etc/ssh/ssh_host_rsa_key
-#HostKey /etc/ssh/ssh_host_ecdsa_key
-#HostKey /etc/ssh/ssh_host_ed25519_key
-
-# Ciphers and keying
-#RekeyLimit default none
-
-# Logging
-#SyslogFacility AUTH
-#LogLevel INFO
-
-# Authentication:
-
-#LoginGraceTime 2m
-PermitRootLogin prohibit-password
-#StrictModes yes
-#MaxAuthTries 6
-#MaxSessions 10
-
-#PubkeyAuthentication yes
-
-# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
-# but this is overridden so installations will only check .ssh/authorized_keys
-AuthorizedKeysFile .ssh/authorized_keys
-
-#AuthorizedPrincipalsFile none
-
-#AuthorizedKeysCommand none
-#AuthorizedKeysCommandUser nobody
-
-# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
-#HostbasedAuthentication no
-# Change to yes if you don't trust ~/.ssh/known_hosts for
-# HostbasedAuthentication
-#IgnoreUserKnownHosts no
-# Don't read the user's ~/.rhosts and ~/.shosts files
-#IgnoreRhosts yes
-
-# Change to yes to enable built-in password authentication.
-# Note that passwords may also be accepted via KbdInteractiveAuthentication.
-PasswordAuthentication no
-#PermitEmptyPasswords no
-
-# Change to no to disable PAM authentication
-#KbdInteractiveAuthentication yes
-
-# Kerberos options
-#KerberosAuthentication no
-#KerberosOrLocalPasswd yes
-#KerberosTicketCleanup yes
-#KerberosGetAFSToken no
-
-# GSSAPI options
-#GSSAPIAuthentication no
-#GSSAPICleanupCredentials yes
-
-# Set this to 'no' to disable PAM authentication, account processing,
-# and session processing. If this is enabled, PAM authentication will
-# be allowed through the KbdInteractiveAuthentication and
-# PasswordAuthentication. Depending on your PAM configuration,
-# PAM authentication via KbdInteractiveAuthentication may bypass
-# the setting of "PermitRootLogin prohibit-password".
-# If you just want the PAM account and session checks to run without
-# PAM authentication, then enable this but set PasswordAuthentication
-# and KbdInteractiveAuthentication to 'no'.
-#UsePAM yes
-
-#AllowAgentForwarding yes
-#AllowTcpForwarding yes
-#GatewayPorts no
-#X11Forwarding no
-#X11DisplayOffset 10
-#X11UseLocalhost yes
-#PermitTTY yes
-#PrintMotd yes
-#PrintLastLog yes
-#TCPKeepAlive yes
-#PermitUserEnvironment no
-#Compression delayed
-#ClientAliveInterval 0
-#ClientAliveCountMax 3
-#UseDNS yes
-#PidFile /var/run/sshd.pid
-#MaxStartups 10:30:100
-#PermitTunnel no
-#ChrootDirectory none
-#UseBlacklist no
-#VersionAddendum FreeBSD-20250219
-
-# no default banner path
-#Banner none
-
-# override default of no subsystems
-Subsystem sftp /usr/libexec/sftp-server
-
-# Example of overriding settings on a per-user basis
-#Match User anoncvs
-# X11Forwarding no
-# AllowTcpForwarding no
-# PermitTTY no
-# ForceCommand cvs server
diff --git a/templates/homepage/etc_crontab.j2 b/templates/homepage/etc_crontab.j2
deleted file mode 100644
index 8541f57..0000000
--- a/templates/homepage/etc_crontab.j2
+++ /dev/null
@@ -1,9 +0,0 @@
-# /etc/crontab - root's crontab for FreeBSD
-#
-#
-SHELL=/bin/sh
-PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
-#
-#minute hour mday month wday who command
-
-# TODO: update linklog
diff --git a/templates/homepage/usr_local_etc_nginx_nginx.conf.j2 b/templates/homepage/usr_local_etc_nginx_nginx.conf.j2
deleted file mode 100644
index ee45405..0000000
--- a/templates/homepage/usr_local_etc_nginx_nginx.conf.j2
+++ /dev/null
@@ -1,55 +0,0 @@
-worker_processes auto;
-
-events {
- worker_connections 1024;
-}
-
-http {
- include mime.types;
- default_type application/octet-stream;
-
- sendfile on;
- keepalive_timeout 65;
-
- gzip on;
- gzip_vary on;
- gzip_proxied any;
- gzip_comp_level 6;
- gzip_min_length 256;
-
- # Compress sensible, text-based response types (HTML is covered by default)
- gzip_types
- text/plain
- text/css
- text/xml
- text/javascript
- application/javascript
- application/json
- application/ld+json
- application/xml
- application/rss+xml
- application/atom+xml
- image/svg+xml;
-
- server {
- listen 80 default_server;
- server_name _;
-
- root /var/www;
-
- index index.html;
-
- # Migration redirects from legacy site
- location ~ ^/archive(?:/(.*))?$ {
- return 307 /posts/$1$is_args$args;
- }
- location = /feed.xml {
- # Serve atom.xml content at the legacy feed.xml URL (no redirect)
- rewrite ^ /atom.xml break;
- }
-
- location / {
- try_files $uri $uri.html $uri/ =404;
- }
- }
-}
diff --git a/templates/hommabot/etc_crontab.j2 b/templates/hommabot/etc_crontab.j2
deleted file mode 100644
index 556d12a..0000000
--- a/templates/hommabot/etc_crontab.j2
+++ /dev/null
@@ -1,10 +0,0 @@
-# /etc/crontab - root's crontab for FreeBSD
-#
-#
-SHELL=/bin/sh
-PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
-#
-#minute hour mday month wday who command
-
-# Run hommabot every Monday at 9:00 AM
-0 9 * * 1 root /bin/sh -c "cd /root/hommabot && node index.js"
diff --git a/templates/hommabot/root_hommabot_deps.sh b/templates/hommabot/root_hommabot_deps.sh
deleted file mode 100644
index 25c0e56..0000000
--- a/templates/hommabot/root_hommabot_deps.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-set -eux
-cd /root/hommabot
-npm ci
-
-# We need to build the better-sqlite3.node file before running the app
-if [ ! -f build/better_sqlite3.node ]; then (
- mkdir -p build
- cd node_modules/better-sqlite3
- npm run build-release
- cp build/Release/better_sqlite3.node ../../build/better_sqlite3.node
-)
-fi
diff --git a/templates/hommabot/root_hommabot_env.j2 b/templates/hommabot/root_hommabot_env.j2
deleted file mode 100644
index c66c666..0000000
--- a/templates/hommabot/root_hommabot_env.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-TELEGRAM_BOT_TOKEN="{{ hommabot_telegram_bot_token }}"
-SHEETS_SPREADSHEET_ID="{{ hommabot_sheets_spreadsheet_id }}"
-SHEETS_RANGE="{{ hommabot_sheets_range }}"
-G_SA_JSON_B64="{{ hommabot_g_sa_json_b64 }}"
diff --git a/templates/ingress/acme-dns-auth.py b/templates/ingress/acme-dns-auth.py
deleted file mode 100755
index 77928e6..0000000
--- a/templates/ingress/acme-dns-auth.py
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/env python3
-#
-# Source: https://github.com/joohoi/acme-dns-certbot-joohoi/blob/master/acme-dns-auth.py
-# Some modifications to configuration values present.
-
-
-import json
-import os
-import sys
-
-import requests
-
-### EDIT THESE: Configuration values ###
-
-# URL to acme-dns instance
-ACMEDNS_URL = "https://auth.acme-dns.io"
-# Path for acme-dns credential storage
-STORAGE_PATH = "/usr/local/etc/letsencrypt/acmedns.json"
-# Whitelist for address ranges to allow the updates from
-# Example: ALLOW_FROM = ["192.168.10.0/24", "::1/128"]
-ALLOW_FROM = []
-# Force re-registration. Overwrites the already existing acme-dns accounts.
-FORCE_REGISTER = False
-
-### DO NOT EDIT BELOW THIS POINT ###
-### HERE BE DRAGONS ###
-
-DOMAIN = os.environ["CERTBOT_DOMAIN"]
-if DOMAIN.startswith("*."):
- DOMAIN = DOMAIN[2:]
-VALIDATION_DOMAIN = "_acme-challenge." + DOMAIN
-VALIDATION_TOKEN = os.environ["CERTBOT_VALIDATION"]
-
-
-class AcmeDnsClient(object):
- """
- Handles the communication with ACME-DNS API
- """
-
- def __init__(self, acmedns_url):
- self.acmedns_url = acmedns_url
-
- def register_account(self, allowfrom):
- """Registers a new ACME-DNS account"""
-
- if allowfrom:
- # Include whitelisted networks to the registration call
- reg_data = {"allowfrom": allowfrom}
- res = requests.post(
- self.acmedns_url + "/register", data=json.dumps(reg_data)
- )
- else:
- res = requests.post(self.acmedns_url + "/register")
- if res.status_code == 201:
- # The request was successful
- return res.json()
- else:
- # Encountered an error
- msg = (
- "Encountered an error while trying to register a new acme-dns "
- "account. HTTP status {}, Response body: {}"
- )
- print(msg.format(res.status_code, res.text))
- sys.exit(1)
-
- def update_txt_record(self, account, txt):
- """Updates the TXT challenge record to ACME-DNS subdomain."""
- update = {"subdomain": account["subdomain"], "txt": txt}
- headers = {
- "X-Api-User": account["username"],
- "X-Api-Key": account["password"],
- "Content-Type": "application/json",
- }
- res = requests.post(
- self.acmedns_url + "/update", headers=headers, data=json.dumps(update)
- )
- if res.status_code == 200:
- # Successful update
- return
- else:
- msg = (
- "Encountered an error while trying to update TXT record in "
- "acme-dns. \n"
- "------- Request headers:\n{}\n"
- "------- Request body:\n{}\n"
- "------- Response HTTP status: {}\n"
- "------- Response body: {}"
- )
- s_headers = json.dumps(headers, indent=2, sort_keys=True)
- s_update = json.dumps(update, indent=2, sort_keys=True)
- s_body = json.dumps(res.json(), indent=2, sort_keys=True)
- print(msg.format(s_headers, s_update, res.status_code, s_body))
- sys.exit(1)
-
-
-class Storage(object):
- def __init__(self, storagepath):
- self.storagepath = storagepath
- self._data = self.load()
-
- def load(self):
- """Reads the storage content from the disk to a dict structure"""
- data = dict()
- filedata = ""
- try:
- with open(self.storagepath, "r") as fh:
- filedata = fh.read()
- except IOError as e:
- if os.path.isfile(self.storagepath):
- # Only error out if file exists, but cannot be read
- print("ERROR: Storage file exists but cannot be read")
- sys.exit(1)
- try:
- data = json.loads(filedata)
- except ValueError:
- if len(filedata) > 0:
- # Storage file is corrupted
- print("ERROR: Storage JSON is corrupted")
- sys.exit(1)
- return data
-
- def save(self):
- """Saves the storage content to disk"""
- serialized = json.dumps(self._data)
- try:
- with os.fdopen(
- os.open(self.storagepath, os.O_WRONLY | os.O_CREAT, 0o600), "w"
- ) as fh:
- fh.truncate()
- fh.write(serialized)
- except IOError as e:
- print("ERROR: Could not write storage file.")
- sys.exit(1)
-
- def put(self, key, value):
- """Puts the configuration value to storage and sanitize it"""
- # If wildcard domain, remove the wildcard part as this will use the
- # same validation record name as the base domain
- if key.startswith("*."):
- key = key[2:]
- self._data[key] = value
-
- def fetch(self, key):
- """Gets configuration value from storage"""
- try:
- return self._data[key]
- except KeyError:
- return None
-
-
-if __name__ == "__main__":
- # Init
- client = AcmeDnsClient(ACMEDNS_URL)
- storage = Storage(STORAGE_PATH)
-
- # Check if an account already exists in storage
- account = storage.fetch(DOMAIN)
- if FORCE_REGISTER or not account:
- # Create and save the new account
- account = client.register_account(ALLOW_FROM)
- storage.put(DOMAIN, account)
- storage.save()
-
- # Display the notification for the user to update the main zone
- msg = "Please add the following CNAME record to your main DNS zone:\n{}"
- cname = "{} CNAME {}.".format(VALIDATION_DOMAIN, account["fulldomain"])
- print(msg.format(cname))
-
- # Update the TXT record in acme-dns instance
- client.update_txt_record(account, VALIDATION_TOKEN)
diff --git a/templates/ingress/etc_crontab.j2 b/templates/ingress/etc_crontab.j2
deleted file mode 100644
index 6879766..0000000
--- a/templates/ingress/etc_crontab.j2
+++ /dev/null
@@ -1,18 +0,0 @@
-# /etc/crontab - root's crontab for FreeBSD
-#
-#
-SHELL=/bin/sh
-PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
-#
-#minute hour mday month wday who command
-
-# Update LetsEncrypt certificates every day after 2:00 AM
-0 2 * * * root certbot certonly -n -m {{ contact_email }} --agree-tos --manual --manual-auth-hook /usr/local/bin/acme-dns-auth.py --preferred-challenges dns --debug-challenges {% for domain in cert_domains %}-d '{{ domain }}' {% endfor %} || echo "ERROR: Failed to renew certs" >&2
-
-# Update dynamic DNS (Hetzner)
-{% for elem in hetzner_zone_record_ids %}
-* * * * * root /usr/local/bin/hetzner_ddns.sh --zone '{{ elem.zone }}' --rr-id '{{ elem.rr_id }}' --iface-cmd 'ifconfig epw1b' >>/var/log/hetzner_ddns.log 2>&1
-{% endfor %}
-
-# Update goaccess report HTML
-0 * * * * root /usr/local/bin/gen_goaccess.sh
diff --git a/templates/ingress/etc_pf.conf.j2 b/templates/ingress/etc_pf.conf.j2
deleted file mode 100644
index c0528e1..0000000
--- a/templates/ingress/etc_pf.conf.j2
+++ /dev/null
@@ -1,27 +0,0 @@
-{% for jail in jails -%}
-{% if jail.name == 'ingress' -%}
-# Interfaces & nets
-lan = "epl{{ jail.num }}b"
-wan = "epw{{ jail.num }}b"
-lan_net = "{{ lan_ipv4_network }}"
-
-table <blocked> persist
-
-# Keep PF out of loopback, drop by default if you add blocks later
-set skip on lo0
-set block-policy drop
-
-# NAT: translate LAN traffic to the WAN interface address
-nat on $wan from $lan_net to any -> ($wan)
-
-# Block traffic from IPs in the blocked table
-block in quick from <blocked> to any
-
-# Allow all outbound traffic from the jail and LAN via both interfaces
-# NAT will be applied automatically when source is in $lan_net and going out $wan
-pass out on $wan all keep state
-pass out on $lan all keep state
-
-pass in on $wan inet proto {tcp, udp} from any to any port {80, 443} keep state
-{% endif %}
-{% endfor %}
diff --git a/templates/ingress/nginx_snippet_ban.inc b/templates/ingress/nginx_snippet_ban.inc
deleted file mode 100644
index 029b965..0000000
--- a/templates/ingress/nginx_snippet_ban.inc
+++ /dev/null
@@ -1,17 +0,0 @@
-# Trap route
-location ^~ /wp-admin/ {
- proxy_set_header X-IP $remote_addr;
- proxy_method POST;
- proxy_pass http://unix:/var/run/pfban/ban.sock:/ban;
-
- proxy_connect_timeout 50ms;
- proxy_send_timeout 50ms;
- proxy_read_timeout 50ms;
-
- # If the socket isn't up yet, still return something
- error_page 500 502 503 504 = @ban_fallback;
-}
-
-location @ban_fallback {
- return 204;
-}
diff --git a/templates/ingress/pf-ban-socket.py b/templates/ingress/pf-ban-socket.py
deleted file mode 100644
index cbcd80e..0000000
--- a/templates/ingress/pf-ban-socket.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python3
-import http.server
-import os
-import re
-import socketserver
-import subprocess
-
-SOCK_PATH = "/var/run/pfban/ban.sock"
-PF_TABLE = "blocked"
-
-# Simple, conservative filter to avoid junk / injection
-IP_RE = re.compile(r"^[0-9A-Fa-f:.]{3,}$")
-
-
-def ensure_socket_dir(path: str) -> None:
- os.makedirs(os.path.dirname(path), mode=0o755, exist_ok=True)
-
-
-class BanHandler(http.server.BaseHTTPRequestHandler):
- # Silence default logging
- def log_message(self, format, *args):
- return
-
- def do_POST(self):
- if self.path != "/ban":
- self.send_response(404)
- self.end_headers()
- return
-
- ip = self.headers.get("X-IP", "").strip()
-
- if ip and IP_RE.match(ip):
- subprocess.run(
- ["/sbin/pfctl", "-t", PF_TABLE, "-T", "add", ip],
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- check=False,
- )
-
- self.send_response(204)
- self.end_headers()
-
- def do_GET(self):
- self.send_response(405)
- self.end_headers()
-
-
-class ThreadingUnixHTTPServer(
- socketserver.ThreadingMixIn,
- socketserver.UnixStreamServer,
-):
- daemon_threads = True
-
-
-def main() -> None:
- ensure_socket_dir(SOCK_PATH)
-
- # Remove stale socket if present
- try:
- os.unlink(SOCK_PATH)
- except FileNotFoundError:
- pass
-
- with ThreadingUnixHTTPServer(SOCK_PATH, BanHandler) as httpd:
- # Allow nginx workers (www) to connect
- os.chmod(SOCK_PATH, 0o660)
-
- httpd.serve_forever()
-
-
-if __name__ == "__main__":
- main()
diff --git a/templates/ingress/usr_local_bin_gen_goaccess.sh.j2 b/templates/ingress/usr_local_bin_gen_goaccess.sh.j2
deleted file mode 100644
index 2cfc93a..0000000
--- a/templates/ingress/usr_local_bin_gen_goaccess.sh.j2
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-TARGET=/mnt/www_goaccess/index.html
-
-cat /var/log/nginx/access.log | awk '$8=$1$8' | /usr/local/bin/goaccess --log-format=VCOMBINED -j "$(($(nproc) + 1))" --keep-last=30 -a -o $TARGET --restore --persist
-chmod 644 $TARGET
-chown www $TARGET
-chgrp www $TARGET
diff --git a/templates/ingress/usr_local_bin_hetzner_ddns.sh.j2 b/templates/ingress/usr_local_bin_hetzner_ddns.sh.j2
deleted file mode 100644
index a2f4430..0000000
--- a/templates/ingress/usr_local_bin_hetzner_ddns.sh.j2
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/bin/sh
-#
-# Hetzner DNS record updater (one-shot for cron)
-# Requirements: curl, awk
-
-set -eu
-
-# ---------------------------- Defaults ---------------------------------------
-# Env-overridable:
-: "${API_TOKEN_FILE:=/usr/local/etc/hetzner_auth}"
-: "${API_BASE:=https://api.hetzner.cloud/v1}"
-# -----------------------------------------------------------------------------
-
-# Defaults
-TTL=300
-
-usage() {
- cat <<'USAGE' >&2
-Usage: hetzner_ddns.sh [OPTIONS]
-
-Options (named):
- --zone NAME_OR_ID Hetzner Zone name or ID (primary mode only)
- --rr-id ID RRSet identifier in the form "rr-name/rr-type" (e.g., "host/A")
- --iface-cmd CMD Command that prints interface info (for IP discovery)
- --ttl TTL Time-to-live of the record (optional)
- -h, --help Show this help
-
-Environment:
- API_TOKEN_FILE Path to file containing ONLY the API token
- (default: /usr/local/etc/hetzner_auth)
- API_BASE Hetzner Cloud DNS API base URL
- (default: https://api.hetzner.cloud/v1)
-
-Examples:
- API_TOKEN_FILE=/secret/token \
- ./hetzner_ddns.sh \
- --zone example.com --rr-name host --rr-type A \
- --iface-cmd "ifconfig em0"
-USAGE
-}
-
-ts() { date +"%Y-%m-%dT%H:%M:%S%z"; }
-fail() { echo "$(ts) ERROR: $*" >&2; exit 2; }
-error() { echo "$(ts) ERROR: $*" >&2; }
-warn() { echo "$(ts) WARN: $*" >&2; }
-info() { echo "$(ts) INFO: $*"; }
-
-# ----------------------------- Arg parsing -----------------------------------
-# Accept both `--key value` and `--key=value`
-
-while [ $# -gt 0 ]; do
- case "$1" in
- --zone=*) ZONE=${1#*=} ;;
- --zone) ZONE=$2; shift ;;
- --rr-id=*) RR_ID=${1#*=} ;;
- --rr-id) RR_ID=$2; shift ;;
- --iface-cmd=*) IFACE_CMD=${1#*=} ;;
- --iface-cmd) IFACE_CMD=$2; shift ;;
- --ttl=*) TTL=${1#*=} ;;
- --ttl) TTL=$2; shift ;;
- -h|--help) usage; exit 0 ;;
- --) shift; break ;;
- -*)
- error "Unknown option: $1"
- usage
- exit 2
- ;;
- *)
- error "Unexpected positional argument: $1"
- usage
- exit 2
- ;;
- esac
- shift
-done
-
-# ----------------------------- Validation ------------------------------------
-[ -n "${ZONE:-}" ] || fail "Missing --zone"
-[ -n "${RR_ID:-}" ] || fail "Missing --rr-id"
-[ -n "${IFACE_CMD:-}" ] || fail "Missing --iface-cmd"
-
-# ------------------------------ Auth -----------------------------------------
-if [ ! -r "${API_TOKEN_FILE}" ]; then
- fail "Token file missing or unreadable: ${API_TOKEN_FILE}"
-fi
-API_TOKEN="$(cat "${API_TOKEN_FILE}" | tr -d '[:space:]')"
-[ -n "${API_TOKEN}" ] || fail "API token is empty"
-
-# ------------------------------ Helpers --------------------------------------
-get_ip() {
- # Extract first IPv4 after 'inet ' (ignore inet6)
- sh -c "${IFACE_CMD}" 2>/dev/null | awk '/(^|[[:space:]])inet[[:space:]]/ {print $2; exit}'
-}
-
-# ------------------------------ Main -----------------------------------------
-IFACE_IP="$(get_ip || true)"
-if [ -z "${IFACE_IP}" ]; then
- warn "No IPv4 address found via '${IFACE_CMD}' (interface not ready?)"
- exit 1
-fi
-
-BODY=$(printf '{"records":[{"value":"%s","comment":"Updated by hetzner_ddns.sh at %s","ttl":"%s"}]}' \
- "${IFACE_IP}" "$(ts)" "${TTL}")
-
-HTTP_CODE=$(
- curl -sS -o /dev/null -w "%{http_code}" -X POST \
- -H "Content-Type: application/json" \
- -H "Authorization: Bearer ${API_TOKEN}" \
- --data "${BODY}" \
- "${API_BASE}/zones/${ZONE}/rrsets/${RR_ID}/actions/set_records"
-)
-
-case "${HTTP_CODE}" in
- 2*)
- info "Updated zone ${ZONE} RRSet ${RR_ID} -> ${IFACE_IP}"
- exit 0
- ;;
- 4*)
- error "Client error from API (HTTP ${HTTP_CODE}) - check zone/rr params/token/body"
- exit 2
- ;;
- 5*)
- warn "Server error from API (HTTP ${HTTP_CODE})"
- exit 1
- ;;
- *)
- warn "Unexpected HTTP status ${HTTP_CODE}"
- exit 1
- ;;
-esac
diff --git a/templates/ingress/usr_local_etc_hetzner_auth.j2 b/templates/ingress/usr_local_etc_hetzner_auth.j2
deleted file mode 100644
index 129dccf..0000000
--- a/templates/ingress/usr_local_etc_hetzner_auth.j2
+++ /dev/null
@@ -1 +0,0 @@
-{{ hetzner_pat }}
diff --git a/templates/ingress/usr_local_etc_nginx_nginx.conf.j2 b/templates/ingress/usr_local_etc_nginx_nginx.conf.j2
deleted file mode 100644
index 16299ef..0000000
--- a/templates/ingress/usr_local_etc_nginx_nginx.conf.j2
+++ /dev/null
@@ -1,141 +0,0 @@
-worker_processes auto;
-
-events {
- worker_connections 1024;
-}
-
-http {
- include mime.types;
- default_type application/octet-stream;
-
- sendfile on;
- keepalive_timeout 65;
-
- log_format vcombined '$host:$server_port '
- '$remote_addr - $remote_user [$time_local] '
- '"$request" $status $body_bytes_sent '
- '"$http_referer" "$http_user_agent"';
-
- access_log /var/log/nginx/access.log vcombined;
-
- gzip on;
- gzip_vary on;
- gzip_min_length 512;
- gzip_types
- text/plain
- text/css
- application/json
- application/javascript
- application/xml
- image/svg+xml;
-
- server {
- listen 80 default_server;
- server_name _;
-
- include /usr/local/etc/nginx/snippets/ban.inc;
-
- location / {
- return 404;
- }
- }
-
- {% for route in ingress_routes -%}
- server {
- listen 80;
- listen [::]:80;
- server_name {{ route.host }};
-
- include /usr/local/etc/nginx/snippets/ban.inc;
-
- return 307 https://$host$request_uri;
- }
-
- server {
- server_name {{ route.host }};
- http2 on;
-
- include /usr/local/etc/nginx/snippets/ban.inc;
-
- listen 443 ssl;
- listen [::]:443 ssl;
-
- # See https://ssl-config.mozilla.org/#server=nginx&version=1.28.0&config=intermediate&openssl=3.4.0&guideline=5.7
- add_header Strict-Transport-Security "max-age=63072000" always;
-
- # Common hardening headers
- add_header X-Content-Type-Options nosniff always;
- add_header X-Frame-Options DENY always;
- add_header Referrer-Policy strict-origin-when-cross-origin always;
- add_header Permissions-Policy interest-cohort=();
-
- # Hide "Server: nginx/1.28.0" header
- server_tokens off;
-
- ssl_certificate /usr/local/etc/letsencrypt/live/{{ cert_name }}/fullchain.pem;
- ssl_certificate_key /usr/local/etc/letsencrypt/live/{{ cert_name }}/privkey.pem;
- include /usr/local/etc/letsencrypt/options-ssl-nginx.conf;
- ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem;
-
- {% if route.jail is defined -%}
- {% for jail in jails if jail.name == route.jail -%}
- location / {
- proxy_pass http://192.168.2.{{ jail.num }}{% if route.port is defined %}:{{ route.port }}{% endif %};
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- {% if jail.name == 'irc_thelounge' -%}
- proxy_http_version 1.1;
- proxy_set_header Connection "Upgrade";
- proxy_set_header Upgrade $http_upgrade;
-
- # by default nginx times out connections in one minute
- proxy_read_timeout 1d;
- proxy_send_timeout 1d;
- proxy_buffering off;
- proxy_request_buffering off;
-
- client_max_body_size 100M;
- {% elif jail.name == 'plex' -%}
- proxy_http_version 1.1;
- proxy_set_header Connection "Upgrade";
- proxy_set_header Upgrade $http_upgrade;
-
- # Streaming-friendly behavior
- proxy_redirect off;
- proxy_buffering off;
-
- # Long streams / slow clients
- proxy_read_timeout 3600s;
- proxy_send_timeout 3600s;
- {% endif %}
- }
- {% endfor %}
- {% elif route.redirect is defined -%}
- return 307 https://{{ route.redirect }}$request_uri;
- {% elif route.ip is defined -%}
- location / {
- proxy_pass http://{{ route.ip }}:{{ route.port }};
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
-
- # TODO: these shouldn't configured for all ip:port proxies but Immich needs them
- proxy_http_version 1.1;
- proxy_set_header Connection "upgrade";
- proxy_set_header Upgrade $http_upgrade;
-
- # by default nginx times out connections in one minute
- proxy_read_timeout 1d;
- proxy_send_timeout 1d;
- proxy_buffering off;
- proxy_request_buffering off;
-
- client_max_body_size 10G;
- }
- {% endif %}
- }
- {% endfor %}
-}
diff --git a/templates/ingress/usr_local_etc_rc.d_pf_ban_socket b/templates/ingress/usr_local_etc_rc.d_pf_ban_socket
deleted file mode 100644
index d21bc2d..0000000
--- a/templates/ingress/usr_local_etc_rc.d_pf_ban_socket
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-#
-# PROVIDE: pf_ban_socket
-# REQUIRE: NETWORKING pf
-# KEYWORD: shutdown
-#
-# Enable in /etc/rc.conf:
-# pf_ban_socket_enable="YES"
-#
-. /etc/rc.subr
-
-name="pf_ban_socket"
-rcvar=pf_ban_socket_enable
-
-load_rc_config $name
-
-: ${pf_ban_socket_command:=/usr/local/bin/pf-ban-socket.py}
-: ${pf_ban_socket_log:=/var/log/${name}.log}
-
-start_cmd="${name}_start"
-stop_cmd="${name}_stop"
-status_cmd="${name}_status"
-
-extra_commands="status"
-
-pf_ban_socket_start() {
- /usr/local/bin/logto ${pf_ban_socket_log} ${pf_ban_socket_command} &
-}
-
-pf_ban_socket_status() {
- if pgrep -f "pf-ban-socket.py"; then
- echo "pf_ban_socket is running"
- else
- echo "pf_ban_socket is not running"
- exit 1
- fi
-}
-
-pf_ban_socket_stop() {
- pkill "pf-ban-socket.py"
-}
-
-run_rc_command "$1"
diff --git a/templates/jail_confs/_default.j2 b/templates/jail_confs/_default.j2
deleted file mode 100644
index 3a4e492..0000000
--- a/templates/jail_confs/_default.j2
+++ /dev/null
@@ -1,5 +0,0 @@
-devfs_ruleset = 4;
-
-{% include 'jail_confs/_epl_network.j2' %}
-
-exec.poststart += "jexec ${name} route add default {{ ingress_ip }} || echo 'Failed to add default route'";
diff --git a/templates/jail_confs/_epl_network.j2 b/templates/jail_confs/_epl_network.j2
deleted file mode 100644
index fa3744a..0000000
--- a/templates/jail_confs/_epl_network.j2
+++ /dev/null
@@ -1,18 +0,0 @@
-## _epl_network begin
-exec.prestart += "ifconfig epair{{ jail.num }}000 create || echo 'Failed to create epair{{ jail.num }}000'";
-exec.prestart += "ifconfig epair{{ jail.num }}000a name epl{{ jail.num }}a";
-exec.prestart += "ifconfig epair{{ jail.num }}000b name epl{{ jail.num }}b";
-exec.prestart += "ifconfig epl{{ jail.num }}b ether random";
-exec.prestart += "ifconfig brlan0 addm epl{{ jail.num }}a";
-
-exec.poststart += "ifconfig epl{{ jail.num }}b vnet ${name}";
-exec.poststart += "jexec ${name} ifconfig epl{{ jail.num }}b up";
-exec.poststart += "ifconfig epl{{ jail.num }}a up";
-exec.poststart += "jexec ${name} ifconfig epl{{ jail.num }}b {{ jail_lan_prefix }}.{{ jail.num + jail_ip_offset }}/{{ jail_lan_prefixlen }}";
-exec.poststart += "jexec ${name} route delete default || echo 'No default route to delete'";
-
-{% if not is_test_vm %}
-exec.poststart += "jexec ${name} route add 10.6.210.0/24 {{ lan_ipv4_gateway }} || echo 'Failed to add Wireguard return route'";
-{% endif %}
-exec.poststop += "ifconfig epl{{ jail.num }}a destroy";
-## _epl_network end
diff --git a/templates/jail_confs/dl.j2 b/templates/jail_confs/dl.j2
deleted file mode 100644
index 8d98ef4..0000000
--- a/templates/jail_confs/dl.j2
+++ /dev/null
@@ -1,6 +0,0 @@
-{% include 'jail_confs/_epl_network.j2' %}
-devfs_ruleset = 4;
-allow.mlock;
-
-exec.prestart += "mount -t nullfs /usr/local/jails/volumes/storage /usr/local/jails/containers/dl/mnt/storage || echo 'Failed to mount'";
-exec.poststop += "umount /usr/local/jails/containers/dl/mnt/storage || echo 'Failed to umount'";
diff --git a/templates/jail_confs/ingress.j2 b/templates/jail_confs/ingress.j2
deleted file mode 100644
index 5964d06..0000000
--- a/templates/jail_confs/ingress.j2
+++ /dev/null
@@ -1,22 +0,0 @@
-devfs_ruleset = 6;
-
-{% include 'jail_confs/_epl_network.j2' %}
-
-exec.prestart += "ifconfig epair{{ jail.num }}001 create || echo 'Failed to create epair{{ jail.num }}001'";
-exec.prestart += "ifconfig epair{{ jail.num }}001a name epw1a";
-exec.prestart += "ifconfig epair{{ jail.num }}001b name epw1b";
-exec.prestart += "ifconfig brwan0 addm epw{{ jail.num }}a";
-
-exec.poststart += "ifconfig epw{{ jail.num }}b vnet ${name}";
-exec.poststart += "jexec ${name} ifconfig epw{{ jail.num }}b up";
-exec.poststart += "ifconfig epw{{ jail.num }}a up";
-{% if is_test_vm %}
-exec.poststart += "jexec ${name} ifconfig epw{{ jail.num }}b inet 10.0.20.3/24";
-exec.poststart += "jexec ${name} route add default 10.0.20.1";
-{% else %}
-exec.poststart += "jexec ${name} service dhclient restart epw{{ jail.num }}b";
-{% endif %}
-
-exec.prestart += "mount -t nullfs /usr/local/jails/containers/goaccess/var/www/goaccess /usr/local/jails/containers/ingress/mnt/www_goaccess || echo 'Failed to mount'";
-exec.poststop += "umount /usr/local/jails/containers/ingress/mnt/www_goaccess || echo 'Failed to umount'";
-exec.poststop += "ifconfig epw{{ jail.num }}a destroy";
diff --git a/templates/jail_confs/komga.j2 b/templates/jail_confs/komga.j2
deleted file mode 100644
index 2567fa2..0000000
--- a/templates/jail_confs/komga.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-{% include 'jail_confs/_default.j2' %}
-
-exec.prestart += "mount -t nullfs /usr/local/jails/volumes/storage/media/manga /usr/local/jails/containers/komga/mnt/manga || echo 'Failed to mount'";
-exec.poststop += "umount /usr/local/jails/containers/komga/mnt/manga || echo 'Failed to umount'";
diff --git a/templates/jail_confs/plex.j2 b/templates/jail_confs/plex.j2
deleted file mode 100644
index 2446a14..0000000
--- a/templates/jail_confs/plex.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-{% include 'jail_confs/_default.j2' %}
-
-exec.prestart += "mount -t nullfs /usr/local/jails/volumes/storage/media /usr/local/jails/containers/plex/mnt/media || echo 'Failed to mount'";
-exec.poststop += "umount /usr/local/jails/containers/plex/mnt/media || echo 'Failed to umount'";
diff --git a/templates/jail_confs/postgres.j2 b/templates/jail_confs/postgres.j2
deleted file mode 100644
index bb3d1f1..0000000
--- a/templates/jail_confs/postgres.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-{% include 'jail_confs/_epl_network.j2' %}
-devfs_ruleset = 5;
-
-allow.sysvipc;
diff --git a/templates/jail_confs/samba.j2 b/templates/jail_confs/samba.j2
deleted file mode 100644
index 24835fa..0000000
--- a/templates/jail_confs/samba.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-{% include 'jail_confs/_default.j2' %}
-
-exec.prestart += "mount -t nullfs /usr/local/jails/volumes/storage /usr/local/jails/containers/samba/mnt/storage || echo 'Failed to mount'";
-exec.poststop += "umount /usr/local/jails/containers/samba/mnt/storage || echo 'Failed to umount'";
diff --git a/templates/jail_confs/syncthing.j2 b/templates/jail_confs/syncthing.j2
deleted file mode 100644
index 980d47c..0000000
--- a/templates/jail_confs/syncthing.j2
+++ /dev/null
@@ -1,11 +0,0 @@
-{% include 'jail_confs/_default.j2' %}
-
-exec.prestart += "mount -t nullfs /usr/local/jails/volumes/storage/docs /usr/local/jails/containers/syncthing/mnt/docs || echo 'Failed to mount'";
-exec.prestart += "mount -t nullfs /usr/local/jails/volumes/storage/vault /usr/local/jails/containers/syncthing/mnt/vault || echo 'Failed to mount'";
-exec.prestart += "mount -t nullfs /usr/local/jails/volumes/storage/jan-systems-2025-content /usr/local/jails/containers/syncthing/mnt/jan-systems-2025-content || echo 'Failed to mount'";
-exec.prestart += "mount -t nullfs /usr/local/jails/volumes/storage/projects-ableton /usr/local/jails/containers/syncthing/mnt/projects-ableton || echo 'Failed to mount'";
-
-exec.poststop += "umount /usr/local/jails/containers/syncthing/mnt/projects-ableton || echo 'Failed to umount'";
-exec.poststop += "umount /usr/local/jails/containers/syncthing/mnt/jan-systems-2025-content || echo 'Failed to umount'";
-exec.poststop += "umount /usr/local/jails/containers/syncthing/mnt/vault || echo 'Failed to umount'";
-exec.poststop += "umount /usr/local/jails/containers/syncthing/mnt/docs || echo 'Failed to umount'";
diff --git a/templates/root_bashrc b/templates/root_bashrc
deleted file mode 100644
index f580db6..0000000
--- a/templates/root_bashrc
+++ /dev/null
@@ -1,7 +0,0 @@
-HISTCONTROL=ignoredups:erasedups # no duplicate entries
-HISTSIZE=100000 # big big history
-HISTFILESIZE=100000 # big big history
-shopt -s histappend # append to history, don't overwrite it
-
-# Save and reload the history after each command finishes
-PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
diff --git a/templates/root_clone.sh b/templates/root_clone.sh
deleted file mode 100644
index 7f92c5f..0000000
--- a/templates/root_clone.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-REPO="$1"
-TARGET="$2"
-
-set -eux
-
-# Exits with 100 if the directory was changed
-
-if [ ! -d "$TARGET" ]; then
- git clone --depth=1 --branch main --single-branch "$REPO" "$TARGET"
- exit 100
-fi
-
-cd "$TARGET"
-before=$(git rev-parse HEAD)
-git fetch --depth=1 --prune origin main
-git reset --hard origin/main
-after=$(git rev-parse HEAD)
-
-if [ "$before" != "$after" ]; then exit 100; fi
diff --git a/templates/root_ssh_config.j2 b/templates/root_ssh_config.j2
deleted file mode 100644
index 96f78f2..0000000
--- a/templates/root_ssh_config.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-Host backup
- HostName {{ backup_ssh_host }}
- User {{ backup_ssh_user }}
- IdentityFile /root/.ssh/backup
diff --git a/templates/usr_local_bin_backup.sh.j2 b/templates/usr_local_bin_backup.sh.j2
deleted file mode 100644
index f6a0e2c..0000000
--- a/templates/usr_local_bin_backup.sh.j2
+++ /dev/null
@@ -1,365 +0,0 @@
-{% raw %}#!/usr/bin/env bash
-set -euo pipefail
-
-# ===== CONFIG (filled by Ansible) =====
-KEEP_LOCAL=30
-KEEP_REMOTE=10
-KEYFILE="/root/.ssh/backup"
-HOST_DIR="backup"
-DATASET="{% endraw %}{{ backup_zfs_dataset }}{% raw %}"
-BACKUP_EXCLUDE_PROP="{% endraw %}{{ backup_zfs_exclude_property | default('com.pursotin:backup') }}{% raw %}"
-USER="{% endraw %}{{ backup_ssh_user }}{% raw %}"
-HOST="{% endraw %}{{ backup_ssh_host }}{% raw %}"
-EMAIL_TO=root
-# =====================================
-
-# ----- Globals for notification -----
-STARTED_AT="$(date '+%Y-%m-%dT%H:%M:%S%z')"
-FINISHED_AT=""
-MESSAGE_LOG=""
-BACKUP_NAME="" # e.g. zroot@2025-09-30-12-00-00-0300.enc
-BACKUP_SIZE_BYTES="" # numeric bytes
-
-# ----- Helpers -----
-die() { echo "Error: $*" >&2; exit 1; }
-
-require_cmds() {
- local cmds=("$@")
- for c in "${cmds[@]}"; do command -v "$c" >/dev/null 2>&1 || die "Missing command: $c"; done
-}
-
-log_note() {
- # Echo to console and append to message buffer
- local msg="$1"
- echo "$msg"
- MESSAGE_LOG+="$msg"$'\n'
-}
-
-timestamp() {
- # Replace '+' with '-' so timezone is filename-safe and lexicographically sortable within TZ.
- date +%Y-%m-%d-%H-%M-%S%z | tr '+' '-'
-}
-
-humanize_bytes() {
- local bytes="$1"
- if [[ "${bytes}" =~ ^[0-9]+$ ]]; then
- awk -v b="${bytes}" '
- BEGIN {
- unit_count = split("B KiB MiB GiB TiB PiB EiB", units, " ")
- i = 1
- while (b >= 1024 && i < unit_count) {
- b = b / 1024
- i++
- }
- if (i == 1) {
- printf "%.0f %s\n", b, units[i]
- } else {
- printf "%.2f %s\n", b, units[i]
- }
- }
- '
- else
- echo "unknown"
- fi
-}
-
-latest_snapshot_for_dataset() {
- # Latest snapshot on the TOP dataset only (newest first). Returns e.g. zroot@2025-09-30-...
- zfs list -t snapshot -o name -S creation "$DATASET" 2>/dev/null \
- | awk 'NR==2{print; exit}'
-}
-
-list_top_snapshots_newest_first() {
- # Only list snapshots on the top dataset (not children), newest first.
- zfs list -t snapshot -o name -S creation "$DATASET" 2>/dev/null \
- | awk 'NR>1{print $1}'
-}
-
-list_excluded_datasets() {
- # List datasets (including inherited values) where backup property is explicitly false.
- zfs get -r -H -o name,value "${BACKUP_EXCLUDE_PROP}" "${DATASET}" 2>/dev/null \
- | awk 'tolower($2)=="false"{print $1}'
-}
-
-list_remote_backups_sorted() {
- # We store files under ${HOST_DIR}/<dataset>@<timestamp>.enc
- echo "ls ${HOST_DIR}" \
- | sftp -q -i "${KEYFILE}" "${USER}@${HOST}" 2>/dev/null \
- | tail -n +2 | sort
-}
-
-# Upload a local file to the storage box path "${HOST_DIR}/<remote_name>"
-sftp_put() {
- local local_file="$1"
- local remote_name="$2" # just the filename, no directory
- sftp -i "${KEYFILE}" "${USER}@${HOST}" <<EOF
-put ${local_file} ${HOST_DIR}/${remote_name}
-EOF
-}
-
-# ----- Subcommands -----
-cmd_init_remote() {
- echo ""
- echo "[init-remote]"
- require_cmds sftp
-
- echo "Checking for remote directory: ${HOST_DIR}"
- if echo "ls ${HOST_DIR}" | sftp -i "${KEYFILE}" "${USER}@${HOST}" >/dev/null 2>&1; then
- echo "Remote directory already exists: ${HOST_DIR}"
- log_note "init-remote: verified remote directory '${HOST_DIR}'"
- return 0
- fi
-
- echo "Creating remote directory: ${HOST_DIR}"
- set +e
- sftp -i "${KEYFILE}" "${USER}@${HOST}" <<EOF
-mkdir ${HOST_DIR}
-EOF
- rc=$?
- set -e
- if [[ $rc -ne 0 ]]; then
- die "Failed to create remote directory ${HOST_DIR}"
- fi
-
- # Re-check
- if echo "ls ${HOST_DIR}" | sftp -q -i "${KEYFILE}" "${USER}@${HOST}" >/dev/null 2>&1; then
- echo "Remote directory created: ${HOST_DIR}"
- log_note "init-remote: created remote directory '${HOST_DIR}'"
- else
- die "Remote directory ${HOST_DIR} not found after creation"
- fi
-}
-
-cmd_snapshot() {
- echo ""
- echo "[snapshot]"
- require_cmds zfs date tr
- local ts snap
- ts="$(timestamp)"
- snap="${DATASET}@${ts}"
- echo "Taking recursive snapshot \"${snap}\""
- (set -x; zfs snapshot -r "${snap}")
- echo "Recursive snapshot \"${snap}\" created"
- log_note "snapshot: created recursive snapshot '${snap}'"
-}
-
-cmd_send_to_remote() {
- echo ""
- echo "[send-to-remote]"
- require_cmds zfs age sftp mktemp stat awk sort
-
- local snap base target tmp size_bytes ds parent skip
- local -a send_args excluded_raw excluded
- snap="$(latest_snapshot_for_dataset)"
- [[ -n "${snap}" ]] || die "No snapshot found to send. Run 'snapshot' first or ensure the dataset has snapshots."
-
- base="$(basename "${snap}")" # e.g., zroot@2025-09-30-12-00-00-0300
- target="${base}.enc"
- tmp="$(mktemp -t backup_send.XXXXXX)"
- trap 'rm -f "${tmp}"' EXIT
-
- send_args=(-Rvc)
- mapfile -t excluded_raw < <(list_excluded_datasets | sort)
- excluded=()
- for ds in "${excluded_raw[@]}"; do
- skip=0
- [[ -n "${ds}" ]] || continue
- for parent in "${excluded[@]}"; do
- if [[ "${ds}" == "${parent}" || "${ds}" == "${parent}/"* ]]; then
- skip=1
- break
- fi
- done
- [[ "${skip}" -eq 1 ]] || excluded+=("${ds}")
- done
-
- if [[ "${#excluded[@]}" -gt 0 ]]; then
- echo "Excluding datasets where ${BACKUP_EXCLUDE_PROP}=false:"
- for ds in "${excluded[@]}"; do
- if [[ "${ds}" == "${DATASET}" ]]; then
- die "Top dataset ${DATASET} is excluded via ${BACKUP_EXCLUDE_PROP}=false; refusing to create an empty backup stream."
- fi
- echo " - ${ds}"
- send_args+=(-X "${ds}")
- done
- log_note "send-to-remote: excluded ${#excluded[@]} dataset(s) using ${BACKUP_EXCLUDE_PROP}=false"
- fi
-
- echo "Creating encrypted replication stream to temp file: ${tmp}"
- # -R: recursive hierarchy, -v: progress to stderr, -c: send compressed (keeps on-disk compression)
- (set -x; zfs send "${send_args[@]}" "${snap}" | age -e -i "${KEYFILE}" > "${tmp}")
-
- size_bytes="$(stat -f %z "${tmp}" 2>/dev/null || stat -c %s "${tmp}" 2>/dev/null || echo "unknown")"
- echo "Local stream size: ${size_bytes} bytes"
-
- echo "Uploading via SFTP to ${HOST}:${HOST_DIR}/${target}"
- if sftp_put "${tmp}" "${target}"; then
- echo "Upload complete"
- else
- die "SFTP upload failed (does the remote directory '${HOST_DIR}' exist? Run 'init-remote')"
- fi
-
- # Set globals for notify()
- BACKUP_NAME="${target}"
- BACKUP_SIZE_BYTES="${size_bytes}"
-
- log_note "send-to-remote: uploaded '${snap}' as '${target}' (${size_bytes} bytes) to ${HOST}:${HOST_DIR}"
- rm -f "${tmp}"
- trap - EXIT
-}
-
-cmd_prune_remote() {
- echo ""
- echo "[prune-remote]"
- require_cmds sftp awk sort wc
-
- echo "Fetching remote backup listing from sftp://${HOST}/${HOST_DIR}"
- BACKUPS="$(list_remote_backups_sorted || true)"
- mapfile -t BACKUP_ARR < <(printf "%s\n" "${BACKUPS}")
- local count="${#BACKUP_ARR[@]}"
-
- if [[ "${count}" -le "${KEEP_REMOTE}" ]]; then
- echo "Remote backups (${count}) <= KEEP_REMOTE (${KEEP_REMOTE}); nothing to prune."
- log_note "prune-remote: kept ${count} (<= ${KEEP_REMOTE}); no deletions"
- return 0
- fi
-
- echo "Pruning remote backups, keeping latest ${KEEP_REMOTE} (will delete $(("${count}" - "${KEEP_REMOTE}")))"
- local to_delete_count=$((count - KEEP_REMOTE))
- local deleted=0
- for ((i=0; i<to_delete_count; i++)); do
- b="${BACKUP_ARR[$i]}"
- [[ -n "${b}" ]] || continue
- echo "Deleting remote: ${b}"
- set +e
- echo "rm ${b}" | sftp -i "${KEYFILE}" "${USER}@${HOST}"
- rc=$?
- set -e
- if [[ $rc -ne 0 ]]; then
- die "Failed to delete remote file: ${b}"
- fi
- deleted=$((deleted+1))
- done
- echo "Remote prune done. Deleted: ${deleted}"
- log_note "prune-remote: deleted ${deleted}, kept ${KEEP_REMOTE}"
-}
-
-cmd_prune_local() {
- echo ""
- echo "[prune-local]"
- require_cmds zfs awk
-
- echo "Pruning local snapshots on dataset: ${DATASET}; keeping latest ${KEEP_LOCAL}"
- mapfile -t snaps < <(list_top_snapshots_newest_first)
- local total="${#snaps[@]}"
- if [[ "${total}" -le "${KEEP_LOCAL}" ]]; then
- echo "Local snapshots (${total}) <= KEEP_LOCAL (${KEEP_LOCAL}); nothing to prune."
- log_note "prune-local: kept ${total} (<= ${KEEP_LOCAL}); no deletions"
- return 0
- fi
-
- local deleted=0
- # List is newest-first; skip first KEEP_LOCAL and destroy the rest RECURSIVELY across the tree
- for ((i=KEEP_LOCAL; i<total; i++)); do
- s="${snaps[$i]}" # e.g., zroot@2025-09-30-...
- echo "Destroying recursive snapshot: ${s}"
- (set -x; zfs destroy -r "${s}")
- deleted=$((deleted+1))
- done
- echo "Local prune done. Deleted: ${deleted}"
- log_note "prune-local: deleted ${deleted}, kept ${KEEP_LOCAL}"
-}
-
-cmd_notify() {
- echo ""
- echo "[notify]"
- require_cmds mail date awk
- local backup_size_human
- FINISHED_AT="$(date '+%Y-%m-%dT%H:%M:%S%z')"
-
- # Derive snapshot name if not set yet (best-effort)
- if [[ -z "${BACKUP_NAME}" ]]; then
- # Try to infer from latest snapshot
- latest="$(latest_snapshot_for_dataset || true)"
- if [[ -n "${latest}" ]]; then
- BACKUP_NAME="$(basename "${latest}").enc"
- else
- BACKUP_NAME="unknown"
- fi
- fi
-
- backup_size_human="$(humanize_bytes "${BACKUP_SIZE_BYTES:-unknown}")"
-
- # Compose subject and body
- local subject="Backup completed: ${BACKUP_NAME}"
- local body=""
- body+="Backup run summary"$'\n'
- body+="Started: ${STARTED_AT}"$'\n'
- body+="Finished: ${FINISHED_AT}"$'\n'
- body+="Dataset: ${DATASET}"$'\n'
- body+="Remote: ${USER}@${HOST}:${HOST_DIR}"$'\n'
- body+="Name: ${BACKUP_NAME}"$'\n'
- body+="Size: ${backup_size_human} (${BACKUP_SIZE_BYTES:-unknown} bytes)"$'\n'
- body+=$'\n'
- body+="Steps:"$'\n'
- body+="${MESSAGE_LOG:-<no steps recorded>}"$'\n'
-
- echo "Sending notification email..."
- printf "%s\n" "$body" | mail -s "$subject" "${EMAIL_TO}"
- log_note "notify: email sent to ${EMAIL_TO}"
-}
-
-usage() {
- cat <<EOF
-Usage: $(basename "$0") [subcommand [subcommand ...]]
-
-Subcommands (executed in order):
- init-remote Create the remote backup directory (\$HOST_DIR). Succeeds if it already exists.
- snapshot Create a new **recursive** ZFS snapshot for \$DATASET
- send-to-remote Create encrypted replication stream to a temp file, then upload via SFTP
- prune-remote Keep latest \$KEEP_REMOTE backups on remote (default ${KEEP_REMOTE})
- prune-local Keep latest \$KEEP_LOCAL local snapshots on the top dataset (default ${KEEP_LOCAL})
- notify Send notification email (includes steps, timestamps, backup name & size)
-
-Notes:
- - Run 'init-remote' once before the first upload, or anytime after changing \$HOST_DIR.
- - Local pruning destroys older snapshots **recursively** to maintain consistency across descendants.
- - Set \${BACKUP_EXCLUDE_PROP}=false on a dataset to exclude it (and inherited descendants) from send-to-remote.
- Example: zfs set com.pursotin:backup=false zroot/some/heavy-dataset
-
-Examples:
- $(basename "$0") init-remote snapshot send-to-remote prune-remote prune-local notify
-EOF
-}
-
-# ----- Main -----
-main() {
- if [[ $# -eq 0 ]]; then
- usage
- exit 1
- fi
-
- # sanity
- [[ -n "${DATASET}" ]] || die "DATASET not set"
- [[ -n "${USER}" && -n "${HOST}" ]] || die "USER/HOST not set"
- [[ -r "${KEYFILE}" ]] || die "KEYFILE not readable: ${KEYFILE}"
-
- while [[ $# -gt 0 ]]; do
- case "$1" in
- init-remote) cmd_init_remote ;;
- snapshot) cmd_snapshot ;;
- send-to-remote) cmd_send_to_remote ;;
- prune-remote) cmd_prune_remote ;;
- prune-local) cmd_prune_local ;;
- notify) cmd_notify ;;
- -h|--help|help) usage; exit 0 ;;
- *) die "Unknown subcommand: $1" ;;
- esac
- shift
- done
-
- echo "Done."
-}
-
-main "$@"
-{% endraw %}
diff --git a/templates/usr_local_bin_logto.sh.j2 b/templates/usr_local_bin_logto.sh.j2
deleted file mode 100644
index 9bb5aa1..0000000
--- a/templates/usr_local_bin_logto.sh.j2
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-
-set -ue
-
-# Wrapper for logging to file and prepending a timestamp.
-# By default writes both stdout and stderr to the log file.
-
-usage() {
- echo "Usage: logto [-s|-e] <log_file> <command>"
- echo "Flags:"
- echo " -s: Write only stdout to the log file."
- echo " -e: Write only stderr to the log file."
- echo ""
- echo "Example usage:"
- echo " logto /var/log/my.log run some command"
- exit 1
-}
-
-mode="all"
-
-while getopts "se" opt; do
- case $opt in
- s) mode="stdout" ;;
- e) mode="stderr" ;;
- *) usage ;;
- esac
-done
-shift $((OPTIND-1))
-
-if [ $# -lt 2 ]; then
- usage
-fi
-
-log_file="$1"
-shift
-
-if [ "$mode" = "stdout" ]; then
- out=$(2>/dev/null $@)
-elif [ "$mode" = "stderr" ]; then
- out=$(2>&1 >/dev/null $@)
-else
- out=$(2>&1 $@)
-fi
-
-if [ ! -z "$out" ]; then
- echo "$(date +"%Y-%m-%dT%H:%M:%S%z")" "$out" >>"$log_file"
-fi
diff --git a/templates/usr_local_bin_pylogsentinel-batch-email.sh.j2 b/templates/usr_local_bin_pylogsentinel-batch-email.sh.j2
deleted file mode 100644
index d28efd9..0000000
--- a/templates/usr_local_bin_pylogsentinel-batch-email.sh.j2
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-FILE=/tmp/pylogsentinel.daily
-
-if [ ! -f "$FILE" ]; then
- echo "Nothing to do"
- exit 0
-fi
-
-echo "Sending email"
-cat "$FILE" | mail -s "pylogsentinel alert batch" root
-
-echo "Removing batch file"
-rm "$FILE"
diff --git a/templates/usr_local_bin_safepf.sh b/templates/usr_local_bin_safepf.sh
deleted file mode 100644
index 1b6efee..0000000
--- a/templates/usr_local_bin_safepf.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-
-set -eu
-
-cmd="pfctl -f /etc/pf.conf"
-read -p "Run this command (y/n)? $cmd " answer
-if [ "$answer" = "y" ]; then
- (set -x; $cmd)
-else
- exit 0
-fi
-
-cmd="service pf restart"
-read -p "Run this command (y/n)? $cmd " answer
-if [ "$answer" = "y" ]; then
- (set -x; $cmd)
-else
- exit 0
-fi
-
-timeout=60
-echo "Running safety timeout ($timeout seconds). Press CTRL-C if everything is working."
-while [ $timeout -gt 0 ]
-do
- sleep 1
- timeout=$((timeout - 1))
- echo -n "."
-done
-
-echo "Timeout reached. Enabling empty pf rules"
-
-set -x
-mv /etc/pf.conf /etc/pf.conf.locked_out
-echo "" > /etc/pf.conf
-pfctl -f /etc/pf.conf
-service pf restart
diff --git a/templates/usr_local_etc_pylogsentinel.conf.j2 b/templates/usr_local_etc_pylogsentinel.conf.j2
deleted file mode 100644
index cb80742..0000000
--- a/templates/usr_local_etc_pylogsentinel.conf.j2
+++ /dev/null
@@ -1,22 +0,0 @@
-[system]
-state_dir = /var/run/pylogsentinel
-max_block_size = 10M
-
-[logs.standard]
-cmd = find / -type f -path '*/var/log/*' ! -name '*access.log' ! -name '*.bz2' ! -name 'dmesg*' ! -name 'syncthing*'
-
-[logs.access]
-paths = /usr/local/jails/containers/ingress/var/log/nginx/access.log
-
-[action.default]
-cmd = echo -e "---------\nMatched $RULE_ID in $FILE at line $LINE, context:\n\n$CONTEXT\n" >> /tmp/pylogsentinel.daily
-
-[rule.error]
-description = Error-like conditions
-pattern = /(error|fatal|exception|killed)/i
-logs = standard
-
-[rule.access]
-description = HTTP code >=500 in access log
-pattern = /HTTP\/[0-9].[0-9]" 5[0-9][0-9]/
-logs = access
diff --git a/templates/usr_local_etc_rc.d_zpool_gpt_labels.j2 b/templates/usr_local_etc_rc.d_zpool_gpt_labels.j2
deleted file mode 100644
index 36bc715..0000000
--- a/templates/usr_local_etc_rc.d_zpool_gpt_labels.j2
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-# PROVIDE: zpool_gpt_labels
-# REQUIRE: zfs
-# BEFORE: LOGIN
-# KEYWORD: nojail
-
-. /etc/rc.subr
-
-name="zpool_gpt_labels"
-rcvar="zpool_gpt_labels_enable"
-start_cmd="zpool_gpt_labels_start"
-
-zpool_gpt_labels_start() {
- logger "Setting zpool vdev paths to GPT labels"
- local zpool_status="$(zpool status)"
- for i in 0 1 2 3; do
- local raw="nda${i}p4.eli"
- local path="/dev/gpt/zfs${i}.eli"
- case "$zpool_status" in
- *"$raw"*)
- zpool set "path=${path}" zroot "${raw}"
- logger "Setting ${raw} -> ${path}"
- ;;
- *)
- logger "Skipping ${raw}..."
- ;;
- esac
- done
-}
-
-load_rc_config $name
-run_rc_command "$1"
diff --git a/templates/usr_local_etc_smartd.conf.j2 b/templates/usr_local_etc_smartd.conf.j2
deleted file mode 100644
index bdcbfd0..0000000
--- a/templates/usr_local_etc_smartd.conf.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-/dev/nvme0 -a -d nvme
-/dev/nvme1 -a -d nvme
-/dev/nvme2 -a -d nvme
-/dev/nvme3 -a -d nvme