aboutsummaryrefslogtreecommitdiff
path: root/scripts/hostclass
diff options
context:
space:
mode:
authorCullum Smith <cullum@sacredheartsc.com>2024-10-15 23:35:53 -0400
committerCullum Smith <cullum@sacredheartsc.com>2024-10-15 23:35:53 -0400
commit145668c3dd67c5271eddcb62d1e7843487d768a7 (patch)
tree4c7d563e9d320e6b122ee3dbf048d93eee6776c3 /scripts/hostclass
parentb2af400a1098ebf445575d169e11a6717867045f (diff)
downloadinfrastructure-145668c3dd67c5271eddcb62d1e7843487d768a7.tar.gz
huge amount of fixes
Diffstat (limited to 'scripts/hostclass')
-rw-r--r--scripts/hostclass/bitwarden_server2
-rw-r--r--scripts/hostclass/cups_server3
-rw-r--r--scripts/hostclass/desktop126
-rw-r--r--scripts/hostclass/freebsd_hypervisor3
-rw-r--r--scripts/hostclass/idm_server/10-slapd15
-rw-r--r--scripts/hostclass/idm_server/90-idm6
-rw-r--r--scripts/hostclass/invidious_server91
-rw-r--r--scripts/hostclass/laptop20
-rw-r--r--scripts/hostclass/nfs_server47
-rw-r--r--scripts/hostclass/pkg_repository10
-rw-r--r--scripts/hostclass/postgresql_server25
-rw-r--r--scripts/hostclass/radius_server56
-rw-r--r--scripts/hostclass/smtp_server/10-rspamd4
-rw-r--r--scripts/hostclass/unifi_controller40
14 files changed, 379 insertions, 69 deletions
diff --git a/scripts/hostclass/bitwarden_server b/scripts/hostclass/bitwarden_server
index 5e19bdd..1f025fe 100644
--- a/scripts/hostclass/bitwarden_server
+++ b/scripts/hostclass/bitwarden_server
@@ -6,7 +6,6 @@
: ${vaultwarden_fqdn:="$fqdn"}
vaultwarden_local_username=$nginx_user
-vaultwarden_uid=$(id -u "$vaultwarden_local_username")
vaultwarden_https_cert="${nginx_conf_dir}/vaultwarden.crt"
vaultwarden_https_key="${nginx_conf_dir}/vaultwarden.key"
vaultwarden_home=/usr/local/www/vaultwarden
@@ -24,6 +23,7 @@ ktadd -k "$vaultwarden_client_keytab" "$vaultwarden_username"
chgrp "$vaultwarden_local_username" "$vaultwarden_client_keytab"
chmod 640 "$vaultwarden_client_keytab"
+vaultwarden_uid=$(id -u "$vaultwarden_local_username")
install_directory -o "$vaultwarden_local_username" -m 0700 "/var/krb5/user/${vaultwarden_uid}"
ln -snfv "$vaultwarden_client_keytab" "/var/krb5/user/${vaultwarden_uid}/client.keytab"
diff --git a/scripts/hostclass/cups_server b/scripts/hostclass/cups_server
index e3ad928..6667829 100644
--- a/scripts/hostclass/cups_server
+++ b/scripts/hostclass/cups_server
@@ -16,6 +16,9 @@ pkg install -y cups cups-filters
install_certificate -g "$cups_user" cups "$cups_tls_cert"
install_certificate_key -g "$cups_user" cups "$cups_tls_key"
+# Generate CUPS pam configuration.
+install_file -m 0644 /etc/pam.d/cups
+
# Copy CUPS configuration.
install_template -o root -g "$cups_user" -m 0640 \
"${cups_conf_dir}/cupsd.conf" \
diff --git a/scripts/hostclass/desktop b/scripts/hostclass/desktop
index 561fb8d..35237fd 100644
--- a/scripts/hostclass/desktop
+++ b/scripts/hostclass/desktop
@@ -1,75 +1,75 @@
#!/bin/sh
-load_kernel_module linux linux64 acpi_ibm
-
-pkg install -y \
- chromium \
- compton \
- dino \
- dmenu \
- eclipse \
- firefox \
- git \
- gnupg \
- krb5 \
- i3 \
- libreoffice \
- libva-intel-media-driver \
- networkmgr \
- password-store \
- py${python_version}-pip \
- stow \
- terminus-font \
- terminus-ttf \
- tmux \
- tree \
- wireguard-tools \
- xfontsel \
- xidle \
- xorg \
- xterm
+: ${desktop_access_role:='desktop-access'}
+: ${desktop_access_gid:='40000'}
+
+: ${sddm_min_uid:='10000'}
+: ${sddm_max_uid:='19999'}
+
+if [ "${enable_idm:-}" = false ]; then
+ desktop_access_role=operator
+else
+ ldap_add "cn=${desktop_access_role},${roles_basedn}" <<EOF
+objectClass: groupOfMembers
+objectClass: posixGroup
+cn: ${desktop_access_role}
+gidNumber: ${desktop_access_gid}
+EOF
+fi
+
+# Load linux kernel modules.
+load_kernel_module linux linux64
+set_loader_conf \
+ linux_load=YES \
+ linux64_load=YES
+
+# Install packages common to all DEs.
+pkg install -y $desktop_common_packages
+
+# Install scripts for creating local (non-NFS) home directories.
+install_file -m 0555 \
+ /usr/local/libexec/pam-create-local-homedir \
+ /etc/profile.d/local-homedir.sh
+install_directory -m 0755 /usr/local/home
case $desktop_type in
i3)
- pkg install \
- dunst \
- i3 \
- i3lock \
- i3status \
- profanity
+ pkg install -y $desktop_i3_packages
;;
kde)
- pkg install \
- juk \
- k3b \
- kde5 \
- kid3-qt6 \
- kmix \
- konversation \
- sddm
+ # Install KDE packages.
+ pkg install -y $desktop_kde_packages
+
+ # Configure pam services.
+ install_file -m 0644 \
+ /etc/pam.d/sddm \
+ /etc/pam.d/kde
+
+ # Copy SDDM config file.
+ install_template -m 0644 /usr/local/etc/sddm.conf
+
+ # Create profile script for KDE environment variables.
+ install_file -m 0644 /etc/profile.d/kde.sh
+
+ # Create SDDM local homedir.
+ install_directory -o sddm -g sddm -m 0700 /usr/local/home/sddm
+
+ # Enable sddm.
+ sysrc -v sddm_enable=YES
;;
esac
+# Tune sysctls for desktop usage.
set_sysctl \
net.local.stream.recvspace=65536 \
net.local.stream.sendspace=65536 \
kern.sched.preempt_thresh=224 \
- vfs.usermount=1 \
- hw.snd.latency=7
+ vfs.usermount=1
set_loader_conf \
kern.ipc.shmseg=1024 \
kern.ipc.shmmni=1024 \
kern.maxproc=100000 \
- linux_load=YES \
- linux64_load=YES \
- acpi_ibm_load=YES \
- compat.linuxkpi.i915_enable_dc=2 \
- compat.linuxkpi.i915_enable_fbc=1 \
- compat.linuxkpi.i915_fastboot=1 \
- compat.linuxkpi.i915_disable_power_well=1 \
- machdep.hwpstate_pkg_ctrl=0 \
- vfs.zfs.txg.timeout=10 \
hw.pci.do_power_nodriver=3
# Create policy file for firefox.
@@ -88,6 +88,18 @@ install_file -m 0644 /usr/local/lib/libreoffice/program/sofficerc
# Add terminus font to X11
install_file -m 0644 /usr/local/etc/X11/xorg.conf.d/terminus.conf
+# Create xdg override directory.
+install_directory -m 0755 \
+ /usr/local/override \
+ /usr/local/override/applications
+
+# Create xdg application overrides.
+install_file -m 0644 \
+ /usr/local/override/applications/signal-desktop.desktop
+
+# Create polkit rules for shutdown/reboot/suspend
+install_template -m 0644 /usr/local/etc/polkit-1/rules.d/51-desktop.rules
+
# Enable dbus.
sysrc -v dbus_enable=YES
service dbus status || service dbus start
@@ -98,6 +110,9 @@ case $graphics_type in
pkg install -y drm-kmod
sysrc -v kld_list+=i915kms
load_kernel_module i915kms
+ set_loader_conf \
+ compat.linuxkpi.i915_enable_fbc=1 \
+ compat.linuxkpi.i915_fastboot=1 \
;;
esac
@@ -164,3 +179,8 @@ xterm-256color|xterm with 256 colors,
tbc=\E[3g, u6=\E[%i%d;%dR, u7=\E[6n,
u8=\E[?%[;0123456789]c, u9=\E[c, vpa=\E[%i%p1%dd,
EOF
+
+# Start login manager.
+case $desktop_type in
+ kde) service sddm status || service sddm start > /dev/null 2>&1 < /dev/null || die 'failed to start sddm' ;;
+esac
diff --git a/scripts/hostclass/freebsd_hypervisor b/scripts/hostclass/freebsd_hypervisor
index bdaa3c0..24c1da5 100644
--- a/scripts/hostclass/freebsd_hypervisor
+++ b/scripts/hostclass/freebsd_hypervisor
@@ -24,6 +24,9 @@ hypervisor_jail_bpf_ruleset=1000
# Required for vnet jails.
set_sysctl net.link.tap.up_on_open=1
+# Required to for kerberized NFS within jails.
+sysrc -v kld_list+='kgssapi kgssapi_krb5'
+
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=262189
set_sysctl vfs.zfs.vol.mode=2
diff --git a/scripts/hostclass/idm_server/10-slapd b/scripts/hostclass/idm_server/10-slapd
index d108ae2..f6c9b4a 100644
--- a/scripts/hostclass/idm_server/10-slapd
+++ b/scripts/hostclass/idm_server/10-slapd
@@ -180,6 +180,21 @@ objectClass: organizationalUnit
ou: $(ldap_rdn_value "$automount_basedn")
EOF
+ # automountMapName=auto_master,ou=automount,dc=example,dc=com
+ ldap_add "automountMapName=auto_master,${automount_basedn}" <<EOF
+objectClass: automountMap
+automountMapName: auto_master
+EOF
+ ldap_add "automountKey=/home,automountMapName=auto_master,${automount_basedn}" <<EOF
+objectClass: automount
+automountKey: /home
+automountInformation: auto_home
+EOF
+ ldap_add "automountMapName=auto_home,${automount_basedn}" <<EOF
+objectClass: automountMap
+automountMapName: auto_home
+EOF
+
# ou=sudo,dc=example,dc=com
ldap_add "$sudo_basedn" <<EOF
objectClass: organizationalUnit
diff --git a/scripts/hostclass/idm_server/90-idm b/scripts/hostclass/idm_server/90-idm
index adfdf36..1f6920b 100644
--- a/scripts/hostclass/idm_server/90-idm
+++ b/scripts/hostclass/idm_server/90-idm
@@ -93,11 +93,11 @@ install_file -m 0555 \
# Create the boxconf administrative user.
if is_primary_server && ! ldap_dn_exists "$boxconf_dn"; then
ldap_add "$boxconf_dn" <<EOF
-objectClass: krbPrincipal
+objectClass: account
objectClass: simpleSecurityObject
-krbPrincipalName: ${boxconf_username}@${realm}
+uid: ${boxconf_username}
userPassword: {SASL}${boxconf_username}@${realm}
EOF
- kadmin.local change_password -pw "$boxconf_password" "$boxconf_username"
+ kadmin.local add_principal -x "dn=${boxconf_dn}" -pw "$boxconf_password" "$boxconf_username"
fi
diff --git a/scripts/hostclass/invidious_server b/scripts/hostclass/invidious_server
new file mode 100644
index 0000000..95333a5
--- /dev/null
+++ b/scripts/hostclass/invidious_server
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+# Note: does not work. inv_sig_helper does not build on FreeBSD...
+
+# Generate using: https://github.com/iv-org/youtube-trusted-session-generator
+: ${invidious_po_token:='changeme'}
+: ${invidious_visitor_data:='changeme'}
+
+: ${invidious_username:='s-invidious'}
+: ${invidious_password:='changeme'}
+: ${invidious_hmac_key:='changemeeeeeeeeeeee'}
+: ${invidious_dbname:='invidious'}
+: ${invidious_dbhost:="$postgres_host"}
+: ${invidious_fqdn:="$fqdn"}
+: ${invidious_repo='https://github.com/iv-org/invidious'}
+: ${invidious_branch='master'}
+
+invidious_dn="uid=${invidious_username},${robots_basedn}"
+invidious_local_username=$nginx_user
+invidious_home=/usr/local/invidious
+invidious_port=8080
+invidious_repo_dir="${invidious_home}/invidious.git"
+invidious_https_cert="${nginx_conf_dir}/invidious.crt"
+invidious_https_key="${nginx_conf_dir}/invidious.key"
+invidious_signature_sock=/tmp/inv_sig_helper.sock
+
+# Install required packages.
+pkg install -y \
+ ca_root_nss \
+ git \
+ crystal \
+ shards \
+ sqlite3 \
+ nginx \
+ postgresql${postgresql_version}-client \
+ rust
+
+# Create invidious user account.
+ldap_add "$invidious_dn" <<EOF
+objectClass: account
+objectClass: simpleSecurityObject
+uid: ${invidious_username}
+userPassword: {SSHA-512}
+EOF
+
+# Set LDAP password for invidious user.
+ldap_passwd "$invidious_dn" "$invidious_password"
+
+# Create postgres user and database.
+postgres_create_role "$invidious_dbhost" "$invidious_username"
+postgres_create_database "$invidious_dbhost" "$invidious_dbname" "$invidious_username"
+
+# Clone git repo.
+install_directory -o "$invidious_local_username" -g "$invidious_local_username" -m 0775 "$invidious_home"
+[ -d "${invidious_repo_dir}" ] || su -m "$invidious_local_username" -c "git clone ${invidious_repo} ${invidious_repo_dir}"
+
+# Update git repo.
+su -m "$invidious_local_username" -c "git -C ${invidious_repo_dir} pull --ff-only"
+su -m "$invidious_local_username" -c "git -C ${invidious_repo_dir} switch ${invidious_branch}"
+
+# Build invidious.
+( cd "$invidious_repo_dir"
+ su -m "$invidious_local_username" -c "HOME=${invidious_home} shards install --production"
+ su -m "$invidious_local_username" -c "HOME=${invidious_home} crystal build src/invidious.cr --release"
+)
+
+# Copy invidious configuration.
+install_template -o "$invidious_local_username" -g "$invidious_local_username" -m 0600 "${invidious_repo_dir}/config/config.yml"
+
+# Copy invidious rc script.
+install_file -m 0555 /usr/local/etc/rc.d/invidious
+
+# Copy TLS certificate for nginx.
+install_certificate invidious "$invidious_https_cert"
+install_certificate_key invidious "$invidious_https_key"
+
+# Generate nginx configuration.
+install_template -m 0644 \
+ /usr/local/etc/nginx/nginx.conf \
+ /usr/local/etc/nginx/vhosts.conf
+
+# Start daemons.
+sysrc -v \
+ invidious_enable=YES \
+ nginx_enable=YES
+service invidious restart
+service nginx restart
+
+# Copy invidous auto-update script.
+install_file -m 0555 /usr/local/libexec/invidious-update
+install_template -m 0644 /etc/cron.d/invidious
diff --git a/scripts/hostclass/laptop b/scripts/hostclass/laptop
index 26f9fe6..dba2c5f 100644
--- a/scripts/hostclass/laptop
+++ b/scripts/hostclass/laptop
@@ -1,5 +1,9 @@
#!/bin/sh
+# Enable thinkpad hardware features.
+load_kernel_module acpi_ibm
+set_loader_conf acpi_ibm_load=YES
+
# Set USB power savings
usbconfig | awk -F: '{ print $1 }' | xargs -rtn1 -I% usbconfig -d % power_save ||:
install_file /etc/rc.local
@@ -14,6 +18,19 @@ load_kernel_module if_urndis
set_loader_conf if_urndis_load=YES
sysrc -v ifconfig_ue0='DHCP'
+# Install laptop packages.
+pkg install -y networkmgr
+
+# Misc power saving stuff.
+set_loader_conf \
+ vfs.zfs.txg.timeout=10 \
+
+if [ "$graphics_type" = intel ]; then
+ set_loader_conf \
+ compat.linuxkpi.i915_disable_power_well=1 \
+ compat.linuxkpi.i915_enable_dc=2
+fi
+
case ${wireless_type:-} in
iwm*)
set_loader_conf \
@@ -28,6 +45,9 @@ case ${wireless_type:-} in
;;
esac
+# Enable power saving for sound card.
+set_sysctl hw.snd.latency=7
+
# Configure wireless card.
sysrc -v \
create_args_wlan0='country US regdomain FCC' \
diff --git a/scripts/hostclass/nfs_server b/scripts/hostclass/nfs_server
new file mode 100644
index 0000000..ce47cfe
--- /dev/null
+++ b/scripts/hostclass/nfs_server
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# Jails serving NFS need 'allow.nfsd' option.
+
+: ${nfsuserd_cache_size:='256'}
+: ${nfsuserd_num_servers:='4'}
+: ${nfsuserd_cache_timeout:='1'}
+: ${nfsd_srvmaxio:='1048576'}
+
+nfs_root=/share
+nfs_dataset="${state_dataset}/nfs"
+
+# Create ZFS dataset for NFS share.
+create_dataset -o "mountpoint=${nfs_root}" "${nfs_dataset}"
+
+# Create nfs service principal and keytab.
+add_principal -nokey -x "containerdn=${services_basedn}" "nfs/${fqdn}"
+ktadd -k "${keytab_dir}/host.keytab" "nfs/${fqdn}"
+
+if [ "$BOXCONF_VIRTUALIZATION_TYPE" != jail ]; then
+ set_sysctl \
+ vfs.nfsd.issue_delegations=1 \
+ vfs.nfsd.enable_locallocks=0
+fi
+
+sysrc -v \
+ nfs_server_managegids=YES \
+ nfsuserd_enable=YES \
+ nfsuserd_flags="-usermax ${nfsuserd_cache_size} -usertimeout ${nfsuserd_cache_timeout} ${nfsuserd_num_servers}" \
+ gssd_enable=YES \
+ nfs_server_enable=YES \
+ nfs_server_flags='-t' \
+ nfs_server_maxio="$nfsd_srvmaxio" \
+ nfsv4_server_only=YES \
+ mountd_enable=YES \
+ mountd_flags='-R -S'
+
+# Our krb5.conf assumes MIT Kerberos, but the gssd in base uses the base
+# Heimdal kerberos, which doesnt support %{euid} expansion. So we must
+# override the keytab path with an environment variable.
+sysrc -v gssd_env="KRB5_KTNAME=${keytab_dir}/host.keytab"
+
+install_template -m 0644 /etc/exports
+
+for service in gssd nfsuserd mountd nfsd; do
+ service "$service" restart
+done
diff --git a/scripts/hostclass/pkg_repository b/scripts/hostclass/pkg_repository
index 6070794..7226b77 100644
--- a/scripts/hostclass/pkg_repository
+++ b/scripts/hostclass/pkg_repository
@@ -9,6 +9,8 @@
: ${poudriere_ccache_size:='50.0G'}
: ${poudriere_default_versions:='imagemagick=7-nox11'}
+poudriere_https_cert="${nginx_conf_dir}/poudriere.crt"
+poudriere_https_key="${nginx_conf_dir}/poudriere.key"
poudriere_data_dir=/usr/local/poudriere
poudriere_conf_dir=/usr/local/etc/poudriere.d
poudriere_patch_dir="${poudriere_conf_dir}/patches"
@@ -42,10 +44,15 @@ install_directory -m 0755 /usr/ports/distfiles
install_directory -m 0755 -o nobody -g nobody "${poudriere_data_dir}/ccache"
install_template -m 0644 -o nobody -g nobody "${poudriere_data_dir}/ccache/ccache.conf"
+# Copy TLS certificate for nginx.
+install_certificate nginx "$poudriere_https_cert"
+install_certificate_key nginx "$poudriere_https_key"
+
# Configure and enable nginx to serve the packages.
install_template -m 0644 \
/usr/local/etc/nginx/nginx.conf \
/usr/local/etc/nginx/vhosts.conf
+
sysrc -v nginx_enable=YES
service nginx restart
@@ -59,7 +66,8 @@ poudriere ports -v -u -p latest
install_directory -m 0755 "$poudriere_patch_dir"
rm -f "${poudriere_patch_dir}/"*.patch
install_file -m 0644 \
- "${poudriere_patch_dir}/postgresql16-gssapi.patch"
+ "${poudriere_patch_dir}/postgresql16-gssapi.patch" \
+ "${poudriere_patch_dir}/chromium-gssapi.patch"
for patch in "${poudriere_patch_dir}/"*.patch; do
[ -f "$patch" ] || continue
diff --git a/scripts/hostclass/postgresql_server b/scripts/hostclass/postgresql_server
index fb0ddcd..10bafc8 100644
--- a/scripts/hostclass/postgresql_server
+++ b/scripts/hostclass/postgresql_server
@@ -8,7 +8,10 @@
: ${postgres_maintenance_work_mem:="$(( memsize / 20 ))"}
: ${postgres_temp_buffers:="$((32 * 1024 * 1024))"}
: ${postgres_effective_cache_size:="$(( memsize * 3 / 4 ))"}
+: ${postgres_ldap_username:='s-postgresql'}
+: ${postgres_ldap_password:='changeme'}
+postgres_dn="uid=${postgres_ldap_username},${robots_basedn}"
postgres_user=postgres
postgres_home=/var/db/postgres
postgres_data_dir="${postgres_home}/data${postgresql_version}"
@@ -16,10 +19,6 @@ postgres_tls_cert="${postgres_home}/postgres.crt"
postgres_tls_key="${postgres_home}/postgres.key"
postgres_keytab="${keytab_dir}/postgres.keytab"
-psql(){
- command psql --quiet --no-align --echo-all --tuples-only --no-password --username=postgres --dbname=postgres "$@"
-}
-
pkg install -y postgresql${postgresql_version}-server
# Create ZFS dataset for postgresql data.
@@ -46,8 +45,16 @@ postgres_uid=$(id -u "$postgres_user")
install_directory -o "$postgres_user" -m 0700 "/var/krb5/user/${postgres_uid}"
ln -snfv "$postgres_keytab" "/var/krb5/user/${postgres_uid}/keytab"
-# Create postgresql PAM service.
-install_template -m 0644 /etc/pam.d/postgresql
+# Create PostgreSQL LDAP user account.
+ldap_add "$postgres_dn" <<EOF
+objectClass: account
+objectClass: simpleSecurityObject
+uid: ${postgres_ldap_username}
+userPassword: {SSHA-512}
+EOF
+
+# Set LDAP password for PostgreSQL user.
+ldap_passwd "$postgres_dn" "$postgres_ldap_password"
# Copy TLS certificate for postgres.
install_certificate -m 0644 -o root -g "$postgres_user" postgres "$postgres_tls_cert"
@@ -63,10 +70,11 @@ install_file -m 0600 -o "$postgres_user" -g "$postgres_user" \
# The postgresql rc script seems to hold onto open descriptors, which causes
# the parent boxconf SSH process to never close.
echo 'Restarting postgresql.'
-service postgresql restart > /dev/null 2>&1 < /dev/null
+service postgresql restart > /dev/null 2>&1 < /dev/null || die 'failed to start postgresql'
# Create boxconf admin user.
-psql -c "DO
+psql --quiet --no-align --echo-all --tuples-only --no-password --username=postgres --dbname=postgres -c \
+"DO
\$$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = '${boxconf_username}') THEN
@@ -74,4 +82,3 @@ BEGIN
END IF;
END
\$$"
-
diff --git a/scripts/hostclass/radius_server b/scripts/hostclass/radius_server
new file mode 100644
index 0000000..bde1be2
--- /dev/null
+++ b/scripts/hostclass/radius_server
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+# radius_clients=client1
+# radius_client1_address='192.168.1.0/24'
+# radius_client1_secret='s3cret'
+
+: ${radius_clients=''}
+
+freeradius_user=freeradius
+freeradius_conf_dir=/usr/local/etc/raddb
+freeradius_tls_cert="${freeradius_conf_dir}/freeradius.crt"
+freeradius_tls_key="${freeradius_conf_dir}/freeradius.key"
+freeradius_cache_dir=/var/cache/radiusd
+freeradius_tlscache_dir="${freeradius_cache_dir}/tlscache"
+
+# Install packages.
+pkg install -y freeradius3
+
+freeradius_version=$(pkg info freeradius3 | awk '$1 == "Version" { print $3 }')
+
+# Generate configuration.
+install_directory -m 0755 "${freeradius_conf_dir}/certs"
+install_template -o "$freeradius_user" -g "$freeradius_user" -m 0640 \
+ "${freeradius_conf_dir}/radiusd.conf" \
+ "${freeradius_conf_dir}/mods-available/eap"
+rm -f "${freeradius_conf_dir}/sites-enabled/inner-tunnel"
+
+# Copy TLS certificate for freeradius.
+install_certificate -g "$freeradius_user" freeradius "$freeradius_tls_cert"
+install_certificate_key -g "$freeradius_user" freeradius "$freeradius_tls_key"
+
+# Generate clients.conf.
+install -Cv -o "$freeradius_user" -g "$freeradius_user" -m 0660 /dev/null "${freeradius_conf_dir}/clients.conf"
+for client_name in $radius_clients; do
+ eval "client_address=\$radius_${client_name}_address"
+ eval "client_secret=\$radius_${client_name}_secret"
+ cat <<EOF >> "${freeradius_conf_dir}/clients.conf"
+client ${client_name} {
+ ipaddr = ${client_address}
+ secret = ${client_secret}
+}
+
+EOF
+done
+
+# Create cache directories.
+install_directory -o "$freeradius_user" -g "$freeradius_user" -m 700 \
+ "$freeradius_cache_dir" \
+ "$freeradius_tlscache_dir"
+
+# Clean up tlscache with cron job.
+install_template -m 0644 /etc/cron.d/freeradius
+
+# Enable and start daemons.
+sysrc -v radiusd_enable=YES
+service radiusd restart
diff --git a/scripts/hostclass/smtp_server/10-rspamd b/scripts/hostclass/smtp_server/10-rspamd
index 1794e04..7b1aae9 100644
--- a/scripts/hostclass/smtp_server/10-rspamd
+++ b/scripts/hostclass/smtp_server/10-rspamd
@@ -77,8 +77,8 @@ install_template -m 0640 -g "$rspamd_user" \
printf '%s\n' ${rspamd_domain_whitelist} | tee "${rspamd_conf_dir}/local.d/maps.d/domain-whitelist.map"
# Copy DKIM keys.
-for domain in $postfix_virtual_domains; do
- install_file -m 0640 -g "$rspamd_user" "${rspamd_data_dir}/dkim/${domain}.key"
+for _domain in $postfix_virtual_domains; do
+ install_file -m 0640 -g "$rspamd_user" "${rspamd_data_dir}/dkim/${_domain}.key"
done
# Add rspamd user to redis group, so it can write to the redis unix socket.
diff --git a/scripts/hostclass/unifi_controller b/scripts/hostclass/unifi_controller
new file mode 100644
index 0000000..32df063
--- /dev/null
+++ b/scripts/hostclass/unifi_controller
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+unifi_user=unifi
+unifi_home=/usr/local/share/java/unifi
+unifi_https_cert="${unifi_home}/data/unifi.crt"
+unifi_https_key="${unifi_home}/data/unifi.key"
+unifi_keystore="${unifi_home}/data/keystore"
+
+# Install required packages.
+pkg install -y unifi8
+
+# Create ZFS dataset for unifi data.
+create_dataset -o "mountpoint=${unifi_home}/data" "${state_dataset}/unifi"
+
+# Set ownership on unifi data dir.
+install_directory -o "$unifi_user" -g "$unifi_user" -m 0700 "${unifi_home}/data"
+
+# Copy TLS certificate for unifi.
+install_certificate -g "$unifi_user" unifi "$unifi_https_cert"
+install_certificate_key -m 0640 -g "$unifi_user" unifi "$unifi_https_key"
+
+# Enable unifi.
+sysrc -v unifi_enable=YES
+
+# Stop the unifi service.
+service unifi status && service unifi stop
+
+# Add HTTPS certificate to unifi keystore.
+[ -f "${unifi_home}/data/keystore" ] || install -Cv -o "$unifi_user" -g "$unifi_user" -m 0600 /dev/null "${unifi_home}/data/keystore"
+su -m "$unifi_user" -c "java -jar ${unifi_home}/lib/ace.jar import_key_cert ${unifi_https_key} ${unifi_https_cert} ${site_cacert_path}"
+
+# Disable analytics.
+install_directory -m 0640 -o "$unifi_user" -g "$unifi_user" \
+ "${unifi_home}/data/sites" \
+ "${unifi_home}/data/sites/default"
+grep -xFq 'config.system_cfg.1=system.analytics.anonymous=disabled' "${unifi_home}/data/sites/default/config.properties" \
+ || echo 'config.system_cfg.1=system.analytics.anonymous=disabled' | tee -a "${unifi_home}/data/sites/default/config.properties"
+
+# Start unifi.
+service unifi start