diff options
author | Cullum Smith <cullum@sacredheartsc.com> | 2024-10-12 08:14:59 -0400 |
---|---|---|
committer | Cullum Smith <cullum@sacredheartsc.com> | 2024-10-12 08:15:33 -0400 |
commit | 99b8524c16cc99ceeaf1ebf588f2fc0f2c0fbe0a (patch) | |
tree | 3ffa4113f23eca6cea8ff2c94ba7ce60188d943e /files | |
parent | 1c882c769e5476b5cb3fa294257c76165a7a6f46 (diff) | |
download | infrastructure-99b8524c16cc99ceeaf1ebf588f2fc0f2c0fbe0a.tar.gz |
add a bunch of hostclasses
Diffstat (limited to 'files')
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' |