aboutsummaryrefslogtreecommitdiff
path: root/files
diff options
context:
space:
mode:
authorCullum Smith <cullum@sacredheartsc.com>2024-10-12 08:14:59 -0400
committerCullum Smith <cullum@sacredheartsc.com>2024-10-12 08:15:33 -0400
commit99b8524c16cc99ceeaf1ebf588f2fc0f2c0fbe0a (patch)
tree3ffa4113f23eca6cea8ff2c94ba7ce60188d943e /files
parent1c882c769e5476b5cb3fa294257c76165a7a6f46 (diff)
downloadinfrastructure-99b8524c16cc99ceeaf1ebf588f2fc0f2c0fbe0a.tar.gz
add a bunch of hostclasses
Diffstat (limited to 'files')
-rw-r--r--files/etc/cron.d/davical.dav_server2
-rw-r--r--files/etc/cron.d/prosody.xmpp_server3
-rw-r--r--files/etc/pam.d/znc.znc_server2
-rw-r--r--files/usr/local/etc/asterisk/extensions.conf.asterisk_server5
-rw-r--r--files/usr/local/etc/asterisk/logger.conf.asterisk_server3
-rw-r--r--files/usr/local/etc/asterisk/pjsip.conf.asterisk_server26
-rw-r--r--files/usr/local/etc/asterisk/pjsip_wizard.conf.asterisk_server65
-rw-r--r--files/usr/local/etc/asterisk/queues.conf.asterisk_server31
-rw-r--r--files/usr/local/etc/asterisk/rtp.conf.asterisk_server3
-rw-r--r--files/usr/local/etc/asterisk/voicemail.conf.asterisk_server31
-rw-r--r--files/usr/local/etc/dovecot/rspamd.conf.sh.imap_server5
-rw-r--r--files/usr/local/etc/nginx/fastcgi_params.common31
-rw-r--r--files/usr/local/etc/nginx/nginx.conf.common37
-rw-r--r--files/usr/local/etc/nginx/vhosts.conf.bitwarden_server36
-rw-r--r--files/usr/local/etc/nginx/vhosts.conf.dav_server55
-rw-r--r--files/usr/local/etc/nginx/vhosts.conf.smtp_server4
-rw-r--r--files/usr/local/etc/nginx/vhosts.conf.ttrss_server43
-rw-r--r--files/usr/local/etc/nginx/vhosts.conf.xmpp_server21
-rw-r--r--files/usr/local/etc/nginx/vhosts.conf.znc_server21
-rw-r--r--files/usr/local/etc/nsd/nsd.conf.authoritative_nameserver22
-rw-r--r--files/usr/local/etc/nslcd.conf.common2
-rw-r--r--files/usr/local/etc/openldap/ldap.conf.common1
-rw-r--r--files/usr/local/etc/openldap/ldap.conf.idm_server1
-rw-r--r--files/usr/local/etc/php-fpm.conf.common4
-rw-r--r--files/usr/local/etc/php-fpm.d/davical.conf.dav_server20
-rw-r--r--files/usr/local/etc/php-fpm.d/ttrss.conf.ttrss_server23
-rw-r--r--files/usr/local/etc/php.ini.common138
-rw-r--r--files/usr/local/etc/poudriere.d/pkglist.pkg_repository28
-rw-r--r--files/usr/local/etc/prosody/prosody.cfg.lua.xmpp_server106
-rw-r--r--files/usr/local/etc/rc.conf.d/vaultwarden.bitwarden_server19
-rw-r--r--files/usr/local/etc/rc.d/ttrssd.ttrss_server47
-rw-r--r--files/usr/local/etc/ssh/sshd_config.d/acmeproxy.conf.common11
-rw-r--r--files/usr/local/etc/ssh/sshd_config.freebsd2
-rw-r--r--files/usr/local/etc/sudoers.d/acme.asterisk_server1
-rw-r--r--files/usr/local/etc/sudoers.d/acme.public_webserver1
-rw-r--r--files/usr/local/etc/sudoers.d/acme.smtp_server2
-rw-r--r--files/usr/local/etc/sudoers.d/acme.xmpp_server1
-rw-r--r--files/usr/local/etc/turnserver.conf.turn_server61
-rw-r--r--files/usr/local/etc/znc/configs/znc.conf.znc_server55
-rw-r--r--files/usr/local/etc/znc/moddata/cyrusauth/.registry.znc_server2
-rw-r--r--files/usr/local/lib/sasl2/znc.conf.znc_server3
-rw-r--r--files/usr/local/libexec/dovecot/sieve-pipe/report-ham.sh.imap_server12
-rw-r--r--files/usr/local/libexec/dovecot/sieve-pipe/report-spam.sh.imap_server12
-rw-r--r--files/usr/local/libexec/idm-ssh-authorized-keys.common8
-rw-r--r--files/usr/local/libexec/idm-ssh-known-hosts.common4
-rw-r--r--files/usr/local/libexec/prosody-acme-proxy.xmpp_server54
-rw-r--r--files/usr/local/libexec/prosody-update-roster.xmpp_server47
-rw-r--r--files/usr/local/www/davical/config/administration.yml.dav_server4
-rw-r--r--files/usr/local/www/davical/config/config.php.dav_server49
-rw-r--r--files/usr/local/www/tt-rss/config.php.ttrss_server28
-rw-r--r--files/usr/local/www/tt-rss/plugins.local/auth_idm/init.php.ttrss_server177
-rw-r--r--files/var/db/postgres/data16/postgresql.conf.postgresql_server2
52 files changed, 1347 insertions, 24 deletions
diff --git a/files/etc/cron.d/davical.dav_server b/files/etc/cron.d/davical.dav_server
new file mode 100644
index 0000000..73f0278
--- /dev/null
+++ b/files/etc/cron.d/davical.dav_server
@@ -0,0 +1,2 @@
+MAILTO=root
+0,15,30,45 * * * * ${nginx_user} ${davical_repo_dir}/scripts/cron-sync-ldap.php ${fqdn}
diff --git a/files/etc/cron.d/prosody.xmpp_server b/files/etc/cron.d/prosody.xmpp_server
new file mode 100644
index 0000000..b95f010
--- /dev/null
+++ b/files/etc/cron.d/prosody.xmpp_server
@@ -0,0 +1,3 @@
+MAILTO=root
+0 0 * * * * ${prosody_local_user} /usr/local/libexec/prosody-acme-proxy -q ${prosody_user}@${prosody_acme_host} ${prosody_domains}
+0 0 * * * * ${prosody_local_user} /usr/local/libexec/prosody-update-roster ${prosody_access_role} > ${prosody_roster_path}
diff --git a/files/etc/pam.d/znc.znc_server b/files/etc/pam.d/znc.znc_server
new file mode 100644
index 0000000..6479aca
--- /dev/null
+++ b/files/etc/pam.d/znc.znc_server
@@ -0,0 +1,2 @@
+auth required /usr/local/lib/pam_ldap.so
+account required /usr/local/lib/pam_ldap.so
diff --git a/files/usr/local/etc/asterisk/extensions.conf.asterisk_server b/files/usr/local/etc/asterisk/extensions.conf.asterisk_server
new file mode 100644
index 0000000..301fe66
--- /dev/null
+++ b/files/usr/local/etc/asterisk/extensions.conf.asterisk_server
@@ -0,0 +1,5 @@
+[public]
+exten => _X.,1,Hangup(3)
+
+[default]
+exten => _X.,1,Hangup(3)
diff --git a/files/usr/local/etc/asterisk/logger.conf.asterisk_server b/files/usr/local/etc/asterisk/logger.conf.asterisk_server
new file mode 100644
index 0000000..3bf2a53
--- /dev/null
+++ b/files/usr/local/etc/asterisk/logger.conf.asterisk_server
@@ -0,0 +1,3 @@
+[logfiles]
+console => notice,warning,error
+syslog.daemon => notice,warning,error,security,verbose1
diff --git a/files/usr/local/etc/asterisk/pjsip.conf.asterisk_server b/files/usr/local/etc/asterisk/pjsip.conf.asterisk_server
new file mode 100644
index 0000000..0f83a81
--- /dev/null
+++ b/files/usr/local/etc/asterisk/pjsip.conf.asterisk_server
@@ -0,0 +1,26 @@
+[transport-defaults](!)
+type = transport
+bind = 0.0.0.0
+local_net = 127.0.0.0/8
+local_net = 10.0.0.0/8
+local_net = 172.16.0.0/12
+local_net = 192.168.0.0/16
+external_media_address = ${asterisk_public_ip}
+external_signaling_address = ${asterisk_public_ip}
+
+[transport-udp](transport-defaults)
+protocol = udp
+
+[transport-tcp](transport-defaults)
+protocol = tcp
+
+[transport-tls](transport-defaults)
+protocol = tls
+bind = 0.0.0.0:5061
+method = tlsv1_2
+cert_file = ${asterisk_public_tls_cert}
+priv_key_file = ${asterisk_public_tls_key}
+ca_list_file = ${ca_root_nss_bundle}
+verify_client = no
+verify_server = yes
+allow_reload = yes
diff --git a/files/usr/local/etc/asterisk/pjsip_wizard.conf.asterisk_server b/files/usr/local/etc/asterisk/pjsip_wizard.conf.asterisk_server
new file mode 100644
index 0000000..1de448f
--- /dev/null
+++ b/files/usr/local/etc/asterisk/pjsip_wizard.conf.asterisk_server
@@ -0,0 +1,65 @@
+;;;;;;;;;;;
+; Trunks
+;;;;;;;;;;;
+
+[trunk-defaults](!)
+type = wizard
+sends_auth = yes
+sends_registrations = yes
+endpoint/rtp_symmetric = yes
+endpoint/rewrite_contact = yes
+endpoint/send_rpid = yes
+endpoint/from_domain = ${asterisk_sip_domain}
+endpoint/allow = !all,ulaw
+registration/max_retries = 4294967295
+registration/auth_rejection_permanent = no
+aor/qualify_frequency = 30
+
+$(for trunk in ${asterisk_trunks:-}; do
+ eval "trunk_proto=\${asterisk_trunk_${trunk}_proto:-'tcp'}"
+ eval "trunk_remote=\${asterisk_trunk_${trunk}_remote}"
+ eval "trunk_username=\${asterisk_trunk_${trunk}_username}"
+ eval "trunk_password=\${asterisk_trunk_${trunk}_password}"
+ eval "trunk_context=\${asterisk_trunk_${trunk}_context}"
+ echo "\
+[${trunk}](trunk-defaults)
+transport = transport-${trunk_proto}
+remote_hosts = ${trunk_remote}
+endpoint/context = ${trunk_context}
+endpoint/media_encryption = no
+outbound_auth/username = ${trunk_username}
+outbound_auth/password = ${trunk_password}
+"; done)
+
+
+[extension-defaults](!)
+type = wizard
+accepts_registrations = yes
+accepts_auth = yes
+aor/remove_existing = yes
+endpoint/allow = !all,g722,ulaw
+endpoint/from_domain = ${asterisk_sip_domain}
+endpoint/subscribe_context = subscribe
+
+$(for ext in ${asterisk_exts:-}; do
+ eval "ext_context=\${asterisk_ext_${ext}_context}"
+ eval "ext_password=\${asterisk_ext_${ext}_password}"
+ eval "ext_max_contacts=\${asterisk_ext_${ext}_max_contacts:-1}"
+ eval "ext_qualify_freq=\${asterisk_ext_${ext}_qualify_freq:-30}"
+ eval "ext_qualify_timeout=\${asterisk_ext_${ext}_qualify_timeout:-3.0}"
+ eval "ext_direct_media=\${asterisk_ext_${ext}_direct_media:-yes}"
+ eval "ext_cid_name=\${asterisk_ext_${ext}_cid_name}"
+ eval "ext_cid_number=\${asterisk_ext_${ext}_cid_number:-$ext}"
+ eval "ext_mailbox=\${asterisk_ext_${ext}_mailbox:-$ext}"
+ echo "\
+[${ext}](extension-defaults)
+endpoint/context = ${ext_context}
+endpoint/mailboxes = ${ext_mailbox}@default
+endpoint/callerid = ${ext_cid_name} <${ext_cid_number}>
+inbound_auth/username = ${ext}
+inbound_auth/password = ${ext_password}
+aor/max_contacts = ${ext_max_contacts}
+aor/qualify_frequency = ${ext_qualify_freq}
+aor/qualify_timeout = ${ext_qualify_timeout}
+endpoint/direct_media = ${ext_direct_media}
+"; done)
diff --git a/files/usr/local/etc/asterisk/queues.conf.asterisk_server b/files/usr/local/etc/asterisk/queues.conf.asterisk_server
new file mode 100644
index 0000000..87b8ed4
--- /dev/null
+++ b/files/usr/local/etc/asterisk/queues.conf.asterisk_server
@@ -0,0 +1,31 @@
+[general]
+persistentmembers = yes
+autofill = yes
+monitor-type = MixMonitor
+shared_lastcall = yes
+log_membername_as_agent = yes
+
+$(for queue in ${asterisk_queues:-}; do
+ eval "queue_strategy=\${asterisk_queue_${queue}_strategy}"
+ eval "queue_timeout=\${asterisk_queue_${queue}_timeout:-15}"
+ eval "queue_retry=\${asterisk_queue_${queue}_retry:-5}"
+ eval "queue_ringinuse=\${asterisk_queue_${queue}_ringinuse:-yes}"
+ eval "queue_members=\${asterisk_queue_${queue}_members}"
+ echo "\
+[${queue}]
+strategy = ${queue_strategy}
+timeout = ${queue_timeout}
+retry = ${queue_retry}
+timeoutpriority = app
+announce-frequency = 0
+announce-holdtime = no
+announce-position = no
+periodic-announce-frequency = 0
+joinempty = yes
+leavewhenempty = no
+ringinuse = ${queue_ringinuse}
+timeoutrestart = yes"
+for member in $queue_members; do
+ eval "member_name=\${asterisk_ext_${member}_cid_name}"
+ echo "member => PJSIP/${member},0,${member_name},PJSIP/${member}"
+done; done)
diff --git a/files/usr/local/etc/asterisk/rtp.conf.asterisk_server b/files/usr/local/etc/asterisk/rtp.conf.asterisk_server
new file mode 100644
index 0000000..d16d1f0
--- /dev/null
+++ b/files/usr/local/etc/asterisk/rtp.conf.asterisk_server
@@ -0,0 +1,3 @@
+[general]
+rtpstart=${asterisk_rtp_start_port}
+rtpend=${asterisk_rtp_end_port}
diff --git a/files/usr/local/etc/asterisk/voicemail.conf.asterisk_server b/files/usr/local/etc/asterisk/voicemail.conf.asterisk_server
new file mode 100644
index 0000000..c67559f
--- /dev/null
+++ b/files/usr/local/etc/asterisk/voicemail.conf.asterisk_server
@@ -0,0 +1,31 @@
+[general]
+format=wav49|gsm|wav
+
+serveremail=${asterisk_from_email}
+attach=yes
+maxmsg=100
+maxsecs=300
+maxgreet=60
+skipms=3000
+maxsilence=10
+silencethreshold=128
+maxlogins=3
+
+emailsubject=New voicemail \${VM_MSGNUM} in mailbox \${VM_MAILBOX}
+emailbody=Hi \${VM_NAME},\n\nYou have a new voicemail in mailbox \${VM_MAILBOX}.\n\nFrom: \${VM_CALLERID}\nDate: \${VM_DATE}\nDuration: \${VM_DUR}\nMessage Number: \${VM_MSGNUM}
+emaildateformat=%A, %B %d, %Y at %r
+
+tz=myzone
+locale=${asterisk_locale}
+minpassword=4
+
+[zonemessages]
+myzone=${asterisk_timezone}|'vm-received' Q 'digits/at' IMp
+
+[default]
+$(for mailbox in ${asterisk_mailboxes:-}; do
+ eval "mailbox_password=\${asterisk_mailbox_${mailbox}_password:-${asterisk_default_mailbox_password}}"
+ eval "mailbox_name=\${asterisk_mailbox_${mailbox}_name:-}"
+ eval "mailbox_email=\${asterisk_mailbox_${mailbox}_email:-}"
+ echo "${mailbox} => ${mailbox_password},${mailbox_name},${mailbox_email},,,"
+done)
diff --git a/files/usr/local/etc/dovecot/rspamd.conf.sh.imap_server b/files/usr/local/etc/dovecot/rspamd.conf.sh.imap_server
new file mode 100644
index 0000000..c1293e4
--- /dev/null
+++ b/files/usr/local/etc/dovecot/rspamd.conf.sh.imap_server
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+RSPAMD_HOST="${rspamd_host}.${domain}"
+RSPAMD_PASSWORD="${rspamd_rw_password}"
+RSPAMD_KEY="${rspamd_pubkey}"
diff --git a/files/usr/local/etc/nginx/fastcgi_params.common b/files/usr/local/etc/nginx/fastcgi_params.common
new file mode 100644
index 0000000..d0a6c69
--- /dev/null
+++ b/files/usr/local/etc/nginx/fastcgi_params.common
@@ -0,0 +1,31 @@
+fastcgi_param QUERY_STRING $query_string;
+fastcgi_param REQUEST_METHOD $request_method;
+fastcgi_param CONTENT_TYPE $content_type;
+fastcgi_param CONTENT_LENGTH $content_length;
+
+fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+fastcgi_param SCRIPT_NAME $fastcgi_script_name;
+fastcgi_param PATH_INFO $fastcgi_path_info;
+fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
+fastcgi_param REQUEST_URI $request_uri;
+fastcgi_param DOCUMENT_URI $document_uri;
+fastcgi_param DOCUMENT_ROOT $document_root;
+fastcgi_param SERVER_PROTOCOL $server_protocol;
+fastcgi_param REQUEST_SCHEME $scheme;
+fastcgi_param HTTPS $https if_not_empty;
+
+fastcgi_param GATEWAY_INTERFACE CGI/1.1;
+fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
+
+fastcgi_param REMOTE_ADDR $remote_addr;
+fastcgi_param REMOTE_PORT $remote_port;
+fastcgi_param SERVER_ADDR $server_addr;
+fastcgi_param SERVER_PORT $server_port;
+fastcgi_param SERVER_NAME $host;
+fastcgi_param REMOTE_USER $remote_user if_not_empty;
+
+# PHP only, required if PHP was built with --enable-force-cgi-redirect
+fastcgi_param REDIRECT_STATUS 200;
+
+# Protect against HTTPoxy vuln
+fastcgi_param HTTP_PROXY "";
diff --git a/files/usr/local/etc/nginx/nginx.conf.common b/files/usr/local/etc/nginx/nginx.conf.common
index 1da7c3c..98ff9f9 100644
--- a/files/usr/local/etc/nginx/nginx.conf.common
+++ b/files/usr/local/etc/nginx/nginx.conf.common
@@ -33,8 +33,22 @@ http {
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
- ssl_protocols TLSv1.3;
- ssl_prefer_server_ciphers off;
+$(if [ "${nginx_public:-}" = true ]; then <<EOF
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
+ ssl_dhparam ${dhparams_path};
+ ssl_stapling on;
+ ssl_stapling_verify on;
+ resolver ${resolvers};
+ resolver_timeout 5s;
+EOF
+else
+ cat <<EOF
+ ssl_protocols TLSv1.3;
+EOF
+fi
+)
+ ssl_prefer_server_ciphers off;
map \$http_upgrade \$connection_upgrade {
default upgrade;
@@ -47,10 +61,11 @@ $([ "${nginx_gssapi:-}" = true ] && cat <<EOF
EOF
)
-$([ "${acme:-}" = true ] && [ "${acme_standalone:-}" != true ] && cat <<EOF
+$(if [ "${acme:-}" = true ] && [ "${acme_standalone:-}" != true ]; then
+cat <<EOF
server {
- listen 0.0.0.0:80 default_server;
- listen [::]:80 default_server;
+ listen 0.0.0.0:80;
+ listen [::]:80;
location /.well-known/acme-challenge/ {
root ${acme_webroot};
@@ -62,6 +77,18 @@ $([ "${acme:-}" = true ] && [ "${acme_standalone:-}" != true ] && cat <<EOF
}
}
EOF
+ elif [ "${nginx_redirect:-}" != false ]; then
+cat <<EOF
+ server {
+ listen 0.0.0.0:80;
+ listen [::]:80;
+
+ location / {
+ return 301 https://\$host\$request_uri;
+ }
+ }
+EOF
+ fi
)
include vhosts.conf;
diff --git a/files/usr/local/etc/nginx/vhosts.conf.bitwarden_server b/files/usr/local/etc/nginx/vhosts.conf.bitwarden_server
new file mode 100644
index 0000000..0ef31bb
--- /dev/null
+++ b/files/usr/local/etc/nginx/vhosts.conf.bitwarden_server
@@ -0,0 +1,36 @@
+upstream vaultwarden {
+ zone vaultwarden 64k;
+ server 127.0.0.1:${vaultwarden_port};
+ keepalive 2;
+}
+
+map \$http_upgrade \$connection_upgrade {
+ default upgrade;
+ '' "";
+}
+
+server {
+ listen 443 ssl default_server;
+ listen [::]:443 ssl default_server;
+ http2 on;
+
+ client_max_body_size 256M;
+
+ ssl_certificate ${vaultwarden_https_cert};
+ ssl_certificate_key ${vaultwarden_https_key};
+
+ add_header Strict-Transport-Security "max-age=63072000" always;
+
+ location / {
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade \$http_upgrade;
+ proxy_set_header Connection \$connection_upgrade;
+
+ 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;
+
+ proxy_pass http://vaultwarden/;
+ }
+}
diff --git a/files/usr/local/etc/nginx/vhosts.conf.dav_server b/files/usr/local/etc/nginx/vhosts.conf.dav_server
new file mode 100644
index 0000000..71bbc71
--- /dev/null
+++ b/files/usr/local/etc/nginx/vhosts.conf.dav_server
@@ -0,0 +1,55 @@
+server {
+ listen 443 ssl default_server;
+ listen [::]:443 ssl default_server;
+ http2 on;
+
+ root ${davical_webroot};
+ index index.html index.php;
+
+ ssl_certificate ${davical_https_cert};
+ ssl_certificate_key ${davical_https_key};
+
+ add_header Strict-Transport-Security "max-age=63072000" always;
+
+ auth_gss_keytab ${davical_keytab};
+ auth_gss_allow_basic_fallback off;
+
+ location / {
+ auth_gss on;
+ satisfy any;
+$(printf ' deny %s;\n' $kerberized_cidrs)
+ allow all;
+ try_files \$uri \$uri/ /caldav.php\$uri?\$query_string;
+ }
+
+ location /.well-known/ {
+ try_files \$uri \$uri/ /caldav.php\$uri?\$query_string;
+ }
+
+ location ~ ^/caldav\.php/\.well-known/ {
+ fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+ if (!-f \$document_root\$fastcgi_script_name) {
+ return 404;
+ }
+ fastcgi_index index.php;
+ fastcgi_intercept_errors on;
+ include fastcgi_params;
+ fastcgi_pass unix:${davical_fpm_socket};
+ }
+
+ location ~ [^/]\.php(/|$) {
+ auth_gss on;
+ satisfy any;
+$(printf ' deny %s;\n' $kerberized_cidrs)
+ allow all;
+
+ fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+ if (!-f \$document_root\$fastcgi_script_name) {
+ return 404;
+ }
+ fastcgi_index index.php;
+ fastcgi_intercept_errors on;
+ include fastcgi_params;
+ fastcgi_pass unix:${davical_fpm_socket};
+ }
+}
diff --git a/files/usr/local/etc/nginx/vhosts.conf.smtp_server b/files/usr/local/etc/nginx/vhosts.conf.smtp_server
index 4b84ede..322ca34 100644
--- a/files/usr/local/etc/nginx/vhosts.conf.smtp_server
+++ b/files/usr/local/etc/nginx/vhosts.conf.smtp_server
@@ -4,8 +4,8 @@ server {
http2 on;
- ssl_certificate ${rspamd_tls_cert};
- ssl_certificate_key ${rspamd_tls_key};
+ ssl_certificate ${rspamd_https_cert};
+ ssl_certificate_key ${rspamd_https_key};
add_header Strict-Transport-Security "max-age=63072000" always;
diff --git a/files/usr/local/etc/nginx/vhosts.conf.ttrss_server b/files/usr/local/etc/nginx/vhosts.conf.ttrss_server
new file mode 100644
index 0000000..fb0343d
--- /dev/null
+++ b/files/usr/local/etc/nginx/vhosts.conf.ttrss_server
@@ -0,0 +1,43 @@
+server {
+ listen 443 ssl default_server;
+ listen [::]:443 ssl default_server;
+ http2 on;
+
+ root ${ttrss_repo_dir};
+ index index.php index.html;
+
+ ssl_certificate ${ttrss_https_cert};
+ ssl_certificate_key ${ttrss_https_key};
+
+ add_header Strict-Transport-Security "max-age=63072000" always;
+
+ auth_gss_keytab ${ttrss_keytab};
+ auth_gss_allow_basic_fallback off;
+
+ location ~ ^/index\.php$ {
+ auth_gss on;
+ satisfy any;
+$(printf ' deny %s;\n' $kerberized_cidrs)
+ allow all;
+
+ fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+ if (!-f \$document_root\$fastcgi_script_name) {
+ return 404;
+ }
+ fastcgi_index index.php;
+ fastcgi_intercept_errors on;
+ include fastcgi_params;
+ fastcgi_pass unix:${ttrss_fpm_socket};
+ }
+
+ location ~ [^/]\.php(/|$) {
+ fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+ if (!-f \$document_root\$fastcgi_script_name) {
+ return 404;
+ }
+ fastcgi_index index.php;
+ fastcgi_intercept_errors on;
+ include fastcgi_params;
+ fastcgi_pass unix:${ttrss_fpm_socket};
+ }
+}
diff --git a/files/usr/local/etc/nginx/vhosts.conf.xmpp_server b/files/usr/local/etc/nginx/vhosts.conf.xmpp_server
new file mode 100644
index 0000000..732a6de
--- /dev/null
+++ b/files/usr/local/etc/nginx/vhosts.conf.xmpp_server
@@ -0,0 +1,21 @@
+server {
+ listen 443 ssl default_server;
+ listen [::]:443 ssl default_server;
+
+ http2 on;
+
+ ssl_certificate ${prosody_https_cert};
+ ssl_certificate_key ${prosody_https_key};
+ ssl_trusted_certificate ${prosody_https_cacert};
+
+ add_header Strict-Transport-Security "max-age=63072000" always;
+
+ location / {
+ proxy_http_version 1.1;
+ 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;
+ proxy_pass http://127.0.0.1:${prosody_http_port};
+ }
+}
diff --git a/files/usr/local/etc/nginx/vhosts.conf.znc_server b/files/usr/local/etc/nginx/vhosts.conf.znc_server
new file mode 100644
index 0000000..ee75878
--- /dev/null
+++ b/files/usr/local/etc/nginx/vhosts.conf.znc_server
@@ -0,0 +1,21 @@
+server {
+ listen 443 ssl default_server;
+ listen [::]:443 ssl default_server;
+ http2 on;
+
+ ssl_certificate ${znc_tls_cert};
+ ssl_certificate_key ${znc_tls_key};
+
+ add_header Strict-Transport-Security "max-age=63072000" always;
+
+ location / {
+ proxy_http_version 1.1;
+
+ 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;
+
+ proxy_pass http://127.0.0.1:${znc_http_port}/;
+ }
+}
diff --git a/files/usr/local/etc/nsd/nsd.conf.authoritative_nameserver b/files/usr/local/etc/nsd/nsd.conf.authoritative_nameserver
new file mode 100644
index 0000000..b6d1e11
--- /dev/null
+++ b/files/usr/local/etc/nsd/nsd.conf.authoritative_nameserver
@@ -0,0 +1,22 @@
+server:
+ server-count: ${nsd_threads}
+ log-only-syslog: yes
+ verbosity: 1
+ hide-version: yes
+ minimal-responses: yes
+ refuse-any: yes
+$(for zone in ${nsd_zones:-}; do
+ eval "zone_name=\${nsd_${zone}_domain}"
+ eval "zone_slaves=\${nsd_${zone}_slaves:-}"
+ echo "zone:
+ name: ${zone_name}
+ zonefile: ${nsd_conf_dir}/${zone_name}.zone"
+ for slave in $zone_slaves; do
+ echo " notify: ${slave} NOKEY"
+ echo " provide-xfr: ${slave} NOKEY"
+ done
+done)
+
+remote-control:
+ control-enable: yes
+ control-interface: ${nsd_run_dir}/nsd.ctl
diff --git a/files/usr/local/etc/nslcd.conf.common b/files/usr/local/etc/nslcd.conf.common
index ca27337..9798ba9 100644
--- a/files/usr/local/etc/nslcd.conf.common
+++ b/files/usr/local/etc/nslcd.conf.common
@@ -12,3 +12,5 @@ sasl_mech GSSAPI
nss_min_uid ${nslcd_min_uid}
nss_initgroups_ignoreusers ALLLOCAL
nss_nested_groups yes
+
+pam_authz_search (&(uid=\$username)(memberOf=cn=\$service-access,${roles_basedn}))
diff --git a/files/usr/local/etc/openldap/ldap.conf.common b/files/usr/local/etc/openldap/ldap.conf.common
index 2be3425..22b20bb 100644
--- a/files/usr/local/etc/openldap/ldap.conf.common
+++ b/files/usr/local/etc/openldap/ldap.conf.common
@@ -11,3 +11,4 @@ ACCOUNTS_BASE ${accounts_basedn}
USERS_BASE ${users_basedn}
GROUPS_BASE ${groups_basedn}
HOSTS_BASE ${hosts_basedn}
+ROLES_BASE ${roles_basedn}
diff --git a/files/usr/local/etc/openldap/ldap.conf.idm_server b/files/usr/local/etc/openldap/ldap.conf.idm_server
index 2e77244..4c7a929 100644
--- a/files/usr/local/etc/openldap/ldap.conf.idm_server
+++ b/files/usr/local/etc/openldap/ldap.conf.idm_server
@@ -11,3 +11,4 @@ ACCOUNTS_BASE ${accounts_basedn}
USERS_BASE ${users_basedn}
GROUPS_BASE ${groups_basedn}
HOSTS_BASE ${hosts_basedn}
+ROLES_BASE ${roles_basedn}
diff --git a/files/usr/local/etc/php-fpm.conf.common b/files/usr/local/etc/php-fpm.conf.common
new file mode 100644
index 0000000..e4c8f88
--- /dev/null
+++ b/files/usr/local/etc/php-fpm.conf.common
@@ -0,0 +1,4 @@
+[global]
+pid = run/php-fpm.pid
+error_log = syslog
+include=/usr/local/etc/php-fpm.d/*.conf
diff --git a/files/usr/local/etc/php-fpm.d/davical.conf.dav_server b/files/usr/local/etc/php-fpm.d/davical.conf.dav_server
new file mode 100644
index 0000000..faf5f62
--- /dev/null
+++ b/files/usr/local/etc/php-fpm.d/davical.conf.dav_server
@@ -0,0 +1,20 @@
+[davical]
+user = ${nginx_user}
+group = ${nginx_user}
+
+listen = ${davical_fpm_socket}
+
+listen.owner = ${nginx_user}
+listen.group = ${nginx_user}
+listen.mode = 0660
+
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 2
+pm.min_spare_servers = 1
+pm.max_spare_servers = 3
+
+chdir = ${davical_webroot}
+
+catch_workers_output = yes
+decorate_workers_output = no
diff --git a/files/usr/local/etc/php-fpm.d/ttrss.conf.ttrss_server b/files/usr/local/etc/php-fpm.d/ttrss.conf.ttrss_server
new file mode 100644
index 0000000..9519ab5
--- /dev/null
+++ b/files/usr/local/etc/php-fpm.d/ttrss.conf.ttrss_server
@@ -0,0 +1,23 @@
+[ttrss]
+user = ${nginx_user}
+group = ${nginx_user}
+
+listen = ${ttrss_fpm_socket}
+
+listen.owner = ${nginx_user}
+listen.group = ${nginx_user}
+listen.mode = 0660
+
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 2
+pm.min_spare_servers = 1
+pm.max_spare_servers = 3
+
+chdir = ${ttrss_repo_dir}
+
+catch_workers_output = yes
+decorate_workers_output = no
+
+; ttrss needs git to show its version info.
+env["PATH"] = "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin"
diff --git a/files/usr/local/etc/php.ini.common b/files/usr/local/etc/php.ini.common
new file mode 100644
index 0000000..40cfa9e
--- /dev/null
+++ b/files/usr/local/etc/php.ini.common
@@ -0,0 +1,138 @@
+[PHP]
+engine = On
+short_open_tag = Off
+precision = 14
+output_buffering = 4096
+zlib.output_compression = Off
+implicit_flush = Off
+unserialize_callback_func =
+serialize_precision = -1
+disable_functions =
+disable_classes =
+zend.enable_gc = On
+zend.exception_ignore_args = On
+zend.exception_string_param_max_len = 0
+expose_php = On
+max_execution_time = 30
+max_input_time = 60
+memory_limit = 128M
+error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
+display_errors = Off
+display_startup_errors = Off
+log_errors = On
+ignore_repeated_errors = Off
+ignore_repeated_source = Off
+report_memleaks = On
+html_errors = Off
+error_log = syslog
+syslog.ident = php
+syslog.facility = user
+variables_order = "GPCS"
+request_order = "GP"
+register_argc_argv = Off
+auto_globals_jit = On
+post_max_size = 8M
+auto_prepend_file =
+auto_append_file =
+default_mimetype = "text/html"
+default_charset = "UTF-8"
+doc_root =
+user_dir =
+enable_dl = Off
+file_uploads = On
+upload_max_filesize = 2M
+max_file_uploads = 20
+allow_url_fopen = On
+allow_url_include = Off
+default_socket_timeout = 60
+
+[CLI Server]
+cli_server.color = On
+
+[Date]
+;date.timezone =
+
+[Pdo_mysql]
+pdo_mysql.default_socket=
+
+
+[mail function]
+mail.add_x_header = Off
+mail.mixed_lf_and_crlf = Off
+
+[ODBC]
+odbc.allow_persistent = On
+odbc.check_persistent = On
+odbc.max_persistent = -1
+odbc.max_links = -1
+odbc.defaultlrl = 4096
+odbc.defaultbinmode = 1
+
+[MySQLi]
+mysqli.max_persistent = -1
+mysqli.allow_persistent = On
+mysqli.max_links = -1
+mysqli.default_port = 3306
+mysqli.default_socket =
+mysqli.default_host =
+mysqli.default_user =
+mysqli.default_pw =
+
+[mysqlnd]
+mysqlnd.collect_statistics = On
+mysqlnd.collect_memory_statistics = Off
+
+
+[PostgreSQL]
+pgsql.allow_persistent = On
+pgsql.auto_reset_persistent = Off
+pgsql.max_persistent = -1
+pgsql.max_links = -1
+pgsql.ignore_notice = 0
+pgsql.log_notice = 0
+
+[bcmath]
+bcmath.scale = 0
+
+[browscap]
+
+[Session]
+session.save_handler = files
+session.use_strict_mode = 1
+session.use_cookies = 1
+session.use_only_cookies = 1
+session.name = PHPSESSID
+session.auto_start = 0
+session.cookie_lifetime = 0
+session.cookie_path = /
+session.cookie_domain =
+session.cookie_httponly =
+session.cookie_samesite =
+session.serialize_handler = php
+session.gc_probability = 1
+session.gc_divisor = 1000
+session.gc_maxlifetime = 1440
+session.referer_check =
+session.cache_limiter = nocache
+session.cache_expire = 180
+session.use_trans_sid = 0
+session.sid_length = 26
+session.trans_sid_tags = "a=href,area=href,frame=src,form="
+session.sid_bits_per_character = 5
+
+[Assertion]
+zend.assertions = -1
+
+
+[Tidy]
+tidy.clean_output = Off
+
+[soap]
+soap.wsdl_cache_enabled=1
+soap.wsdl_cache_dir="/tmp"
+soap.wsdl_cache_ttl=86400
+soap.wsdl_cache_limit = 5
+
+[opcache]
+opcache.enable=1
+opcache.enable_cli=0
diff --git a/files/usr/local/etc/poudriere.d/pkglist.pkg_repository b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository
index d24ce06..848e558 100644
--- a/files/usr/local/etc/poudriere.d/pkglist.pkg_repository
+++ b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository
@@ -1,4 +1,10 @@
+archivers/php${php_version}-phar
+archivers/php${php_version}-zip
converters/php${php_version}-iconv
+converters/php${php_version}-mbstring
+databases/luadbi
+databases/p5-DBD-Pg
+databases/p5-DBI
databases/php${php_version}-pdo_pgsql
databases/php${php_version}-pgsql
databases/postgresql${postgresql_version}-client
@@ -7,6 +13,9 @@ databases/redis
devel/ccache
devel/git@lite
devel/php${php_version}-gettext
+devel/php${php_version}-intl
+devel/php${php_version}-pcntl
+devel/php${php_version}-tokenizer
dns/bind-tools
dns/nsd
dns/powerdns
@@ -14,6 +23,10 @@ dns/unbound
editors/vim@console
editors/vim@tiny
ftp/php${php_version}-curl
+graphics/php${php_version}-exif
+graphics/php${php_version}-gd
+irc/znc
+irc/znc-clientbuffer
java/openjdk21
lang/python
lang/php${php_version}
@@ -25,6 +38,8 @@ mail/postfix
mail/rspamd
mail/sieve-connect
misc/php${php_version}-calendar
+net/asterisk18
+net/lualdap
net/nss-pam-ldapd-sasl
net/openldap26-client
net/openldap26-server
@@ -32,6 +47,10 @@ net/p5-perl-ldap
net/php${php_version}-ldap
net/py-python-ldap
net/rsync
+net/php${php_version}-sockets
+net/turnserver
+net-im/prosody
+net-im/prosody-modules
ports-mgmt/poudriere
security/acme.sh
security/cyrus-sasl2-saslauthd
@@ -41,16 +60,25 @@ security/krb5@ldap
security/openssh-portable
security/pam_krb5@mit
security/pam_mkhomedir
+security/php${php_version}-filter
security/sshpass
security/sudo
+security/vaultwarden
sysutils/htop
sysutils/lsof
sysutils/p5-Sys-Syslog
+sysutils/php${php_version}-fileinfo
+sysutils/php${php_version}-posix
sysutils/pwgen
sysutils/stow
sysutils/tmux
sysutils/tree
+textproc/p5-YAML
+textproc/php${php_version}-ctype
+textproc/php${php_version}-dom
+textproc/php${php_version}-simplexml
textproc/php${php_version}-xml
+textproc/php${php_version}-xmlwriter
www/nginx
www/php${php_version}-opcache
www/php${php_version}-session
diff --git a/files/usr/local/etc/prosody/prosody.cfg.lua.xmpp_server b/files/usr/local/etc/prosody/prosody.cfg.lua.xmpp_server
new file mode 100644
index 0000000..083a6ce
--- /dev/null
+++ b/files/usr/local/etc/prosody/prosody.cfg.lua.xmpp_server
@@ -0,0 +1,106 @@
+$([ -n "${prosody_admins:-}" ] && echo "admins = { \"$(join '", "' $prosody_admins)\" }")
+pidfile = "/var/run/prosody/prosody.pid"
+
+plugin_paths = { "/usr/local/lib/prosody-modules" }
+
+modules_enabled = {
+
+ -- Generally required
+ "disco"; -- Service discovery
+ "roster"; -- Allow users to have a roster. Recommended ;)
+ "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
+ "tls"; -- Add support for secure TLS on c2s/s2s connections
+
+ -- Not essential, but recommended
+ "blocklist"; -- Allow users to block communications with other users
+ "bookmarks"; -- Synchronise the list of open rooms between clients
+ "carbons"; -- Keep multiple online clients in sync
+ "dialback"; -- Support for verifying remote servers using DNS
+ "limits"; -- Enable bandwidth limiting for XMPP connections
+ "pep"; -- Allow users to store public and private data in their account
+ "private"; -- Legacy account storage mechanism (XEP-0049)
+ "smacks"; -- Stream management and resumption (XEP-0198)
+ "vcard4"; -- User profiles (stored in PEP)
+ "vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard
+
+ -- Nice to have
+ "ping"; -- Replies to XMPP pings with pongs
+ "register"; -- Allow users to register on this server using a client and change passwords
+ "time"; -- Let others know the time here on this server
+ "uptime"; -- Report how long server has been running
+ "version"; -- Replies to server version requests
+ "mam"; -- Store recent messages to allow multi-device synchronization
+ "turn_external"; -- Provide external STUN/TURN service for e.g. audio/video calls
+
+ -- Admin interfaces
+ "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
+ "admin_shell"; -- Allow secure administration via 'prosodyctl shell'
+
+ -- Other specific functionality
+ "groups"; -- Shared roster support
+ "csi_battery_saver";
+ "reload_modules";
+}
+
+reload_modules = { "groups", "tls" }
+
+groups_file = "${prosody_roster_path}"
+
+s2s_secure_auth = true
+
+limits = {
+ c2s = {
+ rate = "10kb/s";
+ };
+ s2sin = {
+ rate = "30kb/s";
+ };
+}
+
+authentication = "ldap"
+ldap_server = "${ldap_hosts}"
+ldap_tls = true
+ldap_base = "${users_basedn}"
+ldap_scope = "subtree"
+ldap_filter = "(&(memberOf=cn=${prosody_access_role},${roles_basedn})(mailAddress=\$user@\$host))"
+ldap_rootdn = "${prosody_dn}"
+ldap_password = "${prosody_ldap_password}"
+
+storage = "sql"
+sql = { driver = "PostgreSQL", database = "${prosody_dbname}", username = "${prosody_username}", host = "${prosody_dbhost}" }
+
+archive_expires_after = "${prosody_archive_expiration}"
+
+turn_external_host = "${prosody_turn_host}"
+turn_external_port = ${prosody_turn_port}
+turn_external_secret = "${prosody_turn_secret}"
+
+log = {
+ info = "*syslog";
+}
+
+certificates = "certs"
+
+http_ports = { ${prosody_http_port} }
+http_interfaces = { "127.0.0.1" }
+https_interfaces = { }
+https_ports = { }
+http_external_url = "https://${prosody_public_fqdn}/"
+https_external_url = "https://${prosody_public_fqdn}/"
+trusted_proxies = { "127.0.0.1" }
+http_max_content_size = ${prosody_upload_sizelimit}
+
+Component "${prosody_public_fqdn}" "http_upload"
+http_upload_file_size_limit = ${prosody_upload_sizelimit}
+http_upload_expire_after = ${prosody_upload_expiration}
+http_upload_quota = ${prosody_upload_quota}
+
+$(for vhost in $prosody_domains; do cat <<EOF
+VirtualHost "${vhost}"
+ disco_items = {
+ { "${prosody_public_fqdn}" }
+ }
+Component "conference.${vhost}" "muc"
+ modules_enabled = { "muc_mam"}
+EOF
+done)
diff --git a/files/usr/local/etc/rc.conf.d/vaultwarden.bitwarden_server b/files/usr/local/etc/rc.conf.d/vaultwarden.bitwarden_server
new file mode 100644
index 0000000..a0923d6
--- /dev/null
+++ b/files/usr/local/etc/rc.conf.d/vaultwarden.bitwarden_server
@@ -0,0 +1,19 @@
+export ROCKET_ADDRESS=127.0.0.1
+export ROCKET_PORT="${vaultwarden_port}"
+export ROCKET_CLI_COLORS=false
+export LOG_LEVEL=warn
+export EXTENDED_LOGGING=true
+export IP_HEADER=X-Forwarded-For
+
+export DATABASE_URL="postgresql://${vaultwarden_username}@${vaultwarden_dbhost}/${vaultwarden_dbname}"
+
+export SIGNUPS_ALLOWED=true
+export SIGNUPS_VERIFY=true
+
+export INVITATIONS_ALLOWED=false
+
+export DOMAIN="https://${vaultwarden_fqdn}"
+
+export USE_SENDMAIL=true
+export SMTP_FROM="bitwarden-noreply@${email_domain}"
+export SMTP_FROM_NAME=Bitwarden
diff --git a/files/usr/local/etc/rc.d/ttrssd.ttrss_server b/files/usr/local/etc/rc.d/ttrssd.ttrss_server
new file mode 100644
index 0000000..d04fa3d
--- /dev/null
+++ b/files/usr/local/etc/rc.d/ttrssd.ttrss_server
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# PROVIDE: ttrssd
+# REQUIRE: NETWORKING kstart
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name='ttrssd'
+rcvar='ttrssd_enable'
+
+load_rc_config "$name"
+: ${ttrssd_enable='NO'}
+: ${ttrssd_webroot='/usr/local/www/tt-rss'}
+: ${ttrssd_user='www'}
+: ${ttrssd_syslog_priority:='info'}
+: ${ttrssd_syslog_facility:='daemon'}
+
+ttrssd_syslog_tag=$name
+ttrssd_chdir=$ttrssd_webroot
+
+pidfile="/var/run/${name}/${name}.pid"
+procname=/usr/local/bin/php
+
+command=/usr/sbin/daemon
+command_args="-f \
+-s ${ttrssd_syslog_priority} \
+-l ${ttrssd_syslog_facility} \
+-T ${ttrssd_syslog_tag} \
+-p ${pidfile} \
+-t ${name} \
+/usr/local/bin/php \
+-d syslog.ident=${ttrssd_syslog_tag} \
+-d syslog.facility=${ttrssd_syslog_facility} \
+${ttrssd_webroot}/update_daemon2.php"
+
+required_files="${ttrssd_webroot}/config.php"
+start_precmd=ttrssd_prestart
+
+ttrssd_prestart(){
+ install -d -m 0755 -o ${ttrssd_user} "/var/run/${name}"
+}
+
+# ttrss needs git to show its version info.
+PATH='/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin'
+
+run_rc_command "$1"
diff --git a/files/usr/local/etc/ssh/sshd_config.d/acmeproxy.conf.common b/files/usr/local/etc/ssh/sshd_config.d/acmeproxy.conf.common
new file mode 100644
index 0000000..63022e3
--- /dev/null
+++ b/files/usr/local/etc/ssh/sshd_config.d/acmeproxy.conf.common
@@ -0,0 +1,11 @@
+Match Group ${acmeproxy_client_group}
+ ChrootDirectory ${acmeproxy_home}
+ ForceCommand internal-sftp -R
+ DisableForwarding yes
+ PermitUserRC no
+ PermitTTY no
+ GSSAPIAuthentication yes
+ KbdInteractiveAuthentication no
+ PasswordAuthentication no
+ PubkeyAuthentication no
+ AuthenticationMethods gssapi-with-mic
diff --git a/files/usr/local/etc/ssh/sshd_config.freebsd b/files/usr/local/etc/ssh/sshd_config.freebsd
index 52d9bfe..eca2276 100644
--- a/files/usr/local/etc/ssh/sshd_config.freebsd
+++ b/files/usr/local/etc/ssh/sshd_config.freebsd
@@ -1,4 +1,4 @@
-Include /etc/ssh/sshd_config.d/*.conf
+Include /usr/local/etc/ssh/sshd_config.d/*.conf
PermitRootLogin prohibit-password
AuthorizedKeysFile .ssh/authorized_keys
diff --git a/files/usr/local/etc/sudoers.d/acme.asterisk_server b/files/usr/local/etc/sudoers.d/acme.asterisk_server
new file mode 100644
index 0000000..6ca9cd6
--- /dev/null
+++ b/files/usr/local/etc/sudoers.d/acme.asterisk_server
@@ -0,0 +1 @@
+${acme_user} ALL=(root) NOPASSWD: /usr/sbin/service asterisk reload
diff --git a/files/usr/local/etc/sudoers.d/acme.public_webserver b/files/usr/local/etc/sudoers.d/acme.public_webserver
new file mode 100644
index 0000000..9ca89b8
--- /dev/null
+++ b/files/usr/local/etc/sudoers.d/acme.public_webserver
@@ -0,0 +1 @@
+${acme_user} ALL=(root) NOPASSWD: /usr/sbin/service nginx reload
diff --git a/files/usr/local/etc/sudoers.d/acme.smtp_server b/files/usr/local/etc/sudoers.d/acme.smtp_server
index 5180fdc..4e8c381 100644
--- a/files/usr/local/etc/sudoers.d/acme.smtp_server
+++ b/files/usr/local/etc/sudoers.d/acme.smtp_server
@@ -1 +1 @@
-acme ALL=(root) NOPASSWD: /usr/sbin/service postfix reload
+${acme_user} ALL=(root) NOPASSWD: /usr/sbin/service postfix reload
diff --git a/files/usr/local/etc/sudoers.d/acme.xmpp_server b/files/usr/local/etc/sudoers.d/acme.xmpp_server
new file mode 100644
index 0000000..9ca89b8
--- /dev/null
+++ b/files/usr/local/etc/sudoers.d/acme.xmpp_server
@@ -0,0 +1 @@
+${acme_user} ALL=(root) NOPASSWD: /usr/sbin/service nginx reload
diff --git a/files/usr/local/etc/turnserver.conf.turn_server b/files/usr/local/etc/turnserver.conf.turn_server
new file mode 100644
index 0000000..dc62883
--- /dev/null
+++ b/files/usr/local/etc/turnserver.conf.turn_server
@@ -0,0 +1,61 @@
+relay-threads=${coturn_threads}
+listening-port=${coturn_listen_port}
+tls-listening-port=0
+
+listening-ip=${BOXCONF_DEFAULT_IPV4}
+relay-ip=${BOXCONF_DEFAULT_IPV4}
+external-ip=${coturn_external_ip}
+
+min-port=${coturn_min_port}
+max-port=${coturn_max_port}
+
+verbose
+
+use-auth-secret
+static-auth-secret=${coturn_secret}
+
+realm=${coturn_realm}
+
+no-tls
+no-dtls
+
+syslog
+
+no-software-attribute
+no-multicast-peers
+
+denied-peer-ip=0.0.0.0-0.255.255.255
+denied-peer-ip=10.0.0.0-10.255.255.255
+denied-peer-ip=100.64.0.0-100.127.255.255
+denied-peer-ip=127.0.0.0-127.255.255.255
+denied-peer-ip=169.254.0.0-169.254.255.255
+denied-peer-ip=172.16.0.0-172.31.255.255
+denied-peer-ip=192.0.0.0-192.0.0.255
+denied-peer-ip=192.0.2.0-192.0.2.255
+denied-peer-ip=192.88.99.0-192.88.99.255
+denied-peer-ip=192.168.0.0-192.168.255.255
+denied-peer-ip=198.18.0.0-198.19.255.255
+denied-peer-ip=198.51.100.0-198.51.100.255
+denied-peer-ip=203.0.113.0-203.0.113.255
+denied-peer-ip=240.0.0.0-255.255.255.255
+denied-peer-ip=::1
+denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
+denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
+denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
+denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
+denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+
+secure-stun
+
+# You can't drop privileges here, due to a FreeBSD issue with SO_REUSEPORT:
+# https://github.com/coturn/coturn/issues/1098
+# Do this in /etc/rc.conf instead.
+#proc-user=coturn
+#proc-group=coturn
+
+no-cli
+no-rfc5780
+no-stun-backward-compatibility
+response-origin-only-with-rfc5780
diff --git a/files/usr/local/etc/znc/configs/znc.conf.znc_server b/files/usr/local/etc/znc/configs/znc.conf.znc_server
new file mode 100644
index 0000000..487db8e
--- /dev/null
+++ b/files/usr/local/etc/znc/configs/znc.conf.znc_server
@@ -0,0 +1,55 @@
+LoadModule = cyrusauth saslauthd
+LoadModule = webadmin
+LoadModule = corecaps
+SSLCertFile = ${znc_tls_cert}
+SSLKeyFile = ${znc_tls_key}
+Version = 1.9.0
+
+<Listener web>
+ AllowIRC = false
+ AllowWeb = true
+ IPv4 = true
+ IPv6 = false
+ Host = 127.0.0.1
+ Port = ${znc_http_port}
+ SSL = false
+</Listener>
+
+<Listener irc>
+ AllowIRC = true
+ AllowWeb = false
+ IPv4 = true
+ IPv6 = true
+ Port = ${znc_irc_port}
+ SSL = true
+</Listener>
+
+<User admin>
+ Admin = true
+ Nick = znc_admin
+ AltNick = znc_admin_
+ Ident = znc_admin
+ RealName = ZNC Administrator
+
+ <Pass password>
+ Hash = ::
+ Method = MD5
+ Salt = ::
+ </Pass>
+</User>
+
+<User ${znc_clone_user}>
+ Admin = false
+ Nick = znc_user
+ AltNick = znc_user_
+ Ident = znc_user
+ RealName = ZNC User
+ MaxNetworks = ${znc_max_networks}
+ LoadModule = chansaver
+
+ <Pass password>
+ Hash = ::
+ Method = MD5
+ Salt = ::
+ </Pass>
+</User>
diff --git a/files/usr/local/etc/znc/moddata/cyrusauth/.registry.znc_server b/files/usr/local/etc/znc/moddata/cyrusauth/.registry.znc_server
new file mode 100644
index 0000000..539fee0
--- /dev/null
+++ b/files/usr/local/etc/znc/moddata/cyrusauth/.registry.znc_server
@@ -0,0 +1,2 @@
+CloneUser ${znc_clone_user}
+CreateUser yes
diff --git a/files/usr/local/lib/sasl2/znc.conf.znc_server b/files/usr/local/lib/sasl2/znc.conf.znc_server
new file mode 100644
index 0000000..f272cc7
--- /dev/null
+++ b/files/usr/local/lib/sasl2/znc.conf.znc_server
@@ -0,0 +1,3 @@
+mech_list: plain login
+pwcheck_method: saslauthd
+saslauthd_path: ${saslauthd_runtime_dir}/mux
diff --git a/files/usr/local/libexec/dovecot/sieve-pipe/report-ham.sh.imap_server b/files/usr/local/libexec/dovecot/sieve-pipe/report-ham.sh.imap_server
index e09674a..b5b0d2d 100644
--- a/files/usr/local/libexec/dovecot/sieve-pipe/report-ham.sh.imap_server
+++ b/files/usr/local/libexec/dovecot/sieve-pipe/report-ham.sh.imap_server
@@ -1,7 +1,11 @@
#!/bin/sh
-exec /usr/local/bin/rspamc \\
- --connect="${rspamd_host}.${domain}" \\
- --password="${rspamd_rw_password}" \\
- --key="${rspamd_pubkey}" \\
+set -e
+
+. /usr/local/etc/dovecot/rspamd.conf.sh
+
+exec /usr/local/bin/rspamc \
+ --connect="$RSPAMD_HOST" \
+ --password="$RSPAMD_PASSWORD" \
+ --key="$RSPAMD_KEY" \
learn_ham
diff --git a/files/usr/local/libexec/dovecot/sieve-pipe/report-spam.sh.imap_server b/files/usr/local/libexec/dovecot/sieve-pipe/report-spam.sh.imap_server
index 825113f..ec46319 100644
--- a/files/usr/local/libexec/dovecot/sieve-pipe/report-spam.sh.imap_server
+++ b/files/usr/local/libexec/dovecot/sieve-pipe/report-spam.sh.imap_server
@@ -1,7 +1,11 @@
#!/bin/sh
-exec /usr/local/bin/rspamc \\
- --connect="${rspamd_host}.${domain}" \\
- --password="${rspamd_rw_password}" \\
- --key="${rspamd_pubkey}" \\
+set -e
+
+. /usr/local/etc/dovecot/rspamd.conf.sh
+
+exec /usr/local/bin/rspamc \
+ --connect="$RSPAMD_HOST" \
+ --password="$RSPAMD_PASSWORD" \
+ --key="$RSPAMD_KEY" \
learn_spam
diff --git a/files/usr/local/libexec/idm-ssh-authorized-keys.common b/files/usr/local/libexec/idm-ssh-authorized-keys.common
index 89d2f20..ef7ba3c 100644
--- a/files/usr/local/libexec/idm-ssh-authorized-keys.common
+++ b/files/usr/local/libexec/idm-ssh-authorized-keys.common
@@ -7,7 +7,7 @@ use Net::LDAP;
use Net::LDAP::Util qw(escape_filter_value);
use Authen::SASL;
-open my $fh, '<', '/usr/local/etc/openldap/ldap.conf' or quit($!);
+open my $fh, '<', '/usr/local/etc/openldap/ldap.conf' or die($!);
my %config;
while (<$fh>) {
chomp;
@@ -18,9 +18,9 @@ while (<$fh>) {
}
close($fh);
-my $mech = $config{SASL_MECH} // 'GSSAPI';
-my $uri = $config{URI} // quit('URI not specified');
-my $basedn = $config{USERS_BASE} // quit('USERS_BASE not specified');
+my $mech = $config{SASL_MECH} // 'GSSAPI';
+my $uri = $config{URI} // die("URI not specified\n");
+my $basedn = $config{USERS_BASE} // die("USERS_BASE not specified\n");
@ARGV == 1 or die "usage: $0 USERNAME\n";
my $username = $ARGV[0];
diff --git a/files/usr/local/libexec/idm-ssh-known-hosts.common b/files/usr/local/libexec/idm-ssh-known-hosts.common
index 5b784d6..3bbcf65 100644
--- a/files/usr/local/libexec/idm-ssh-known-hosts.common
+++ b/files/usr/local/libexec/idm-ssh-known-hosts.common
@@ -29,8 +29,8 @@ while (<$fh>) {
}
close($fh);
-my $mech = $config{SASL_MECH} // 'GSSAPI';
-my $uri = $config{URI} // quit('URI not specified');
+my $mech = $config{SASL_MECH} // 'GSSAPI';
+my $uri = $config{URI} // quit('URI not specified');
my $basedn = $config{HOSTS_BASE} // quit('HOSTS_BASE not specified');
my $conn = Net::LDAP->new($uri, version => '3') or quit($@);
diff --git a/files/usr/local/libexec/prosody-acme-proxy.xmpp_server b/files/usr/local/libexec/prosody-acme-proxy.xmpp_server
new file mode 100644
index 0000000..d69017b
--- /dev/null
+++ b/files/usr/local/libexec/prosody-acme-proxy.xmpp_server
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+# Retrieves ACME certificates from a different host over SFTP.
+# Reloads prosody if any certificates were changed.
+
+set -eu -o pipefail
+
+PROSODY_USER=prosody
+CERT_DIR=/usr/local/etc/prosody/certs
+CHECKSUM_FILE="${CERT_DIR}/certs.md5"
+
+prog=$(basename "$(readlink -f "$0")")
+usage="${prog} [-q] USER@TARGET_HOST DOMAIN..."
+
+usage(){
+ printf 'usage: %s\n' "$usage" 1>&2
+ exit 2
+}
+
+while getopts hq opt; do
+ case $opt in
+ h) usage ;;
+ q) exec 1>/dev/null ;;
+ esac
+done
+shift $((OPTIND - 1))
+
+[ $# -ge 2 ] || usage
+acmeproxy_target=$1; shift
+
+# Get md5 of any existing certificates.
+touch "$CHECKSUM_FILE"
+md5_old=$(cat "$CHECKSUM_FILE")
+
+# Retrieve certs from the proxy host via SFTP.
+{ printf 'lcd %s\n' "$CERT_DIR"
+ printf 'get certs/%s.crt\n' "$@"
+ printf 'get certs/%s.key\n' "$@"
+ printf 'quit\n'
+} | sftp -b - "$acmeproxy_target"
+
+# Get md5 of the new certificates.
+md5_new=$(md5sum "$CERT_DIR"/*.crt "$CERT_DIR"/*.key | tee "$CHECKSUM_FILE")
+
+# If any certificates differ, reload prosody.
+if [ "$md5_old" != "$md5_new" ]; then
+ if prosodyctl status >/dev/null 2>&1; then
+ prosodyctl reload
+ else
+ echo 'prosody not running, not reloading'
+ fi
+else
+ echo 'certificates unchanged'
+fi
diff --git a/files/usr/local/libexec/prosody-update-roster.xmpp_server b/files/usr/local/libexec/prosody-update-roster.xmpp_server
new file mode 100644
index 0000000..1b79747
--- /dev/null
+++ b/files/usr/local/libexec/prosody-update-roster.xmpp_server
@@ -0,0 +1,47 @@
+#!/usr/local/bin/perl
+
+use strict;
+use warnings;
+
+use Net::LDAP;
+use Authen::SASL;
+
+@ARGV == 1 or die "usage: $0 ROLE_NAME\n";
+my $role = $ARGV[0];
+
+open my $fh, '<', '/usr/local/etc/openldap/ldap.conf' or quit($!);
+my %config;
+while (<$fh>) {
+ chomp;
+ next if /^#/;
+ my @pair = split(' ', $_, 2);
+ next unless (@pair == 2);
+ $config{$pair[0]} = $pair[1];
+}
+close($fh);
+
+my $mech = $config{SASL_MECH} // 'GSSAPI';
+my $uri = $config{URI} // die("URI not specified\n");
+my $users_basedn = $config{USERS_BASE} // die("USERS_BASE not specified\n");
+my $roles_basedn = $config{ROLES_BASE} // die("ROLES_BASE not specified\n");
+
+my $conn = Net::LDAP->new($ldap_uris, version => '3') or die "$@";
+my $sasl = Authen::SASL->new($mech);
+my $status = $conn->bind(sasl => $sasl);
+$status->code and die $status->error;
+
+my $search = $conn->search(
+ scope => 'sub',
+ base => $users_basedn,
+ filter => "(&(memberOf=cn=$role,$roles_basedn)(mailAddress=*))",
+ attrs => ['mailAddress', 'cn']);
+
+print "[Internal]\n";
+
+foreach my $entry ($search->entries) {
+ my $jid = ($entry->get_value('mailAddress'))[0];
+ my $cn = ($entry->get_value('cn'))[0] // $jid;
+ print "$jid=$cn\n";
+}
+
+system('prosodyctl reload');
diff --git a/files/usr/local/www/davical/config/administration.yml.dav_server b/files/usr/local/www/davical/config/administration.yml.dav_server
new file mode 100644
index 0000000..fdd5da2
--- /dev/null
+++ b/files/usr/local/www/davical/config/administration.yml.dav_server
@@ -0,0 +1,4 @@
+admin_db_user: ${boxconf_username}
+admin_db_host: ${davical_dbhost}
+admin_db_name: ${davical_dbname}
+app_db_user: '"${davical_username}"'
diff --git a/files/usr/local/www/davical/config/config.php.dav_server b/files/usr/local/www/davical/config/config.php.dav_server
new file mode 100644
index 0000000..ec2cb26
--- /dev/null
+++ b/files/usr/local/www/davical/config/config.php.dav_server
@@ -0,0 +1,49 @@
+<?php
+\$c->pg_connect[] = 'dbname=${davical_dbname} user=${davical_username} host=${davical_dbhost}';
+\$c->admin_email = '${davical_admin_email}';
+
+\$c->restrict_setup_to_admin = true;
+
+\$c->home_calendar_name = 'calendar';
+\$c->home_addressbook_name = 'addressbook';
+\$c->default_privileges = array('read-free-busy', 'schedule-deliver');
+\$c->external_refresh = 60;
+\$c->default_locale = 'en';
+\$c->allow_get_email_visibility = true;
+
+\$c->trust_x_forwarded = true;
+
+\$c->authenticate_hook['call'] = 'LDAP_check';
+\$c->authenticate_hook['config'] = array(
+ 'uri' => '${ldap_uri}',
+ 'host' => '${ldap_hosts}',
+ 'port' => '389',
+ 'sasl' => 'yes',
+ 'sasl_mech' => 'GSSAPI',
+ 'baseDNUsers' => '${users_basedn}',
+ 'baseDNGroups' => '${groups_basedn}',
+ 'scope' => 'onelevel',
+ 'protocolVersion' => 3,
+ 'optReferrals' => 0,
+ 'filterUsers' => '(memberOf=cn=${davical_access_role},${roles_basedn})',
+ 'filterGroups' => '(objectclass=groupOfMembers)',
+ 'mapping_field' => array('username' => 'uid',
+ 'modified' => 'modifyTimestamp',
+ 'fullname' => 'cn',
+ 'email' => 'mailAddress'),
+ 'group_mapping_field' => array('name' => 'cn',
+ 'fullname' => 'cn',
+ 'modified' => 'modifyTimestamp',
+ 'email' => 'mailAddress',
+ 'members' => 'member'),
+ 'group_member_dnfix' => true,
+ 'default_value' => array('date_format_type' => 'I','locale' => 'en'),
+ 'format_updated' => array('Y' => array(0,4),
+ 'm' => array(4,2),
+ 'd' => array(6,2),
+ 'H' => array(8,2),
+ 'M' => array(10,2),
+ 'S' => array(12,2)),
+ 'i_use_mode_kerberos' => 'i_know_what_i_am_doing',
+);
+include_once('drivers_ldap.php');
diff --git a/files/usr/local/www/tt-rss/config.php.ttrss_server b/files/usr/local/www/tt-rss/config.php.ttrss_server
new file mode 100644
index 0000000..3598ef2
--- /dev/null
+++ b/files/usr/local/www/tt-rss/config.php.ttrss_server
@@ -0,0 +1,28 @@
+<?php
+putenv('TTRSS_DB_TYPE=pgsql');
+putenv('TTRSS_DB_HOST=${ttrss_dbhost}');
+putenv('TTRSS_DB_USER=${ttrss_username}');
+putenv('TTRSS_DB_NAME=${ttrss_dbname}');
+
+putenv('TTRSS_SELF_URL_PATH=https://${ttrss_fqdn}/');
+putenv('TTRSS_PHP_EXECUTABLE=/usr/local/bin/php');
+
+putenv('TTRSS_SESSION_COOKIE_LIFETIME=604800');
+
+putenv('TTRSS_SMTP_FROM_NAME=Tiny Tiny RSS');
+putenv('TTRSS_SMTP_FROM_ADDRESS=${ttrss_mail_from}');
+
+putenv('TTRSS_CHECK_FOR_UPDATES=false');
+putenv('TTRSS_CHECK_FOR_PLUGIN_UPDATES=false');
+putenv('TTRSS_ENABLE_PLUGIN_INSTALLER=false');
+putenv('TTRSS_ENABLE_GZIP_OUTPUT=false');
+putenv('TTRSS_PLUGINS=auth_idm');
+
+putenv('TTRSS_LOG_DESTINATION=syslog');
+
+putenv('TTRSS_AUTH_IDM_URI=${ldap_uri}');
+putenv('TTRSS_AUTH_IDM_STARTTLS=false');
+putenv('TTRSS_AUTH_IDM_BASEDN=${users_basedn}');
+putenv('TTRSS_AUTH_IDM_SCOPE=sub');
+putenv('TTRSS_AUTH_IDM_FILTER=(memberOf=cn=${ttrss_access_role},${roles_basedn})');
+putenv('TTRSS_AUTH_IDM_ADMIN_FILTER=(memberOf=cn=${ttrss_admin_role},${roles_basedn})');
diff --git a/files/usr/local/www/tt-rss/plugins.local/auth_idm/init.php.ttrss_server b/files/usr/local/www/tt-rss/plugins.local/auth_idm/init.php.ttrss_server
new file mode 100644
index 0000000..c025026
--- /dev/null
+++ b/files/usr/local/www/tt-rss/plugins.local/auth_idm/init.php.ttrss_server
@@ -0,0 +1,177 @@
+<?php
+/**
+ * The following options may be specified in config.php:
+ *
+ * putenv('TTRSS_AUTH_IDM_URI=ldap://ldap.idm.example.com');
+ * putenv('TTRSS_AUTH_IDM_BASEDN=ou=users,dc=idm,dc=example,dc=com');
+ * putenv('TTRSS_AUTH_IDM_FILTER=(memberOf=cn=ttrss-users,ou=groups,dc=idm,dc=example,dc=com)');
+ * putenv('TTRSS_AUTH_IDM_ADMIN_FILTER=(memberOf=cn=ttrss-admins,ou=groups,dc=idm,dc=example,dc=com)');
+ * putenv('TTRSS_AUTH_IDM_FULLNAME_ATTRIBUTE=cn');
+ * putenv('TTRSS_AUTH_IDM_EMAIL_ATTRIBUTE=mail');
+ */
+
+class Auth_Idm extends Auth_Base {
+
+ const AUTH_IDM_URI = 'AUTH_IDM_URI';
+ const AUTH_IDM_STARTTLS = 'AUTH_IDM_STARTTLS';
+ const AUTH_IDM_BASEDN = 'AUTH_IDM_BASEDN';
+ const AUTH_IDM_SCOPE = 'AUTH_IDM_SCOPE';
+ const AUTH_IDM_FILTER = 'AUTH_IDM_FILTER';
+ const AUTH_IDM_ADMIN_FILTER = 'AUTH_IDM_ADMIN_FILTER';
+ const AUTH_IDM_USERNAME_ATTR = 'AUTH_IDM_USERNAME_ATTRIBUTE';
+ const AUTH_IDM_FULLNAME_ATTR = 'AUTH_IDM_FULLNAME_ATTRIBUTE';
+ const AUTH_IDM_EMAIL_ATTR = 'AUTH_IDM_EMAIL_ATTRIBUTE';
+
+ function about() {
+ return array(null,
+ 'Authenticates against REMOTE_USER variable and LDAP server',
+ 'cullum@sacredheartsc.com',
+ true);
+ }
+
+ function init($host) {
+ $host->add_hook($host::HOOK_AUTH_USER, $this);
+
+ Config::add(self::AUTH_IDM_URI, '', Config::T_STRING);
+ Config::add(self::AUTH_IDM_STARTTLS, false, Config::T_BOOL);
+ Config::add(self::AUTH_IDM_BASEDN, '', Config::T_STRING);
+ Config::add(self::AUTH_IDM_SCOPE, 'sub', Config::T_STRING);
+ Config::add(self::AUTH_IDM_FILTER, '', Config::T_STRING);
+ Config::add(self::AUTH_IDM_ADMIN_FILTER, '', Config::T_STRING);
+ Config::add(self::AUTH_IDM_USERNAME_ATTR, 'uid', Config::T_STRING);
+ Config::add(self::AUTH_IDM_FULLNAME_ATTR, 'cn', Config::T_STRING);
+ Config::add(self::AUTH_IDM_EMAIL_ATTR, 'mail', Config::T_STRING);
+ }
+
+ private function ldap_get_user($username, $filter = null) {
+ switch ($this->scope) {
+ case 'sub':
+ $searchfunc = 'ldap_search'; break;
+ case 'one':
+ $searchfunc = 'ldap_list'; break;
+ case 'base':
+ $searchfunc = 'ldap_read'; break;
+ default:
+ Logger::log(E_USER_ERROR, "auth_idm: invalid search scope: $scope");
+ return null;
+ }
+
+ $uid_filter = '('
+ . ldap_escape($this->username_attr, '', LDAP_ESCAPE_FILTER)
+ . '='
+ . ldap_escape($username, '', LDAP_ESCAPE_FILTER)
+ . ')';
+
+ if (empty($filter)) {
+ $filter = $uid_filter;
+ } else {
+ $filter = "(&$filter$uid_filter)";
+ }
+
+ $results = $searchfunc($this->conn, $this->basedn, $filter, [$this->fullname_attr, $this->email_attr]);
+ if ($results && ldap_count_entries($this->conn, $results) == 1) {
+ if ($entry = ldap_first_entry($this->conn, $results)) {
+ if ($dn = ldap_get_dn($this->conn, $entry)) {
+ if ($attrs = ldap_get_attributes($this->conn, $entry)) {
+ return array(
+ 'dn' => $dn,
+ 'email' => $attrs[$this->email_attr][0],
+ 'fullname' => $attrs[$this->fullname_attr][0]
+ );
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ function authenticate($username = null, $password = null, $service = '') {
+ $this->basedn = Config::get(self::AUTH_IDM_BASEDN);
+ $this->scope = Config::get(self::AUTH_IDM_SCOPE);
+ $this->username_attr = Config::get(self::AUTH_IDM_USERNAME_ATTR);
+ $this->fullname_attr = Config::get(self::AUTH_IDM_FULLNAME_ATTR);
+ $this->email_attr = Config::get(self::AUTH_IDM_EMAIL_ATTR);
+ $uri = Config::get(self::AUTH_IDM_URI);
+ $starttls = Config::get(self::AUTH_IDM_STARTTLS);
+ $filter = Config::get(self::AUTH_IDM_FILTER);
+ $admin_filter = Config::get(self::AUTH_IDM_ADMIN_FILTER);
+
+ // Get ldap connection handle.
+ if (!$this->conn = ldap_connect($uri)) {
+ return false;
+ }
+
+ // Set protocol version 3.
+ if (!ldap_set_option($this->conn, LDAP_OPT_PROTOCOL_VERSION, 3)) {
+ return false;
+ }
+
+ // Bind using kerberos credentials from the environment.
+ if (!ldap_sasl_bind($this->conn, null, null, 'GSSAPI')) {
+ return false;
+ }
+
+ // Initiate STARTTLS (if requested)
+ if ($starttls and !ldap_start_tls($this->conn)) {
+ return false;
+ }
+
+ // If REMOTE_USER was set by the webserver, use that.
+ if (!empty($_SERVER['REMOTE_USER'])) {
+ $username = $_SERVER['REMOTE_USER'];
+ } elseif (empty($username)) {
+ return false;
+ }
+
+ $is_admin = false;
+ $user = null;
+
+ // First, check if the ADIN_FILTER matches (if set).
+ if (!empty($admin_filter)) {
+ $user = $this->ldap_get_user($username, $admin_filter);
+ isset($user) && $is_admin = true;
+ }
+
+ // If ADMIN_FILTER didn't match, try FILTER.
+ if (!isset($user)) {
+ $user = $this->ldap_get_user($username, $filter);
+ }
+
+ // If no matching user from LDAP, reject.
+ if (!isset($user)) {
+ return false;
+ }
+
+ // If webserver didn't validate the password, try an LDAP bind with the provided creds.
+ if (empty($_SERVER['REMOTE_USER']) and !ldap_bind($this->conn, $user['dn'], $password)) {
+ return false;
+ }
+
+ // Get the TTRSS internal user ID.
+ if (!($userid = $this->auto_create_user($username))) {
+ return false;
+ }
+
+ // Populate user details using the LDAP attributes.
+ if (Config::get(Config::AUTH_AUTO_CREATE)) {
+ if (!empty($user['fullname'])) {
+ $sth = $this->pdo->prepare('UPDATE ttrss_users SET full_name = ? WHERE id = ?');
+ $sth->execute([$user['fullname'], $userid]);
+ }
+
+ if (!empty($user['email'])) {
+ $sth = $this->pdo->prepare('UPDATE ttrss_users SET email = ? WHERE id = ?');
+ $sth->execute([$user['email'], $userid]);
+ }
+
+ $sth = $this->pdo->prepare('UPDATE ttrss_users SET access_level = ? WHERE id = ?');
+ $sth->execute([$is_admin ? 10 : 0, $userid]);
+ }
+
+ return $userid;
+ }
+
+ function api_version() {
+ return 2;
+ }
+}
diff --git a/files/var/db/postgres/data16/postgresql.conf.postgresql_server b/files/var/db/postgres/data16/postgresql.conf.postgresql_server
index e95104f..55874e7 100644
--- a/files/var/db/postgres/data16/postgresql.conf.postgresql_server
+++ b/files/var/db/postgres/data16/postgresql.conf.postgresql_server
@@ -5,7 +5,7 @@ krb_server_keyfile = 'FILE:${postgres_keytab}'
krb_caseins_users = on
ssl = on
-ssl_ca_file = '${ca_cert}'
+ssl_ca_file = '${site_cacert_path}'
ssl_cert_file = '${postgres_tls_cert}'
ssl_key_file = '${postgres_tls_key}'
ssl_min_protocol_version = 'TLSv1.3'