diff options
author | Cullum Smith <cullum@sacredheartsc.com> | 2024-10-03 08:37:38 -0400 |
---|---|---|
committer | Cullum Smith <cullum@sacredheartsc.com> | 2024-10-03 08:37:38 -0400 |
commit | 47f90d0916ac34ef132e3bb6da92a4a67dffbba8 (patch) | |
tree | 764a6aee2dea7a69096eba27c4264776f8190380 | |
parent | ee583b5929925b2e9658385430da4f73b4883287 (diff) | |
download | infrastructure-47f90d0916ac34ef132e3bb6da92a4a67dffbba8.tar.gz |
add postfix/rspamd
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 |