You've already forked docker-mailserver
							
							
				mirror of
				https://github.com/docker-mailserver/docker-mailserver.git
				synced 2025-10-31 00:17:45 +02:00 
			
		
		
		
	ci(fix): Normalize for .gitattributes + improve eclint coverage (#3566)
				
					
				
			This commit is contained in:
		| @@ -8,6 +8,7 @@ root = true | ||||
| [*] | ||||
| charset = utf-8 | ||||
| end_of_line = lf | ||||
| indent_size = 2 | ||||
| indent_style = space | ||||
| insert_final_newline = true | ||||
| trim_trailing_whitespace = true | ||||
| @@ -16,21 +17,9 @@ trim_trailing_whitespace = true | ||||
| # --- Specific ---------------------------------- | ||||
| # ----------------------------------------------- | ||||
|  | ||||
| [*.{yaml,yml,sh,bats}] | ||||
| indent_size = 2 | ||||
|  | ||||
| [Makefile] | ||||
| [{Makefile,.gitmodules}] | ||||
| indent_style = tab | ||||
| indent_size = 4 | ||||
|  | ||||
| [*.md] | ||||
| trim_trailing_whitespace = false | ||||
|  | ||||
| # ----------------------------------------------- | ||||
| # --- Git Submodules ---------------------------- | ||||
| # ----------------------------------------------- | ||||
|  | ||||
| [{test/bats/**,test/test_helper/**}] | ||||
| indent_style = none | ||||
| indent_size = none | ||||
| end_of_line = none | ||||
|   | ||||
							
								
								
									
										6
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/pull_request_template.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1,9 @@ | ||||
| # Description | ||||
|  | ||||
| <!-- Include a summary of the change. | ||||
|      Please also include relevant motivation and context. --> | ||||
| <!-- | ||||
|   Include a summary of the change. | ||||
|   Please also include relevant motivation and context. | ||||
| --> | ||||
|  | ||||
| <!-- Link the issue which will be fixed (if any) here: --> | ||||
| Fixes # | ||||
|   | ||||
| @@ -311,8 +311,8 @@ In this release the relay-host support saw [significant internal refactoring](ht | ||||
|  | ||||
| 1. **Many** minor improvements were made (cleanup & refactoring). Please refer to the section below to get an overview over all improvements. Moreover, there was a lot of cleanup in the scripts and in the tests. The documentation was adjusted accordingly. | ||||
| 2. New environment variables were added: | ||||
|    1. [`CLAMAV_MESSAGE_SIZE_LIMIT`](https://docker-mailserver.github.io/docker-mailserver/v11.0/config/environment/#clamav_message_size_limit) | ||||
|    2. [`TZ`](https://docker-mailserver.github.io/docker-mailserver/v11.0/config/environment/#tz) | ||||
|     1. [`CLAMAV_MESSAGE_SIZE_LIMIT`](https://docker-mailserver.github.io/docker-mailserver/v11.0/config/environment/#clamav_message_size_limit) | ||||
|     2. [`TZ`](https://docker-mailserver.github.io/docker-mailserver/v11.0/config/environment/#tz) | ||||
| 3. SpamAssassin KAM was added with [`ENABLE_SPAMASSASSIN_KAM`](https://docker-mailserver.github.io/docker-mailserver/v11.0/config/environment/#enable_spamassassin_kam). | ||||
| 4. The `fail2ban` command was reworked and can now ban IP addresses as well. | ||||
| 5. There were a few small fixes, especially when it comes to bugs in scripts and service restart loops (no functionality changes, only fixes of existing functionality). When building an image from the Dockerfile - Installation of Postfix on modern Linux distributions should now always succeed. | ||||
| @@ -368,8 +368,7 @@ In this release the relay-host support saw [significant internal refactoring](ht | ||||
|  | ||||
| ### Critical Changes | ||||
|  | ||||
| 1. This release fixes a critical issue for LDAP users, installing a needed package on Debian 11 | ||||
|    on build-time. Moreover, a race-condition was eliminated ([#2341](https://github.com/docker-mailserver/docker-mailserver/pull/2341)). | ||||
| 1. This release fixes a critical issue for LDAP users, installing a needed package on Debian 11 on build-time. Moreover, a race-condition was eliminated ([#2341](https://github.com/docker-mailserver/docker-mailserver/pull/2341)). | ||||
| 2. A resource leak in `check-for-changes.sh` was fixed ([#2401](https://github.com/docker-mailserver/docker-mailserver/pull/2401)) | ||||
|  | ||||
| ### Other Minor Changes | ||||
|   | ||||
| @@ -134,9 +134,7 @@ EOF | ||||
|  | ||||
| COPY target/postsrsd/postsrsd /etc/default/postsrsd | ||||
| COPY target/postgrey/postgrey /etc/default/postgrey | ||||
| COPY target/postgrey/postgrey.init /etc/init.d/postgrey | ||||
| RUN <<EOF | ||||
|   chmod 755 /etc/init.d/postgrey | ||||
|   mkdir /var/run/postgrey | ||||
|   chown postgrey:postgrey /var/run/postgrey | ||||
|   curl -Lsfo /etc/postgrey/whitelist_clients https://postgrey.schweikert.ch/pub/postgrey_whitelist_clients | ||||
|   | ||||
| @@ -18,4 +18,4 @@ Once a master account is configured, it is possible to connect to any users mail | ||||
|  | ||||
| Username: `<EMAIL ADDRESS>*<MASTER ACCOUNT NAME>` | ||||
|  | ||||
| Password: `<MASTER ACCOUNT PASSWORD>` | ||||
| Password: `<MASTER ACCOUNT PASSWORD>` | ||||
|   | ||||
| @@ -132,7 +132,7 @@ Next, configure a network with an IPv6 subnet for your container with any of the | ||||
|  | ||||
|         !!! warning "This approach is discouraged" | ||||
|  | ||||
|              The [`bridge` network is considered legacy][docker-docs-network-bridge-legacy]. | ||||
|             The [`bridge` network is considered legacy][docker-docs-network-bridge-legacy]. | ||||
|  | ||||
|         Add these two extra IPv6 settings to your daemon config. They only apply to the [default `bridge` docker network][docker-docs-ipv6-create-default] aka `docker0` (_which containers are attached to by default when using `docker run`_). | ||||
|  | ||||
|   | ||||
| @@ -69,12 +69,12 @@ It is possible to sort subaddresses such as `user+mailing-lists@example.com` int | ||||
| require ["envelope", "fileinto", "mailbox", "subaddress", "variables"]; | ||||
|  | ||||
| if envelope :detail :matches "to" "*" { | ||||
| 	set :lower :upperfirst "tag" "${1}"; | ||||
| 	if mailboxexists "INBOX.${1}" { | ||||
| 		fileinto "INBOX.${1}"; | ||||
| 	} else { | ||||
| 		fileinto :create "INBOX.${tag}"; | ||||
| 	} | ||||
|   set :lower :upperfirst "tag" "${1}"; | ||||
|   if mailboxexists "INBOX.${1}" { | ||||
|     fileinto "INBOX.${1}"; | ||||
|   } else { | ||||
|     fileinto :create "INBOX.${tag}"; | ||||
|   } | ||||
| } | ||||
| ``` | ||||
|  | ||||
|   | ||||
| @@ -161,8 +161,9 @@ Obtain a Cloudflare API token: | ||||
|     dns_cloudflare_api_token = YOUR_CLOUDFLARE_TOKEN_HERE | ||||
|     ``` | ||||
|  | ||||
|    - As this is sensitive data, you should restrict access to it with `chmod 600` and `chown 0:0`. | ||||
|    - Store the file in a folder if you like, such as `docker-data/certbot/secrets/`. | ||||
|     - As this is sensitive data, you should restrict access to it with `chmod 600` and `chown 0:0`. | ||||
|     - Store the file in a folder if you like, such as `docker-data/certbot/secrets/`. | ||||
|  | ||||
| 5. Your `compose.yaml` should include the following: | ||||
|  | ||||
|     ```yaml | ||||
| @@ -594,7 +595,7 @@ This setup only comes with one caveat: The domain has to be configured on anothe | ||||
|         container_name: mailserver | ||||
|         hostname: mail.example.com | ||||
|         volumes: | ||||
|            - ./docker-data/traefik/acme.json:/etc/letsencrypt/acme.json:ro | ||||
|           - ./docker-data/traefik/acme.json:/etc/letsencrypt/acme.json:ro | ||||
|         environment: | ||||
|           SSL_TYPE: letsencrypt | ||||
|           SSL_DOMAIN: mail.example.com | ||||
| @@ -605,26 +606,26 @@ This setup only comes with one caveat: The domain has to be configured on anothe | ||||
|         image: docker.io/traefik:latest #v2.5 | ||||
|         container_name: docker-traefik | ||||
|         ports: | ||||
|            - "80:80" | ||||
|            - "443:443" | ||||
|           - "80:80" | ||||
|           - "443:443" | ||||
|         command: | ||||
|            - --providers.docker | ||||
|            - --entrypoints.http.address=:80 | ||||
|            - --entrypoints.http.http.redirections.entryPoint.to=https | ||||
|            - --entrypoints.http.http.redirections.entryPoint.scheme=https | ||||
|            - --entrypoints.https.address=:443 | ||||
|            - --entrypoints.https.http.tls.certResolver=letsencrypt | ||||
|            - --certificatesresolvers.letsencrypt.acme.email=admin@example.com | ||||
|            - --certificatesresolvers.letsencrypt.acme.storage=/acme.json | ||||
|            - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http | ||||
|           - --providers.docker | ||||
|           - --entrypoints.http.address=:80 | ||||
|           - --entrypoints.http.http.redirections.entryPoint.to=https | ||||
|           - --entrypoints.http.http.redirections.entryPoint.scheme=https | ||||
|           - --entrypoints.https.address=:443 | ||||
|           - --entrypoints.https.http.tls.certResolver=letsencrypt | ||||
|           - --certificatesresolvers.letsencrypt.acme.email=admin@example.com | ||||
|           - --certificatesresolvers.letsencrypt.acme.storage=/acme.json | ||||
|           - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http | ||||
|         volumes: | ||||
|            - ./docker-data/traefik/acme.json:/acme.json | ||||
|            - /var/run/docker.sock:/var/run/docker.sock:ro | ||||
|           - ./docker-data/traefik/acme.json:/acme.json | ||||
|           - /var/run/docker.sock:/var/run/docker.sock:ro | ||||
|  | ||||
|       whoami: | ||||
|         image: docker.io/traefik/whoami:latest | ||||
|         labels: | ||||
|            - "traefik.http.routers.whoami.rule=Host(`mail.example.com`)" | ||||
|           - "traefik.http.routers.whoami.rule=Host(`mail.example.com`)" | ||||
|     ``` | ||||
|  | ||||
| ### Self-Signed Certificates | ||||
|   | ||||
| @@ -85,10 +85,10 @@ In this example, you've made a change to the Rspamd feature support (_or adjuste | ||||
| ```console | ||||
| $ make clean generate-accounts test/rspamd | ||||
| rspamd.bats | ||||
|  ✓ [Rspamd] Postfix's main.cf was adjusted [12] | ||||
|  ✓ [Rspamd] normal mail passes fine [44] | ||||
|  ✓ [Rspamd] detects and rejects spam [122] | ||||
|  ✓ [Rspamd] detects and rejects virus [189] | ||||
|   ✓ [Rspamd] Postfix's main.cf was adjusted [12] | ||||
|   ✓ [Rspamd] normal mail passes fine [44] | ||||
|   ✓ [Rspamd] detects and rejects spam [122] | ||||
|   ✓ [Rspamd] detects and rejects virus [189] | ||||
| ``` | ||||
|  | ||||
| As your feature work progresses your change for Rspamd also affects ClamAV. As your change now spans more than just the Rspamd test file, you could run multiple test files serially: | ||||
| @@ -96,16 +96,17 @@ As your feature work progresses your change for Rspamd also affects ClamAV. As y | ||||
| ```console | ||||
| $ make clean generate-accounts test/rspamd,clamav | ||||
| rspamd.bats | ||||
|  ✓ [Rspamd] Postfix's main.cf was adjusted [12] | ||||
|  ✓ [Rspamd] normal mail passes fine [44] | ||||
|  ✓ [Rspamd] detects and rejects spam [122] | ||||
|  ✓ [Rspamd] detects and rejects virus [189] | ||||
|   ✓ [Rspamd] Postfix's main.cf was adjusted [12] | ||||
|   ✓ [Rspamd] normal mail passes fine [44] | ||||
|   ✓ [Rspamd] detects and rejects spam [122] | ||||
|   ✓ [Rspamd] detects and rejects virus [189] | ||||
|  | ||||
| clamav.bats | ||||
|  ✓ [ClamAV] log files exist at /var/log/mail directory [68] | ||||
|  ✓ [ClamAV] should be identified by Amavis [67] | ||||
|  ✓ [ClamAV] freshclam cron is enabled [76] | ||||
|  ✓ [ClamAV] env CLAMAV_MESSAGE_SIZE_LIMIT is set correctly [63] | ||||
|  ✓ [ClamAV] rejects virus [60] | ||||
|   ✓ [ClamAV] log files exist at /var/log/mail directory [68] | ||||
|   ✓ [ClamAV] should be identified by Amavis [67] | ||||
|   ✓ [ClamAV] freshclam cron is enabled [76] | ||||
|   ✓ [ClamAV] env CLAMAV_MESSAGE_SIZE_LIMIT is set correctly [63] | ||||
|   ✓ [ClamAV] rejects virus [60] | ||||
| ``` | ||||
|  | ||||
| You're almost finished with your change before submitting it as a PR. It's a good idea to run the full parallel set those individual tests belong to (_especially if you've modified any tests_): | ||||
| @@ -113,13 +114,15 @@ You're almost finished with your change before submitting it as a PR. It's a goo | ||||
| ```console | ||||
| $ make clean generate-accounts tests/parallel/set1 | ||||
| default_relay_host.bats | ||||
|  ✓ [Relay] (ENV) 'DEFAULT_RELAY_HOST' should configure 'main.cf:relayhost' [88] | ||||
|   ✓ [Relay] (ENV) 'DEFAULT_RELAY_HOST' should configure 'main.cf:relayhost' [88] | ||||
|  | ||||
| spam_virus/amavis.bats | ||||
|  ✓ [Amavis] SpamAssassin integration should be active [1165] | ||||
|   ✓ [Amavis] SpamAssassin integration should be active [1165] | ||||
|  | ||||
| spam_virus/clamav.bats | ||||
|  ✓ [ClamAV] log files exist at /var/log/mail directory [73] | ||||
|  ✓ [ClamAV] should be identified by Amavis [67] | ||||
|  ✓ [ClamAV] freshclam cron is enabled [76] | ||||
|   ✓ [ClamAV] log files exist at /var/log/mail directory [73] | ||||
|   ✓ [ClamAV] should be identified by Amavis [67] | ||||
|   ✓ [ClamAV] freshclam cron is enabled [76] | ||||
| ... | ||||
| ``` | ||||
|  | ||||
| @@ -127,7 +130,6 @@ Even better, before opening a PR run the full test suite: | ||||
|  | ||||
| ```console | ||||
| $ make clean tests | ||||
| ... | ||||
| ``` | ||||
|  | ||||
| [BATS]: https://github.com/bats-core/bats-core | ||||
|   | ||||
| @@ -511,8 +511,9 @@ require ["comparator-i;ascii-numeric","relational","fileinto"]; | ||||
| if header :contains "X-Spam-Flag" "YES" { | ||||
|   fileinto "Junk"; | ||||
| } elsif allof ( | ||||
|    not header :matches "x-spam-score" "-*", | ||||
|    header :value "ge" :comparator "i;ascii-numeric" "x-spam-score" "3.75" ) { | ||||
|   not header :matches "x-spam-score" "-*", | ||||
|   header :value "ge" :comparator "i;ascii-numeric" "x-spam-score" "3.75" | ||||
| ) { | ||||
|   fileinto "Junk"; | ||||
| } | ||||
| ``` | ||||
|   | ||||
| @@ -43,10 +43,10 @@ Here's where DMS's toolchain fits within the delivery chain: | ||||
|  | ||||
| ```txt | ||||
|                                     docker-mailserver is here: | ||||
|                                                          ┏━━━━━━━┓ | ||||
| Sending an email:    MUA ---> MTA ---> (MTA relays) ---> ┫ MTA ╮ ┃ | ||||
| Fetching an email:   MUA <------------------------------ ┫ MDA ╯ ┃ | ||||
|                                                          ┗━━━━━━━┛ | ||||
|                                                         ┏━━━━━━━┓ | ||||
| Sending an email:   MUA ---> MTA ---> (MTA relays) ---> ┫ MTA ╮ ┃ | ||||
| Fetching an email:  MUA <------------------------------ ┫ MDA ╯ ┃ | ||||
|                                                         ┗━━━━━━━┛ | ||||
| ``` | ||||
|  | ||||
| ??? example "An Example" | ||||
| @@ -86,18 +86,18 @@ When it comes to the specifics of email exchange, we have to look at protocols a | ||||
| The following picture gives a visualization of the interplay of all components and their [respective ports][docs-understandports]: | ||||
|  | ||||
| ```txt | ||||
|  ┏━━━━━━━━━━ Submission ━━━━━━━━━━━━┓┏━━━━━━━━━━━━━ Transfer/Relay ━━━━━━━━━━━┓ | ||||
|   ┏━━━━━━━━━━ Submission ━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━ Transfer/Relay ━━━━━━━━━━━┓ | ||||
|  | ||||
|                            ┌─────────────────────┐                    ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐ | ||||
| MUA ----- STARTTLS ------> ┤(587)   MTA ╮    (25)├ <-- cleartext ---> ┊ Third-party MTA ┊ | ||||
|     ----- implicit TLS --> ┤(465)       │        |                    └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘ | ||||
|     ----- cleartext -----> ┤(25)        │        | | ||||
|                            |┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄| | ||||
| MUA <---- STARTTLS ------- ┤(143)   MDA ╯        | | ||||
|     <---- implicit TLS --- ┤(993)                | | ||||
|                            └─────────────────────┘ | ||||
|                             ┌─────────────────────┐                    ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐ | ||||
| MUA ----- STARTTLS -------> ┤(587)   MTA ╮    (25)├ <-- cleartext ---> ┊ Third-party MTA ┊ | ||||
|     ----- implicit TLS ---> ┤(465)       │        |                    └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘ | ||||
|     ----- cleartext ------> ┤(25)        │        | | ||||
|                             |┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄| | ||||
| MUA <---- STARTTLS -------- ┤(143)   MDA ╯        | | ||||
|     <---- implicit TLS ---- ┤(993)                | | ||||
|                             └─────────────────────┘ | ||||
|  | ||||
|  ┗━━━━━━━━━━ Retrieval ━━━━━━━━━━━━━┛ | ||||
|   ┗━━━━━━━━━━ Retrieval ━━━━━━━━━━━━━━┛ | ||||
| ``` | ||||
|  | ||||
| If you're new to email infrastructure, both that table and the schema may be confusing. | ||||
| @@ -124,7 +124,7 @@ My MTA will thus have to support two kinds of Submission: | ||||
| - Inbound Submission (third-party email has been submitted & relayed, then is accepted "inside" by the MTA) | ||||
|  | ||||
| ```txt | ||||
|  ┏━━━━ Outbound Submission ━━━━┓ | ||||
|   ┏━━━ Outbound Submission ━━━┓ | ||||
|  | ||||
|                     ┌────────────────────┐                    ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐ | ||||
| Me ---------------> ┤                    ├ -----------------> ┊                 ┊ | ||||
| @@ -132,7 +132,7 @@ Me ---------------> ┤                    ├ -----------------> ┊ | ||||
|                     │                    ├ <----------------- ┊                 ┊ | ||||
|                     └────────────────────┘                    └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘ | ||||
|  | ||||
|                                ┗━━━━━━━━━━ Inbound Submission ━━━━━━━━━━┛ | ||||
|                               ┗━━━━━━━━━━ Inbound Submission ━━━━━━━━━━┛ | ||||
| ``` | ||||
|  | ||||
| #### Outbound Submission | ||||
| @@ -168,7 +168,7 @@ Granted it's still very difficult enforcing encryption between MTAs (Transfer/Re | ||||
| Overall, DMS's default configuration for SMTP looks like this: | ||||
|  | ||||
| ```txt | ||||
|  ┏━━━━ Outbound Submission ━━━━┓ | ||||
|   ┏━━━ Outbound Submission ━━━┓ | ||||
|  | ||||
|                     ┌────────────────────┐                    ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐ | ||||
| Me -- cleartext --> ┤(25)            (25)├ --- cleartext ---> ┊                 ┊ | ||||
| @@ -177,7 +177,7 @@ Me -- STARTTLS ---> ┤(587)               │                    ┊ | ||||
|                     │                (25)├ <---cleartext ---- ┊                 ┊ | ||||
|                     └────────────────────┘                    └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘ | ||||
|  | ||||
|                                ┗━━━━━━━━━━ Inbound Submission ━━━━━━━━━━┛ | ||||
|                               ┗━━━━━━━━━━ Inbound Submission ━━━━━━━━━━┛ | ||||
| ``` | ||||
|  | ||||
| ### Retrieval - IMAP | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| use strict; | ||||
|  | ||||
| @local_domains_maps = ( | ||||
|    read_hash('/etc/postfix/vhost') | ||||
|   read_hash('/etc/postfix/vhost') | ||||
| ); | ||||
|  | ||||
| 1;  # ensure a defined return | ||||
|   | ||||
| @@ -42,8 +42,8 @@ ${ORANGE}OPTIONS${RESET} | ||||
|         selector  Set a manual selector for the key. | ||||
|                   Default: mail | ||||
|         domain    Provide the domain(s) for which to generate keys for. | ||||
|                   Default: The FQDN assigned to DMS, excluding any subdomain. | ||||
|                            'ACCOUNT_PROVISIONER=FILE' also sources domains from mail accounts. | ||||
|                   Default:  The FQDN assigned to DMS, excluding any subdomain. | ||||
|                             'ACCOUNT_PROVISIONER=FILE' also sources domains from mail accounts. | ||||
|  | ||||
| ${ORANGE}EXAMPLES${RESET} | ||||
|     ${LWHITE}setup config dkim keysize 4096${RESET} | ||||
|   | ||||
| @@ -1,154 +0,0 @@ | ||||
| #! /bin/sh | ||||
|  | ||||
| # postgrey      start/stop the postgrey greylisting deamon for postfix | ||||
| #               (priority should be smaller than that of postfix) | ||||
| # | ||||
| # Author:       (c)2004-2006 Adrian von Bidder <avbidder@fortytwo.ch> | ||||
| #               Based on Debian sarge's 'skeleton' example | ||||
| #               Distribute and/or modify at will. | ||||
| # | ||||
| # Version:      $Id: postgrey.init 1436 2006-12-07 07:15:03Z avbidder $ | ||||
| #               altered by Georg Lauterbach as aendeavor 2020-11.05 14:02:00Z | ||||
|  | ||||
| ### BEGIN INIT INFO | ||||
| # Provides:          postgrey | ||||
| # Required-Start:    $syslog $local_fs $remote_fs | ||||
| # Required-Stop:     $syslog $local_fs $remote_fs | ||||
| # Default-Start:     2 3 4 5 | ||||
| # Default-Stop:      0 1 6 | ||||
| # Short-Description: Start/stop the postgrey daemon | ||||
| ### END INIT INFO | ||||
|  | ||||
| set -e | ||||
|  | ||||
| PATH='/sbin:/bin:/usr/sbin:/usr/bin' | ||||
| DAEMON='/usr/sbin/postgrey' | ||||
| DAEMON_NAME='postgrey' | ||||
| DESC='postfix greylisting daemon' | ||||
| DAEMON_USER='postgrey' | ||||
|  | ||||
| PIDFILE="/var/run/${DAEMON_NAME}/${DAEMON_NAME}.pid" | ||||
| SCRIPTNAME="/etc/init.d/${DAEMON_NAME}" | ||||
|  | ||||
| # gracefully exit if the package has been removed. | ||||
| [ -x "${DAEMON}" ] || exit 0 | ||||
|  | ||||
| # shellcheck source=/dev/null | ||||
| . /lib/lsb/init-functions | ||||
|  | ||||
| # Read config file if it is present. | ||||
| # shellcheck source=/dev/null | ||||
| [ -r "/etc/default/${DAEMON_NAME}" ] && . "/etc/default/${DAEMON_NAME}" | ||||
|  | ||||
| POSTGREY_OPTS="--pidfile=${PIDFILE} --daemonize ${POSTGREY_OPTS}" | ||||
|  | ||||
| if [ -z "${POSTGREY_TEXT}" ]; then | ||||
|     POSTGREY_TEXT_OPT="" | ||||
| else | ||||
|     POSTGREY_TEXT_OPT="--greylist-text=${POSTGREY_TEXT}" | ||||
| fi | ||||
|  | ||||
| ret=0 | ||||
|  | ||||
| do_start() | ||||
| { | ||||
|     # Return | ||||
|     #   0 if daemon has been started | ||||
|     #   1 if daemon was already running | ||||
|     #   2 if daemon could not be started | ||||
|     start-stop-daemon --start --quiet --pidfile \ | ||||
| 		"${PIDFILE}" --exec "${DAEMON}" --test >/dev/null  || return 1 | ||||
|  | ||||
| 	start-stop-daemon --start --quiet --pidfile \ | ||||
| 		"${PIDFILE}" --exec "${DAEMON}" -- "${POSTGREY_OPTS}" \ | ||||
| 		"${POSTGREY_TEXT_OPT}" || return 2 | ||||
| } | ||||
|  | ||||
| do_stop() | ||||
| { | ||||
| 	# Return | ||||
| 	#   0 if daemon has been stopped | ||||
| 	#   1 if daemon was already stopped | ||||
| 	#   2 if daemon could not be stopped | ||||
| 	#   other if a failure occurred | ||||
|     start-stop-daemon --user "${DAEMON_USER}" --stop --quiet \ | ||||
| 		--retry=TERM/30/KILL/5 --pidfile "${PIDFILE}" | ||||
|  | ||||
| 	RETVAL="$?" | ||||
|     [ "${RETVAL}" -eq 2 ] && return 2 | ||||
|  | ||||
| 	# Wait for children to finish too if this is a daemon that forks | ||||
| 	# and if the daemon is only ever run from this initscript. | ||||
| 	# If the above conditions are not satisfied then add some other code | ||||
| 	# that waits for the process to drop all resources that could be | ||||
| 	# needed by services started subsequently.  A last resort is to | ||||
| 	# sleep for some time. | ||||
| 	start-stop-daemon --user "${DAEMON_USER}" --stop --quiet \ | ||||
| 		--oknodo --retry=0/30/KILL/5 --exec "${DAEMON}" | ||||
| 	[ "$?" -eq 2 ] && return 2 | ||||
|  | ||||
| 	# Many daemons don't delete their pidfiles when they exit. | ||||
| 	rm -f "${PIDFILE}" | ||||
| 	return "${RETVAL}" | ||||
| } | ||||
|  | ||||
| do_reload() | ||||
| { | ||||
| 	# | ||||
| 	# If the daemon can reload its configuration without | ||||
| 	# restarting (for example, when it is sent a SIGHUP), | ||||
| 	# then implement that here. | ||||
| 	# | ||||
| 	start-stop-daemon --stop --signal 1 --quiet --pidfile "${PIDFILE}" | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| case "${1}" in | ||||
|   start ) | ||||
| 	[ "${VERBOSE}" != no ] && log_daemon_msg "Starting ${DESC}" "${DAEMON_NAME}" | ||||
| 	do_start | ||||
|  | ||||
| 	case "${?}" in | ||||
| 		0|1) [ "${VERBOSE}" != no ] && log_end_msg 0 ;; | ||||
| 		2) [ "${VERBOSE}" != no ] && log_end_msg 1 ;; | ||||
| 	esac | ||||
|     ;; | ||||
|  | ||||
|   stop ) | ||||
| 	[ "${VERBOSE}" != no ] && log_daemon_msg "Stopping ${DESC}" "${DAEMON_NAME}" | ||||
|     do_stop | ||||
|  | ||||
| 	case "${?}" in | ||||
| 		0|1) [ "${VERBOSE}" != no ] && log_end_msg 0 ;; | ||||
| 		2) [ "${VERBOSE}" != no ] && log_end_msg 1 ;; | ||||
| 	esac | ||||
|     ;; | ||||
|  | ||||
|   reload|force-reload) | ||||
| 	[ "${VERBOSE}" != no ] && log_daemon_msg "Reloading ${DESC}" "${DAEMON_NAME}" | ||||
|     do_reload | ||||
|  | ||||
| 	case "${?}" in | ||||
| 		0|1) [ "${VERBOSE}" != no ] && log_end_msg 0 ;; | ||||
| 		2) [ "${VERBOSE}" != no ] && log_end_msg 1 ;; | ||||
| 	esac | ||||
|     ;; | ||||
|  | ||||
|   restart ) | ||||
|     do_stop | ||||
|     do_start | ||||
|     ;; | ||||
|  | ||||
|   status ) | ||||
|     status_of_proc -p "${PIDFILE}" "${DAEMON}" "${DAEMON_NAME}" 2>/dev/null | ||||
|     ret=${?} | ||||
|     ;; | ||||
|  | ||||
|   * ) | ||||
|     echo "Usage: ${SCRIPTNAME} {start|stop|restart|reload|force-reload|status}" >&2 | ||||
|     exit 1 | ||||
|     ;; | ||||
| esac | ||||
|  | ||||
| exit ${ret} | ||||
|  | ||||
| @@ -1,2 +1,2 @@ | ||||
| mail._domainkey	IN	TXT	( "v=DKIM1; k=rsa; " | ||||
| 	  "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzUJyyhq+TeT1wlIth5Z0yr7Ohd62n4rL5X3vRJO4EDyOEicJ73cjuaU4JLTYhbqmbNalOyXE9btS9I55Gv3RyomVBD1JpVTKdjVBUQug2L/ggw2dtt1FAn99svQWMs1XxmxiTR+sCEVkgKMmLSkCJuDCIfY/Bc9nlcng9+juB8wIDAQAB" )  ; ----- DKIM key mail for localhost.localdomain | ||||
|   "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzUJyyhq+TeT1wlIth5Z0yr7Ohd62n4rL5X3vRJO4EDyOEicJ73cjuaU4JLTYhbqmbNalOyXE9btS9I55Gv3RyomVBD1JpVTKdjVBUQug2L/ggw2dtt1FAn99svQWMs1XxmxiTR+sCEVkgKMmLSkCJuDCIfY/Bc9nlcng9+juB8wIDAQAB" )  ; ----- DKIM key mail for localhost.localdomain | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| mail._domainkey	IN	TXT	( "v=DKIM1; k=rsa; " | ||||
| 	  "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCurRsOh4NyTOqDnpPlPLGlQDuoQl32Gdkfzw7BBRKDcelIZBmQf0uhXKSZVKe5Q596w/3ESJ9WOlB03SISnHy8lq/ZJ1+vhSZQfHvp0cHQl4BgNzktRCARdPY+5nVerF8aUSsT3bG2O+2r09AY4okLCVfkiwg6Nz2Eo7j4Z7mqNwIDAQAB" )  ; ----- DKIM key mail for otherdomain.tld | ||||
|   "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCurRsOh4NyTOqDnpPlPLGlQDuoQl32Gdkfzw7BBRKDcelIZBmQf0uhXKSZVKe5Q596w/3ESJ9WOlB03SISnHy8lq/ZJ1+vhSZQfHvp0cHQl4BgNzktRCARdPY+5nVerF8aUSsT3bG2O+2r09AY4okLCVfkiwg6Nz2Eo7j4Z7mqNwIDAQAB" )  ; ----- DKIM key mail for otherdomain.tld | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| poll pop3.third-party.test. with proto POP3 | ||||
| 	user 'remote_username' there with | ||||
| 	password 'secret' | ||||
| 	is 'local_username' here | ||||
| 	options keep ssl | ||||
|   user 'remote_username' there with | ||||
|   password 'secret' | ||||
|   is 'local_username' here | ||||
|   options keep ssl | ||||
|  | ||||
| poll imap.remote-service.test. with proto IMAP | ||||
| 	user 'user3' there with | ||||
| 	password 'secret' | ||||
| 	is 'user3@example.test' here | ||||
| 	options keep ssl | ||||
|   user 'user3' there with | ||||
|   password 'secret' | ||||
|   is 'user3@example.test' here | ||||
|   options keep ssl | ||||
|   | ||||
| @@ -1,14 +1,14 @@ | ||||
| dn: cn=postfix-book,cn=schema,cn=config | ||||
| objectClass: olcSchemaConfig | ||||
| cn: postfix-book | ||||
| olcAttributeTypes: {0}( 1.3.6.1.4.1.29426.1.10.1 NAME 'mailHomeDirectory' DESC 'The absolute path to the mail user home directory' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) | ||||
| olcAttributeTypes: {1}( 1.3.6.1.4.1.29426.1.10.2 NAME 'mailAlias' DESC 'RFC822 Mailbox - mail alias' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} ) | ||||
| olcAttributeTypes: {2}( 1.3.6.1.4.1.29426.1.10.3 NAME 'mailUidNumber' DESC 'UID required to access the mailbox' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) | ||||
| olcAttributeTypes: {3}( 1.3.6.1.4.1.29426.1.10.4 NAME 'mailGidNumber' DESC 'GID required to access the mailbox' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) | ||||
| olcAttributeTypes: {4}( 1.3.6.1.4.1.29426.1.10.5 NAME 'mailEnabled' DESC 'TRUE to enable, FALSE to disable account' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) | ||||
| olcAttributeTypes: {5}( 1.3.6.1.4.1.29426.1.10.6 NAME 'mailGroupMember' DESC 'Name of a mail distribution list' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) | ||||
| olcAttributeTypes: {6}( 1.3.6.1.4.1.29426.1.10.7 NAME 'mailQuota' DESC 'Mail quota limit in kilobytes' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) | ||||
| olcAttributeTypes: {7}( 1.3.6.1.4.1.29426.1.10.8 NAME 'mailStorageDirectory' DESC 'The absolute path to the mail users mailbox' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) | ||||
| # PostfixBook object classes: | ||||
| olcObjectClasses: {0}( 1.3.6.1.4.1.29426.1.2.2.1 NAME 'PostfixBookMailAccount' DESC 'Mail account used in Postfix Book' SUP top AUXILIARY MUST mail MAY ( mailHomeDirectory $ mailAlias $ mailGroupMember $ mailUidNumber $ mailGidNumber $ mailEnabled $ mailQuota $ mailStorageDirectory ) ) | ||||
| olcObjectClasses: {1}( 1.3.6.1.4.1.29426.1.2.2.2 NAME 'PostfixBookMailForward' DESC 'Mail forward used in Postfix Book' SUP top AUXILIARY MUST ( mail $ mailAlias ) ) | ||||
| dn: cn=postfix-book,cn=schema,cn=config | ||||
| objectClass: olcSchemaConfig | ||||
| cn: postfix-book | ||||
| olcAttributeTypes: {0}( 1.3.6.1.4.1.29426.1.10.1 NAME 'mailHomeDirectory' DESC 'The absolute path to the mail user home directory' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) | ||||
| olcAttributeTypes: {1}( 1.3.6.1.4.1.29426.1.10.2 NAME 'mailAlias' DESC 'RFC822 Mailbox - mail alias' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} ) | ||||
| olcAttributeTypes: {2}( 1.3.6.1.4.1.29426.1.10.3 NAME 'mailUidNumber' DESC 'UID required to access the mailbox' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) | ||||
| olcAttributeTypes: {3}( 1.3.6.1.4.1.29426.1.10.4 NAME 'mailGidNumber' DESC 'GID required to access the mailbox' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) | ||||
| olcAttributeTypes: {4}( 1.3.6.1.4.1.29426.1.10.5 NAME 'mailEnabled' DESC 'TRUE to enable, FALSE to disable account' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) | ||||
| olcAttributeTypes: {5}( 1.3.6.1.4.1.29426.1.10.6 NAME 'mailGroupMember' DESC 'Name of a mail distribution list' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) | ||||
| olcAttributeTypes: {6}( 1.3.6.1.4.1.29426.1.10.7 NAME 'mailQuota' DESC 'Mail quota limit in kilobytes' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) | ||||
| olcAttributeTypes: {7}( 1.3.6.1.4.1.29426.1.10.8 NAME 'mailStorageDirectory' DESC 'The absolute path to the mail users mailbox' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) | ||||
| # PostfixBook object classes: | ||||
| olcObjectClasses: {0}( 1.3.6.1.4.1.29426.1.2.2.1 NAME 'PostfixBookMailAccount' DESC 'Mail account used in Postfix Book' SUP top AUXILIARY MUST mail MAY ( mailHomeDirectory $ mailAlias $ mailGroupMember $ mailUidNumber $ mailGidNumber $ mailEnabled $ mailQuota $ mailStorageDirectory ) ) | ||||
| olcObjectClasses: {1}( 1.3.6.1.4.1.29426.1.2.2.2 NAME 'PostfixBookMailForward' DESC 'Mail forward used in Postfix Book' SUP top AUXILIARY MUST ( mail $ mailAlias ) ) | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| max_idle = 600s | ||||
| # this is a comment | ||||
|      # this is also a comment | ||||
|     # this is also a comment | ||||
| readme_directory = /tmp | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| submission/inet/smtpd_sasl_security_options=noanonymous | ||||
| # this is a test comment, please don't delete me :'( | ||||
|      # this is also a test comment, :O | ||||
|     # this is also a test comment, :O | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| /^test[0-9][0-9]*@localhost.localdomain/ user1@localhost.localdomain | ||||
| # this is a test comment, please don't delete me :'( | ||||
|      # this is also a test comment, :O | ||||
|     # this is also a test comment, :O | ||||
| /^bounce.*@.*/ external1@otherdomain.tld | ||||
| /^postmaster@/ user1@localhost.localdomain | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| alias1@localhost.localdomain user1@localhost.localdomain | ||||
| # this is a test comment, please don't delete me :'( | ||||
|      # this is also a test comment, :O | ||||
|     # this is also a test comment, :O | ||||
| alias2@localhost.localdomain external1@otherdomain.tld | ||||
| @localdomain2.com user1@localhost.localdomain | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| masterusername|{SHA512-CRYPT}$6$IOybywiyl1nuDno0$gRW625qH7ThmbRaByNVpuAGgDOkMd7tc3yuVmwVRuk7IXgiN8KDwcqtMcU0LyvS5RGAskbplavjPpCmFjbKEt1 | ||||
| masterusername|{SHA512-CRYPT}$6$IOybywiyl1nuDno0$gRW625qH7ThmbRaByNVpuAGgDOkMd7tc3yuVmwVRuk7IXgiN8KDwcqtMcU0LyvS5RGAskbplavjPpCmFjbKEt1 | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| user1@localhost.localdomain|{SHA512-CRYPT}$6$DBEbjh4I9P7aROk8$XosqE.YI2Z4bUkWD1/bedrSNpw79nsO60yiAKk04jARhPVX5VD/SaVM5HWFDQyzftESVDjbVdhzn/d4TJxFwg0 | ||||
| user2@otherdomain.tld|{SHA512-CRYPT}$6$PQRkR3RRzpYP4WET$NKLJk3PkwTRRSxryqFhQloBR7qSAYjoQH/IbD1ZQKX2UJJ3jmdbOMQPfMRGXBZv3JGhDUPmAiWzoJL6/NJN5d/ | ||||
| user3@localhost.localdomain|{SHA512-CRYPT}$6$lZwv0IoijHyEjDtM$vGsAS7KM5O5Q1NdWjard1LbJyGiHcqHhKAXBKDIMudjB/CuVvOvXKVy2yKeeRvKxVtkCdYac738VQPL.kpSVB.|userdb_mail=mbox:~/mail:INBOX=~/inbox | ||||
| user1@localhost.localdomain|{SHA512-CRYPT}$6$DBEbjh4I9P7aROk8$XosqE.YI2Z4bUkWD1/bedrSNpw79nsO60yiAKk04jARhPVX5VD/SaVM5HWFDQyzftESVDjbVdhzn/d4TJxFwg0 | ||||
| user2@otherdomain.tld|{SHA512-CRYPT}$6$PQRkR3RRzpYP4WET$NKLJk3PkwTRRSxryqFhQloBR7qSAYjoQH/IbD1ZQKX2UJJ3jmdbOMQPfMRGXBZv3JGhDUPmAiWzoJL6/NJN5d/ | ||||
| user3@localhost.localdomain|{SHA512-CRYPT}$6$lZwv0IoijHyEjDtM$vGsAS7KM5O5Q1NdWjard1LbJyGiHcqHhKAXBKDIMudjB/CuVvOvXKVy2yKeeRvKxVtkCdYac738VQPL.kpSVB.|userdb_mail=mbox:~/mail:INBOX=~/inbox | ||||
| # this is a test comment, please don't delete me :'( | ||||
|            # this is also a test comment, :O | ||||
|     # this is also a test comment, :O | ||||
|   | ||||
| @@ -1,25 +1,9 @@ | ||||
| { | ||||
|   "Verbose": false, | ||||
|   "Debug": false, | ||||
|   "IgnoreDefaults": false, | ||||
|   "SpacesAftertabs": true, | ||||
|   "NoColor": false, | ||||
|   "Exclude": [ | ||||
|     "^test/", | ||||
|     "\\.git.*", | ||||
|     "\\.cf$", | ||||
|     "\\.conf$", | ||||
|     "\\.init$", | ||||
|     "\\.md$" | ||||
|   ], | ||||
|   "AllowedContentTypes": [], | ||||
|   "PassedFiles": [], | ||||
|   "Disable": { | ||||
|     "EndOfLine": false, | ||||
|     "Indentation": false, | ||||
|     "InsertFinalNewline": false, | ||||
|     "TrimTrailingWhitespace": false, | ||||
|     "IndentSize": false, | ||||
|     "MaxLineLength": false | ||||
|   } | ||||
|     "^test/bats/", | ||||
|     "^test/test_helper/bats-(assert|support)", | ||||
|     "^test/test-files/", | ||||
|     "\\.git/" | ||||
|   ] | ||||
| } | ||||
|   | ||||
| @@ -19,7 +19,7 @@ function setup_file() { | ||||
|  | ||||
|   CONTAINER_NAME=${CONTAINER2_NAME} | ||||
|   _init_with_defaults | ||||
|    local CUSTOM_SETUP_ARGUMENTS=( | ||||
|   local CUSTOM_SETUP_ARGUMENTS=( | ||||
|     --env ENABLE_AMAVIS=0 | ||||
|     --env ENABLE_SPAMASSASSIN=0 | ||||
|   ) | ||||
|   | ||||
| @@ -50,7 +50,7 @@ function setup_file() { | ||||
|   # For this lookup `%s` only represents the domain, not a full email address. Hence the match pattern using a wildcard prefix `*@`. | ||||
|   # For a breakdown, see QUERY_SENDERS comment. | ||||
|   # NOTE: Although `result_attribute = mail` will return each accounts full email address, Postfix will only compare to domain-part. | ||||
|   local QUERY_DOMAIN='(| (& (|(mail=*@%s) (mailAlias=*@%s) (mailGroupMember=*@%s)) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) ) (&(mailAlias=*@%s)(objectClass=PostfixBookMailForward)) )'   | ||||
|   local QUERY_DOMAIN='(| (& (|(mail=*@%s) (mailAlias=*@%s) (mailGroupMember=*@%s)) (&(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)) ) (&(mailAlias=*@%s)(objectClass=PostfixBookMailForward)) )' | ||||
|  | ||||
|   # Simple queries for a single attribute that additionally requires `mailEnabled=TRUE` from the `PostfixBookMailAccount` class: | ||||
|   # NOTE: `mail` attribute is not unique to `PostfixBookMailAccount`. The `mailEnabled` attribute is to further control valid mail accounts. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user