From cb47973861827cf816b71264ced318544eb01cae Mon Sep 17 00:00:00 2001 From: Mar Alegre Date: Mon, 12 Aug 2024 16:24:42 -0400 Subject: [PATCH 1/8] add SPF checking for recieved mail --- mailsrv/Containerfile | 6 +- mailsrv/assets/postfix/main.cf.part | 9 +- mailsrv/assets/postfix/master.cf | 2 + mailsrv/assets/postfix/policyd-spf.conf | 138 ++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 mailsrv/assets/postfix/policyd-spf.conf diff --git a/mailsrv/Containerfile b/mailsrv/Containerfile index 49ba0d1..1c68c45 100644 --- a/mailsrv/Containerfile +++ b/mailsrv/Containerfile @@ -29,7 +29,7 @@ ARG FILESUID=5000 ARG DEBIAN_FRONTEND=noninteractive # install packages we want -RUN apt update -y && apt install -y rsyslog postfix dovecot-imapd dovecot-lmtpd dovecot-sieve cron +RUN apt update -y && apt install -y rsyslog postfix dovecot-imapd dovecot-lmtpd dovecot-sieve cron postfix-policyd-spf-python # add virtual mail user RUN addgroup --gid ${FILESUID:?} vmail && \ @@ -64,6 +64,10 @@ RUN systemctl enable mkvirtual.service # copy postfix config COPY assets/postfix /etc/postfix +# replace SPF server config file with symlink to the config file in the postfix dir +RUN rm /etc/postfix-policyd-spf-python/policyd-spf.conf && \ + ln -s /etc/postfix/policyd-spf.conf /etc/postfix-policyd-spf-python/policyd-spf.conf + ### ### Dovecot ### diff --git a/mailsrv/assets/postfix/main.cf.part b/mailsrv/assets/postfix/main.cf.part index 4648cc4..5562eb8 100644 --- a/mailsrv/assets/postfix/main.cf.part +++ b/mailsrv/assets/postfix/main.cf.part @@ -74,10 +74,11 @@ smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/deny, pe smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, - reject_unknown_client_hostname, # weaker version of reject_unknown_client_hostname -# the strong version may cause problems with some legitimate senders (eg, Verizon) -# reject_unknown_reverse_client_hostname, +# the strong version may cause problems with some legitimate senders + reject_unknown_reverse_client_hostname, +# check if sender meets SPF policy for its domain + check_policy_service unix:private/policy-spf, # reject clients from lists of known spammers # reject_rbl_client zen.spamhaus.org, # reject_rhsbl_reverse_client dbl.spamhaus.org, @@ -94,3 +95,5 @@ biff = no compatibility_level = 2 # maximum size allowed for sent messages, in bytes message_size_limit = 102400000 +# longer timeout for SPF policy server +policy-spf_time_limit = 3600s diff --git a/mailsrv/assets/postfix/master.cf b/mailsrv/assets/postfix/master.cf index a95bb63..851b9c9 100644 --- a/mailsrv/assets/postfix/master.cf +++ b/mailsrv/assets/postfix/master.cf @@ -57,3 +57,5 @@ postlog unix-dgram n - n - 1 postlogd # dovecot unix - n n - - pipe flags=DROhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${user}@${nexthop} +policy-spf unix - n n - - spawn + user=nobody argv=/usr/bin/policyd-spf diff --git a/mailsrv/assets/postfix/policyd-spf.conf b/mailsrv/assets/postfix/policyd-spf.conf new file mode 100644 index 0000000..c908fe3 --- /dev/null +++ b/mailsrv/assets/postfix/policyd-spf.conf @@ -0,0 +1,138 @@ +# Amount of debugging information logged. 0 logs no debugging messages +# 5 includes all debug messages. +debugLevel = 1 + +# If set to 0, no messages are rejected by SPF. This allows you to see the +# potential impact of SPF checking in your mail logs without rejecting mail. +TestOnly = 1 + +# Reject and deferred reason +#Reason_Message = Message {rejectdefer} due to: {spf}. Please see {url} + +# HELO check rejection policy. Options are: +# HELO_reject = SPF_Not_Pass (default) - Reject if result not Pass/None/Tempfail. +# HELO_reject = Softfail - Reject if result Softfail and Fail +# HELO_reject = Fail - Reject on HELO Fail +# HELO_reject = Null - Only reject HELO Fail for Null sender (SPF Classic) +# HELO_reject = False - Never reject/defer on HELO, append header only. +# HELO_reject = No_Check - Never check HELO. +HELO_reject = Fail + +# HELO pass restriction policy. +# HELO_pass_restriction = helo_passed_spf - Apply the given restriction when +# the HELO checking result is Pass. The given restriction must be an +# action as defined for a Postfix SMTP server access table access(5). +#HELO_pass_restriction + +# Mail From rejection policy. Options are: +# Mail_From_reject = SPF_Not_Pass - Reject if result not Pass/None/Tempfail. +# Mail_From_reject = Softfail - Reject if result Softfail and Fail +# Mail_From_reject = Fail - Reject on Mail From Fail (default) +# Mail_From_reject = False - Never reject/defer on Mail From, append header only +# Mail_From_reject = No_Check - Never check Mail From/Return Path. +Mail_From_reject = Fail + +# Reject only from domains that send no mail. Options are: +# No_Mail = False - Normal SPF record processing (default) +# No_Mail = True - Only reject for "v=spf1 -all" records + +# Mail From pass restriction policy. +# Mail_From_pass_restriction = mfrom_passed_spf - Apply the given +# restriction when the Mail From checking result is Pass. The given +# restriction must be an action as defined for a Postfix SMTP server +# access table access(5). +#Mail_From_pass_restriction + +# Reject mail for Netural/Softfail results for these domains. +# Recevier policy option to reject mail from certain domains when SPF is not +# Pass/None even if their SPF record does not produce a Fail result. This +# Option does not change the effect of PermError_reject or TempError_Defer +#Reject_Not_Pass_Domains = aol.com,hotmail.com + +# Policy for rejecting due to SPF PermError. Options are: +# PermError_reject = True +# PermError_reject = False +PermError_reject = False + +# Policy for deferring messages due to SPF TempError. Options are: +# TempError_Defer = True +# TempError_Defer = False +TempError_Defer = False + +# Prospective SPF checking - Check to see if mail sent from the defined IP +# address would pass. +# Prospective = 192.168.0.4 + +# Do not check SPF for localhost addresses - add to skip addresses to +# skip SPF for internal networks if desired. Defaults are standard IPv4 and +# IPv6 localhost addresses. +skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0/104,::1 + +# Whitelist: CIDR Notation list of IP addresses not to check SPF for. +# Example (default is no whitelist): +# Whitelist = 192.168.0.0/31,192.168.1.12 + +# SPF HELO WHITELIST: HELO/EHLO host names to skip SPF checks for. +# Example (default is no HELO_Whitelist): +# HELO_Whitelist = relay.example.com,sender.example.org + +# Domain_Whitelist: List of domains whose sending IPs (defined by passing +# their SPF check should be whitelisted from SPF. +# Example (default is no domain whitelist): +# Domain_Whitelist = pobox.com,trustedforwarder.org + +# Domain_Whitelist_PTR: List of domains to whitelist against SPF checks base +# on PTR match. +# Example (default is no PTR whitelist) +# Domain_Whitelist_PTR = yahoo.com + +# SPF ENHANCED STATUS CODES: Override Postfix enhanced status codes to use the +# RFC 7372 codes. Disable by setting this option to "No". +# SPF_Enhanced_Status_Codes = No + +# Type of header to insert to document SPF result. Can be Received-SPF (SPF) +# or Authentication Results (AR). It cannot be both. +# Examples: (default is Received-SPF): +# Header_Type = AR +# Header_Type = SPF + +# In order to avoid disclosing BCC recipients in SPF header fields, +# Hide_Receiver is set to Yes by default in the interest of maximizing +# privacy. This setting will replace the actual recipient with both +# in header fields and SMTP responses. The latter may make it more difficult +# for senders to troubleshoot issues with their SPF deployments. +#Hide_Receiver = No +Hide_Receiver = Yes + +# Every Authentication-Results header field has an authentication identifier +# field ('Authserv_Id'). This is similar in syntax to a fully-qualified domain +# name. See policyd-spf.conf.5 and RFC 7001 paragraph 2.4 for details. +# Default is HOSTNAME (as provided by socket.gethostname). Authserv-Id must +# be provided if Header_Type 'AR' is used. +# Authserv_Id = mx.example.com +Authserv_Id = HEADER + +# RFC 7208 recommends an elapsed time limit for SPF checks of at least 20 +# seconds. Lookup_Time allows the maximum time (seconds) to be adjusted. 20 +# seconds is the default. +# Lookup_Time = 20 + +# Some of the available whitelisting mechanisms, i.e. Domain_Whitelist, +# Domain_Whitelist_PTR, and HELO_Whitelist, require specific non-SPF DNS +# lookups to determine if a connection should be white listed from SPF checks. +# The maximum amount of time (in seconds) allocated for each of these checks, +# when used (none are enabled by default), is controlled by the +# Whitelist_Lookup_Time parameter. It defaults to 10 seconds and is applied +# independently to each whitelisting method in use. +# Whitelist_Lookup_Time = 10 + +# RFC 7208 adds a new processing limit called "void lookup limit" (See section +# 4.6.4). Default is 2, but it can be adjusted. +# Void_Limit = 2 + +# In some versions of postfix, for bizarre Sendmail compatibility reasons, the +# first header field added by a policy server is not visible to milters. To +# make this easy to work around, set the Mock value to true and a fixed header +# field will be inserted so the actual SPF check will be the second field and +# visible to milters such as DMARC milter. +# Mock = False From 41f4fc14475ba08fb4d0f3fe6f269e0103dc2172 Mon Sep 17 00:00:00 2001 From: Mar Alegre Date: Mon, 12 Aug 2024 18:23:07 -0400 Subject: [PATCH 2/8] more stringent checking --- mailsrv/assets/postfix/policyd-spf.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mailsrv/assets/postfix/policyd-spf.conf b/mailsrv/assets/postfix/policyd-spf.conf index c908fe3..9471260 100644 --- a/mailsrv/assets/postfix/policyd-spf.conf +++ b/mailsrv/assets/postfix/policyd-spf.conf @@ -16,7 +16,7 @@ TestOnly = 1 # HELO_reject = Null - Only reject HELO Fail for Null sender (SPF Classic) # HELO_reject = False - Never reject/defer on HELO, append header only. # HELO_reject = No_Check - Never check HELO. -HELO_reject = Fail +HELO_reject = Softfail # HELO pass restriction policy. # HELO_pass_restriction = helo_passed_spf - Apply the given restriction when @@ -30,7 +30,7 @@ HELO_reject = Fail # Mail_From_reject = Fail - Reject on Mail From Fail (default) # Mail_From_reject = False - Never reject/defer on Mail From, append header only # Mail_From_reject = No_Check - Never check Mail From/Return Path. -Mail_From_reject = Fail +Mail_From_reject = Softfail # Reject only from domains that send no mail. Options are: # No_Mail = False - Normal SPF record processing (default) @@ -52,7 +52,7 @@ Mail_From_reject = Fail # Policy for rejecting due to SPF PermError. Options are: # PermError_reject = True # PermError_reject = False -PermError_reject = False +PermError_reject = True # Policy for deferring messages due to SPF TempError. Options are: # TempError_Defer = True From 95fa44196da984af58e818c0e30f1206edd09d7d Mon Sep 17 00:00:00 2001 From: Mar Alegre Date: Thu, 22 Aug 2024 12:25:45 -0400 Subject: [PATCH 3/8] be less strict about SPF --- mailsrv/assets/postfix/policyd-spf.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mailsrv/assets/postfix/policyd-spf.conf b/mailsrv/assets/postfix/policyd-spf.conf index 9471260..c908fe3 100644 --- a/mailsrv/assets/postfix/policyd-spf.conf +++ b/mailsrv/assets/postfix/policyd-spf.conf @@ -16,7 +16,7 @@ TestOnly = 1 # HELO_reject = Null - Only reject HELO Fail for Null sender (SPF Classic) # HELO_reject = False - Never reject/defer on HELO, append header only. # HELO_reject = No_Check - Never check HELO. -HELO_reject = Softfail +HELO_reject = Fail # HELO pass restriction policy. # HELO_pass_restriction = helo_passed_spf - Apply the given restriction when @@ -30,7 +30,7 @@ HELO_reject = Softfail # Mail_From_reject = Fail - Reject on Mail From Fail (default) # Mail_From_reject = False - Never reject/defer on Mail From, append header only # Mail_From_reject = No_Check - Never check Mail From/Return Path. -Mail_From_reject = Softfail +Mail_From_reject = Fail # Reject only from domains that send no mail. Options are: # No_Mail = False - Normal SPF record processing (default) @@ -52,7 +52,7 @@ Mail_From_reject = Softfail # Policy for rejecting due to SPF PermError. Options are: # PermError_reject = True # PermError_reject = False -PermError_reject = True +PermError_reject = False # Policy for deferring messages due to SPF TempError. Options are: # TempError_Defer = True From 6d7acfba526ae940b6211d0e44ab78bdbf5ae887 Mon Sep 17 00:00:00 2001 From: Mar Alegre Date: Thu, 22 Aug 2024 12:28:23 -0400 Subject: [PATCH 4/8] ok I give up, use the spamhaus list even though it has problems --- mailsrv/assets/postfix/main.cf.part | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mailsrv/assets/postfix/main.cf.part b/mailsrv/assets/postfix/main.cf.part index 5562eb8..8821ee5 100644 --- a/mailsrv/assets/postfix/main.cf.part +++ b/mailsrv/assets/postfix/main.cf.part @@ -80,10 +80,10 @@ smtpd_client_restrictions = # check if sender meets SPF policy for its domain check_policy_service unix:private/policy-spf, # reject clients from lists of known spammers -# reject_rbl_client zen.spamhaus.org, -# reject_rhsbl_reverse_client dbl.spamhaus.org, -# reject_rhsbl_helo dbl.spamhaus.org, -# reject_rhsbl_sender dbl.spamhaus.org, + reject_rbl_client zen.spamhaus.org, + reject_rhsbl_reverse_client dbl.spamhaus.org, + reject_rhsbl_helo dbl.spamhaus.org, + reject_rhsbl_sender dbl.spamhaus.org, permit ### Misc ### From 79e053cdb01e31aa49127cb7df6fe97526e48afe Mon Sep 17 00:00:00 2001 From: Fernando Alegre Date: Fri, 18 Oct 2024 09:20:01 -0500 Subject: [PATCH 5/8] dry-run option for pdm-launch --- .install/bin/pdm-launch | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/.install/bin/pdm-launch b/.install/bin/pdm-launch index 696689c..82d1ff0 100755 --- a/.install/bin/pdm-launch +++ b/.install/bin/pdm-launch @@ -9,33 +9,36 @@ badarg() { exit 2 } -help="Usage: $(basename $0) [-fch] [-l label] [-e options] image [container] +help="Usage: $(basename $0) [-fcdh] [-l label] [-e options] image [container] Create and start a container from a local image, and assign it the given name. If second argument is omitted, defaults to assigning the container the same name as the image. Options: - -f Force overwrite if a container with the given name already exists -c Configure the container with deploy options stored in the image metadata. By default, uses the metadata tag labeled 'config_default' - -l [label] Label from which to get the deploy options. Automatically sets -c + -d Dry-run -e [options] Extra deploy options to assign to the container. If -e and -c are both used, options from image metadata and command line are combined + -f Force overwrite if a container with the given name already exists + -l [label] Label from which to get the deploy options. Automatically sets -c -h Display this help and exit" # Handle options opt_force=0 +opt_dryrun=0 opt_config=0 opt_label='config_default' opt_extras='' -while getopts ':fcl:e:h' arg; do +while getopts ':fcdl:e:h' arg; do case $arg in - f) opt_force=1;; c) opt_config=1;; - l) opt_config=1; opt_label="${OPTARG}";; + d) opt_dryrun=1;; e) opt_extras="${OPTARG}";; + f) opt_force=1;; h) echo "$help"; exit 0;; + l) opt_config=1; opt_label="${OPTARG}";; :) badarg "Argument missing for option '-$OPTARG'";; ?) badarg "Invalid option '-$OPTARG'";; esac @@ -76,5 +79,9 @@ if [[ $opt_force -eq 1 ]]; then podman rm -i -f "$container" fi -podman run -itd --name "$container" --hostname "$container" $deployconf "$image" -echo "Done!" +if [[ $opt_dryrun -eq 1 ]]; then + echo podman run -itd --name "$container" --hostname "$container" $deployconf "$image" +else + podman run -itd --name "$container" --hostname "$container" $deployconf "$image" +fi + From 08752e13c730b914c413007493af225dd99eb92c Mon Sep 17 00:00:00 2001 From: Fernando Alegre Date: Fri, 18 Oct 2024 09:22:07 -0500 Subject: [PATCH 6/8] bugfix: nextcloud handling of psql config; skip download if latest.zip exists --- nextcloud/Containerfile | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/nextcloud/Containerfile b/nextcloud/Containerfile index d35e3e5..11aa188 100644 --- a/nextcloud/Containerfile +++ b/nextcloud/Containerfile @@ -7,8 +7,8 @@ FROM localhost/debian # -p (port) and -v (volume) both go host:container LABEL config_default="\ -p 9080:80 \ --v /srv/vol/nextcloud/files:/vol/files \ --v /srv/vol/nextcloud/data:/vol/data +-v $HOME/vol/nextcloud/files:/vol/files \ +-v $HOME/vol/nextcloud/data:/vol/data \ --shm-size=1g" # Build Variables @@ -66,12 +66,12 @@ RUN mv php/php.ini /etc/php/${PHPV:?}/fpm/ && \ ### # configure PostgreSQL -COPY --chown=postgres:postgres assets/postgresql ./ +COPY --chown=postgres:postgres assets/postgresql/ postgresql/ # If the posgresql.conf file contains multiple entries for the same parameter, all but the last one is ignored. # So we can just append our settings to the already-existing postgresql.conf file. -RUN mv postgresql/pg_hba.conf /etc/postgresql/${PSQLV:?}/main/ & \ - cat postgresql/postgresql.conf >> /etc/postgresql/${PSQLV:?}/main/postgresql.conf - +RUN mv postgresql/pg_hba.conf /etc/postgresql/${PSQLV:?}/main/ && \ + cat postgresql/postgresql.conf >> /etc/postgresql/${PSQLV:?}/main/postgresql.conf && \ + rm -rf postgresql ### @@ -101,12 +101,16 @@ RUN usermod -a -G redis www-data ### # download nextcloud +COPY assets/nextcloud/ ./ +RUN test -f latest.zip || \ + wget --progress=dot:giga https://download.nextcloud.com/server/releases/latest.zip + + WORKDIR /var/www/html -RUN wget --progress=dot:giga https://download.nextcloud.com/server/releases/latest.zip && \ - echo "Unzipping ..." && \ - unzip -q latest.zip && \ +RUN echo "Unzipping ..." && \ + unzip -q $HOME/latest.zip && \ chown -R www-data:www-data nextcloud && \ - rm latest.zip + rm $HOME/latest.zip # create data dir for nextcloud RUN mkdir -p /vol/files && \ From 362903e003063f87bcb34b89f2a14c9e9997aa69 Mon Sep 17 00:00:00 2001 From: Fernando Alegre Date: Fri, 18 Oct 2024 09:24:43 -0500 Subject: [PATCH 7/8] bugfix: make database owned by ncadmin to prevent occ to fail --- nextcloud/assets/bin/db-make | 1 + 1 file changed, 1 insertion(+) diff --git a/nextcloud/assets/bin/db-make b/nextcloud/assets/bin/db-make index 7a230d6..e0aba59 100755 --- a/nextcloud/assets/bin/db-make +++ b/nextcloud/assets/bin/db-make @@ -9,4 +9,5 @@ cmd "DROP DATABASE IF EXISTS ${DBNAME:?};" cmd "DROP USER IF EXISTS ${DBUSER:?};" cmd "CREATE USER ${DBUSER:?};" cmd "CREATE DATABASE ${DBNAME:?};" +cmd "ALTER DATABASE ${DBNAME:?} OWNER TO ${DBUSER:?};" cmd "GRANT ALL PRIVILEGES ON DATABASE ${DBNAME:?} TO ${DBUSER:?};" From a8ca6686dc6839c44cf398eeb1f0203817a30c61 Mon Sep 17 00:00:00 2001 From: Fernando Alegre Date: Fri, 18 Oct 2024 09:46:53 -0500 Subject: [PATCH 8/8] feat: place versions here --- nextcloud/assets/nextcloud/.versions | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 nextcloud/assets/nextcloud/.versions diff --git a/nextcloud/assets/nextcloud/.versions b/nextcloud/assets/nextcloud/.versions new file mode 100644 index 0000000..e69de29