aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCullum Smith <cullum@sacredheartsc.com>2024-10-03 08:37:38 -0400
committerCullum Smith <cullum@sacredheartsc.com>2024-10-03 08:37:38 -0400
commit47f90d0916ac34ef132e3bb6da92a4a67dffbba8 (patch)
tree764a6aee2dea7a69096eba27c4264776f8190380
parentee583b5929925b2e9658385430da4f73b4883287 (diff)
downloadinfrastructure-47f90d0916ac34ef132e3bb6da92a4a67dffbba8.tar.gz
add postfix/rspamd
-rw-r--r--files/usr/local/etc/nginx/acme.conf.common4
-rw-r--r--files/usr/local/etc/nginx/nginx.conf-acme55
l---------files/usr/local/etc/nginx/nginx.conf.smtp_server1
-rw-r--r--files/usr/local/etc/nginx/vhosts.conf.smtp_server22
-rw-r--r--files/usr/local/etc/nslcd.conf.common2
-rw-r--r--files/usr/local/etc/nslcd.conf.idm_server2
-rw-r--r--files/usr/local/etc/openldap/ldap.conf.common4
-rw-r--r--files/usr/local/etc/openldap/ldap.conf.idm_server4
-rw-r--r--files/usr/local/etc/openldap/slapd.ldif.idm_server14
-rw-r--r--files/usr/local/etc/postfix/main.cf.smtp_server124
-rw-r--r--files/usr/local/etc/postfix/master.cf.smtp_server29
-rw-r--r--files/usr/local/etc/postfix/virtual_aliases.cf.smtp_server8
-rw-r--r--files/usr/local/etc/postfix/virtual_mailboxes.cf.smtp_server7
-rw-r--r--files/usr/local/etc/poudriere.d/pkglist.pkg_repository8
-rw-r--r--files/usr/local/etc/redis-rspamd-bayes.conf.smtp_server74
-rw-r--r--files/usr/local/etc/redis-rspamd.conf.smtp_server74
-rw-r--r--files/usr/local/etc/rspamd/local.d/classifier-bayes.conf.smtp_server3
-rw-r--r--files/usr/local/etc/rspamd/local.d/dkim_signing.conf.smtp_server3
-rw-r--r--files/usr/local/etc/rspamd/local.d/logging.inc.smtp_server2
-rw-r--r--files/usr/local/etc/rspamd/local.d/multimap.conf.smtp_server9
-rw-r--r--files/usr/local/etc/rspamd/local.d/phishing.conf.smtp_server1
-rw-r--r--files/usr/local/etc/rspamd/local.d/redis.conf.smtp_server1
-rw-r--r--files/usr/local/etc/rspamd/local.d/replies.conf.smtp_server1
-rw-r--r--files/usr/local/etc/rspamd/local.d/worker-controller.inc.smtp_server12
-rw-r--r--files/usr/local/etc/rspamd/local.d/worker-normal.inc.smtp_server1
-rw-r--r--files/usr/local/etc/rspamd/local.d/worker-proxy.inc.smtp_server7
-rw-r--r--files/usr/local/libexec/idm-ssh-authorized-keys.common4
-rw-r--r--files/usr/local/libexec/idm-ssh-known-hosts.common4
-rw-r--r--hostclasses2
-rw-r--r--scripts/common/10-vars7
-rw-r--r--scripts/hostclass/idm_server/10-slapd10
-rw-r--r--scripts/hostclass/smtp_server/10-rspamd103
-rw-r--r--scripts/hostclass/smtp_server/20-postfix87
-rw-r--r--vars/common7
-rw-r--r--vars/hostclass/smtp_server4
-rw-r--r--vars/hostname/smtp13
-rw-r--r--vars/os/freebsd1
37 files changed, 682 insertions, 22 deletions
diff --git a/files/usr/local/etc/nginx/acme.conf.common b/files/usr/local/etc/nginx/acme.conf.common
new file mode 100644
index 0000000..583ca98
--- /dev/null
+++ b/files/usr/local/etc/nginx/acme.conf.common
@@ -0,0 +1,4 @@
+location /.well-known/acme-challenge/ {
+ root ${acme_webroot};
+ default_type text/plain;
+}
diff --git a/files/usr/local/etc/nginx/nginx.conf-acme b/files/usr/local/etc/nginx/nginx.conf-acme
new file mode 100644
index 0000000..d77c0de
--- /dev/null
+++ b/files/usr/local/etc/nginx/nginx.conf-acme
@@ -0,0 +1,55 @@
+worker_processes ${nginx_worker_processes};
+worker_rlimit_nofile ${nginx_nofile};
+
+events {
+ worker_connections ${nginx_worker_connections};
+}
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+ index index.html;
+
+ aio threads;
+ aio_write on;
+ sendfile on;
+ directio 4m;
+ tcp_nopush on;
+ tcp_nodelay on;
+ keepalive_timeout 65;
+ types_hash_max_size 2048;
+ server_tokens off;
+ client_max_body_size 5m;
+ charset utf-8;
+ gzip on;
+ gzip_http_version 1.0;
+ gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json image/svg+xml;
+
+ proxy_buffers 64 32k;
+ proxy_busy_buffers_size 64k;
+ fastcgi_buffers 64 32k;
+
+ ssl_session_timeout 1d;
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_tickets off;
+ ssl_protocols TLSv1.3;
+ ssl_prefer_server_ciphers off;
+
+ map \$http_upgrade \$connection_upgrade {
+ default upgrade;
+ '' keep-alive;
+ }
+
+ server {
+ listen 0.0.0.0:80 default_server;
+ listen [::]:80 default_server;
+
+ include acme.conf;
+
+ location / {
+ return 301 https://\$host\$request_uri;
+ }
+ }
+
+ include vhost*.conf;
+}
diff --git a/files/usr/local/etc/nginx/nginx.conf.smtp_server b/files/usr/local/etc/nginx/nginx.conf.smtp_server
new file mode 120000
index 0000000..53de10f
--- /dev/null
+++ b/files/usr/local/etc/nginx/nginx.conf.smtp_server
@@ -0,0 +1 @@
+nginx.conf-acme \ No newline at end of file
diff --git a/files/usr/local/etc/nginx/vhosts.conf.smtp_server b/files/usr/local/etc/nginx/vhosts.conf.smtp_server
new file mode 100644
index 0000000..71d6db8
--- /dev/null
+++ b/files/usr/local/etc/nginx/vhosts.conf.smtp_server
@@ -0,0 +1,22 @@
+server {
+ listen 443 ssl default_server;
+ listen [::]:443 ssl default_server;
+
+ http2 on;
+
+ ssl_certificate ${rspamd_tls_cert};
+ ssl_certificate_key ${rspamd_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:${rspamd_port}/;
+ }
+}
diff --git a/files/usr/local/etc/nslcd.conf.common b/files/usr/local/etc/nslcd.conf.common
index 6494c70..ca27337 100644
--- a/files/usr/local/etc/nslcd.conf.common
+++ b/files/usr/local/etc/nslcd.conf.common
@@ -4,7 +4,7 @@ gid ${nslcd_user}
uri ${ldap_uri}
base ${basedn}
-base passwd ${accounts_basedn}
+base passwd ${users_basedn}
base group ${groups_basedn}
sasl_mech GSSAPI
diff --git a/files/usr/local/etc/nslcd.conf.idm_server b/files/usr/local/etc/nslcd.conf.idm_server
index 1f74779..5d6315b 100644
--- a/files/usr/local/etc/nslcd.conf.idm_server
+++ b/files/usr/local/etc/nslcd.conf.idm_server
@@ -4,7 +4,7 @@ gid ${nslcd_user}
uri ${slapd_ldapi_uri}
base ${basedn}
-base passwd ${accounts_basedn}
+base passwd ${users_basedn}
base group ${groups_basedn}
sasl_mech EXTERNAL
diff --git a/files/usr/local/etc/openldap/ldap.conf.common b/files/usr/local/etc/openldap/ldap.conf.common
index b56dc94..2be3425 100644
--- a/files/usr/local/etc/openldap/ldap.conf.common
+++ b/files/usr/local/etc/openldap/ldap.conf.common
@@ -7,3 +7,7 @@ SASL_REALM ${realm}
GSSAPI_SIGN yes
GSSAPI_ENCRYPT yes
SUDOERS_BASE ${sudo_basedn}
+ACCOUNTS_BASE ${accounts_basedn}
+USERS_BASE ${users_basedn}
+GROUPS_BASE ${groups_basedn}
+HOSTS_BASE ${hosts_basedn}
diff --git a/files/usr/local/etc/openldap/ldap.conf.idm_server b/files/usr/local/etc/openldap/ldap.conf.idm_server
index a3e18f2..2e77244 100644
--- a/files/usr/local/etc/openldap/ldap.conf.idm_server
+++ b/files/usr/local/etc/openldap/ldap.conf.idm_server
@@ -7,3 +7,7 @@ SASL_REALM ${realm}
GSSAPI_SIGN yes
GSSAPI_ENCRYPT yes
SUDOERS_BASE ${sudo_basedn}
+ACCOUNTS_BASE ${accounts_basedn}
+USERS_BASE ${users_basedn}
+GROUPS_BASE ${groups_basedn}
+HOSTS_BASE ${hosts_basedn}
diff --git a/files/usr/local/etc/openldap/slapd.ldif.idm_server b/files/usr/local/etc/openldap/slapd.ldif.idm_server
index d63641e..894d159 100644
--- a/files/usr/local/etc/openldap/slapd.ldif.idm_server
+++ b/files/usr/local/etc/openldap/slapd.ldif.idm_server
@@ -17,7 +17,7 @@ $(echo "$idm_server_list" | while read -r _hostname id ipv4; do
echo "olcServerID: ${id} ldaps://${ipv4}/"
done)
olcAuthzRegexp: {0}^gidNumber=[0-9]+\+uidNumber=0,cn=peercred,cn=external,cn=auth$ ${slapd_root_dn}
-olcAuthzRegexp: {1}^gidNumber=[0-9]+\+uidNumber=([^,]+),cn=peercred,cn=external,cn=auth$ ldap:///${accounts_basedn}??sub?(uidNumber=\$1)
+olcAuthzRegexp: {1}^gidNumber=[0-9]+\+uidNumber=([^,]+),cn=peercred,cn=external,cn=auth$ ldap:///${users_basedn}??sub?(uidNumber=\$1)
olcAuthzRegexp: {2}^uid=([^,]+),cn=(gssapi|plain|login),cn=auth$ ldap:///${accounts_basedn}??sub?(krbPrincipalName=\$1@${realm})
# Load dynamic modules.
@@ -196,15 +196,11 @@ dn: olcOverlay={3}unique,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcUniqueConfig
olcOverlay: unique
-olcUniqueURI: ldap:///${accounts_basedn}?uid?sub
-olcUniqueURI: ldap:///${accounts_basedn}?uidNumber?sub
+olcUniqueURI: ldap:///${users_basedn}?uid,uidNumber?sub
+olcUniqueURI: ldap:///${groups_basedn}?cn,gidNumber?sub
olcUniqueURI: ldap:///${accounts_basedn}?krbPrincipalName?sub
-olcUniqueURI: ldap:///${accounts_basedn}?mail?sub
-olcUniqueURI: ldap:///${accounts_basedn}?mailAddress,mailAlternateAddress,mailPrivateAddress,mailContactAddress?sub
-olcUniqueURI: ldap:///${groups_basedn}?cn?sub
-olcUniqueURI: ldap:///${groups_basedn}?gidNumber?sub
-olcUniqueURI: ldap:///${hosts_basedn}?cn,dc?sub
-olcUniqueURI: ldap:///${services_basedn}?cn?sub
+olcUniqueURI: ldap:///${accounts_basedn}?mail,mailAddress,mailAlternateAddress,mailPrivateAddress,mailContactAddress?sub
+olcUniqueURI: ldap:///${hosts_basedn}?cn,dc,associatedDomain?sub
olcUniqueURI: ldap:///${sudo_basedn}?cn?sub
olcUniqueURI: ldap:///${dns_basedn}?associatedDomain?sub
diff --git a/files/usr/local/etc/postfix/main.cf.smtp_server b/files/usr/local/etc/postfix/main.cf.smtp_server
new file mode 100644
index 0000000..c1e40a4
--- /dev/null
+++ b/files/usr/local/etc/postfix/main.cf.smtp_server
@@ -0,0 +1,124 @@
+compatibility_level = 3.8
+
+queue_directory = /var/spool/postfix
+command_directory = /usr/local/sbin
+daemon_directory = /usr/local/libexec/postfix
+data_directory = /var/db/postfix
+sendmail_path = /usr/local/sbin/sendmail
+newaliases_path = /usr/local/bin/newaliases
+mailq_path = /usr/local/bin/mailq
+html_directory = no
+manpage_directory = /usr/local/man
+sample_directory = /usr/local/etc/postfix
+meta_directory = /usr/local/libexec/postfix
+shlib_directory = /usr/local/lib/postfix
+readme_directory = no
+mail_owner = ${postfix_user}
+setgid_group = maildrop
+
+import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY LANG=C POSTLOG_SERVICE POSTLOG_HOSTNAME KRB5_KTNAME=${postfix_keytab} KRB5_CLIENT_KTNAME=${postfix_keytab}
+
+myorigin = ${postfix_myorigin}
+myhostname = ${postfix_public_fqdn}
+mynetworks = 127.0.0.0/8 [::1]/128 [fe80::]/64 ${postfix_mynetworks}
+mydestination =
+
+inet_interfaces = all
+inet_protocols = all
+
+alias_database =
+alias_maps =
+
+recipient_delimiter = ${postfix_recipient_delimiter}
+message_size_limit = ${postfix_message_size_limit}
+strict_rfc821_envelopes = yes
+allow_percent_hack = no
+swap_bangpath = no
+disable_vrfy_command = yes
+show_user_unknown_table_name = no
+tls_medium_cipherlist = ${postfix_cipherlist}
+tls_preempt_cipherlist = no
+
+$(if [ "$postfix_public_fqdn" != "$fqdn" ]; then
+cat <<EOF
+smtpd_tls_chain_files =
+ ${postfix_public_tls_key},
+ ${postfix_public_tls_cert}
+tls_server_sni_maps =
+ inline:{
+ { ${postfix_public_fqdn} = ${postfix_public_tls_key},${postfix_public_tls_cert} },
+ { .${domain} = ${postfix_local_tls_key},${postfix_local_tls_cert} }
+ }
+EOF
+else
+cat <<EOF
+smtpd_tls_chain_files =
+ ${postfix_local_tls_key},
+ ${postfix_local_tls_cert}
+EOF
+)
+
+smtpd_tls_security_level = may
+smtpd_tls_auth_only = yes
+smtpd_tls_mandatory_protocols = >=TLSv1.2
+smtpd_tls_mandatory_ciphers = medium
+smtpd_tls_dh1024_param_file = ${postfix_dhparams}
+smtpd_tls_loglevel = 1
+smtpd_sasl_security_options = noanonymous, noplaintext
+smtpd_sasl_tls_security_options = noanonymous
+smtpd_helo_required = yes
+
+smtp_tls_CApath = ${system_ca_dir}
+smtp_tls_security_level = may
+smtp_tls_session_cache_database = btree:\$data_directory/smtp_scache
+smtp_tls_loglevel = 1
+
+lmtp_tls_CApath = ${system_ca_dir}
+lmtp_tls_security_level = encrypt
+lmtp_tls_wrappermode = yes
+lmtp_tls_session_cache_database = btree:\$data_directory/lmtp_scache
+smtp_tls_loglevel = 1
+
+smtpd_helo_required = yes
+smtpd_client_restrictions =
+ permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_unauth_pipelining,
+ reject_unknown_reverse_client_hostname
+smtpd_helo_restrictions =
+ permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_invalid_helo_hostname,
+ reject_non_fqdn_helo_hostname,
+ reject_unauth_pipelining
+smtpd_sender_restrictions =
+ permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_non_fqdn_sender,
+ reject_unknown_sender_domain,
+ reject_unauth_pipelining
+smtpd_relay_restrictions =
+ permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_unauth_destination
+smtpd_recipient_restrictions =
+ reject_unknown_recipient_domain,
+ reject_unlisted_recipient,
+ reject_unauth_destination,
+ check_policy_service inet:${imap_host}.${domain}:${quota_status_port},
+ permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_non_fqdn_recipient,
+ reject_unauth_pipelining
+smtpd_data_restrictions =
+ permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_unauth_pipelining
+
+virtual_transport = lmtp:inet:${imap_host}.${domain}:${lmtp_port}
+virtual_mailbox_domains = ${postfix_virtual_domains}
+virtual_mailbox_maps = proxy:ldap:\$config_directory/virtual_mailboxes.cf
+virtual_alias_maps = proxy:ldap:\$config_directory/virtual_aliases.cf
+
+milter_default_action = accept
+smtpd_milters = unix:${rspamd_milter_sock}
diff --git a/files/usr/local/etc/postfix/master.cf.smtp_server b/files/usr/local/etc/postfix/master.cf.smtp_server
new file mode 100644
index 0000000..e0b5bbb
--- /dev/null
+++ b/files/usr/local/etc/postfix/master.cf.smtp_server
@@ -0,0 +1,29 @@
+smtp inet n - n - - smtpd
+submission inet n - n - - smtpd
+ -o smtpd_tls_security_level=encrypt
+ -o smtpd_sasl_auth_enable=yes
+pickup unix n - n 60 1 pickup
+cleanup unix n - n - 0 cleanup
+qmgr unix n - n 300 1 qmgr
+tlsmgr unix - - n 1000? 1 tlsmgr
+rewrite unix - - n - - trivial-rewrite
+bounce unix - - n - 0 bounce
+defer unix - - n - 0 bounce
+trace unix - - n - 0 bounce
+verify unix - - n - 1 verify
+flush unix n - n 1000? 0 flush
+proxymap unix - - n - - proxymap
+proxywrite unix - - n - 1 proxymap
+smtp unix - - n - - smtp
+relay unix - - n - - smtp
+ -o syslog_name=postfix/$service_name
+showq unix n - n - - showq
+error unix - - n - - error
+retry unix - - n - - error
+discard unix - - n - - discard
+local unix - n n - - local
+virtual unix - n n - - virtual
+lmtp unix - - n - - lmtp
+anvil unix - - n - 1 anvil
+scache unix - - n - 1 scache
+postlog unix-dgram n - n - 1 postlogd
diff --git a/files/usr/local/etc/postfix/virtual_aliases.cf.smtp_server b/files/usr/local/etc/postfix/virtual_aliases.cf.smtp_server
new file mode 100644
index 0000000..6fa9715
--- /dev/null
+++ b/files/usr/local/etc/postfix/virtual_aliases.cf.smtp_server
@@ -0,0 +1,8 @@
+version = 3
+bind = sasl
+sasl_mechs = gssapi
+server_host = ${ldap_uri}
+search_base = ${accounts_basedn}
+query_filter = (|(mailAddress=%s)(mailAlternateAddress=%s))
+special_result_attribute = member
+leaf_result_attribute = mailAddress
diff --git a/files/usr/local/etc/postfix/virtual_mailboxes.cf.smtp_server b/files/usr/local/etc/postfix/virtual_mailboxes.cf.smtp_server
new file mode 100644
index 0000000..b07e459
--- /dev/null
+++ b/files/usr/local/etc/postfix/virtual_mailboxes.cf.smtp_server
@@ -0,0 +1,7 @@
+version = 3
+bind = sasl
+sasl_mechs = gssapi
+server_host = ${ldap_uri}
+search_base = ${users_basedn}
+query_filter = (mailAddress=%s)
+result_attribute = mailAddress
diff --git a/files/usr/local/etc/poudriere.d/pkglist.pkg_repository b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository
index 157ae8e..4a54ec5 100644
--- a/files/usr/local/etc/poudriere.d/pkglist.pkg_repository
+++ b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository
@@ -1,3 +1,4 @@
+databases/redis
devel/ccache
devel/git@lite
dns/bind-tools
@@ -7,6 +8,13 @@ dns/unbound
editors/vim@console
editors/vim@tiny
lang/python
+mail/dovecot
+mail/dovecot-pigeonhole
+mail/isync
+mail/mutt
+mail/postfix
+mail/rspamd
+mail/sieve-connect
net/nss-pam-ldapd-sasl
net/openldap26-client
net/openldap26-server
diff --git a/files/usr/local/etc/redis-rspamd-bayes.conf.smtp_server b/files/usr/local/etc/redis-rspamd-bayes.conf.smtp_server
new file mode 100644
index 0000000..610deb5
--- /dev/null
+++ b/files/usr/local/etc/redis-rspamd-bayes.conf.smtp_server
@@ -0,0 +1,74 @@
+pidfile /var/run/redis/rspamd-bayes.pid
+proc-title-template "{title} rspamd-bayes"
+dir ${rspamd_bayes_redis_data_dir}
+unixsocket ${rspamd_bayes_redis_sock}
+unixsocketperm 770
+
+maxmemory ${rspamd_redis_maxmemory}
+maxmemory-policy volatile-ttl
+
+port 0
+
+databases 1
+syslog-enabled yes
+loglevel notice
+logfile ""
+
+# The rest of these values are unchanged from the FreeBSD defaults:
+daemonize yes
+protected-mode yes
+tcp-backlog 511
+timeout 0
+tcp-keepalive 300
+always-show-logo no
+set-proc-title yes
+locale-collate ""
+stop-writes-on-bgsave-error yes
+rdbcompression yes
+rdbchecksum yes
+dbfilename dump.rdb
+rdb-del-sync-files no
+lazyfree-lazy-eviction no
+lazyfree-lazy-expire no
+lazyfree-lazy-server-del no
+replica-lazy-flush no
+lazyfree-lazy-user-del no
+lazyfree-lazy-user-flush no
+oom-score-adj no
+oom-score-adj-values 0 200 800
+disable-thp yes
+appendonly no
+appendfilename "appendonly.aof"
+appenddirname "appendonlydir"
+appendfsync everysec
+no-appendfsync-on-rewrite no
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+aof-load-truncated yes
+aof-use-rdb-preamble yes
+aof-timestamp-enabled no
+slowlog-log-slower-than 10000
+slowlog-max-len 128
+latency-monitor-threshold 0
+notify-keyspace-events ""
+hash-max-listpack-entries 512
+hash-max-listpack-value 64
+list-max-listpack-size -2
+list-compress-depth 0
+set-max-intset-entries 512
+set-max-listpack-entries 128
+set-max-listpack-value 64
+zset-max-listpack-entries 128
+zset-max-listpack-value 64
+hll-sparse-max-bytes 3000
+stream-node-max-bytes 4096
+stream-node-max-entries 100
+activerehashing yes
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit replica 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+hz 10
+dynamic-hz yes
+aof-rewrite-incremental-fsync yes
+rdb-save-incremental-fsync yes
+jemalloc-bg-thread yes
diff --git a/files/usr/local/etc/redis-rspamd.conf.smtp_server b/files/usr/local/etc/redis-rspamd.conf.smtp_server
new file mode 100644
index 0000000..c073cce
--- /dev/null
+++ b/files/usr/local/etc/redis-rspamd.conf.smtp_server
@@ -0,0 +1,74 @@
+pidfile /var/run/redis/rspamd.pid
+proc-title-template "{title} rspamd"
+dir ${rspamd_redis_data_dir}
+unixsocket ${rspamd_redis_sock}
+unixsocketperm 770
+
+maxmemory ${rspamd_redis_maxmemory}
+maxmemory-policy allkeys-lru
+
+port 0
+
+databases 1
+syslog-enabled yes
+loglevel notice
+logfile ""
+
+# The rest of these values are unchanged from the FreeBSD defaults:
+daemonize yes
+protected-mode yes
+tcp-backlog 511
+timeout 0
+tcp-keepalive 300
+always-show-logo no
+set-proc-title yes
+locale-collate ""
+stop-writes-on-bgsave-error yes
+rdbcompression yes
+rdbchecksum yes
+dbfilename dump.rdb
+rdb-del-sync-files no
+lazyfree-lazy-eviction no
+lazyfree-lazy-expire no
+lazyfree-lazy-server-del no
+replica-lazy-flush no
+lazyfree-lazy-user-del no
+lazyfree-lazy-user-flush no
+oom-score-adj no
+oom-score-adj-values 0 200 800
+disable-thp yes
+appendonly no
+appendfilename "appendonly.aof"
+appenddirname "appendonlydir"
+appendfsync everysec
+no-appendfsync-on-rewrite no
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+aof-load-truncated yes
+aof-use-rdb-preamble yes
+aof-timestamp-enabled no
+slowlog-log-slower-than 10000
+slowlog-max-len 128
+latency-monitor-threshold 0
+notify-keyspace-events ""
+hash-max-listpack-entries 512
+hash-max-listpack-value 64
+list-max-listpack-size -2
+list-compress-depth 0
+set-max-intset-entries 512
+set-max-listpack-entries 128
+set-max-listpack-value 64
+zset-max-listpack-entries 128
+zset-max-listpack-value 64
+hll-sparse-max-bytes 3000
+stream-node-max-bytes 4096
+stream-node-max-entries 100
+activerehashing yes
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit replica 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+hz 10
+dynamic-hz yes
+aof-rewrite-incremental-fsync yes
+rdb-save-incremental-fsync yes
+jemalloc-bg-thread yes
diff --git a/files/usr/local/etc/rspamd/local.d/classifier-bayes.conf.smtp_server b/files/usr/local/etc/rspamd/local.d/classifier-bayes.conf.smtp_server
new file mode 100644
index 0000000..38dcf1d
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/classifier-bayes.conf.smtp_server
@@ -0,0 +1,3 @@
+backend = "redis";
+servers = "${rspamd_bayes_redis_sock}";
+autolearn = true;
diff --git a/files/usr/local/etc/rspamd/local.d/dkim_signing.conf.smtp_server b/files/usr/local/etc/rspamd/local.d/dkim_signing.conf.smtp_server
new file mode 100644
index 0000000..f988541
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/dkim_signing.conf.smtp_server
@@ -0,0 +1,3 @@
+path = "${rspamd_data_dir}/dkim/\$domain.key";
+selector = "${rspamd_dkim_selector}";
+allow_username_mismatch = true;
diff --git a/files/usr/local/etc/rspamd/local.d/logging.inc.smtp_server b/files/usr/local/etc/rspamd/local.d/logging.inc.smtp_server
new file mode 100644
index 0000000..7e38af5
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/logging.inc.smtp_server
@@ -0,0 +1,2 @@
+type = syslog;
+facility = mail;
diff --git a/files/usr/local/etc/rspamd/local.d/multimap.conf.smtp_server b/files/usr/local/etc/rspamd/local.d/multimap.conf.smtp_server
new file mode 100644
index 0000000..40b90ee
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/multimap.conf.smtp_server
@@ -0,0 +1,9 @@
+sender_from_whitelist_domain {
+ type = "header";
+ header = "from";
+ filter = "email:domain";
+ map = "file://$LOCAL_CONFDIR/local.d/maps.d/domain-whitelist.map";
+ symbol = "SENDER_FROM_WHITELIST_DOMAIN";
+ description = "Local sender domain whitelist";
+ score = -6.0;
+}
diff --git a/files/usr/local/etc/rspamd/local.d/phishing.conf.smtp_server b/files/usr/local/etc/rspamd/local.d/phishing.conf.smtp_server
new file mode 100644
index 0000000..caa3afe
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/phishing.conf.smtp_server
@@ -0,0 +1 @@
+openphish_enabled = true;
diff --git a/files/usr/local/etc/rspamd/local.d/redis.conf.smtp_server b/files/usr/local/etc/rspamd/local.d/redis.conf.smtp_server
new file mode 100644
index 0000000..cbd32dc
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/redis.conf.smtp_server
@@ -0,0 +1 @@
+servers = "${rspamd_redis_sock}";
diff --git a/files/usr/local/etc/rspamd/local.d/replies.conf.smtp_server b/files/usr/local/etc/rspamd/local.d/replies.conf.smtp_server
new file mode 100644
index 0000000..5f7bc7c
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/replies.conf.smtp_server
@@ -0,0 +1 @@
+action = "no action";
diff --git a/files/usr/local/etc/rspamd/local.d/worker-controller.inc.smtp_server b/files/usr/local/etc/rspamd/local.d/worker-controller.inc.smtp_server
new file mode 100644
index 0000000..26b9b2a
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/worker-controller.inc.smtp_server
@@ -0,0 +1,12 @@
+bind_socket = "0.0.0.0:${rspamd_port}";
+
+password = "${rspamd_ro_password_hash}";
+enable_password = "${rspamd_rw_password_hash}";
+
+keypair {
+ algorithm = "curve25519";
+ privkey = "${rspamd_privkey}";
+ type = "kex";
+ encoding = "base32";
+ pubkey = "${rspamd_pubkey}";
+}
diff --git a/files/usr/local/etc/rspamd/local.d/worker-normal.inc.smtp_server b/files/usr/local/etc/rspamd/local.d/worker-normal.inc.smtp_server
new file mode 100644
index 0000000..a6ee831
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/worker-normal.inc.smtp_server
@@ -0,0 +1 @@
+enabled = false;
diff --git a/files/usr/local/etc/rspamd/local.d/worker-proxy.inc.smtp_server b/files/usr/local/etc/rspamd/local.d/worker-proxy.inc.smtp_server
new file mode 100644
index 0000000..f28080b
--- /dev/null
+++ b/files/usr/local/etc/rspamd/local.d/worker-proxy.inc.smtp_server
@@ -0,0 +1,7 @@
+bind_socket = "${rspamd_milter_sock} owner=${rspamd_user} group=${postfix_user} mode=0660";
+
+count = ${rspamd_processes};
+
+upstream "local" {
+ self_scan = yes;
+}
diff --git a/files/usr/local/libexec/idm-ssh-authorized-keys.common b/files/usr/local/libexec/idm-ssh-authorized-keys.common
index d18b199..89d2f20 100644
--- a/files/usr/local/libexec/idm-ssh-authorized-keys.common
+++ b/files/usr/local/libexec/idm-ssh-authorized-keys.common
@@ -20,7 +20,7 @@ close($fh);
my $mech = $config{SASL_MECH} // 'GSSAPI';
my $uri = $config{URI} // quit('URI not specified');
-my $basedn = $config{BASE} // quit('BASE not specified');
+my $basedn = $config{USERS_BASE} // quit('USERS_BASE not specified');
@ARGV == 1 or die "usage: $0 USERNAME\n";
my $username = $ARGV[0];
@@ -32,7 +32,7 @@ $status->code and die "$0: ".$status->error;
my $search = $conn->search(
scope => 'sub',
- base => "ou=accounts,$basedn",
+ base => $basedn,
filter => '(&(objectClass=posixAccount)(sshPublicKey=*)(uid=' . escape_filter_value($username) . '))',
attrs => ['sshPublicKey']);
$search->code and die "$0: ".$search->error;
diff --git a/files/usr/local/libexec/idm-ssh-known-hosts.common b/files/usr/local/libexec/idm-ssh-known-hosts.common
index 78b48fc..5b784d6 100644
--- a/files/usr/local/libexec/idm-ssh-known-hosts.common
+++ b/files/usr/local/libexec/idm-ssh-known-hosts.common
@@ -31,7 +31,7 @@ close($fh);
my $mech = $config{SASL_MECH} // 'GSSAPI';
my $uri = $config{URI} // quit('URI not specified');
-my $basedn = $config{BASE} // quit('BASE not specified');
+my $basedn = $config{HOSTS_BASE} // quit('HOSTS_BASE not specified');
my $conn = Net::LDAP->new($uri, version => '3') or quit($@);
my $sasl = Authen::SASL->new($mech);
@@ -40,7 +40,7 @@ $status->code and quit($status->error);
my $search = $conn->search(
scope => 'sub',
- base => "ou=hosts,ou=accounts,$basedn",
+ base => $basedn,
filter => '(&(sshPublicKey=*)(associatedDomain=' . escape_filter_value($hostname) . '))',
attrs => ['sshPublicKey']);
$search->code and quit($search->error);
diff --git a/hostclasses b/hostclasses
index cebd7af..22b77ce 100644
--- a/hostclasses
+++ b/hostclasses
@@ -1,7 +1,7 @@
freebsd_hypervisor ^alcatraz[0-9]
pkg_repository ^pkg[0-9]
idm_server ^idm[0-9]
-smtp_server ^mx[0-9]
+smtp_server ^smtp[0-9]
imap_server ^imap[0-9]
dev_server ^dev[0-9]
radius_server ^radius[0-9]
diff --git a/scripts/common/10-vars b/scripts/common/10-vars
index 3b01cd2..6ea7cad 100644
--- a/scripts/common/10-vars
+++ b/scripts/common/10-vars
@@ -20,8 +20,9 @@ ldap_uri=$(printf "ldap://%s.${domain}/ " $idm_hostnames)
ldaps_uri=$(printf "ldaps://%s.${domain}/ " $idm_hostnames)
ldap_hosts=$(printf "%s.${domain} " $idm_hostnames)
accounts_basedn="ou=accounts,${basedn}"
-people_basedn="ou=people,${accounts_basedn}"
-robots_basedn="ou=robots,${accounts_basedn}"
+users_basedn="ou=users,${accounts_basedn}"
+people_basedn="ou=people,${users_basedn}"
+robots_basedn="ou=robots,${users_basedn}"
hosts_basedn="ou=hosts,${accounts_basedn}"
services_basedn="ou=services,${accounts_basedn}"
groups_basedn="ou=groups,${accounts_basedn}"
@@ -31,7 +32,5 @@ automount_basedn="ou=automount,${basedn}"
sudo_basedn="ou=sudo,${basedn}"
dns_basedn="ou=dns,${basedn}"
kdc_basedn="cn=kdc,${basedn}"
-mail_basedn="ou=mail,${basedn}"
-mail_domains_basedn="ou=domains,${mail_basedn}"
boxconf_dn="krbPrincipalName=${boxconf_username}@${realm},${robots_basedn}"
diff --git a/scripts/hostclass/idm_server/10-slapd b/scripts/hostclass/idm_server/10-slapd
index 83cdbb6..d108ae2 100644
--- a/scripts/hostclass/idm_server/10-slapd
+++ b/scripts/hostclass/idm_server/10-slapd
@@ -120,13 +120,19 @@ objectClass: organizationalUnit
ou: $(ldap_rdn_value "$accounts_basedn")
EOF
- # ou=people,ou=accounts,dc=example,dc=com
+ # ou=users,ou=accounts,dc=example,dc=com
+ ldap_add "$users_basedn" <<EOF
+objectClass: organizationalUnit
+ou: $(ldap_rdn_value "$users_basedn")
+EOF
+
+ # ou=people,ou=users,ou=accounts,dc=example,dc=com
ldap_add "$people_basedn" <<EOF
objectClass: organizationalUnit
ou: $(ldap_rdn_value "$people_basedn")
EOF
- # ou=robots,ou=accounts,dc=example,dc=com
+ # ou=robots,ou=users,ou=accounts,dc=example,dc=com
ldap_add "$robots_basedn" <<EOF
objectClass: organizationalUnit
ou: $(ldap_rdn_value "$robots_basedn")
diff --git a/scripts/hostclass/smtp_server/10-rspamd b/scripts/hostclass/smtp_server/10-rspamd
new file mode 100644
index 0000000..d104e9c
--- /dev/null
+++ b/scripts/hostclass/smtp_server/10-rspamd
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+: ${rspamd_processes:="$nproc"}
+: ${rspamd_dkim_selector:='dkim'}
+: ${rspamd_domain_whitelist:=''}
+: ${rspamd_port:='11334'}
+: ${rspamd_redis_maxmemory:='1g'}
+: ${postfix_virtual_domains:="$email_domain"}
+
+postfix_user=postfix
+postfix_home_dir=/var/spool/postfix
+
+redis_user=redis
+redis_data_dir=/var/db/redis
+rspamd_user=rspamd
+rspamd_conf_dir=/usr/local/etc/rspamd
+rspamd_milter_sock="${postfix_home_dir}/rspamd.sock"
+rspamd_data_dir=/var/db/rspamd
+rspamd_redis_sock=/var/run/redis/rspamd.sock
+rspamd_bayes_redis_sock=/var/run/redis/rspamd-bayes.sock
+rspamd_redis_data_dir="${redis_data_dir}/rspamd"
+rspamd_bayes_redis_data_dir="${redis_data_dir}/rspamd-bayes"
+rspamd_tls_cert=/usr/local/etc/nginx/rspamd.crt
+rspamd_tls_key=/usr/local/etc/nginx/rspamd.key
+
+pkg install -y \
+ postfix \
+ redis \
+ rspamd \
+ nginx
+
+# Create ZFS dataset for Redis DBs.
+create_dataset -o "mountpoint=${redis_data_dir}" "${state_dataset}/redis"
+
+# Generate config files for redis instances.
+install_template -m 0644 \
+ /usr/local/etc/redis-rspamd.conf \
+ /usr/local/etc/redis-rspamd-bayes.conf
+
+# Create data directories for each redis instance.
+install_directory -o "$redis_user" -m 0700 \
+ "$rspamd_redis_data_dir" \
+ "$rspamd_bayes_redis_data_dir"
+
+# Enable and start redis instances.
+sysrc -v \
+ redis_enable=YES \
+ redis_profiles='rspamd rspamd-bayes'
+service redis restart
+
+# Copy rspamd config files.
+install_directory -m 0755 \
+ "${rspamd_conf_dir}/local.d" \
+ "${rspamd_conf_dir}/local.d/maps.d"
+
+install_directory -m 0750 -g "$rspamd_user" "${rspamd_data_dir}/dkim"
+
+install_file -m 0640 -g "$rspamd_user" \
+ "${rspamd_conf_dir}/local.d/logging.inc" \
+ "${rspamd_conf_dir}/local.d/multimap.conf" \
+ "${rspamd_conf_dir}/local.d/phishing.conf" \
+ "${rspamd_conf_dir}/local.d/replies.conf" \
+ "${rspamd_conf_dir}/local.d/worker-normal.inc"
+
+rspamd_ro_password_hash=$(rspamadm pw -p "$rspamd_ro_password")
+rspamd_rw_password_hash=$(rspamadm pw -p "$rspamd_rw_password")
+
+install_template -m 0640 -g "$rspamd_user" \
+ "${rspamd_conf_dir}/local.d/classifier-bayes.conf" \
+ "${rspamd_conf_dir}/local.d/dkim_signing.conf" \
+ "${rspamd_conf_dir}/local.d/redis.conf" \
+ "${rspamd_conf_dir}/local.d/worker-controller.inc" \
+ "${rspamd_conf_dir}/local.d/worker-proxy.inc"
+
+printf '%s\n' ${rspamd_domain_whitelist} | tee "${rspamd_conf_dir}/local.d/maps.d/domain-whitelist.map"
+
+# Copy DKIM keys.
+for domain in $postfix_virtual_domains; do
+ install_file -m 0640 -g "$rspamd_user" "${rspamd_data_dir}/dkim/${domain}.key"
+done
+
+# Add rspamd user to redis group, so it can write to the redis unix socket.
+pw groupmod "$redis_user" -m "$rspamd_user"
+
+# Generate nginx configuration.
+install_template -m 0644 \
+ /usr/local/etc/nginx/nginx.conf \
+ /usr/local/etc/nginx/acme.conf \
+ /usr/local/etc/nginx/vhosts.conf
+
+# Copy TLS certificate for nginx.
+install_certificate nginx "$rspamd_tls_cert"
+install_certificate_key nginx "$rspamd_tls_key"
+
+# Enable and start rspamd and nginx.
+sysrc -v \
+ rspamd_enable=YES \
+ nginx_enable=YES
+
+# The rspamd rc script seems to hold onto open descriptors, which causes
+# the parent boxconf SSH process to never close.
+service rspamd restart > /dev/null 2>&1 < /dev/null
+service nginx restart
diff --git a/scripts/hostclass/smtp_server/20-postfix b/scripts/hostclass/smtp_server/20-postfix
new file mode 100644
index 0000000..6f891da
--- /dev/null
+++ b/scripts/hostclass/smtp_server/20-postfix
@@ -0,0 +1,87 @@
+#!/bin/sh
+
+: ${postfix_public_fqdn:="$fqdn"}
+: ${postfix_cipherlist:='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'}
+: ${postfix_myorigin:="$email_domain"}
+: ${postfix_mynetworks:=''}
+: ${postfix_recipient_delimiter:='+'}
+: ${postfix_message_size_limit:='67108864'} # 64 MB
+: ${postfix_virtual_domains:="$email_domain"}
+: ${postfix_lmtp_port:='24'}
+: ${postfix_quota_port:='10993'}
+
+: ${imap_host='imap'}
+: ${lmtp_port='25'}
+: ${quota_status_port='10993'}
+
+postfix_conf_dir=/usr/local/etc/postfix
+postfix_user=postfix
+postfix_keytab="${keytab_dir}/postfix.keytab"
+postfix_public_tls_cert="${acme_cert_dir}/postfix.crt"
+postfix_public_tls_key="${acme_cert_dir}/postfix.key"
+postfix_local_tls_cert="${postfix_conf_dir}/postfix.crt"
+postfix_local_tls_key="${postfix_conf_dir}/postfix.key"
+postfix_dhparams="${postfix_conf_dir}/dhparams.pem"
+
+# Install packages.
+pkg install -y \
+ postfix \
+ cyrus-sasl-saslauthd
+
+# Create SMTP service principal and keytab.
+add_principal -nokey -x "containerdn=${services_basedn}" "smtp/${fqdn}"
+
+ktadd -k "$postfix_keytab" "smtp/${fqdn}"
+chgrp "$postfix_user" "$postfix_keytab"
+chmod 640 "$postfix_keytab"
+
+postfix_uid=$(id -u "$postfix_user")
+install_directory -o "$postfix_user" -m 0700 "/var/krb5/user/${postfix_uid}"
+ln -snfv "$postfix_keytab" "/var/krb5/user/${postfix_uid}/keytab"
+ln -snfv "$postfix_keytab" "/var/krb5/user/${postfix_uid}/client.keytab"
+
+# Generate postfix configuration.
+install_template -m 0644 \
+ "${postfix_conf_dir}/main.cf" \
+ "${postfix_conf_dir}/virtual_mailboxes.cf" \
+ "${postfix_conf_dir}/virtual_aliases.cf" \
+ /usr/local/lib/sasl2/smtpd.conf
+install_file -m 0644 "${postfix_conf_dir}/master.cf"
+
+# Allow postfix to read the saslauthd socket.
+install_directory -m 0750 -o "$saslauthd_user" -g "$postfix_user" "$saslauthd_runtime_dir"
+
+# Copy internal TLS certificate.
+install_certificate -m 0644 -o root -g "$postfix_user" postfix "$postfix_local_tls_cert"
+install_certificate_key -m 0640 -o root -g "$postfix_user" postfix "$postfix_local_tls_key"
+
+# Generate dhparams.
+[ -f "$postfix_dhparams" ] || openssl dhparam -out "$postfix_dhparams" 2048
+
+if [ "$postfix_public_fqdn" != "$fqdn" ]; then
+ # Acquire public TLS certificate.
+ install_file /usr/local/etc/sudoers.d/acme
+ get_acme_certificate \
+ -c "$postfix_public_tls_cert" \
+ -k "$postfix_public_tls_key" \
+ -g "$postfix_user" \
+ -r 'sudo service postfix reload' \
+ "$postfix_public_fqdn"
+fi
+
+# Enable and start postfix and saslauthd.
+sysrc -v \
+ saslauthd_flags='-a kerberos5' \
+ saslauthd_enable=YES \
+ postfix_enable=YES
+
+service saslauthd restart
+service postfix restart
+
+# Use postfix as the system MTA.
+install_directory -m 0755 /usr/local/etc/mail
+install_file -m 0644 /usr/local/etc/mail/mailer.conf
+
+# Configure local aliases.
+install_template -m 0644 /etc/aliases
+newaliases
diff --git a/vars/common b/vars/common
index 5c22f09..7c54673 100644
--- a/vars/common
+++ b/vars/common
@@ -11,6 +11,7 @@ root_authorized_keys='ssh-ed25519 changeme
ssh-ed25519 changeme'
root_mail_alias="you@${email_domain}"
smtp_host_ip=1.2.3.4
+pkg_host_ip=1.2.3.4
timezone=America/New_York
# hostname id ipv4
@@ -20,6 +21,11 @@ idm2 2 5.6.7.8"
reverse_dns_zones="0.168.192.in-addr.arpa 12.11.10.in-addr.arpa"
+rspamd_privkey='changeme with: rspamadm keypair'
+rspamd_pubkey='changeme with: rspamadm keypair'
+rspamd_ro_password='changeme'
+rspamd_rw_password='changeme'
+
###############################################################################
# Variables following this line do not (generally) need to be changed.
@@ -38,6 +44,7 @@ krb5_renew_lifetime=7d
nslcd_min_uid=1000
nscd_ttl=600
nscd_negative_ttl=20
+rspamd_port=11334
ssh_authzkeys_uid=789
ssh_authzkeys_username=sshkeys
tcp_buffer_size=2097152 # suitable for 1 GigE
diff --git a/vars/hostclass/smtp_server b/vars/hostclass/smtp_server
new file mode 100644
index 0000000..1e8838e
--- /dev/null
+++ b/vars/hostclass/smtp_server
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+allowed_tcp_ports="ssh smtp submission ${rspamd_port} http https"
+postfix_mynetworks='127.0.0.1/8'
diff --git a/vars/hostname/smtp1 b/vars/hostname/smtp1
new file mode 100644
index 0000000..f7da91f
--- /dev/null
+++ b/vars/hostname/smtp1
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+cnames=smtp
diff --git a/vars/os/freebsd b/vars/os/freebsd
index 9f5f068..308408b 100644
--- a/vars/os/freebsd
+++ b/vars/os/freebsd
@@ -11,6 +11,7 @@ see_other_uids=0
export ASSUME_ALWAYS_YES=yes
acme_standalone_port=9080
acme_uid=169
+acme_webroot=/usr/local/www/acme
keytab_dir=/var/db/keytabs
nfscbd_port=7745
nslcd_user=nslcd