1
1
Fork 0
mirror of https://github.com/docker-mailserver/docker-mailserver synced 2024-04-24 03:45:07 +02:00

Final Migration Step (#6)

* first migration steps
  * altered issue templates
  * altered README
  * removed .travis.yml
* adjusting registry & repository, Dockerfile and compose.env
* Close stale issues automatically
* Integrated CI with Github Actions (#3)
* feat: integrated ci with github actions
* fix: use secrets for docker org and update image
* docs: clarify why we use -t if no tty exists
* fix: correct remaining references to old repo
chore: prettier automatically updated markdown as well
* fix: hardcode docker org
* change testing image to just testing
* ci: add armv7 as a supported platform
* finished migration steps
* corrected linting in build-push action
* corrected linting in build-push action (2)
* minor preps for PR
* correcting push on pull request and minor details
* adjusted workflows to adhere closer to @wernerfred's diagram
* minor patches
* adjusting Dockerfile's installation of base packages
* adjusting schedule for stale issue action
* reverting license text
* improving CONTRIBUTING.md PR text
* Update CONTRIBUTING.md
* a bigger patch at the end
  * moved all scripts into one directory under target/scripts/
  * moved the quota-warning.sh script into target/scripts/ and removed empty directory /target/dovecot/scripts
  * minor fixes here and there
  * adjusted workflows for use a fully qualified name (i.e. docker.io/...)
  * improved on the Dockerfile layer count
  * corrected local tests - now they (actually) work (fine)!
  * corrected start-mailserver.sh to make use of defaults consistently
  * removed very old, deprecated variables (actually only one)
* various smaller improvements in the end
* last commit before merging #6
* rearranging variables to use alphabetic order

Co-authored-by: casperklein <casperklein@users.noreply.github.com>
Co-authored-by: Nick Pappas <radicand@users.noreply.github.com>
Co-authored-by: William Desportes <williamdes@wdes.fr>
This commit is contained in:
Georg Lauterbach 2021-01-16 10:16:05 +01:00 committed by GitHub
parent 66422cbcb0
commit 189e5376cc
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 1644 additions and 1671 deletions

View File

@ -1,4 +1,6 @@
.github
.git
.idea
.vscode
test/

View File

@ -1,37 +0,0 @@
## Pull requests
We gladly accept pull requests to add documentation, fix bugs and, in some circumstances,
add new features to Spree.
Here's a quick guide:
1. Fork the repo
2. Clone the fork to your local machine
3. Create new branch then make changes and add tests for your changes. Only
refactoring and documentation changes require no new tests. If you are adding
functionality or fixing a bug, we need tests!
4. Run the tests. `make build-no-cache generate-accounts run fixtures tests clean`
5. Push to your fork and submit a pull request. If the changes will apply cleanly
to the master branch, you will only need to submit one pull request.
Don't do pull requests against `-stable` branches. Always target the master branch. Any bugfixes we'll backport to those branches.
At this point, you're waiting on us. We like to at least comment on, if not
accept, pull requests within several days.
We may suggest some changes or improvements or alternatives.
Some things that will increase the chance that your pull request is accepted.
Syntax:
* Two spaces, no tabs.
* No trailing whitespace. Blank lines should not have any space.
* Follow the conventions you see used in the source already.
* Alphabetize the class methods to keep them organized
And in case we didn't emphasize it enough: we love tests!

View File

@ -1,20 +1,16 @@
---
name: "\U0001F41E Bug report"
about: Create a report about a reproducible bug
title: ''
labels: bug, needs triage
assignees: ''
title: "[BUG]"
labels: area/bug, meta/needs triage, priority/medium
assignees: ""
---
<!--- Provide a general summary of the issue in the Title above -->
<!-- Thanks for the bug report! -->
<!---
## Possible answers to you issue
Possible answers to your issue
* ClamAV keeps restarting:
https://github.com/tomav/docker-mailserver#requirements
https://github.com/docker-mailserver/docker-mailserver#requirements
* Email seen as spam:
https://github.com/tomav/docker-mailserver/wiki/Configure-SPF
@ -34,53 +30,52 @@ assignees: ''
https://github.com/tomav/docker-mailserver/wiki
* Open issues
https://github.com/tomav/docker-mailserver/issues
https://github.com/docker-mailserver/docker-mailserver/issues
-->
# Bug Report
## Context
<!--- Provide a more detailed introduction to the issue itself -->
<!--- How has this issue affected you? What were you trying to accomplish? -->
### *What* is affected by this bug?
<!--- Provide a general summary of the bug -->
### What is affected by this bug?
### When does this occur?
### *When* does this occur?
## *How* do we replicate the issue?
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this issue include code to reproduce, if relevant -->
### How do we replicate the issue?
1.
2.
3.
4.
## Actual Behavior
<!--- Tell us what happens instead -->
## Behavior
## Expected behavior (i.e. solution)
<!--- Tell us what should happen -->
### Actual Behavior
### Expected Behavior
## Your Environment
<!--- Include as many relevant details about the environment you experienced the issue in -->
* Amount of RAM available:
* Mailserver version used:
* Docker version used:
* Environment settings relevant to the config:
* Any relevant stack traces ("Full trace" preferred):
<!---
Please remember to format code using triple backticks (`) so that it is neatly formatted when the issue is posted.
- version: `v`
- available RAM: `GB`
- Docker version: `v`
Spoilers are recommended for readability:
<details>
<summary>Click me to expand </summary>
```sh
echo "hello world"
```
</details>
### Environment Variables
-->
```CFG
```
### Relevant Stack Traces
<!-- Remember to format code using triple backticks (`) so that it is neatly formatted when the issue is posted. -->
```BASH
# BEGIN
# END
```

View File

@ -1,42 +1,48 @@
---
name: "\U0001F389 Feature request"
about: Suggest an idea for this project
title: ''
labels: feature request, needs triage
title: '[FR]'
labels: area/enhancement, kind/feature request, meta/needs triage, priority/low
assignees: ''
---
## Is your feature request related to a problem?
<!-- A clear and concise description of what the problem is. -->
# Feature Request
## Context
## Describe the solution you'd like
<!-- A clear and concise description of what you want to happen. -->
### Is your Feature Request related to a Problem?
## Alternatives you've considered
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
### Describe the Solution you'd like
## Who will that feature be useful to?
<!-- Is it solving a common problem, or is it an improvement that all current users will benefit from? -->
### Are you going to implement it?
<!-- Select one, remove the other and do not shorten the sentence -->
Yes, because I know the probability of someone else doing it is low and I can learn from it.
## What have you done already?
<!-- If you already built a prototype or a complete implementation of that feature, where is it possible to see it? -->
No, and I understand that it is highly likely no one will implement it. Furthermore, I understand that this issue will likely become stale and will be closed.
## What are you going to contribute?
<!-- Besides testing volunteering work made by other people, what are you going to contribute in order to help have that feature implemented, tested and documented? -->
### What are you going to contribute??
## Additional context
<!-- Add any other context about the feature request here. -->
### Alternatives you've considered
### Who will that Feature be useful to?
### What have you done already?

View File

@ -1,21 +1,27 @@
---
name: "❓ Question"
name: "❓ Question / Other"
about: Ask a question about docker-mailserver
title: ''
labels: question, needs triage
labels: kind/question, priority/low, meta/help wanted, meta/needs triage
assignees: ''
---
## Subject
<!-- Select one, remove the others: -->
# Subject
* [ ] I would like to contribute to the project (code, documentation, advocacy, integration, ...)
* [ ] I would like some help for integrating this container with another service (rainloop, PostFWD, ...)
* [ ] I would like to configure a not documented mail server use case
* [ ] I would like some feedback concerning a use case
* [ ] I have questions about TLS/SSL/STARTTLS/OpenSSL
* [ ] Other
<!-- Select one, remove the others -->
I would like to contribute to the project
I would like to configure a not documented mail server use case
I would like some feedback concerning a use case
I have questions about TLS/SSL/STARTTLS/OpenSSL
Other
## Description
<!-- When copy/pasting code, format the code with tripe backticks (`) ! -->
``` BASH
# CODE GOES HERE
```

View File

@ -0,0 +1,22 @@
name: "Close Stale Issues"
on:
schedule:
- cron: "0 1 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 1 # TODO just for testing purposes, otherwise (20)
days-before-close: 1 # TODO just for testing purposes, otherwise (10)
stale-issue-label: "meta/stale"
close-issue-label: "meta/frozen due to age or inactivity"
stale-issue-message: >
This issue has become stale because it has been open for 20 days without
activity. Remove the label and comment or this issue will be closed in 10 days.
close-issue-message: >
This issue was closed due to inactivity.

116
.github/workflows/default_on_push.yml vendored Normal file
View File

@ -0,0 +1,116 @@
name: "Build, Test & Deploy"
on:
push:
branches: [ "master", "stable" ]
jobs:
build:
runs-on: ubuntu-latest
outputs:
imagetag: ${{ steps.prep.outputs.imagetag }}
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=docker.io/mailserver/testing
TAGS="${DOCKER_IMAGE}:${GITHUB_SHA::8},${DOCKER_IMAGE}:latest"
echo ::set-output name=tags::${TAGS}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
id: buildx
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build image locally
uses: docker/build-push-action@v2
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
build-args: |
VCS_REF=${{ github.sha }}
VCS_VER=${{ github.ref }}
platforms: linux/amd64,linux/arm/v7,linux/arm64
pull: true
push: true
tags: ${{ steps.prep.outputs.tags }}
cache-to: type=local,dest=/tmp/.buildx-cache
test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
- name: run test suite
run: |
NAME=docker.io/mailserver/testing:${GITHUB_SHA::8} bash -c 'make generate-accounts tests'
env:
CI: true
publish:
needs: test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=docker.io/mailserver/docker-mailserver
VERSION=latest
[[ $GITHUB_REF == refs/tags/* ]] && VERSION=${GITHUB_REF#refs/tags/v}
TAGS="${DOCKER_IMAGE}:${VERSION}"
[[ $VERSION =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && TAGS="$TAGS,${DOCKER_IMAGE}:latest"
echo ::set-output name=tags::${TAGS}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
id: buildx
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build image locally
uses: docker/build-push-action@v2
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
build-args: |
VCS_REF=${{ github.sha }}
VCS_VER=${{ github.ref }}
platforms: linux/amd64,linux/arm/v7,linux/arm64
pull: true
push: true
tags: ${{ steps.prep.outputs.tags }}
cache-from: type=local,src=/tmp/.buildx-cache

40
.github/workflows/linting.yml vendored Normal file
View File

@ -0,0 +1,40 @@
name: "Lint"
on:
pull_request:
branches: [ "*" ]
push:
branches: [ "master", "stable" ]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
- name: Hadolint
run: |
sudo curl -S -L https://github.com/hadolint/hadolint/releases/download/v${HADOLINT_VERSION}/hadolint-$(uname -s)-$(uname -m) -o /usr/local/bin/hadolint
sudo chmod +rx /usr/local/bin/hadolint
make hadolint
env:
HADOLINT_VERSION: 1.19.0
- name: ShellCheck
run: |
sudo curl -S -L "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/shellcheck-v${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar -xJ
sudo mv "shellcheck-v${SHELLCHECK_VERSION}/shellcheck" /usr/bin/
sudo rm -rf "shellcheck-v${SHELLCHECK_VERSION}"
make shellcheck
env:
SHELLCHECK_VERSION: 0.7.1
- name: ECLint
run: |
sudo curl -S -L "https://github.com/editorconfig-checker/editorconfig-checker/releases/download/${ECLINT_VERSION}/ec-linux-amd64.tar.gz" | tar -xaz
sudo mv bin/ec-linux-amd64 /usr/bin/eclint
sudo rm -rf bin
sudo chmod +x /usr/bin/eclint
make eclint
env:
ECLINT_VERSION: 2.3.1

43
.github/workflows/scheduled_builds.yml vendored Normal file
View File

@ -0,0 +1,43 @@
name: "Build Stable on Schedule"
on:
schedule:
- cron: "0 0 * * 5"
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: stable
submodules: recursive
- name: Prepare
id: prep
run: |
TAGS="docker.io/mailserver/docker-mailserver:stable"
echo ::set-output name=tags::${TAGS}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
id: buildx
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build image locally
uses: docker/build-push-action@v2
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
build-args: |
VCS_REF=${{ github.sha }}
VCS_VER=${{ github.ref }}
platforms: linux/amd64,linux/arm/v7,linux/arm64
pull: true
push: true
tags: ${{ steps.prep.outputs.tags }}

View File

@ -0,0 +1,59 @@
name: "Test Merge Requests"
on:
pull_request:
branches: [ "*" ]
jobs:
build:
runs-on: ubuntu-latest
outputs:
imagetag: ${{ steps.prep.outputs.imagetag }}
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=docker.io/mailserver/testing
TAGS="${DOCKER_IMAGE}:${GITHUB_SHA::8},${DOCKER_IMAGE}:latest"
echo ::set-output name=tags::${TAGS}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
id: buildx
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build image locally
uses: docker/build-push-action@v2
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
build-args: |
VCS_REF=${{ github.sha }}
VCS_VER=${{ github.ref }}
platforms: linux/amd64
pull: true
push: true
tags: ${{ steps.prep.outputs.tags }}
test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
- name: run test suite
run: |
NAME=docker.io/mailserver/testing:${GITHUB_SHA::8} bash -c 'make generate-accounts tests'
env:
CI: true

View File

@ -1,55 +0,0 @@
branches:
except:
- donttestme
language: bash
sudo: required
env:
global:
- HADOLINT_VERSION=1.18.0
- SHELLCHECK_VERSION=0.7.1
- ECLINT_VERSION=2.1.0
addons:
apt:
packages:
- xz-utils
services:
- docker
before_install:
# HADOLINT
- sudo curl -L https://github.com/hadolint/hadolint/releases/download/v${HADOLINT_VERSION}/hadolint-$(uname -s)-$(uname -m) -o /usr/local/bin/hadolint
- sudo chmod +rx /usr/local/bin/hadolint
# SHELLCHECK
- sudo wget -qO- "https://github.com/koalaman/shellcheck/releases/download/v${SHELLCHECK_VERSION}/shellcheck-v${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar -xJ
- sudo mv "shellcheck-v${SHELLCHECK_VERSION}/shellcheck" /usr/bin/
# ECLINT
- sudo wget -qO- "https://github.com/editorconfig-checker/editorconfig-checker/releases/download/${ECLINT_VERSION}/ec-linux-amd64.tar.gz" | tar -xaz
- sudo mv bin/ec-linux-amd64 /usr/bin/eclint
- sudo chmod +x /usr/bin/eclint
install:
- travis_retry travis_wait make build
script:
- make eclint
- make hadolint
- make shellcheck
- make generate-accounts tests
after_script:
- make clean
notifications:
slack:
secure: TTo1z9nbZCWcIdfPwypubNa3y+pwvfgDGlzEVAGEuK7uuIpmEoAcAUNSSPTnbewDGHnDl8t/ml93MtvP+a+IVuAKytMqF39PHyoZO7aUl9J62V+G75OmnyGjXGJm40pQosCS6LzqoRRYXotl9+fwH568Kf4ifXCrMZX1d+ir7Ww=
webhooks:
on_success: always
on_failure: always
on_start: never
urls:
- https://webhooks.gitter.im/e/7ec65291bfb4bf1f8518

View File

@ -1,169 +1,60 @@
# Changelog
## Next Major Release
- migrated the whole repository to `docker-mailserver/docker-mailserver`
- switched from TravisCI to GitHub Actions for CI/CD
- integrated stale issues action to automatically close stale issues
- adjusted issue templates
- adjusted `README.md` and split off `ENVIRONMENT.md`
- completely refactored `Dockerfile`
- adjusted `Makefile`
## v7.2.0
- Refactored `target/bin/`
- Enhanced and refactored all tests
- Added Code of Conduct
- Redesigned environment variable use
- Added missing Dovecot descriptions
## v7.1.0
- The use of default variables has changed slightly. Consult the [environment variables](./ENVIRONMENT.md) page
- New contributing guidelines were added
- Added coherent coding style and linting
- Added option to use non-default network interface
- SELinux is now supported
## 6.2.0+
* see <https://github.com/tomav/docker-mailserver/releases>
- see <https://github.com/docker-mailserver/docker-mailserver/releases>
## 6.1.0
* Deliver root mail (#952)
* don't update permissions on non-existent file (#956)
* Update docker-configomat (#959)
* Support for detecting running container mount (#884)
* Report sender (#965)
- Deliver root mail (#952)
- don't update permissions on non-existent file (#956)
- Update docker-configomat (#959)
- Support for detecting running container mount (#884)
- Report sender (#965)
added REPORT_SENDER env variable to the container.
* Add saslauthd option for ldap_start_tls & ldap_tls_check_peer - (#979, #980)
* fix SASL domain (#892, #970)
* DOMAINNAME can fail to be set in postsrsd-wrapper.sh (#989)
- Add saslauthd option for ldap_start_tls & ldap_tls_check_peer - (#979, #980)
- fix SASL domain (#892, #970)
- DOMAINNAME can fail to be set in postsrsd-wrapper.sh (#989)
## 6.0.0
* Implementation of multi-domain relay hosts (#922, #926)
- Implementation of multi-domain relay hosts (#922, #926)
AWS_SES_HOST and AWS_SES_PORT are deprecated now.
RELAY_HOST and RELAY_PORT are introduced to replace them.
* Password creation fix (#908, #914)
* Fixes 'duplicate log entry for /var/log/mail/mail.log' (#925, #927)
* fixed cleanup (mail_with_relays didn't get cleaned up) (#930)
* fix line breaks in postfix-summary mail error case (#936)
* Set default virus delete time (#932, #935)
- Password creation fix (#908, #914)
- Fixes 'duplicate log entry for /var/log/mail/mail.log' (#925, #927)
- fixed cleanup (mail_with_relays didn't get cleaned up) (#930)
- fix line breaks in postfix-summary mail error case (#936)
- Set default virus delete time (#932, #935)
This defaults to 7 days
* Ensure that the account contains a @ (#923, #924)
* Introducing global filters. (#934)
* add missing env vars to docker-compose.yml (#937)
* set postmaster address to a sensible default (#938, #939, #940)
* Testfixes & more (#942)
## 5.8.1
* add headers to postfix summary mail (#919)
* quotes needed to run multi-word command inside
container (#921)
* Fix uncommented lines in .env file (#920)
* Tls level fix (#916)
* test/config backup & restore (#907)
* Restore userdb for tests (#913)
## 5.8.0
* Adding daily mail review from Issue 839 (#881)
You can enable REPORT_RECIPIENT for REPORT_INTERVAL
reports. Default is disabled.
* introducing ENABLE_SRS env variable (#906, #852)
In v3.2.0 was SRS introduced and enabled by default
Now it is disabled by default and can be enabled with
the new env variable.
* fixed delalias, added additional tests (#909)
Fixes to setup where made for deletion and addition.
## 5.7.0
* Delmailuser (#878)
You can now delete users and the mailbox
* Backup config folder while testing (#901)
* added error messages to letsencrypt on startup (#898)
## 5.6.1
* Update docker-configomat (#680)
## 5.6.0
* Generate SRS secret on first run and store it (#891)
The secret will be constant afther this.
## 5.5.0
* Add /var/lib/dovecot to mailstate persistence (#887)
## 5.4.0
* Allow configuring SRS secrets using the environment (#885)
You can set your own secret with the env SRS_SECRET
By default it uses the docker generated secret
* Removed unneeded check for Let's encrypt cert.pem (#843)
## 5.3.0
* Added reject_authenticated_sender_login_mismatch (#872)
You can enable it with the env SPOOF_PROTECTION
It is not enabled by default
## 5.2.0
* Setting quiet mode on invoke-rc.d (#792)
* Implement undef option for SA_SPAM_SUBJECT (#767)
## 5.1.0
* Dkim key size can be changed (#868)
It defaults to 2048 bits
## 5.0.1
* update postmaster_address in dovecot config according to
POSTMASTER_ADDRESS env var (#866)
## 5.0.0
* Use Nist tls recommendations (#831)
This might break access with older email clients that use
an older version of openssl. You can TLS_LEVEL to lower
the ciphers.
## 4.2.0
* Add environment variable to allow for customizing postsrsd's SRS_EXCLUDE_DOMAINS setting (#849, #842)
## 4.1.0
* fixed greedy postgrey sed command (#845)
* postscreen implementation altered (#846)
You can now apply sender and receives restrictions
## 4.0.0
* moved fail2ban function from setup.sh to own file (#837)
This might break automatic scripting and you need to use
fail2ban now
## 3.4.0
* Generate new DH param weekly instead of daily (#834, #836)
## 3.3.1
* added config-path option to setup.sh script (#698)
## 3.3.0
* Restrict access (#452, #816)
## 3.2.3
* Introduce .env for docker-compose examples (#815)
## 3.2.2
* Changed Junk folder to be created and subscribed by default (#806)
## 3.2.1 (2018-02-06)
* Added reject_sender_login_mismatch (#811)
## 3.2.0 (2018-02-06)
* Add SRS to fix SPF issues on redirect (#611, #814)
## 3.1.0 (2018-02-04)
* Introduced Postscreen
Breaks email submission on port 25. Sending emails should be done on port 465 or 587
## 3.0.0 (2018-02-04)
* Image rebased on Debian stable
## 2.0.0 (2016-05-09)
* New version
* Major redesign of configuration
- Ensure that the account contains a @ (#923, #924)
- Introducing global filters. (#934)
- add missing env vars to docker-compose.yml (#937)
- set postmaster address to a sensible default (#938, #939, #940)
- Testfixes & more (#942)

View File

@ -1,4 +1,3 @@
# Contributor Covenant Code of Conduct
## Our Pledge

View File

@ -1,6 +1,6 @@
# Contributing
`docker-mailserver` is OpenSource. That means that you can contribute on enhancements, bug fixing or improving the documentation in the Wiki.
This project is Open Source. That means that you can contribute on enhancements, bug fixing or improving the documentation in the [Wiki](https://github.com/docker-mailserver/docker-mailserver/wiki).
1. [Issues & PRs](#issues--prs)
1. [Opening an Issue](#opening-an-issue)
@ -23,20 +23,18 @@ You want to add a feature? Feel free to start creating an issue explaining what
The development workflow is the following:
- Fork the project and clone your fork
- Create a branch using `git checkout -b branch_name` (you can use `issue-xxx` if fixing an existing issue)
- Run `git submodule init` and `git submodule update` to get the BATS submodules
- Code :-)
- Add integration tests in `test/tests.bats`
- Use `make clean all` to build image locally and run tests
Note that tests work on Linux only; they hang on Mac and Windows.
- Document your improvements in `README.md` or Wiki depending on content
- [Commit][commit], if possible with [signing your commit with a GPG key][gpg], push and make a pull-request
- Pull-request is automatically tested on Travis
- When tests are green, a review may be done
- When changed are validated, your branch is merged into `master`
- `master` is automatically tested on Travis
- Docker builds a new `latest` image
1. Fork the project and clone your fork
1. Create a new branch to work on
2. Run `git submodule update --init --recursive`
2. Write the code that is needed :D
3. Add integration tests if necessary
4. Get the linters with `make install_linters`
5. Use `make clean all` to build image locally and run tests (note that tests work on Linux **only**)
6. Document your improvements if necessary (e.g. if you introduced new environment variables, write the description in [`ENVIRONMENT.md`](./ENVIRONMENT.md))
7. [Commit][commit] and [sign your commit][gpg], push and create a pull-request to merge into `master`
1. Pull requests are automatically tested against the CI and will be reviewed when tests pass
2. When your changes are validated, your branch is merged
3. CI builds the new `:latest` image
## Coding Style

View File

@ -1,104 +1,136 @@
FROM debian:buster-slim
FROM docker.io/debian:buster-slim
ARG VCS_VER
ARG VCS_REF
ARG VCS_VERSION
LABEL maintainer="Thomas VIAL" \
org.label-schema.name="docker-mailserver" \
org.label-schema.description="A fullstack but simple mailserver (smtp, imap, antispam, antivirus, ssl...)" \
org.label-schema.url="https://github.com/tomav/docker-mailserver" \
org.label-schema.vcs-ref=$VCS_REF \
org.label-schema.vcs-url="https://github.com/tomav/docker-mailserver" \
org.label-schema.version=$VCS_VERSION \
org.label-schema.schema-version="1.0"
ARG DEBIAN_FRONTEND=noninteractive
ENV VIRUSMAILS_DELETE_DELAY=7
ENV ONE_DIR=0
LABEL org.opencontainers.image.version=${VCS_VER}
LABEL org.opencontainers.image.revision=${VCS_REF}
LABEL org.opencontainers.image.title="docker-mailserver"
LABEL org.opencontainers.image.vendor="The Docker Mailserver Organization"
LABEL org.opencontainers.image.authors="The Docker Mailserver Organization on GitHub"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.description="A fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.). Only configuration files, no SQL database."
LABEL org.opencontainers.image.url="https://github.com/docker-mailserver"
LABEL org.opencontainers.image.documentation="https://github.com/docker-mailserver/docker-mailserver/blob/master/README.md"
LABEL org.opencontainers.image.source="https://github.com/docker-mailserver/docker-mailserver"
ENV ENABLE_POSTGREY=0
ENV FETCHMAIL_POLL=300
ENV ONE_DIR=0
ENV POSTGREY_AUTO_WHITELIST_CLIENTS=5
ENV POSTGREY_DELAY=300
ENV POSTGREY_MAX_AGE=35
ENV POSTGREY_AUTO_WHITELIST_CLIENTS=5
ENV POSTGREY_TEXT="Delayed by postgrey"
ENV POSTGREY_TEXT="Delayed by Postgrey"
ENV SASLAUTHD_MECHANISMS=pam
ENV SASLAUTHD_MECH_OPTIONS=""
ENV VIRUSMAILS_DELETE_DELAY=7
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Packages
# hadolint ignore=DL3015,DL3005
#
# Install Basic Software
#
RUN \
apt-get update -q --fix-missing && \
apt-get -y upgrade && \
apt-get -y install postfix && \
apt-get -y install --no-install-recommends \
altermime \
amavisd-new \
apt-transport-https \
arj \
binutils \
bzip2 \
ca-certificates \
cabextract \
clamav \
clamav-daemon \
cpio \
curl \
ed \
fail2ban \
fetchmail \
file \
gamin \
gzip \
gnupg \
iproute2 \
iptables \
locales \
logwatch \
lhasa \
libdate-manip-perl \
liblz4-tool \
libmail-spf-perl \
libnet-dns-perl \
libsasl2-modules \
lrzip \
lzop \
netcat-openbsd \
nomarch \
opendkim \
opendkim-tools \
opendmarc \
pax \
pflogsumm \
p7zip-full \
postfix-ldap \
postfix-pcre \
postfix-policyd-spf-python \
postsrsd \
pyzor \
razor \
rpm2cpio \
rsyslog \
sasl2-bin \
spamassassin \
supervisor \
postgrey \
unrar-free \
unzip \
whois \
xz-utils \
dovecot-core \
dovecot-imapd \
dovecot-ldap \
dovecot-lmtpd \
dovecot-managesieved \
dovecot-pop3d \
dovecot-sieve \
dovecot-solr \
&& \
apt-get autoclean && \
apt-get -qq --fix-missing update && \
apt-get -y dist-upgrade >/dev/null && \
apt-get -y install apt-utils &>/dev/null && \
apt-get -y install postfix >/dev/null && \
apt-get -y --no-install-recommends install \
# A - E
altermime amavisd-new apt-transport-https arj binutils bzip2 \
dovecot-core dovecot-imapd dovecot-ldap dovecot-lmtpd \
dovecot-managesieved dovecot-pop3d dovecot-sieve dovecot-solr \
ca-certificates cabextract clamav clamav-daemon cpio curl ed \
# F - O
fail2ban fetchmail file gamin gnupg gzip iproute2 iptables \
locales logwatch lhasa libdate-manip-perl liblz4-tool \
libmail-spf-perl libnet-dns-perl libsasl2-modules lrzip lzop \
netcat-openbsd nomarch opendkim opendkim-tools opendmarc \
# P - Z
pax pflogsumm postgrey p7zip-full postfix-ldap postfix-pcre \
postfix-policyd-spf-python postsrsd pyzor \
razor rpm2cpio rsyslog sasl2-bin spamassassin supervisor \
unrar-free unzip whois xz-utils >/dev/null && \
# cleanup
apt-get -qq autoclean && \
apt-get -qq clean && \
rm -rf /var/lib/apt/lists/* && \
c_rehash 2>/dev/null
#
# ClamAV & FeshClam
#
RUN \
echo '0 */6 * * * clamav /usr/bin/freshclam --quiet' > /etc/cron.d/clamav-freshclam && \
chmod 644 /etc/clamav/freshclam.conf && \
freshclam && \
sed -i 's/Foreground false/Foreground true/g' /etc/clamav/clamd.conf && \
mkdir /var/run/clamav && \
chown -R clamav:root /var/run/clamav && \
rm -rf /var/log/clamav/
#
# Dovecot
#
COPY target/dovecot/auth-passwdfile.inc target/dovecot/??-*.conf /etc/dovecot/conf.d/
COPY target/dovecot/sieve/ /etc/dovecot/sieve/
COPY target/dovecot/dovecot-purge.cron /etc/cron.d/dovecot-purge.disabled
RUN chmod 0 /etc/cron.d/dovecot-purge.disabled
WORKDIR /usr/share/dovecot
# hadolint ignore=SC2016,SC2086,SC2069
RUN \
sed -i -e 's/include_try \/usr\/share\/dovecot\/protocols\.d/include_try \/etc\/dovecot\/protocols\.d/g' /etc/dovecot/dovecot.conf && \
sed -i -e 's/#mail_plugins = \$mail_plugins/mail_plugins = \$mail_plugins sieve/g' /etc/dovecot/conf.d/15-lda.conf && \
sed -i -e 's/^.*lda_mailbox_autocreate.*/lda_mailbox_autocreate = yes/g' /etc/dovecot/conf.d/15-lda.conf && \
sed -i -e 's/^.*lda_mailbox_autosubscribe.*/lda_mailbox_autosubscribe = yes/g' /etc/dovecot/conf.d/15-lda.conf && \
sed -i -e 's/^.*postmaster_address.*/postmaster_address = '${POSTMASTER_ADDRESS:="postmaster@domain.com"}'/g' /etc/dovecot/conf.d/15-lda.conf && \
sed -i 's/#imap_idle_notify_interval = 2 mins/imap_idle_notify_interval = 29 mins/' /etc/dovecot/conf.d/20-imap.conf && \
# adapt mkcert for Dovecot community repo
sed -i 's/CERTDIR=.*/CERTDIR=\/etc\/dovecot\/ssl/g' /usr/share/dovecot/mkcert.sh && \
sed -i 's/KEYDIR=.*/KEYDIR=\/etc\/dovecot\/ssl/g' /usr/share/dovecot/mkcert.sh && \
sed -i 's/KEYFILE=.*/KEYFILE=\$KEYDIR\/dovecot.key/g' /usr/share/dovecot/mkcert.sh && \
sed -i 's/RANDFILE.*//g' /usr/share/dovecot/dovecot-openssl.cnf && \
# create directory for certificates required by mkcert
mkdir /etc/dovecot/ssl && \
chmod 755 /etc/dovecot/ssl && \
./mkcert.sh 2>&1 >/dev/null && \
mkdir -p /usr/lib/dovecot/sieve-pipe /usr/lib/dovecot/sieve-filter /usr/lib/dovecot/sieve-global && \
chmod 755 -R /usr/lib/dovecot/sieve-pipe /usr/lib/dovecot/sieve-filter /usr/lib/dovecot/sieve-global
#
# LDAP & Spamassassin's Cron
#
COPY target/dovecot/dovecot-ldap.conf.ext /etc/dovecot
COPY \
target/postfix/ldap-users.cf \
target/postfix/ldap-groups.cf \
target/postfix/ldap-aliases.cf \
target/postfix/ldap-domains.cf \
/etc/postfix/
# hadolint ignore=SC2016
RUN \
sed -i -r 's/^(CRON)=0/\1=1/g' /etc/default/spamassassin && \
sed -i -r 's/^\$INIT restart/supervisorctl restart amavis/g' /etc/spamassassin/sa-update-hooks.d/amavisd-new
#
# Scripts & Miscellaneous
#
COPY \
./target/bin/* \
./target/scripts/*.sh \
./target/docker-configomat/configomat.sh \
/usr/local/bin/
RUN \
chmod +x /usr/local/bin/* && \
rm -rf /usr/share/locale/* && \
rm -rf /usr/share/man/* && \
rm -rf /usr/share/doc/* && \
@ -107,102 +139,76 @@ RUN \
rm /etc/postsrsd.secret && \
rm /etc/cron.daily/00logwatch
RUN echo "0 */6 * * * clamav /usr/bin/freshclam --quiet" > /etc/cron.d/clamav-freshclam && \
chmod 644 /etc/clamav/freshclam.conf && \
freshclam && \
sed -i 's/Foreground false/Foreground true/g' /etc/clamav/clamd.conf && \
mkdir /var/run/clamav && \
chown -R clamav:root /var/run/clamav && \
rm -rf /var/log/clamav/
#
# PostSRSD, Postgrey & Amavis
#
# Configures Dovecot
COPY target/dovecot/auth-passwdfile.inc target/dovecot/??-*.conf /etc/dovecot/conf.d/
COPY target/dovecot/scripts/quota-warning.sh /usr/local/bin/quota-warning.sh
COPY target/dovecot/sieve/ /etc/dovecot/sieve/
COPY target/dovecot/dovecot-purge.cron /etc/cron.d/dovecot-purge.disabled
RUN chmod 0 /etc/cron.d/dovecot-purge.disabled
WORKDIR /usr/share/dovecot
# hadolint ignore=SC2016,SC2086
RUN sed -i -e 's/include_try \/usr\/share\/dovecot\/protocols\.d/include_try \/etc\/dovecot\/protocols\.d/g' /etc/dovecot/dovecot.conf && \
sed -i -e 's/#mail_plugins = \$mail_plugins/mail_plugins = \$mail_plugins sieve/g' /etc/dovecot/conf.d/15-lda.conf && \
sed -i -e 's/^.*lda_mailbox_autocreate.*/lda_mailbox_autocreate = yes/g' /etc/dovecot/conf.d/15-lda.conf && \
sed -i -e 's/^.*lda_mailbox_autosubscribe.*/lda_mailbox_autosubscribe = yes/g' /etc/dovecot/conf.d/15-lda.conf && \
sed -i -e 's/^.*postmaster_address.*/postmaster_address = '${POSTMASTER_ADDRESS:="postmaster@domain.com"}'/g' /etc/dovecot/conf.d/15-lda.conf && \
sed -i 's/#imap_idle_notify_interval = 2 mins/imap_idle_notify_interval = 29 mins/' /etc/dovecot/conf.d/20-imap.conf && \
# Adapt mkcert for Dovecot community repo
sed -i 's/CERTDIR=.*/CERTDIR=\/etc\/dovecot\/ssl/g' /usr/share/dovecot/mkcert.sh && \
sed -i 's/KEYDIR=.*/KEYDIR=\/etc\/dovecot\/ssl/g' /usr/share/dovecot/mkcert.sh && \
sed -i 's/KEYFILE=.*/KEYFILE=\$KEYDIR\/dovecot.key/g' /usr/share/dovecot/mkcert.sh && \
# create directory for certificates created by mkcert
mkdir /etc/dovecot/ssl && \
chmod 755 /etc/dovecot/ssl && \
./mkcert.sh && \
mkdir -p /usr/lib/dovecot/sieve-pipe /usr/lib/dovecot/sieve-filter /usr/lib/dovecot/sieve-global && \
chmod 755 -R /usr/lib/dovecot/sieve-pipe /usr/lib/dovecot/sieve-filter /usr/lib/dovecot/sieve-global
# Configures LDAP
COPY target/dovecot/dovecot-ldap.conf.ext /etc/dovecot
COPY target/postfix/ldap-users.cf target/postfix/ldap-groups.cf target/postfix/ldap-aliases.cf target/postfix/ldap-domains.cf /etc/postfix/
# Enables Spamassassin CRON updates and update hook for supervisor
# hadolint ignore=SC2016
RUN sed -i -r 's/^(CRON)=0/\1=1/g' /etc/default/spamassassin && \
sed -i -r 's/^\$INIT restart/supervisorctl restart amavis/g' /etc/spamassassin/sa-update-hooks.d/amavisd-new
# Enables Postgrey
COPY target/postsrsd/postsrsd /etc/default/postsrsd
COPY target/postgrey/postgrey /etc/default/postgrey
COPY target/postgrey/postgrey.init /etc/init.d/postgrey
RUN chmod 755 /etc/init.d/postgrey && \
RUN \
chmod 755 /etc/init.d/postgrey && \
mkdir /var/run/postgrey && \
chown postgrey:postgrey /var/run/postgrey
# Copy PostSRSd Config
COPY target/postsrsd/postsrsd /etc/default/postsrsd
# Copy shared ffdhe params
COPY target/shared/ffdhe4096.pem /etc/postfix/shared/ffdhe4096.pem
# Enables Amavis
COPY target/amavis/conf.d/* /etc/amavis/conf.d/
RUN sed -i -r 's/#(@| \\%)bypass/\1bypass/g' /etc/amavis/conf.d/15-content_filter_mode && \
adduser clamav amavis && \
adduser amavis clamav && \
RUN \
sed -i -r 's/#(@| \\%)bypass/\1bypass/g' /etc/amavis/conf.d/15-content_filter_mode && \
adduser clamav amavis >/dev/null && \
adduser amavis clamav >/dev/null && \
# no syslog user in debian compared to ubuntu
adduser --system syslog && \
useradd -u 5000 -d /home/docker -s /bin/bash -p "$(echo docker | openssl passwd -1 -stdin)" docker && \
adduser --system syslog >/dev/null && \
useradd -u 5000 -d /home/docker -s /bin/bash -p "$(echo docker | openssl passwd -1 -stdin)" docker >/dev/null && \
echo "0 4 * * * /usr/local/bin/virus-wiper" | crontab - && \
chmod 644 /etc/amavis/conf.d/*
# Configure Fail2ban
RUN su - amavis -c "razor-admin -create && razor-admin -register"
#
# Fail2Ban, DKIM & DMARC
#
COPY target/fail2ban/jail.conf /etc/fail2ban/jail.conf
COPY target/fail2ban/filter.d/postfix-sasl.conf /etc/fail2ban/filter.d/postfix-sasl.conf
RUN mkdir /var/run/fail2ban
# Enables Pyzor and Razor
RUN su - amavis -c "razor-admin -create && razor-admin -register"
# Configure DKIM (opendkim)
# DKIM config files
COPY target/opendkim/opendkim.conf /etc/opendkim.conf
COPY target/opendkim/default-opendkim /etc/default/opendkim
# Configure DMARC (opendmarc)
COPY target/opendmarc/opendmarc.conf /etc/opendmarc.conf
COPY target/opendmarc/default-opendmarc /etc/default/opendmarc
COPY target/opendmarc/ignore.hosts /etc/opendmarc/ignore.hosts
# Configure fetchmail
RUN \
# switch iptables and ip6tables to legacy for fail2ban
update-alternatives --set iptables /usr/sbin/iptables-legacy && \
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
#
# Fetchmail, Postfix & Let'sEncrypt
#
COPY target/fetchmail/fetchmailrc /etc/fetchmailrc_general
RUN sed -i 's/START_DAEMON=no/START_DAEMON=yes/g' /etc/default/fetchmail
RUN mkdir /var/run/fetchmail && chown fetchmail /var/run/fetchmail
# Configures Postfix
COPY target/postfix/main.cf target/postfix/master.cf /etc/postfix/
COPY target/postfix/header_checks.pcre target/postfix/sender_header_filter.pcre target/postfix/sender_login_maps.pcre /etc/postfix/maps/
RUN echo "" > /etc/aliases
COPY target/shared/ffdhe4096.pem /etc/postfix/shared/ffdhe4096.pem
COPY \
target/postfix/header_checks.pcre \
target/postfix/sender_header_filter.pcre \
target/postfix/sender_login_maps.pcre \
/etc/postfix/maps/
# Configuring Logs
RUN sed -i -r "/^#?compress/c\compress\ncopytruncate" /etc/logrotate.conf && \
RUN \
: >/etc/aliases && \
sed -i 's/START_DAEMON=no/START_DAEMON=yes/g' /etc/default/fetchmail && \
mkdir /var/run/fetchmail && chown fetchmail /var/run/fetchmail && \
curl -s https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem >/etc/ssl/certs/lets-encrypt-x3-cross-signed.pem
#
# Logs
#
RUN \
sed -i -r "/^#?compress/c\compress\ncopytruncate" /etc/logrotate.conf && \
mkdir -p /var/log/mail && \
chown syslog:root /var/log/mail && \
touch /var/log/mail/clamav.log && \
@ -222,31 +228,20 @@ RUN sed -i -r "/^#?compress/c\compress\ncopytruncate" /etc/logrotate.conf && \
# prevent syslog logrotate warnings \
sed -i -e 's/\(printerror "could not determine current runlevel"\)/#\1/' /usr/sbin/invoke-rc.d && \
sed -i -e 's/^\(POLICYHELPER=\).*/\1/' /usr/sbin/invoke-rc.d && \
# Prevent syslog warning about imklog permissions.
# We won't want to look at that inside a container anyway.
# prevent syslog warning about imklog permissions
sed -i -e 's/^module(load=\"imklog\")/#module(load=\"imklog\")/' /etc/rsyslog.conf && \
# prevent email when /sbin/init or init system is not existing \
sed -i -e 's|invoke-rc.d rsyslog rotate > /dev/null|/usr/bin/supervisorctl signal hup rsyslog >/dev/null|g' /usr/lib/rsyslog/rsyslog-rotate
# Get LetsEncrypt signed certificate
RUN curl -s https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > /etc/ssl/certs/lets-encrypt-x3-cross-signed.pem
#
# Supervisord & Start
#
COPY ./target/bin /usr/local/bin
# Start-mailserver script
COPY ./target/bin-helper.sh ./target/helper-functions.sh ./target/check-for-changes.sh ./target/start-mailserver.sh ./target/fail2ban-wrapper.sh ./target/postfix-wrapper.sh ./target/postsrsd-wrapper.sh ./target/docker-configomat/configomat.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/*
# Configure supervisor
COPY target/supervisor/supervisord.conf /etc/supervisor/supervisord.conf
COPY target/supervisor/conf.d/* /etc/supervisor/conf.d/
WORKDIR /
# Switch iptables and ip6tables to legacy for fail2ban
RUN update-alternatives --set iptables /usr/sbin/iptables-legacy \
&& update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
EXPOSE 25 587 143 465 993 110 995 4190
CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]

656
ENVIRONMENT.md Normal file
View File

@ -0,0 +1,656 @@
# Environment
## Variables
1. If an option doesn't work as documented here, check if you are running the latest image!
2. Values in **bold** are the default values.
3. Since `docker-mailserver v7.1.0`, comparisons for environment variables are executed differently. If you previously used `VARIABLE=''` as the `empty` value, **update** to now use `VARIABLE=`.
### Assignments
#### General
##### DMS_DEBUG
- **0** => Debug disabled
- 1 => Enables debug on startup
##### ENABLE_CLAMAV
- **0** => Clamav is disabled
- 1 => Clamav is enabled
##### ONE_DIR
- **0** => state in default directories
- 1 => consolidate all states into a single directory (`/var/mail-state`) to allow persistence using docker volumes
##### ENABLE_POP3
- **empty** => POP3 service disabled
- 1 => Enables POP3 service
##### ENABLE_FAIL2BAN
- **0** => fail2ban service disabled
- 1 => Enables fail2ban service
If you enable Fail2Ban, don't forget to add the following lines to your `docker-compose.yml`:
``` BASH
cap_add:
- NET_ADMIN
```
Otherwise, `iptables` won't be able to ban IPs.
##### SMTP_ONLY
- **empty** => all daemons start
- 1 => only launch postfix smtp
##### SSL_TYPE
- **empty** => SSL disabled
- letsencrypt => Enables Let's Encrypt certificates
- custom => Enables custom certificates
- manual => Let you manually specify locations of your SSL certificates for non-standard cases
- self-signed => Enables self-signed certificates
- _any other value_ => SSL required, settings by default
Please read [the SSL page in the wiki](https://github.com/tomav/docker-mailserver/wiki/Configure-SSL) for more information.
##### TLS_LEVEL
- **empty** => modern
- modern => Enables TLSv1.2 and modern ciphers only. (default)
- intermediate => Enables TLSv1, TLSv1.1 and TLSv1.2 and broad compatibility ciphers.
- old => NOT implemented. If you really need it, then customize the TLS ciphers overriding postfix and dovecot settings [wiki](https://github.com/tomav/docker-mailserver/wiki/)
##### SPOOF_PROTECTION
Configures the handling of creating mails with forged sender addresses.
- **empty** => Mail address spoofing allowed. Any logged in user may create email messages with a forged sender address. See also [Wikipedia](https://en.wikipedia.org/wiki/Email_spoofing)(not recommended, but default for backwards compatibility reasons)
- 1 => (recommended) Mail spoofing denied. Each user may only send with his own or his alias addresses. Addresses with [extension delimiters](http://www.postfix.org/postconf.5.html#recipient_delimiter) are not able to send messages.
##### ENABLE_SRS
Enables the Sender Rewriting Scheme. SRS is needed if your mail server acts as forwarder. See [postsrsd](https://github.com/roehling/postsrsd/blob/master/README.md#sender-rewriting-scheme-crash-course) for further explanation.
- **0** => Disabled
- 1 => Enabled
##### PERMIT_DOCKER
Set different options for mynetworks option (can be overwrite in postfix-main.cf) **WARNING**: Adding the docker network's gateway to the list of trusted hosts, e.g. using the `network` or `connected-networks` option, can create an [**open relay**](https://en.wikipedia.org/wiki/Open_mail_relay), for instance if IPv6 is enabled on the host machine but not in Docker.
- **empty** => localhost only
- host => Add docker host (ipv4 only)
- network => Add the docker default bridge network (172.16.0.0/12); **WARNING**: `docker-compose` might use others (e.g. 192.168.0.0/16) use `PERMIT_DOCKER=connected-networks` in this case
- connected-networks => Add all connected docker networks (ipv4 only)
Note: you probably want to [set `POSTFIX_INET_PROTOCOLS=ipv4`](#postfix_inet_protocols) to make it work fine with Docker.
##### NETWORK_INTERFACE
In case your network interface differs from `eth0`, e.g. when you are using HostNetworking in Kubernetes, you can set this to whatever interface you want. This interface will then be used.
- **empty** => `eth0`
##### VIRUSMAILS_DELETE_DELAY
Set how many days a virusmail will stay on the server before being deleted
- **empty** => 7 days
##### ENABLE_POSTFIX_VIRTUAL_TRANSPORT
This Option is activating the Usage of POSTFIX_DAGENT to specify a ltmp client different from default dovecot socket.
- **empty** => disabled
- 1 => enabled
##### POSTFIX_DAGENT
Enabled by ENABLE_POSTFIX_VIRTUAL_TRANSPORT. Specify the final delivery of postfix
- **empty**: fail
- `lmtp:unix:private/dovecot-lmtp` (use socket)
- `lmtps:inet:<host>:<port>` (secure lmtp with starttls, take a look at <https://sys4.de/en/blog/2014/11/17/sicheres-lmtp-mit-starttls-in-dovecot/>)
- `lmtp:<kopano-host>:2003` (use kopano as mailstore)
- etc.
##### POSTFIX\_MAILBOX\_SIZE\_LIMIT
Set the mailbox size limit for all users. If set to zero, the size will be unlimited (default).
- **empty** => 0 (no limit)
##### ENABLE_QUOTAS
- **1** => Dovecot quota is enabled
- 0 => Dovecot quota is disabled
See [mailbox quota](https://github.com/tomav/docker-mailserver/wiki/Configure-Accounts#mailbox-quota).
##### POSTFIX\_MESSAGE\_SIZE\_LIMIT
Set the message size limit for all users. If set to zero, the size will be unlimited (not recommended!)
- **empty** => 10240000 (~10 MB)
##### ENABLE_MANAGESIEVE
- **empty** => Managesieve service disabled
- 1 => Enables Managesieve on port 4190
##### OVERRIDE_HOSTNAME
- **empty** => uses the `hostname` command to get the mail server's canonical hostname
- => Specify a fully-qualified domainname to serve mail for. This is used for many of the config features so if you can't set your hostname (e.g. you're in a container platform that doesn't let you) specify it in this environment variable.
##### POSTMASTER_ADDRESS
- **empty** => postmaster@domain.com
- => Specify the postmaster address
##### POSTSCREEN_ACTION
- **enforce** => Allow other tests to complete. Reject attempts to deliver mail with a 550 SMTP reply, and log the helo/sender/recipient information. Repeat this test the next time the client connects.
- drop => Drop the connection immediately with a 521 SMTP reply. Repeat this test the next time the client connects.
- ignore => Ignore the failure of this test. Allow other tests to complete. Repeat this test the next time the client connects. This option is useful for testing and collecting statistics without blocking mail.
##### DOVECOT_MAILBOX_FORMAT
- **maildir** => uses very common Maildir format, one file contains one message
- sdbox => (experimental) uses Dovecot high-performance mailbox format, one file contains one message
- mdbox ==> (experimental) uses Dovecot high-performance mailbox format, multiple messages per file and multiple files per box
This option has been added in November 2019. Using other format than Maildir is considered as experimental in docker-mailserver and should only be used for testing purpose. For more details, please refer to [Dovecot Documentation](https://wiki2.dovecot.org/MailboxFormat).
##### POSTFIX_INET_PROTOCOLS
- **all** => All possible protocols.
- ipv4 => Use only IPv4 traffic. Most likely you want this behind Docker.
- ipv6 => Use only IPv6 traffic.
Note: More details in <http://www.postfix.org/postconf.5.html#inet_protocols>
#### Reports
##### PFLOGSUMM_TRIGGER
Enables regular pflogsumm mail reports.
- **not set** => No report
- daily_cron => Daily report for the previous day
- logrotate => Full report based on the mail log when it is rotated
This is a new option. The old REPORT options are still supported for backwards compatibility.
If this is not set and reports are enabled with the old options, logrotate will be used.
##### PFLOGSUMM_RECIPIENT
Recipient address for pflogsumm reports.
- **not set** => Use REPORT_RECIPIENT or POSTMASTER_ADDRESS
- => Specify the recipient address(es)
##### PFLOGSUMM_SENDER
From address for pflogsumm reports.
- **not set** => Use REPORT_SENDER or POSTMASTER_ADDRESS
- => Specify the sender address
##### LOGWATCH_INTERVAL
Interval for logwatch report.
- **none** => No report is generated
- daily => Send a daily report
- weekly => Send a report every week
##### LOGWATCH_RECIPIENT
Recipient address for logwatch reports if they are enabled.
- **not set** => Use REPORT_RECIPIENT or POSTMASTER_ADDRESS
- => Specify the recipient address(es)
##### REPORT_RECIPIENT (deprecated)
Enables a report being sent (created by pflogsumm) on a regular basis.
- **0** => Report emails are disabled unless enabled by other options
- 1 => Using POSTMASTER_ADDRESS as the recipient
- => Specify the recipient address
##### REPORT_SENDER (deprecated)
Change the sending address for mail report
- **empty** => mailserver-report@hostname
- => Specify the report sender (From) address
##### REPORT_INTERVAL (deprecated)
Changes the interval in which logs are rotated and a report is being sent (deprecated).
- **daily** => Send a daily report
- weekly => Send a report every week
- monthly => Send a report every month
Note: This variable used to control logrotate inside the container and sent the pflogsumm report when the logs were rotated.
It is still supported for backwards compatibility, but the new option LOGROTATE_INTERVAL has been added that only rotates
the logs.
##### LOGROTATE_INTERVAL
Defines the interval in which the mail log is being rotated.
- **daily** => Rotate daily.
- weekly => Rotate weekly.
- monthly => Rotate monthly.
Note that only the log inside the container is affected.
The full log output is still available via `docker logs mail` (or your respective container name).
If you want to control logrotation for the docker generated logfile see: [Docker Logging Drivers](https://docs.docker.com/config/containers/logging/configure/).
Also note that by default the logs are lost when the container is recycled. To keep the logs, mount a volume.
Finally the logrotate interval **may** affect the period for generated reports. That is the case when the reports are triggered by log rotation.
#### Spamassassin
##### ENABLE_SPAMASSASSIN
- **0** => Spamassassin is disabled
- 1 => Spamassassin is enabled
**/!\\ Spam delivery:** when Spamassassin is enabled, messages marked as spam WILL NOT BE DELIVERED.
Use `SPAMASSASSIN_SPAM_TO_INBOX=1` for receiving spam messages.
##### SPAMASSASSIN_SPAM_TO_INBOX
- **0** => Spam messages will be bounced (_rejected_) without any notification (_dangerous_).
- 1 => Spam messages will be delivered to the inbox and tagged as spam using `SA_SPAM_SUBJECT`.
##### MOVE_SPAM_TO_JUNK
- **1** => Spam messages will be delivered in the `Junk` folder.
- 0 => Spam messages will be delivered in the mailbox.
Note: this setting needs `SPAMASSASSIN_SPAM_TO_INBOX=1`
##### SA_TAG
- **2.0** => add spam info headers if at, or above that level
Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1`
##### SA_TAG2
- **6.31** => add 'spam detected' headers at that level
Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1`
##### SA_KILL
- **6.31** => triggers spam evasive actions
Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1`. By default, the mailserver is configured to quarantine spam emails. If emails are quarantined, they are compressed and stored in a location dependent on the ONE_DIR setting above. If `ONE_DIR=1` the location is /var/mail-state/lib-amavis/virusmails/. If `ONE_DIR=0` it is /var/lib/amavis/virusmails/. These paths are inside the docker container. To inhibit this behaviour and deliver spam emails, set this to a very high value e.g. 100.0.
##### SA_SPAM_SUBJECT
- **\*\*\*SPAM\*\*\*** => add tag to subject if spam detected
Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1`. Add the spamassassin score to the subject line by inserting the keyword _SCORE_: **\*\*\*SPAM(_SCORE_)\*\*\***.
##### SA_SHORTCIRCUIT_BAYES_SPAM
- **1** => will activate spamassassin short circuiting for bayes spam detection.
This will uncomment the respective line in ```/etc/spamassasin/local.cf```
Note: activate this only if you are confident in your bayes database for identifying spam.
##### SA_SHORTCIRCUIT_BAYES_HAM
- **1** => will activate spamassassin short circuiting for bayes ham detection
This will uncomment the respective line in ```/etc/spamassasin/local.cf```
Note: activate this only if you are confident in your bayes database for identifying ham.
#### Fetchmail
##### ENABLE_FETCHMAIL
- **0** => `fetchmail` disabled
- 1 => `fetchmail` enabled
##### FETCHMAIL_POLL
- **300** => `fetchmail` The number of seconds for the interval
#### LDAP
##### ENABLE_LDAP
- **empty** => LDAP authentification is disabled
- 1 => LDAP authentification is enabled
- NOTE:
- A second container for the ldap service is necessary (e.g. [docker-openldap](https://github.com/osixia/docker-openldap))
- For preparing the ldap server to use in combination with this container [this](http://acidx.net/wordpress/2014/06/installing-a-mailserver-with-postfix-dovecot-sasl-ldap-roundcube/) article may be helpful
##### LDAP_START_TLS
- **empty** => no
- yes => LDAP over TLS enabled for Postfix
##### LDAP_SERVER_HOST
- **empty** => mail.domain.com
- => Specify the dns-name/ip-address where the ldap-server
- NOTE: If you going to use the mailserver in combination with docker-compose you can set the service name here
##### LDAP_SEARCH_BASE
- **empty** => ou=people,dc=domain,dc=com
- => e.g. LDAP_SEARCH_BASE=dc=mydomain,dc=local
##### LDAP_BIND_DN
- **empty** => cn=admin,dc=domain,dc=com
- => take a look at examples of SASL_LDAP_BIND_DN
##### LDAP_BIND_PW
- **empty** => admin
- => Specify the password to bind against ldap
##### LDAP_QUERY_FILTER_USER
- e.g. `(&(mail=%s)(mailEnabled=TRUE))`
- => Specify how ldap should be asked for users
##### LDAP_QUERY_FILTER_GROUP
- e.g. `(&(mailGroupMember=%s)(mailEnabled=TRUE))`
- => Specify how ldap should be asked for groups
##### LDAP_QUERY_FILTER_ALIAS
- e.g. `(&(mailAlias=%s)(mailEnabled=TRUE))`
- => Specify how ldap should be asked for aliases
##### LDAP_QUERY_FILTER_DOMAIN
- e.g. `(&(|(mail=*@%s)(mailalias=*@%s)(mailGroupMember=*@%s))(mailEnabled=TRUE))`
- => Specify how ldap should be asked for domains
##### DOVECOT_TLS
- **empty** => no
- yes => LDAP over TLS enabled for Dovecot
#### Dovecot
The following variables overwrite the default values for ```/etc/dovecot/dovecot-ldap.conf.ext```.
##### DOVECOT_BASE
- **empty** => same as `LDAP_SEARCH_BASE`
- => Tell Dovecot to search only below this base entry. (e.g. `ou=people,dc=domain,dc=com`)
##### DOVECOT_DEFAULT_PASS_SCHEME
- **empty** => `SSHA`
- => Select one crypt scheme for password hashing from this list of [password schemes](https://doc.dovecot.org/configuration_manual/authentication/password_schemes/).
##### DOVECOT_DN
- **empty** => same as `LDAP_BIND_DN`
- => Bind dn for LDAP connection. (e.g. `cn=admin,dc=domain,dc=com`)
##### DOVECOT_DNPASS
- **empty** => same as `LDAP_BIND_PW`
- => Password for LDAP dn sepecifified in `DOVECOT_DN`.
##### DOVECOT_HOSTS
- **empty** => same as `LDAP_SERVER_HOST`
- => Specify a space separated list of LDAP hosts.
##### DOVECOT_LDAP_VERSION
- **empty** => 3
- 2 => LDAP version 2 is used
- 3 => LDAP version 3 is used
##### DOVECOT_AUTH_BIND
- **empty** => no
- yes => Enable [LDAP authentication binds](https://wiki.dovecot.org/AuthDatabase/LDAP/AuthBinds)
##### DOVECOT_USER_FILTER
- e.g. `(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))`
##### DOVECOT_USER_ATTRS
- e.g. `homeDirectory=home,qmailUID=uid,qmailGID=gid,mailMessageStore=mail`
- => Specify the directory to dovecot attribute mapping that fits your directory structure.
- Note: This is necessary for directories that do not use the [Postfix Book Schema](test/docker-openldap/bootstrap/schema/mmc/postfix-book.schema).
- Note: The left-hand value is the directory attribute, the right hand value is the dovecot variable.
- More details on the [Dovecot Wiki](https://wiki.dovecot.org/AuthDatabase/LDAP/Userdb)
##### DOVECOT_PASS_FILTER
- e.g. `(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))`
##### DOVECOT_PASS_ATTRS
- e.g. `uid=user,userPassword=password`
- => Specify the directory to dovecot variable mapping that fits your directory structure.
- Note: This is necessary for directories that do not use the [Postfix Book Schema](test/docker-openldap/bootstrap/schema/mmc/postfix-book.schema).
- Note: The left-hand value is the directory attribute, the right hand value is the dovecot variable.
- More details on the [Dovecot Wiki](https://wiki.dovecot.org/AuthDatabase/LDAP/PasswordLookups)
#### Postgrey
##### ENABLE_POSTGREY
- **0** => `postgrey` is disabled
- 1 => `postgrey` is enabled
##### POSTGREY_DELAY
- **300** => greylist for N seconds
Note: This postgrey setting needs `ENABLE_POSTGREY=1`
##### POSTGREY_MAX_AGE
- **35** => delete entries older than N days since the last time that they have been seen
Note: This postgrey setting needs `ENABLE_POSTGREY=1`
##### POSTGREY_AUTO_WHITELIST_CLIENTS
- **5** => whitelist host after N successful deliveries (N=0 to disable whitelisting)
Note: This postgrey setting needs `ENABLE_POSTGREY=1`
##### POSTGREY_TEXT
- **Delayed by Postgrey** => response when a mail is greylisted
Note: This postgrey setting needs `ENABLE_POSTGREY=1`
#### SASL Auth
##### ENABLE_SASLAUTHD
- **0** => `saslauthd` is disabled
- 1 => `saslauthd` is enabled
##### SASLAUTHD_MECHANISMS
- empty => pam
- `ldap` => authenticate against ldap server
- `shadow` => authenticate against local user db
- `mysql` => authenticate against mysql db
- `rimap` => authenticate against imap server
- NOTE: can be a list of mechanisms like pam ldap shadow
##### SASLAUTHD_MECH_OPTIONS
- empty => None
- e.g. with SASLAUTHD_MECHANISMS rimap you need to specify the ip-address/servername of the imap server ==> xxx.xxx.xxx.xxx
##### SASLAUTHD_LDAP_SERVER
- empty => localhost
##### SASLAUTHD_LDAP_SSL
- empty or 0 => `ldap://` will be used
- 1 => `ldaps://` will be used
##### SASLAUTHD_LDAP_START_TLS
- **empty** => `no`
- `yes` => Enable `ldap_start_tls` option
##### SASLAUTHD_LDAP_TLS_CHECK_PEER
- **empty** => `no`
- `yes` => Enable `ldap_tls_check_peer` option
##### SASLAUTHD_LDAP_TLS_CACERT_DIR
Path to directory with CA (Certificate Authority) certificates.
- **empty** => Nothing is added to the configuration
- Any value => Fills the `ldap_tls_cacert_dir` option
##### SASLAUTHD_LDAP_TLS_CACERT_FILE
File containing CA (Certificate Authority) certificate(s).
- **empty** => Nothing is added to the configuration
- Any value => Fills the `ldap_tls_cacert_file` option
##### SASLAUTHD_LDAP_BIND_DN
- empty => anonymous bind
- specify an object with privileges to search the directory tree
- e.g. active directory: SASLAUTHD_LDAP_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=net
- e.g. openldap: SASLAUTHD_LDAP_BIND_DN=cn=admin,dc=mydomain,dc=net
##### SASLAUTHD_LDAP_PASSWORD
- empty => anonymous bind
##### SASLAUTHD_LDAP_SEARCH_BASE
- empty => Reverting to SASLAUTHD_MECHANISMS pam
- specify the search base
##### SASLAUTHD_LDAP_FILTER
- empty => default filter `(&(uniqueIdentifier=%u)(mailEnabled=TRUE))`
- e.g. for active directory: `(&(sAMAccountName=%U)(objectClass=person))`
- e.g. for openldap: `(&(uid=%U)(objectClass=person))`
##### SASLAUTHD_LDAP_PASSWORD_ATTR
Specify what password attribute to use for password verification.
- **empty** => Nothing is added to the configuration but the documentation says it is `userPassword` by default.
- Any value => Fills the `ldap_password_attr` option
##### SASL_PASSWD
- **empty** => No sasl_passwd will be created
- string => `/etc/postfix/sasl_passwd` will be created with the string as password
##### SASLAUTHD_LDAP_AUTH_METHOD
- **empty** => `bind` will be used as a default value
- `fastbind` => The fastbind method is used
- `custom` => The custom method uses userPassword attribute to verify the password
##### SASLAUTHD_LDAP_MECH
Specify the authentication mechanism for SASL bind.
- **empty** => Nothing is added to the configuration
- Any value => Fills the `ldap_mech` option
#### SRS (Sender Rewriting Scheme)
##### SRS_SENDER_CLASSES
An email has an "envelope" sender (indicating the sending server) and a
"header" sender (indicating who sent it). More strict SPF policies may require
you to replace both instead of just the envelope sender.
[More info](https://www.mybluelinux.com/what-is-email-envelope-and-email-header/).
- **envelope_sender** => Rewrite only envelope sender address
- header_sender => Rewrite only header sender (not recommended)
- envelope_sender,header_sender => Rewrite both senders
##### SRS_EXCLUDE_DOMAINS
- **empty** => Envelope sender will be rewritten for all domains
- provide comma separated list of domains to exclude from rewriting
##### SRS_SECRET
- **empty** => generated when the container is started for the first time
- provide a secret to use in base64
- you may specify multiple keys, comma separated. the first one is used for signing and the remaining will be used for verification. this is how you rotate and expire keys
- if you have a cluster/swarm make sure the same keys are on all nodes
- example command to generate a key: `dd if=/dev/urandom bs=24 count=1 2>/dev/null | base64`
##### SRS_DOMAINNAME
- **empty** => Derived from OVERRIDE_HOSTNAME, DOMAINNAME, or the container's hostname
- Set this if auto-detection fails, isn't what you want, or you wish to have a separate container handle DSNs
#### Default Relay Host
##### DEFAULT_RELAY_HOST
- **empty** => don't set default relayhost setting in main.cf
- default host and port to relay all mail through.
Format: `[example.com]:587` (don't forget the brackets if you need this to
be compatible with `$RELAY_USER` and `$RELAY_PASSWORD`, explained below).
#### Multi-domain Relay Hosts
##### RELAY_HOST
- **empty** => don't configure relay host
- default host to relay mail through
##### RELAY_PORT
- **empty** => 25
- default port to relay mail through
##### RELAY_USER
- **empty** => no default
- default relay username (if no specific entry exists in postfix-sasl-password.cf)
##### RELAY_PASSWORD
- **empty** => no default
- password for default relay user

View File

@ -1,6 +1,8 @@
The MIT License (MIT)
Copyright (c) 2016 Thomas VIAL
Copyright © 2016 & 2017 Thomas Vial & Contributors
Copyright © 2016 - 2020 The GitHub Community & Contributors
Copyright © 2021 - PRESENT The Docker Mailserver Organization & Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,23 +1,38 @@
SHELL = /bin/bash
NAME = tvial/docker-mailserver:testing
NAME ?= docker.io/mailserver/testing:local
VCS_REF := $(shell git rev-parse --short HEAD)
VCS_VERSION := $(shell git describe --tags --contains --always)
VCS_VER := $(shell git describe --tags --contains --always)
all: build backup generate-accounts tests clean
no-build: backup generate-accounts tests clean
complete_test: lint build generate-accounts tests
HADOLINT_VERSION := 1.19.0
SHELLCHECK_VERSION := 0.7.1
ECLINT_VERSION := 2.3.1
#
# Generic Build Targets
#
all: lint build backup generate-accounts tests clean
build:
docker build -t $(NAME) . \
--build-arg VCS_REF=$(VCS_REF) \
--build-arg VCS_VERSION=$(VCS_VERSION) \
docker build -t $(NAME) . --build-arg VCS_VER=$(VCS_VER) --build-arg VCS_REF=$(VCS_REF)
backup:
# if backup directories exist, clean hasn't been called, therefore
# we shouldn't overwrite it. It still contains the original content.
@ [[ ! -d config.bak ]] && cp -rp config config.bak
@ [[ ! -d testconfig.bak ]] && cp -rp test/config testconfig.bak
-@ [[ ! -d config.bak ]] && cp -rp config config.bak || :
-@ [[ ! -d testconfig.bak ]] && cp -rp test/config testconfig.bak || :
clean:
# remove running and stopped test containers
-@ [[ -d config.bak ]] && { rm -rf config ; mv config.bak config ; } || :
-@ [[ -d testconfig.bak ]] && { sudo rm -rf test/config ; mv testconfig.bak test/config ; } || :
-@ docker ps -a | grep -E "testing:local|ldap_for_mail|mail_override_hostname" | cut -f 1-1 -d ' ' | xargs --no-run-if-empty docker rm -f
-@ sudo rm -rf test/onedir test/alias test/quota test/relay test/config/dovecot-lmtp/userdb test/config/key* test/config/opendkim/keys/domain.tld/ test/config/opendkim/keys/example.com/ test/config/opendkim/keys/localdomain2.com/ test/config/postfix-aliases.cf test/config/postfix-receive-access.cf test/config/postfix-receive-access.cfe test/config/dovecot-quotas.cf test/config/postfix-send-access.cf test/config/postfix-send-access.cfe test/config/relay-hosts/chksum test/config/relay-hosts/postfix-aliases.cf test/config/dhparams.pem test/config/dovecot-lmtp/dh.pem test/config/relay-hosts/dovecot-quotas.cf test/config/user-patches.sh test/alias/config/postfix-virtual.cf test/quota/config/dovecot-quotas.cf test/quota/config/postfix-accounts.cf test/relay/config/postfix-relaymap.cf test/relay/config/postfix-sasl-password.cf test/duplicate_configs/
#
# Tests
#
generate-accounts:
@ docker run --rm -e MAIL_USER=user1@localhost.localdomain -e MAIL_PASS=mypassword -t $(NAME) /bin/sh -c 'echo "$$MAIL_USER|$$(doveadm pw -s SHA512-CRYPT -u $$MAIL_USER -p $$MAIL_PASS)"' > test/config/postfix-accounts.cf
@ -26,18 +41,11 @@ generate-accounts:
@ echo " # this is also a test comment, :O" >> test/config/postfix-accounts.cf
tests:
./test/bats/bin/bats test/*.bats
@ NAME=$(NAME) ./test/bats/bin/bats test/*.bats
.PHONY: ALWAYS_RUN
test/%.bats: ALWAYS_RUN
./test/bats/bin/bats $@
clean:
# remove running and stopped test containers
-@ docker ps -a | grep -E "docker-mailserver:testing|ldap_for_mail" | cut -f 1-1 -d ' ' | xargs --no-run-if-empty docker rm -f
-@ [[ -d config.bak ]] && { rm -rf config ; mv config.bak config ; } || :
-@ [[ -d testconfig.bak ]] && { sudo rm -rf test/config ; mv testconfig.bak test/config ; } || :
-@ sudo rm -rf test/onedir test/alias test/quota test/relay test/config/dovecot-lmtp/userdb test/config/key* test/config/opendkim/keys/domain.tld/ test/config/opendkim/keys/example.com/ test/config/opendkim/keys/localdomain2.com/ test/config/postfix-aliases.cf test/config/postfix-receive-access.cf test/config/postfix-receive-access.cfe test/config/dovecot-quotas.cf test/config/postfix-send-access.cf test/config/postfix-send-access.cfe test/config/relay-hosts/chksum test/config/relay-hosts/postfix-aliases.cf test/config/dhparams.pem test/config/dovecot-lmtp/dh.pem test/config/relay-hosts/dovecot-quotas.cf test/config/user-patches.sh test/alias/config/postfix-virtual.cf test/quota/config/dovecot-quotas.cf test/quota/config/postfix-accounts.cf test/relay/config/postfix-relaymap.cf test/relay/config/postfix-sasl-password.cf test/duplicate_configs/
@ ./test/bats/bin/bats $@
lint: eclint hadolint shellcheck
@ -49,3 +57,16 @@ shellcheck:
eclint:
@ ./test/linting/lint.sh eclint
install_linters:
@ sudo curl -S -L \
"https://github.com/hadolint/hadolint/releases/download/v$(HADOLINT_VERSION)/hadolint-$(shell uname -s)-$(shell uname -m)" -o /usr/local/bin/hadolint
@ sudo curl -S -L \
"https://github.com/koalaman/shellcheck/releases/download/v$(SHELLCHECK_VERSION)/shellcheck-v$(SHELLCHECK_VERSION).linux.x86_64.tar.xz" | tar -xJ
@ sudo curl -S -L \
"https://github.com/editorconfig-checker/editorconfig-checker/releases/download/$(ECLINT_VERSION)/ec-linux-amd64.tar.gz" | tar -xaz
@ sudo chmod +rx /usr/local/bin/hadolint
@ sudo mv "shellcheck-v$(SHELLCHECK_VERSION)/shellcheck" /usr/bin/
@ sudo mv bin/ec-linux-amd64 /usr/bin/eclint
@ sudo chmod +x /usr/bin/eclint
@ sudo rm -rf "shellcheck-v$(SHELLCHECK_VERSION)" bin

794
README.md
View File

@ -1,53 +1,28 @@
# docker-mailserver
# Docker Mailserver
![build_status] [![docker_pulls]][docker::hub]
[![ci::status]][ci::github] [![docker::pulls]][docker::hub]
[![gh_stars]][repo] [![contributors]][repo] [![forks]][repo]
[ci::status]: https://img.shields.io/github/workflow/status/docker-mailserver/docker-mailserver/Build%2C%20Test%20%26%20Deploy?color=blue&label=CI&logo=github&logoColor=white&style=for-the-badge
[ci::github]: https://github.com/docker-mailserver/docker-mailserver/actions
[docker::pulls]: https://img.shields.io/docker/pulls/mailserver/docker-mailserver.svg?style=for-the-badge&logo=docker&logoColor=white
[docker::hub]: https://hub.docker.com/r/mailserver/docker-mailserver/
[build_status]: https://img.shields.io/travis/tomav/docker-mailserver/master?style=for-the-badge
[docker_pulls]: https://img.shields.io/docker/pulls/tvial/docker-mailserver.svg?style=for-the-badge
[docker::hub]: https://hub.docker.com/r/tvial/docker-mailserver/
[gh_stars]: https://img.shields.io/github/stars/tomav/docker-mailserver.svg?label=github%20%E2%98%85&style=for-the-badge
[contributors]: https://img.shields.io/github/contributors/tomav/docker-mailserver.svg?style=for-the-badge
[forks]: https://img.shields.io/github/forks/tomav/docker-mailserver.svg?label=github%20forks&style=for-the-badge
[repo]: https://github.com/tomav/docker-mailserver/
A fullstack but simple mail server (SMTP, IMAP, Antispam, Antivirus...). Only configuration files, no SQL database. Keep it simple and versioned. Easy to deploy and upgrade.
A fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.). Only configuration files, no SQL database. Keep it simple and versioned. Easy to deploy and upgrade.
[Why this image was created.](http://tvi.al/simple-mail-server-with-docker/)
1. [Release Notes](#release-notes)
2. [Includes](#includes)
3. [Issues & Contributing](#issues--contributing)
4. [Requirements](#requirements)
5. [Usage](#usage)
6. [Examples](#examples)
7. [Environment Variables](#environment-variables)
1. [Included Services](#included-services)
2. [Opening Issues and Contributing](#opening-issues-and-contributing)
3. [Requirements](#requirements)
4. [Usage](#usage)
5. [Examples](#examples)
6. [Environment Variables](./ENVIRONMENT.md)
7. [Release Notes](./CHANGELOG.md)
## Release Notes
### `v7.2.0`
1. Refactored `target/bin/`
2. Enhanced and refactored all tests
3. Added Code of Conduct
4. Redesigned environment variable use
5. Added missing Dovecot descriptions
### `v7.1.0`
1. The use of default variables has changed slightly. Consult the [environment variables](#environment-variables) section
2. New contributing guidelines were added
3. Added coherent coding style and linting
4. Added option to use non-default network interface
5. SELinux is now supported
## Includes
## Included Services
- [Postfix](http://www.postfix.org) with SMTP or LDAP auth
- [Dovecot](https://www.dovecot.org) for SASL, IMAP (and optional POP3) with SSL support, with LDAP auth, Sieve and [quotas](https://github.com/tomav/docker-mailserver/wiki/Configure-Accounts#mailbox-quota)
- [Dovecot](https://www.dovecot.org) for SASL, IMAP (or POP3), with LDAP Auth, Sieve and [quotas](https://github.com/tomav/docker-mailserver/wiki/Configure-Accounts#mailbox-quota)
- [Amavis](https://www.amavis.org/)
- [Spamassasin](http://spamassassin.apache.org/) supporting custom rules
- [ClamAV](https://www.clamav.net/) with automatic updates
@ -59,29 +34,25 @@ A fullstack but simple mail server (SMTP, IMAP, Antispam, Antivirus...). Only co
- [Postgrey](https://postgrey.schweikert.ch/)
- [LetsEncrypt](https://letsencrypt.org/) and self-signed certificates
- [Setup script](https://github.com/tomav/docker-mailserver/wiki/Setup-docker-mailserver-using-the-script-setup.sh) to easily configure and maintain your mailserver
- basic [Sieve support](https://github.com/tomav/docker-mailserver/wiki/Configure-Sieve-filters) using dovecot
- Basic [Sieve support](https://github.com/tomav/docker-mailserver/wiki/Configure-Sieve-filters) using dovecot
- SASLauthd with LDAP auth
- persistent data and state (but think about backups!)
- [Integration tests](https://travis-ci.org/tomav/docker-mailserver)
- [Automated builds on docker hub](https://hub.docker.com/r/tvial/docker-mailserver/)
- Plus addressing (a.k.a. [extension delimiters](http://www.postfix.org/postconf.5.html#recipient_delimiter))
works out of the box: email for `you+extension@example.com` go to `you@example.com`
- Persistent data and state
- [CI/CD](https://github.com/docker-mailserver/docker-mailserver/actions)
- [Extension Delimiters](http://www.postfix.org/postconf.5.html#recipient_delimiter) (`you+extension@example.com` go to `you@example.com`)
## Issues & Contributing
## Opening Issues and Contributing
Before opening an issue, please have a look this `README`, the [Wiki](https://github.com/tomav/docker-mailserver/wiki/) and the Postfix/Dovecot documentation.
If you'd like to contribute, read [`CONTRIBUTING.md`](./CONTRIBUTING.md) thoroughly.
**Before opening an issue**, read this `README` carefully, use the [Wiki](https://github.com/tomav/docker-mailserver/wiki/), the Postfix/Dovecot documentation and your search engine you trust. The issue tracker is not meant to be used for unrelated questions! If you'd like to contribute, read [`CONTRIBUTING.md`](./CONTRIBUTING.md) thoroughly.
## Requirements
Recommended:
**Recommended**:
- 1 Core
- 1-2GB RAM
- Swap enabled for the container
Minimum:
**Minimum**:
- 1 vCore
- 512MB RAM
@ -95,10 +66,10 @@ Minimum:
Download the `docker-compose.yml`, `compose.env`, `mailserver.env` and the `setup.sh` files:
``` BASH
wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/setup.sh
wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/docker-compose.yml
wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/mailserver.env
wget -O .env https://raw.githubusercontent.com/tomav/docker-mailserver/master/compose.env
wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/stable/setup.sh
wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/stable/docker-compose.yml
wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/stable/mailserver.env
wget -O .env https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/stable/compose.env
chmod a+x ./setup.sh
```
@ -107,31 +78,27 @@ chmod a+x ./setup.sh
- [Install the latest docker-compose](https://docs.docker.com/compose/install/)
- Edit the files `.env` and `mailserver.env` to your liking:
- `.env` contains the configuration for docker-compose
- `.env` contains the configuration for Docker Compose
- `mailserver.env` contains the configuration for the mailserver container
- These files supports only simple `VAR=VAL` lines (see [Documentation](https://docs.docker.com/compose/env-file/)).
- Don't quote your values.
- Variable substitution is *not* supported (e.g. `OVERRIDE_HOSTNAME=$HOSTNAME.$DOMAINNAME`).
**Note:** Variables in `.env` are expanded in the `docker-compose.yml` file **only** and **not** in the container. The file `mailserver.env` serves this case where environment variables are used in the container.
**Note:** If you want to use a bare domain (host name equals domain name) see [FAQ](https://github.com/tomav/docker-mailserver/wiki/FAQ-and-Tips#can-i-use-nakedbare-domains-no-host-name).
- these files supports [only simple `VAR=VAL`](https://docs.docker.com/compose/env-file/)
- don't quote your values
- variable substitution is *not* supported (e.g. `OVERRIDE_HOSTNAME=$HOSTNAME.$DOMAINNAME`).
- Variables in `.env` are expanded in the `docker-compose.yml` file **only** and **not** in the container. The file `mailserver.env` serves this case where environment variables are used in the container.
- If you want to use a bare domain (host name = domain name), see [FAQ](https://github.com/tomav/docker-mailserver/wiki/FAQ-and-Tips#can-i-use-nakedbare-domains-no-host-name)
### Get up and running
If you'd like to use SELinux, add `-Z` to the variable `SELINUX_LABEL` in `.env`. If you want the volume bind mount to be shared among other containers switch `-Z` to `-z`
``` BASH
# without SELinux
docker-compose up -d mail
# without SELinux
./setup.sh email add <user@domain> [<password>]
./setup.sh alias add postmaster@<domain> <user@domain>
./setup.sh config dkim
# with SELinux
docker-compose up -d mail
./setup.sh -Z email add <user@domain> [<password>]
./setup.sh -Z alias add postmaster@<domain> <user@domain>
./setup.sh -Z config dkim
@ -141,37 +108,26 @@ docker-compose up -d mail
#### DNS - DKIM
Now that the keys are generated, you can configure your DNS server by just pasting the content of `config/opendkim/keys/domain.tld/mail.txt` in your `domain.tld.hosts` zone.
When keys are generated, you can configure your DNS server by just pasting the content of `config/opendkim/keys/domain.tld/mail.txt` to [set up DKIM](https://mxtoolbox.com/dmarc/dkim/setup/how-to-setup-dkim).
#### Custom user changes & patches
If you'd like to change, patch or alter files or behavior of `docker-mailserver`, you can use a script. Just place it the `config/` folder that is created on startup and call it `user-patches.sh`. The setup is done like this:
``` BASH
$ pwd
/where/docker-mailserver/resides/
$ ls -lhA
-rw-r--r-- USER GROUP SIZE DATE .env
-rw-r--r-- USER GROUP SIZE DATE docker-compose.yml
-rw-r--r-- USER GROUP SIZE DATE mailserver.env
# 1. Either create the config/ directory yourself
# or let docker-mailserver create it on initial
# startup
$ mkdir config
$ cd config
/where/docker-mailserver/resides/ $ mkdir config && cd config
# 2. Create the user-patches.sh script and make it
# executable
$ touch user-patches.sh
$ chmod +x user-patches.sh
$ ls -lh
-rwxr-xr-x USER GROUP SIZE DATE user-patches.sh
/where/docker-mailserver/resides/config/ $ touch user-patches.sh
/where/docker-mailserver/resides/config/ $ chmod +x user-patches.sh
# 3. Edit it
$ vi user-patches.sh
$ cat user-patches.sh
/where/docker-mailserver/resides/config/ $ vi user-patches.sh
/where/docker-mailserver/resides/config/ $ cat user-patches.sh
#! /bin/bash
# ! THIS IS AN EXAMPLE !
@ -187,13 +143,10 @@ then
echo -e '192.168.0.1 some.domain.com' >> /etc/hosts
fi
sed -i "s/smtpd_sender_restrictions = /smtpd_sender_restrictions = reject_unknown_reverse_client_hostname, /" /etc/postfix/main.cf
sed -i "s/smtpd_sender_restrictions = /smtpd_sender_restrictions = reject_unknown_client_hostname, /" /etc/postfix/main.cf
echo 'user-patches.sh finished successfully'
```
And you're done. the user patches script runs right before starting daemons. That means, all the other configuration is in place, so the script can make final adjustments.
And you're done. The user patches script runs right before starting daemons. That means, all the other configuration is in place, so the script can make final adjustments.
#### Supported Operating Systems
@ -213,7 +166,7 @@ We are currently providing support for Linux. Windows is _not_ supported and is
``` BASH
docker-compose down
docker pull tvial/docker-mailserver:<VERSION TAG>
docker pull docker.io/mailserver/docker-mailserver:<VERSION TAG>
docker-compose up -d mail
```
@ -242,14 +195,14 @@ See the [wiki](https://github.com/tomav/docker-mailserver/wiki) for further deta
### With Relevant Environmental Variables
This example provides you only with a basic example of what a minimal setup could look like. We **strongly recommend** that you go through the configuration file yourself and adjust everything to your needs.
This example provides you only with a basic example of what a minimal setup could look like. We **strongly recommend** that you go through the configuration file yourself and adjust everything to your needs. The default [docker-compose.yml](./docker-compose.yml) can be used for the purpose out-of-the-box, see the [usage section](#usage).
``` YAML
version: '3.8'
services:
mail:
image: docker.io/tvial/docker-mailserver:latest
image: docker.io/mailserver/docker-mailserver:latest
hostname: mail # ${HOSTNAME}
domainname: domain.com # ${DOMAINNAME}
container_name: mail # ${CONTAINER_NAME}
@ -290,7 +243,7 @@ version: '3.8'
services:
mail:
image: docker.io/tvial/docker-mailserver:latest
image: docker.io/mailserver/docker-mailserver:latest
hostname: mail # ${HOSTNAME}
domainname: domain.com # ${DOMAINNAME}
container_name: mail # ${CONTAINER_NAME}
@ -342,658 +295,3 @@ volumes:
mailstate:
maillogs:
```
## Environment Variables
If an option doesn't work as documented here, check if you are running the latest image! Values in **bold** are the default values.
**Note**: Since `docker-mailserver v7.1.0`, comparisons for environment variables are executed differently. If you previously used `VARIABLE=''` as the `empty` value, please **update** to now use `VARIABLE=`.
### Assignments
#### General
##### DMS_DEBUG
- **0** => Debug disabled
- 1 => Enables debug on startup
##### ENABLE_CLAMAV
- **0** => Clamav is disabled
- 1 => Clamav is enabled
##### ONE_DIR
- **0** => state in default directories
- 1 => consolidate all states into a single directory (`/var/mail-state`) to allow persistence using docker volumes
##### ENABLE_POP3
- **empty** => POP3 service disabled
- 1 => Enables POP3 service
##### ENABLE_FAIL2BAN
- **0** => fail2ban service disabled
- 1 => Enables fail2ban service
If you enable Fail2Ban, don't forget to add the following lines to your `docker-compose.yml`:
``` BASH
cap_add:
- NET_ADMIN
```
Otherwise, `iptables` won't be able to ban IPs.
##### SMTP_ONLY
- **empty** => all daemons start
- 1 => only launch postfix smtp
##### SSL_TYPE
- **empty** => SSL disabled
- letsencrypt => Enables Let's Encrypt certificates
- custom => Enables custom certificates
- manual => Let you manually specify locations of your SSL certificates for non-standard cases
- self-signed => Enables self-signed certificates
- _any other value_ => SSL required, settings by default
Please read [the SSL page in the wiki](https://github.com/tomav/docker-mailserver/wiki/Configure-SSL) for more information.
##### TLS_LEVEL
- **empty** => modern
- modern => Enables TLSv1.2 and modern ciphers only. (default)
- intermediate => Enables TLSv1, TLSv1.1 and TLSv1.2 and broad compatibility ciphers.
- old => NOT implemented. If you really need it, then customize the TLS ciphers overriding postfix and dovecot settings [wiki](https://github.com/tomav/docker-mailserver/wiki/)
##### SPOOF_PROTECTION
Configures the handling of creating mails with forged sender addresses.
- **empty** => Mail address spoofing allowed. Any logged in user may create email messages with a forged sender address. See also [Wikipedia](https://en.wikipedia.org/wiki/Email_spoofing)(not recommended, but default for backwards compatibility reasons)
- 1 => (recommended) Mail spoofing denied. Each user may only send with his own or his alias addresses. Addresses with [extension delimiters](http://www.postfix.org/postconf.5.html#recipient_delimiter) are not able to send messages.
##### ENABLE_SRS
Enables the Sender Rewriting Scheme. SRS is needed if your mail server acts as forwarder. See [postsrsd](https://github.com/roehling/postsrsd/blob/master/README.md#sender-rewriting-scheme-crash-course) for further explanation.
- **0** => Disabled
- 1 => Enabled
##### PERMIT_DOCKER
Set different options for mynetworks option (can be overwrite in postfix-main.cf) **WARNING**: Adding the docker network's gateway to the list of trusted hosts, e.g. using the `network` or `connected-networks` option, can create an [**open relay**](https://en.wikipedia.org/wiki/Open_mail_relay), [for instance](https://github.com/tomav/docker-mailserver/issues/1405#issuecomment-590106498) if IPv6 is enabled on the host machine but not in Docker.
- **empty** => localhost only
- host => Add docker host (ipv4 only)
- network => Add the docker default bridge network (172.16.0.0/12); **WARNING**: `docker-compose` might use others (e.g. 192.168.0.0/16) use `PERMIT_DOCKER=connected-networks` in this case
- connected-networks => Add all connected docker networks (ipv4 only)
Note: you probably want to [set `POSTFIX_INET_PROTOCOLS=ipv4`](#postfix_inet_protocols) to make it work fine with Docker.
##### NETWORK_INTERFACE
In case your network interface differs from `eth0`, e.g. when you are using HostNetworking in Kubernetes, you can set this to whatever interface you want. This interface will then be used.
- **empty** => `eth0`
##### VIRUSMAILS_DELETE_DELAY
Set how many days a virusmail will stay on the server before being deleted
- **empty** => 7 days
##### ENABLE_POSTFIX_VIRTUAL_TRANSPORT
This Option is activating the Usage of POSTFIX_DAGENT to specify a ltmp client different from default dovecot socket.
- **empty** => disabled
- 1 => enabled
##### POSTFIX_DAGENT
Enabled by ENABLE_POSTFIX_VIRTUAL_TRANSPORT. Specify the final delivery of postfix
- **empty**: fail
- `lmtp:unix:private/dovecot-lmtp` (use socket)
- `lmtps:inet:<host>:<port>` (secure lmtp with starttls, take a look at <https://sys4.de/en/blog/2014/11/17/sicheres-lmtp-mit-starttls-in-dovecot/>)
- `lmtp:<kopano-host>:2003` (use kopano as mailstore)
- etc.
##### POSTFIX\_MAILBOX\_SIZE\_LIMIT
Set the mailbox size limit for all users. If set to zero, the size will be unlimited (default).
- **empty** => 0 (no limit)
##### ENABLE_QUOTAS
- **1** => Dovecot quota is enabled
- 0 => Dovecot quota is disabled
See [mailbox quota](https://github.com/tomav/docker-mailserver/wiki/Configure-Accounts#mailbox-quota).
##### POSTFIX\_MESSAGE\_SIZE\_LIMIT
Set the message size limit for all users. If set to zero, the size will be unlimited (not recommended!)
- **empty** => 10240000 (~10 MB)
##### ENABLE_MANAGESIEVE
- **empty** => Managesieve service disabled
- 1 => Enables Managesieve on port 4190
##### OVERRIDE_HOSTNAME
- **empty** => uses the `hostname` command to get the mail server's canonical hostname
- => Specify a fully-qualified domainname to serve mail for. This is used for many of the config features so if you can't set your hostname (e.g. you're in a container platform that doesn't let you) specify it in this environment variable.
##### POSTMASTER_ADDRESS
- **empty** => postmaster@domain.com
- => Specify the postmaster address
##### POSTSCREEN_ACTION
- **enforce** => Allow other tests to complete. Reject attempts to deliver mail with a 550 SMTP reply, and log the helo/sender/recipient information. Repeat this test the next time the client connects.
- drop => Drop the connection immediately with a 521 SMTP reply. Repeat this test the next time the client connects.
- ignore => Ignore the failure of this test. Allow other tests to complete. Repeat this test the next time the client connects. This option is useful for testing and collecting statistics without blocking mail.
##### DOVECOT_MAILBOX_FORMAT
- **maildir** => uses very common Maildir format, one file contains one message
- sdbox => (experimental) uses Dovecot high-performance mailbox format, one file contains one message
- mdbox ==> (experimental) uses Dovecot high-performance mailbox format, multiple messages per file and multiple files per box
This option has been added in November 2019. Using other format than Maildir is considered as experimental in docker-mailserver and should only be used for testing purpose. For more details, please refer to [Dovecot Documentation](https://wiki2.dovecot.org/MailboxFormat).
##### POSTFIX_INET_PROTOCOLS
- **all** => All possible protocols.
- ipv4 => Use only IPv4 traffic. Most likely you want this behind Docker.
- ipv6 => Use only IPv6 traffic.
Note: More details in <http://www.postfix.org/postconf.5.html#inet_protocols>
#### Reports
##### PFLOGSUMM_TRIGGER
Enables regular pflogsumm mail reports.
- **not set** => No report
- daily_cron => Daily report for the previous day
- logrotate => Full report based on the mail log when it is rotated
This is a new option. The old REPORT options are still supported for backwards compatibility.
If this is not set and reports are enabled with the old options, logrotate will be used.
##### PFLOGSUMM_RECIPIENT
Recipient address for pflogsumm reports.
- **not set** => Use REPORT_RECIPIENT or POSTMASTER_ADDRESS
- => Specify the recipient address(es)
##### PFLOGSUMM_SENDER
From address for pflogsumm reports.
- **not set** => Use REPORT_SENDER or POSTMASTER_ADDRESS
- => Specify the sender address
##### LOGWATCH_INTERVAL
Interval for logwatch report.
- **none** => No report is generated
- daily => Send a daily report
- weekly => Send a report every week
##### LOGWATCH_RECIPIENT
Recipient address for logwatch reports if they are enabled.
- **not set** => Use REPORT_RECIPIENT or POSTMASTER_ADDRESS
- => Specify the recipient address(es)
##### REPORT_RECIPIENT (deprecated)
Enables a report being sent (created by pflogsumm) on a regular basis.
- **0** => Report emails are disabled unless enabled by other options
- 1 => Using POSTMASTER_ADDRESS as the recipient
- => Specify the recipient address
##### REPORT_SENDER (deprecated)
Change the sending address for mail report
- **empty** => mailserver-report@hostname
- => Specify the report sender (From) address
##### REPORT_INTERVAL (deprecated)
Changes the interval in which logs are rotated and a report is being sent (deprecated).
- **daily** => Send a daily report
- weekly => Send a report every week
- monthly => Send a report every month
Note: This variable used to control logrotate inside the container and sent the pflogsumm report when the logs were rotated.
It is still supported for backwards compatibility, but the new option LOGROTATE_INTERVAL has been added that only rotates
the logs.
##### LOGROTATE_INTERVAL
Defines the interval in which the mail log is being rotated.
- **daily** => Rotate daily.
- weekly => Rotate weekly.
- monthly => Rotate monthly.
Note that only the log inside the container is affected.
The full log output is still available via `docker logs mail` (or your respective container name).
If you want to control logrotation for the docker generated logfile see: [Docker Logging Drivers](https://docs.docker.com/config/containers/logging/configure/).
Also note that by default the logs are lost when the container is recycled. To keep the logs, mount a volume.
Finally the logrotate interval **may** affect the period for generated reports. That is the case when the reports are triggered by log rotation.
#### Spamassassin
##### ENABLE_SPAMASSASSIN
- **0** => Spamassassin is disabled
- 1 => Spamassassin is enabled
**/!\\ Spam delivery:** when Spamassassin is enabled, messages marked as spam WILL NOT BE DELIVERED.
Use `SPAMASSASSIN_SPAM_TO_INBOX=1` for receiving spam messages.
##### SPAMASSASSIN_SPAM_TO_INBOX
- **0** => Spam messages will be bounced (_rejected_) without any notification (_dangerous_).
- 1 => Spam messages will be delivered to the inbox and tagged as spam using `SA_SPAM_SUBJECT`.
##### MOVE_SPAM_TO_JUNK
- **1** => Spam messages will be delivered in the `Junk` folder.
- 0 => Spam messages will be delivered in the mailbox.
Note: this setting needs `SPAMASSASSIN_SPAM_TO_INBOX=1`
##### SA_TAG
- **2.0** => add spam info headers if at, or above that level
Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1`
##### SA_TAG2
- **6.31** => add 'spam detected' headers at that level
Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1`
##### SA_KILL
- **6.31** => triggers spam evasive actions
Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1`. By default, the mailserver is configured to quarantine spam emails. If emails are quarantined, they are compressed and stored in a location dependent on the ONE_DIR setting above. If `ONE_DIR=1` the location is /var/mail-state/lib-amavis/virusmails/. If `ONE_DIR=0` it is /var/lib/amavis/virusmails/. These paths are inside the docker container. To inhibit this behaviour and deliver spam emails, set this to a very high value e.g. 100.0.
##### SA_SPAM_SUBJECT
- **\*\*\*SPAM\*\*\*** => add tag to subject if spam detected
Note: this spamassassin setting needs `ENABLE_SPAMASSASSIN=1`. Add the spamassassin score to the subject line by inserting the keyword _SCORE_: **\*\*\*SPAM(_SCORE_)\*\*\***.
##### SA_SHORTCIRCUIT_BAYES_SPAM
- **1** => will activate spamassassin short circuiting for bayes spam detection.
This will uncomment the respective line in ```/etc/spamassasin/local.cf```
Note: activate this only if you are confident in your bayes database for identifying spam.
##### SA_SHORTCIRCUIT_BAYES_HAM
- **1** => will activate spamassassin short circuiting for bayes ham detection
This will uncomment the respective line in ```/etc/spamassasin/local.cf```
Note: activate this only if you are confident in your bayes database for identifying ham.
#### Fetchmail
##### ENABLE_FETCHMAIL
- **0** => `fetchmail` disabled
- 1 => `fetchmail` enabled
##### FETCHMAIL_POLL
- **300** => `fetchmail` The number of seconds for the interval
#### LDAP
##### ENABLE_LDAP
- **empty** => LDAP authentification is disabled
- 1 => LDAP authentification is enabled
- NOTE:
- A second container for the ldap service is necessary (e.g. [docker-openldap](https://github.com/osixia/docker-openldap))
- For preparing the ldap server to use in combination with this container [this](http://acidx.net/wordpress/2014/06/installing-a-mailserver-with-postfix-dovecot-sasl-ldap-roundcube/) article may be helpful
##### LDAP_START_TLS
- **empty** => no
- yes => LDAP over TLS enabled for Postfix
##### LDAP_SERVER_HOST
- **empty** => mail.domain.com
- => Specify the dns-name/ip-address where the ldap-server
- NOTE: If you going to use the mailserver in combination with docker-compose you can set the service name here
##### LDAP_SEARCH_BASE
- **empty** => ou=people,dc=domain,dc=com
- => e.g. LDAP_SEARCH_BASE=dc=mydomain,dc=local
##### LDAP_BIND_DN
- **empty** => cn=admin,dc=domain,dc=com
- => take a look at examples of SASL_LDAP_BIND_DN
##### LDAP_BIND_PW
- **empty** => admin
- => Specify the password to bind against ldap
##### LDAP_QUERY_FILTER_USER
- e.g. `(&(mail=%s)(mailEnabled=TRUE))`
- => Specify how ldap should be asked for users
##### LDAP_QUERY_FILTER_GROUP
- e.g. `(&(mailGroupMember=%s)(mailEnabled=TRUE))`
- => Specify how ldap should be asked for groups
##### LDAP_QUERY_FILTER_ALIAS
- e.g. `(&(mailAlias=%s)(mailEnabled=TRUE))`
- => Specify how ldap should be asked for aliases
##### LDAP_QUERY_FILTER_DOMAIN
- e.g. `(&(|(mail=*@%s)(mailalias=*@%s)(mailGroupMember=*@%s))(mailEnabled=TRUE))`
- => Specify how ldap should be asked for domains
##### DOVECOT_TLS
- **empty** => no
- yes => LDAP over TLS enabled for Dovecot
#### Dovecot
The following variables overwrite the default values for ```/etc/dovecot/dovecot-ldap.conf.ext```.
##### DOVECOT_BASE
- **empty** => same as `LDAP_SEARCH_BASE`
- => Tell Dovecot to search only below this base entry. (e.g. `ou=people,dc=domain,dc=com`)
##### DOVECOT_DEFAULT_PASS_SCHEME
- **empty** => `SSHA`
- => Select one crypt scheme for password hashing from this list of [password schemes](https://doc.dovecot.org/configuration_manual/authentication/password_schemes/).
##### DOVECOT_DN
- **empty** => same as `LDAP_BIND_DN`
- => Bind dn for LDAP connection. (e.g. `cn=admin,dc=domain,dc=com`)
##### DOVECOT_DNPASS
- **empty** => same as `LDAP_BIND_PW`
- => Password for LDAP dn sepecifified in `DOVECOT_DN`.
##### DOVECOT_HOSTS
- **empty** => same as `LDAP_SERVER_HOST`
- => Specify a space separated list of LDAP hosts.
##### DOVECOT_LDAP_VERSION
- **empty** => 3
- 2 => LDAP version 2 is used
- 3 => LDAP version 3 is used
##### DOVECOT_AUTH_BIND
- **empty** => no
- yes => Enable [LDAP authentication binds](https://wiki.dovecot.org/AuthDatabase/LDAP/AuthBinds)
##### DOVECOT_USER_FILTER
- e.g. `(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))`
##### DOVECOT_USER_ATTRS
- e.g. `homeDirectory=home,qmailUID=uid,qmailGID=gid,mailMessageStore=mail`
- => Specify the directory to dovecot attribute mapping that fits your directory structure.
- Note: This is necessary for directories that do not use the [Postfix Book Schema](test/docker-openldap/bootstrap/schema/mmc/postfix-book.schema).
- Note: The left-hand value is the directory attribute, the right hand value is the dovecot variable.
- More details on the [Dovecot Wiki](https://wiki.dovecot.org/AuthDatabase/LDAP/Userdb)
##### DOVECOT_PASS_FILTER
- e.g. `(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))`
##### DOVECOT_PASS_ATTRS
- e.g. `uid=user,userPassword=password`
- => Specify the directory to dovecot variable mapping that fits your directory structure.
- Note: This is necessary for directories that do not use the [Postfix Book Schema](test/docker-openldap/bootstrap/schema/mmc/postfix-book.schema).
- Note: The left-hand value is the directory attribute, the right hand value is the dovecot variable.
- More details on the [Dovecot Wiki](https://wiki.dovecot.org/AuthDatabase/LDAP/PasswordLookups)
#### Postgrey
##### ENABLE_POSTGREY
- **0** => `postgrey` is disabled
- 1 => `postgrey` is enabled
##### POSTGREY_DELAY
- **300** => greylist for N seconds
Note: This postgrey setting needs `ENABLE_POSTGREY=1`
##### POSTGREY_MAX_AGE
- **35** => delete entries older than N days since the last time that they have been seen
Note: This postgrey setting needs `ENABLE_POSTGREY=1`
##### POSTGREY_AUTO_WHITELIST_CLIENTS
- **5** => whitelist host after N successful deliveries (N=0 to disable whitelisting)
Note: This postgrey setting needs `ENABLE_POSTGREY=1`
##### POSTGREY_TEXT
- **Delayed by postgrey** => response when a mail is greylisted
Note: This postgrey setting needs `ENABLE_POSTGREY=1`
#### SASL Auth
##### ENABLE_SASLAUTHD
- **0** => `saslauthd` is disabled
- 1 => `saslauthd` is enabled
##### SASLAUTHD_MECHANISMS
- empty => pam
- `ldap` => authenticate against ldap server
- `shadow` => authenticate against local user db
- `mysql` => authenticate against mysql db
- `rimap` => authenticate against imap server
- NOTE: can be a list of mechanisms like pam ldap shadow
##### SASLAUTHD_MECH_OPTIONS
- empty => None
- e.g. with SASLAUTHD_MECHANISMS rimap you need to specify the ip-address/servername of the imap server ==> xxx.xxx.xxx.xxx
##### SASLAUTHD_LDAP_SERVER
- empty => localhost
##### SASLAUTHD_LDAP_SSL
- empty or 0 => `ldap://` will be used
- 1 => `ldaps://` will be used
##### SASLAUTHD_LDAP_START_TLS
- **empty** => `no`
- `yes` => Enable `ldap_start_tls` option
##### SASLAUTHD_LDAP_TLS_CHECK_PEER
- **empty** => `no`
- `yes` => Enable `ldap_tls_check_peer` option
##### SASLAUTHD_LDAP_TLS_CACERT_DIR
Path to directory with CA (Certificate Authority) certificates.
- **empty** => Nothing is added to the configuration
- Any value => Fills the `ldap_tls_cacert_dir` option
##### SASLAUTHD_LDAP_TLS_CACERT_FILE
File containing CA (Certificate Authority) certificate(s).
- **empty** => Nothing is added to the configuration
- Any value => Fills the `ldap_tls_cacert_file` option
##### SASLAUTHD_LDAP_BIND_DN
- empty => anonymous bind
- specify an object with privileges to search the directory tree
- e.g. active directory: SASLAUTHD_LDAP_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=net
- e.g. openldap: SASLAUTHD_LDAP_BIND_DN=cn=admin,dc=mydomain,dc=net
##### SASLAUTHD_LDAP_PASSWORD
- empty => anonymous bind
##### SASLAUTHD_LDAP_SEARCH_BASE
- empty => Reverting to SASLAUTHD_MECHANISMS pam
- specify the search base
##### SASLAUTHD_LDAP_FILTER
- empty => default filter `(&(uniqueIdentifier=%u)(mailEnabled=TRUE))`
- e.g. for active directory: `(&(sAMAccountName=%U)(objectClass=person))`
- e.g. for openldap: `(&(uid=%U)(objectClass=person))`
##### SASLAUTHD_LDAP_PASSWORD_ATTR
Specify what password attribute to use for password verification.
- **empty** => Nothing is added to the configuration but the documentation says it is `userPassword` by default.
- Any value => Fills the `ldap_password_attr` option
##### SASL_PASSWD
- **empty** => No sasl_passwd will be created
- string => `/etc/postfix/sasl_passwd` will be created with the string as password
##### SASLAUTHD_LDAP_AUTH_METHOD
- **empty** => `bind` will be used as a default value
- `fastbind` => The fastbind method is used
- `custom` => The custom method uses userPassword attribute to verify the password
##### SASLAUTHD_LDAP_MECH
Specify the authentication mechanism for SASL bind.
- **empty** => Nothing is added to the configuration
- Any value => Fills the `ldap_mech` option
#### SRS (Sender Rewriting Scheme)
##### SRS_SENDER_CLASSES
An email has an "envelope" sender (indicating the sending server) and a
"header" sender (indicating who sent it). More strict SPF policies may require
you to replace both instead of just the envelope sender.
[More info](https://www.mybluelinux.com/what-is-email-envelope-and-email-header/).
- **envelope_sender** => Rewrite only envelope sender address
- header_sender => Rewrite only header sender (not recommended)
- envelope_sender,header_sender => Rewrite both senders
##### SRS_EXCLUDE_DOMAINS
- **empty** => Envelope sender will be rewritten for all domains
- provide comma separated list of domains to exclude from rewriting
##### SRS_SECRET
- **empty** => generated when the container is started for the first time
- provide a secret to use in base64
- you may specify multiple keys, comma separated. the first one is used for signing and the remaining will be used for verification. this is how you rotate and expire keys
- if you have a cluster/swarm make sure the same keys are on all nodes
- example command to generate a key: `dd if=/dev/urandom bs=24 count=1 2>/dev/null | base64`
##### SRS_DOMAINNAME
- **empty** => Derived from OVERRIDE_HOSTNAME, DOMAINNAME, or the container's hostname
- Set this if auto-detection fails, isn't what you want, or you wish to have a separate container handle DSNs
#### Default Relay Host
##### DEFAULT_RELAY_HOST
- **empty** => don't set default relayhost setting in main.cf
- default host and port to relay all mail through.
Format: `[example.com]:587` (don't forget the brackets if you need this to
be compatible with `$RELAY_USER` and `$RELAY_PASSWORD`, explained below).
#### Multi-domain Relay Hosts
##### RELAY_HOST
- **empty** => don't configure relay host
- default host to relay mail through
##### RELAY_PORT
- **empty** => 25
- default port to relay mail through
##### RELAY_USER
- **empty** => no default
- default relay username (if no specific entry exists in postfix-sasl-password.cf)
##### RELAY_PASSWORD
- **empty** => no default
- password for default relay user

View File

@ -2,13 +2,13 @@
# Docker Compose Settings Variables
#
HOSTNAME=mail
DOMAINNAME=domain.com
CONTAINER_NAME=mail
HOSTNAME=<INSERT 'HOSTNAME' HERE>
DOMAINNAME=<INSERT 'DOMAIN.TLD' HERE>
CONTAINER_NAME=<INSERT 'CONTAINER NAME' HERE>
#
# SELinux Compose File Settings Variables
# options: -z or -Z
# options: empty, '-z' or '-Z'
#
SELINUX_LABEL=

View File

@ -1,11 +1,12 @@
version: '3.8'
services:
mail:
image: tvial/docker-mailserver:latest
mailserver:
image: docker.io/mailserver/docker-mailserver:latest
hostname: ${HOSTNAME}
domainname: ${DOMAINNAME}
container_name: ${CONTAINER_NAME}
env_file: mailserver.env
ports:
- "25:25"
- "143:143"
@ -16,12 +17,8 @@ services:
- mailstate:/var/mail-state
- maillogs:/var/log/mail
- ./config/:/tmp/docker-mailserver/${SELINUX_LABEL}
env_file:
- mailserver.env
cap_add:
- NET_ADMIN
- SYS_PTRACE
restart: always
cap_add: [ "NET_ADMIN", "SYS_PTRACE" ]
volumes:
maildata:

View File

@ -1,9 +0,0 @@
#! /bin/sh
VCS_REF="$(git rev-parse --short HEAD)"
VCS_VERSION="$(git describe --tags --contains --always)"
docker build \
--build-arg VCS_REF="${VCS_REF}" \
--build-arg VCS_VERSION="${VCS_VERSION}" \
-f "${DOCKERFILE_PATH}" -t "${IMAGE_NAME}" .

View File

@ -289,7 +289,7 @@ POSTGREY_DELAY=300
# delete entries older than N days since the last time that they have been seen
POSTGREY_MAX_AGE=35
# response when a mail is greylisted
POSTGREY_TEXT=Delayed by postgrey
POSTGREY_TEXT=Delayed by Postgrey
# whitelist host after N successful deliveries (N=0 to disable whitelisting)
POSTGREY_AUTO_WHITELIST_CLIENTS=5

View File

@ -1,7 +1,8 @@
#! /bin/bash
# Wrapper for various setup scripts
# included in docker-mailserver
# version v0.2.4 stable
# executed manually (via Make)
# task wrapper for various setup scripts
SCRIPT='setup.sh'
@ -11,16 +12,11 @@ trap '_unset_vars || :' EXIT
function __log_err
{
local FUNC_NAME LINE EXIT_CODE
FUNC_NAME="${1} / ${2}"
LINE="${3}"
EXIT_CODE="${4}"
printf "\n \e[1m\e[31mUNCHECKED ERROR\e[0m\n%s\n%s\n%s\n%s\n\n" \
" script = ${SCRIPT:-${0}}" \
" function = ${FUNC_NAME}" \
" line = ${LINE}" \
" exit code = ${EXIT_CODE}" 1>&2
" function = ${1} / ${2}" \
" line = ${3}" \
" exit code = ${4}" >&2
}
function _unset_vars
@ -62,7 +58,7 @@ function _check_root
if [[ ${EUID} -ne 0 ]]
then
echo "Curently docker-mailserver doesn't support podman's rootless mode, please run this script as root user."
return 1
exit 1
fi
}
@ -108,8 +104,8 @@ Usage: ${0} [-i IMAGE_NAME] [-c CONTAINER_NAME] <subcommand> <subcommand> [args]
OPTIONS:
-i IMAGE_NAME The name of the docker-mailserver image, by default
'tvial/docker-mailserver:latest' for docker, and
'docker.io/tvial/docker-mailserver:latest' for podman.
'mailserver/docker-mailserver:latest' for docker, and
'docker.io/mailserver/docker-mailserver:latest' for podman.
-c CONTAINER_NAME The name of the running container.
@ -170,12 +166,8 @@ SUBCOMMANDS:
function _docker_image_exists
{
if ${CRI} history -q "${1}" >/dev/null 2>&1
then
return 0
else
return 1
fi
${CRI} history -q "${1}" &>/dev/null
return ${?}
}
function _docker_image
@ -204,17 +196,17 @@ function _docker_container
then
${CRI} exec "${USE_TTY}" "${CONTAINER_NAME}" "${@}"
else
echo "The docker-mailserver is not running!"
exit 5
echo "The mailserver is not running!"
exit 1
fi
}
function _main
{
if [[ -n $(command -v docker) ]]
if command -v docker &>/dev/null
then
CRI=docker
elif [[ -n $(command -v podman) ]]
elif command -v podman &>/dev/null
then
CRI=podman
_check_root
@ -223,29 +215,25 @@ function _main
exit 10
fi
INFO=$(${CRI} ps \
--no-trunc \
--format "{{.Image}};{{.Names}}" \
--filter label=org.label-schema.name="docker-mailserver" | \
tail -1)
INFO=$(${CRI} ps --no-trunc --format "{{.Image}};{{.Names}}" --filter \
label=org.opencontainers.image.title="docker-mailserver" | tail -1)
IMAGE_NAME=${INFO%;*}
CONTAINER_NAME=${INFO#*;}
if [[ -z ${IMAGE_NAME} ]]
then
if [[ ${CRI} == "docker" ]]
then
IMAGE_NAME=tvial/docker-mailserver:latest
elif [[ ${CRI} == "podman" ]]
then
IMAGE_NAME=docker.io/tvial/docker-mailserver:latest
fi
IMAGE_NAME=${NAME:-'docker.io/mailserver/docker-mailserver:latest'}
fi
if tty -s
if test -t 0
then
USE_TTY="-ti"
else
# GitHub Actions will fail (or really anything else
# lacking an interactive tty) if we don't set a
# value here; "-t" alone works for these cases.
USE_TTY="-t"
fi
local OPTIND

View File

@ -1,15 +0,0 @@
#! /bin/bash
# executed from scripts in target/bin/
# task provides frequently used functions
function errex
{
echo "${@}" 1>&2
exit 1
}
function escape
{
echo "${1//./\\.}"
}

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-virtual.cf}

View File

@ -2,8 +2,8 @@
# shellcheck disable=SC2094
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-relaymap.cf}

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-sasl-password.cf}

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-virtual.cf}

View File

@ -5,8 +5,8 @@
# ? being used below. (This disables the message file-wide.)
# shellcheck disable=SC2094
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}
ALIAS_DATABASE="/tmp/docker-mailserver/postfix-virtual.cf"

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/dovecot-quotas.cf}
USER_DATABASE=${USER_DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-relaymap.cf}

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
function usage { echo "Usage: ${0} [<unban> <ip-address>]" ; }

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-virtual.cf}

View File

@ -5,8 +5,8 @@
# ? being used below. (This disables the message file-wide.)
# shellcheck disable=SC2094
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
HOSTNAME=${1}
RECIPIENT=${2}

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
set -o errexit
set -o pipefail

View File

@ -1,7 +1,7 @@
#! /bin/bash
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
MODE="${1}"
USER="${3}"

View File

@ -5,8 +5,8 @@
# ? being used below. (This disables the message file-wide.)
# shellcheck disable=SC2094
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/dovecot-quotas.cf}
USER_DATABASE=${USER_DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}

View File

@ -5,8 +5,8 @@
# ? being used below. (This disables the message file-wide.)
# shellcheck disable=SC2094
# shellcheck source=../bin-helper.sh
. /usr/local/bin/bin-helper.sh
# shellcheck source=../scripts/helper-functions.sh
. /usr/local/bin/helper-functions.sh
DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf}

View File

@ -251,7 +251,7 @@ mail_plugins = $mail_plugins quota
# (For systems setting struct dirent->d_type, this check is free and it's
# done always regardless of this setting)
# -------
# tomav/docker-mailserver:
# mailserver/docker-mailserver:
# Seen dovecot-sieve is always enabled, setting `maildir_stat_dirs = yes` permits
# to avoid `/var/mail/domain.tld/user/.dovecot.sieve` (symlink) to be treated as a directory (default behavior).
# According to https://github.com/Mailu/Mailu/issues/143#issuecomment-274596931, there is no noticeable impact when this is enabled.

View File

@ -1,15 +0,0 @@
#! /usr/bin/env sh
# Report a quota usage warning to an user
PERCENT="${1}"
USER="${2}"
DOMAIN="${3}"
# shellcheck disable=SC2250
cat << EOF | /usr/lib/dovecot/dovecot-lda -d "$USER" -o "plugin/quota=maildir:User quota:noenforcing"
From: postmaster@$DOMAIN
Subject: quota warning
Your mailbox is now $PERCENT% full.
EOF

View File

@ -6,34 +6,35 @@
LOG_DATE=$(date +"%Y-%m-%d %H:%M:%S ")
echo "${LOG_DATE} Start check-for-changes script."
# ? Checks ------------------------------------------------
# ? Checks
cd /tmp/docker-mailserver || exit 1
# Check postfix-accounts.cf exist else break
# check postfix-accounts.cf exist else break
if [[ ! -f postfix-accounts.cf ]]
then
echo "${LOG_DATE} postfix-accounts.cf is missing! This should not run! Exit!"
exit
exit 0
fi
# Verify checksum file exists; must be prepared by start-mailserver.sh
# verify checksum file exists; must be prepared by start-mailserver.sh
if [[ ! -f ${CHKSUM_FILE} ]]
then
echo "${LOG_DATE} ${CHKSUM_FILE} is missing! Start script failed? Exit!"
exit
exit 0
fi
# ? Actual script begins ----------------------------------
# ? Actual script begins
# Determine postmaster address, duplicated from start-mailserver.sh
# This script previously didn't work when POSTMASTER_ADDRESS was empty
# determine postmaster address, duplicated from start-mailserver.sh
# this script previously didn't work when POSTMASTER_ADDRESS was empty
if [[ -n ${OVERRIDE_HOSTNAME} ]]
then
DOMAINNAME="${OVERRIDE_HOSTNAME#*.}"
else
DOMAINNAME="$(hostname -d)"
fi
PM_ADDRESS="${POSTMASTER_ADDRESS:=postmaster@${DOMAINNAME}}"
echo "${LOG_DATE} Using postmaster address ${PM_ADDRESS}"
sleep 10

View File

@ -1,7 +1,21 @@
#! /bin/bash
# ? IP and CIDR -------------------------------------------
DMS_DEBUG="${DMS_DEBUG:=0}"
# ? BIN HELPER
function errex
{
echo "${@}" 1>&2
exit 1
}
function escape
{
echo "${1//./\\.}"
}
# ? IP & CIDR
function _mask_ip_digit
{
@ -43,9 +57,7 @@ function _sanitize_ipv4_to_subnet_cidr
}
export -f _sanitize_ipv4_to_subnet_cidr
# ? ACME certs --------------------------------------------
# ? ACME
function _extract_certs_from_acme
{
@ -94,60 +106,30 @@ for key, value in acme.items():
}
export -f _extract_certs_from_acme
# ? Notification ------------------------------------------
declare -A DEFAULT_VARS
DEFAULT_VARS["DMS_DEBUG"]="${DMS_DEBUG:=0}"
# ? Notifications
function _notify
{
c_red="\e[0;31m"
c_green="\e[0;32m"
c_brown="\e[0;33m"
c_blue="\e[0;34m"
c_bold="\033[1m"
c_reset="\e[0m"
local FINAL_MSG=''
local MSG="${2:-}"
local TYPE="${1:-}"
notification_type=${1}
notification_msg=${2}
notification_format=${3}
msg=""
case "${notification_type}" in
'taskgrp' ) msg="${c_bold}${notification_msg}${c_reset}" ;;
'task' )
if [[ ${DEFAULT_VARS["DMS_DEBUG"]} -eq 1 ]]
then
msg=" ${notification_msg}${c_reset}"
fi
;;
'inf' )
if [[ ${DEFAULT_VARS["DMS_DEBUG"]} -eq 1 ]]
then
msg="${c_green} * ${notification_msg}${c_reset}"
fi
;;
'started' ) msg="${c_green} ${notification_msg}${c_reset}" ;;
'warn' ) msg="${c_brown} Warning ${notification_msg}${c_reset}" ;;
'err' ) msg="${c_blue} Error ${notification_msg}${c_reset}" ;;
'fatal' ) msg="${c_red} Fatal Error: ${notification_msg}${c_reset}" ;;
* ) msg="" ;;
case "${TYPE}" in
'none' ) FINAL_MSG=' ' ;;
'tasklog' ) FINAL_MSG="[ \e[0;92mTASKLOG\e[0m ] ${MSG}" ;; # light green
'warn' ) FINAL_MSG="[ \e[0;93mWARNING\e[0m ] ${MSG}" ;; # light yellow
'err' ) FINAL_MSG="[ \e[0;31mERROR\e[0m ] ${MSG}" ;; # light red
'fatal' ) FINAL_MSG="[ \e[0;91mFATAL\e[0m ] ${MSG}" ;; # red
'inf' ) [[ ${DMS_DEBUG} -eq 1 ]] && FINAL_MSG="[[ \e[0;34mINFO\e[0m ]] ${MSG}" ;; # light blue
'task' ) [[ ${DMS_DEBUG} -eq 1 ]] && FINAL_MSG="[[ \e[0;37mTASK\e[0m ]] ${MSG}" ;; # light grey
* ) ;;
esac
case "${notification_format}" in
'n' ) options="-ne" ;;
* ) options="-e" ;;
esac
[[ -n "${msg}" ]] && echo "${options}" "${msg}"
[[ -n ${FINAL_MSG} ]] && echo "-e${3:-}" "${FINAL_MSG}"
}
export -f _notify
# ? Relay Host Map ----------------------------------------
# ? Relay Host Map
# setup /etc/postfix/relayhost_map
# --
@ -184,9 +166,7 @@ function _populate_relayhost_map
}
export -f _populate_relayhost_map
# ? File checksums ----------------------------------------
# ? File Checksums
# file storing the checksums of the monitored files.
# shellcheck disable=SC2034

View File

@ -1,6 +1,6 @@
#! /bin/bash
function _generate_secret { ( umask 0077 ; dd if=/dev/urandom bs=24 count=1 2>/dev/null | base64 -w0 > "${1}" ) }
function _generate_secret { ( umask 0077 ; dd if=/dev/urandom bs=24 count=1 2>/dev/null | base64 -w0 > "${1}" ; ) ; }
if [[ -n ${SRS_DOMAINNAME} ]]
then
@ -23,7 +23,7 @@ POSTSRSD_STATE_SECRET_FILE="${POSTSRSD_STATE_DIR}/postsrsd.secret"
if [[ -n ${SRS_SECRET} ]]
then
( umask 0077 ; echo "${SRS_SECRET}" | tr ',' '\n' > "${POSTSRSD_SECRET_FILE}" )
( umask 0077 ; echo "${SRS_SECRET}" | tr ',' '\n' > "${POSTSRSD_SECRET_FILE}" ; )
else
if [[ ${ONE_DIR} -eq 1 ]]
then

14
target/scripts/quota-warning.sh Executable file
View File

@ -0,0 +1,14 @@
#! /bin/bash
# Report a quota usage warning to an user
PERCENT="${1}"
USER="${2}"
DOMAIN="${3}"
cat << EOF | /usr/lib/dovecot/dovecot-lda -d "${USER}" -o "plugin/quota=maildir:User quota:noenforcing"
From: postmaster@${DOMAIN}
Subject: quota warning
Your mailbox is now ${PERCENT}% full.
EOF

View File

@ -1,108 +1,92 @@
#! /bin/bash
##########################################################################
# >> DEFAULT VARS
#
# add them here.
# Example: DEFAULT_VARS["KEY"]="VALUE"
# >> SETUP DEFAULT VALUES
##########################################################################
declare -A DEFAULT_VARS
DEFAULT_VARS["ENABLE_CLAMAV"]="${ENABLE_CLAMAV:=0}"
DEFAULT_VARS["ENABLE_SPAMASSASSIN"]="${ENABLE_SPAMASSASSIN:=0}"
DEFAULT_VARS["ENABLE_POP3"]="${ENABLE_POP3:=0}"
DEFAULT_VARS["ENABLE_FAIL2BAN"]="${ENABLE_FAIL2BAN:=0}"
DEFAULT_VARS["ENABLE_MANAGESIEVE"]="${ENABLE_MANAGESIEVE:=0}"
DEFAULT_VARS["ENABLE_FETCHMAIL"]="${ENABLE_FETCHMAIL:=0}"
DEFAULT_VARS["FETCHMAIL_POLL"]="${FETCHMAIL_POLL:=300}"
DEFAULT_VARS["ENABLE_LDAP"]="${ENABLE_LDAP:=0}"
DEFAULT_VARS["ENABLE_QUOTAS"]="${ENABLE_QUOTAS:=1}"
DEFAULT_VARS["LDAP_START_TLS"]="${LDAP_START_TLS:="no"}"
DEFAULT_VARS["DOVECOT_TLS"]="${DOVECOT_TLS:="no"}"
DEFAULT_VARS["DOVECOT_MAILBOX_FORMAT"]="${DOVECOT_MAILBOX_FORMAT:="maildir"}"
DEFAULT_VARS["ENABLE_POSTGREY"]="${ENABLE_POSTGREY:=0}"
DEFAULT_VARS["POSTGREY_DELAY"]="${POSTGREY_DELAY:=300}"
DEFAULT_VARS["POSTGREY_MAX_AGE"]="${POSTGREY_MAX_AGE:=35}"
DEFAULT_VARS["POSTGREY_AUTO_WHITELIST_CLIENTS"]="${POSTGREY_AUTO_WHITELIST_CLIENTS:=5}"
DEFAULT_VARS["POSTGREY_TEXT"]="${POSTGREY_TEXT:="Delayed by postgrey"}"
DEFAULT_VARS["POSTFIX_MESSAGE_SIZE_LIMIT"]="${POSTFIX_MESSAGE_SIZE_LIMIT:=10240000}" # ~10 MB by default
DEFAULT_VARS["POSTFIX_MAILBOX_SIZE_LIMIT"]="${POSTFIX_MAILBOX_SIZE_LIMIT:=0}" # no limit by default
DEFAULT_VARS["POSTFIX_INET_PROTOCOLS"]="${POSTFIX_INET_PROTOCOLS:="all"}"
DEFAULT_VARS["ENABLE_SASLAUTHD"]="${ENABLE_SASLAUTHD:=0}"
DEFAULT_VARS["SMTP_ONLY"]="${SMTP_ONLY:=0}"
DEFAULT_VARS["OVERRIDE_HOSTNAME"]="${OVERRIDE_HOSTNAME}"
DEFAULT_VARS["POSTSCREEN_ACTION"]="${POSTSCREEN_ACTION:="enforce"}"
DEFAULT_VARS["SPOOF_PROTECTION"]="${SPOOF_PROTECTION:=0}"
DEFAULT_VARS["TLS_LEVEL"]="${TLS_LEVEL:="modern"}"
DEFAULT_VARS["ENABLE_SRS"]="${ENABLE_SRS:=0}"
DEFAULT_VARS["SRS_SENDER_CLASSES"]="${SRS_SENDER_CLASSES:="envelope_sender"}"
DEFAULT_VARS["REPORT_RECIPIENT"]="${REPORT_RECIPIENT:=0}"
DEFAULT_VARS["LOGROTATE_INTERVAL"]="${LOGROTATE_INTERVAL:=${REPORT_INTERVAL:-"daily"}}"
DEFAULT_VARS["LOGWATCH_INTERVAL"]="${LOGWATCH_INTERVAL:="none"}"
DEFAULT_VARS["EXPLICITLY_DEFINED_SPAMASSASSIN_SPAM_TO_INBOX"]="$( [ -z "${SPAMASSASSIN_SPAM_TO_INBOX}" ] && echo "0" || echo "1" )" # used for backward compatibility
DEFAULT_VARS["SPAMASSASSIN_SPAM_TO_INBOX"]="${SPAMASSASSIN_SPAM_TO_INBOX:=0}"
DEFAULT_VARS["MOVE_SPAM_TO_JUNK"]="${MOVE_SPAM_TO_JUNK:=1}"
DEFAULT_VARS["VIRUSMAILS_DELETE_DELAY"]="${VIRUSMAILS_DELETE_DELAY:=7}"
DEFAULT_VARS["NETWORK_INTERFACE"]="${NETWORK_INTERFACE:="eth0"}"
# DEFAULT_VARS["DMS_DEBUG"] defined in helper-functions.sh
DOVECOT_MAILBOX_FORMAT="${DOVECOT_MAILBOX_FORMAT:=maildir}"
DOVECOT_TLS="${DOVECOT_TLS:=no}"
ENABLE_CLAMAV="${ENABLE_CLAMAV:=0}"
ENABLE_FAIL2BAN="${ENABLE_FAIL2BAN:=0}"
ENABLE_FETCHMAIL="${ENABLE_FETCHMAIL:=0}"
ENABLE_LDAP="${ENABLE_LDAP:=0}"
ENABLE_MANAGESIEVE="${ENABLE_MANAGESIEVE:=0}"
ENABLE_POP3="${ENABLE_POP3:=0}"
ENABLE_POSTGREY="${ENABLE_POSTGREY:=0}"
ENABLE_QUOTAS="${ENABLE_QUOTAS:=1}"
ENABLE_SASLAUTHD="${ENABLE_SASLAUTHD:=0}"
ENABLE_SPAMASSASSIN="${ENABLE_SPAMASSASSIN:=0}"
ENABLE_SRS="${ENABLE_SRS:=0}"
FETCHMAIL_POLL="${FETCHMAIL_POLL:=300}"
LDAP_START_TLS="${LDAP_START_TLS:=no}"
LOGROTATE_INTERVAL="${LOGROTATE_INTERVAL:=${REPORT_INTERVAL:-daily}}"
LOGWATCH_INTERVAL="${LOGWATCH_INTERVAL:=none}"
MOVE_SPAM_TO_JUNK="${MOVE_SPAM_TO_JUNK:=1}"
NETWORK_INTERFACE="${NETWORK_INTERFACE:=eth0}"
ONE_DIR="${ONE_DIR:=0}"
OVERRIDE_HOSTNAME="${OVERRIDE_HOSTNAME}"
POSTGREY_AUTO_WHITELIST_CLIENTS="${POSTGREY_AUTO_WHITELIST_CLIENTS:=5}"
POSTGREY_DELAY="${POSTGREY_DELAY:=300}"
POSTGREY_MAX_AGE="${POSTGREY_MAX_AGE:=35}"
POSTGREY_TEXT="${POSTGREY_TEXT:=Delayed by Postgrey}"
POSTFIX_INET_PROTOCOLS="${POSTFIX_INET_PROTOCOLS:=all}"
POSTFIX_MAILBOX_SIZE_LIMIT="${POSTFIX_MAILBOX_SIZE_LIMIT:=0}" # no limit by default
POSTFIX_MESSAGE_SIZE_LIMIT="${POSTFIX_MESSAGE_SIZE_LIMIT:=10240000}" # ~10 MB by default
POSTSCREEN_ACTION="${POSTSCREEN_ACTION:=enforce}"
REPORT_RECIPIENT="${REPORT_RECIPIENT:="0"}"
SMTP_ONLY="${SMTP_ONLY:=0}"
SPAMASSASSIN_SPAM_TO_INBOX_IS_SET="$( if [[ -n ${SPAMASSASSIN_SPAM_TO_INBOX+'set'} ]]; then echo true ; else echo false ; fi )"
SPAMASSASSIN_SPAM_TO_INBOX="${SPAMASSASSIN_SPAM_TO_INBOX:=0}"
SPOOF_PROTECTION="${SPOOF_PROTECTION:=0}"
SRS_SENDER_CLASSES="${SRS_SENDER_CLASSES:=envelope_sender}"
SSL_TYPE="${SSL_TYPE:=''}"
TLS_LEVEL="${TLS_LEVEL:=modern}"
VIRUSMAILS_DELETE_DELAY="${VIRUSMAILS_DELETE_DELAY:=7}"
##########################################################################
# << DEFAULT VARS
##########################################################################
##########################################################################
# >> GLOBAL VARS
#
# add your global script variables here.
#
# Example: KEY="VALUE"
# >> GLOBAL VARIABLES
##########################################################################
HOSTNAME="$(hostname -f)"
DOMAINNAME="$(hostname -d)"
CHKSUM_FILE=/tmp/docker-mailserver-config-chksum
##########################################################################
# << GLOBAL VARS
##########################################################################
##########################################################################
# >> REGISTER FUNCTIONS
#
# add your new functions/methods here.
# Add your new functions/methods here.
#
# NOTE: position matters when registering a function in stacks. First in First out
# Execution Logic:
# > check functions
# > setup functions
# > fix functions
# > misc functions
# > start-daemons
# NOTE: Position matters when registering a function in stacks.
# First in First out
#
# Execution Logic:
# > check functions
# > setup functions
# > fix functions
# > misc functions
# > start-daemons
#
# Example:
#
# if [[ CONDITION IS MET ]]
# then
# _register_{setup,fix,check,start}_{functions,daemons} "$FUNCNAME"
# _register_{setup,fix,check,start}_{functions,daemons} "${FUNCNAME}"
# fi
#
# Implement them in the section-group: {check,setup,fix,start}
# Implement them in the section-group: {check, setup, fix, start}
#
##########################################################################
function register_functions
{
_notify 'taskgrp' 'Initializing setup'
_notify 'task' 'Registering check,setup,fix,misc and start-daemons functions'
_notify 'tasklog' 'Initializing setup'
_notify 'task' 'Registering check, setup, fix, misc and start-daemons functions'
################### >> check funcs
_register_check_function "_check_environment_variables"
_register_check_function "_check_hostname"
################### << check funcs
################### >> setup funcs
_register_setup_function "_setup_default_vars"
@ -153,14 +137,9 @@ function register_functions
_register_setup_function "_setup_postfix_access_control"
if [[ -n ${AWS_SES_HOST} ]] && [[ -n ${AWS_SES_USERPASS} ]]
then
_register_setup_function "_setup_postfix_relay_hosts"
fi
[[ -n ${DEFAULT_RELAY_HOST} ]] && _register_setup_function "_setup_postfix_default_relay_host"
[[ -n ${RELAY_HOST} ]] && _register_setup_function "_setup_postfix_relay_hosts"
[[ ${ENABLE_POSTFIX_VIRTUAL_TRANSPORT} -eq 1 ]] && _register_setup_function "_setup_postfix_virtual_transport"
[[ -n ${DEFAULT_RELAY_HOST:-''} ]] && _register_setup_function "_setup_postfix_default_relay_host"
[[ -n ${RELAY_HOST:-''} ]] && _register_setup_function "_setup_postfix_relay_hosts"
[[ ${ENABLE_POSTFIX_VIRTUAL_TRANSPORT:-0} -eq 1 ]] && _register_setup_function "_setup_postfix_virtual_transport"
_register_setup_function "_setup_postfix_override_configuration"
_register_setup_function "_setup_environment"
@ -171,11 +150,9 @@ function register_functions
_register_setup_function "_setup_user_patches"
# Compute last as the config files are modified in-place
# compute last as the config files are modified in-place
_register_setup_function "_setup_chksum_file"
################### << setup funcs
################### >> fix funcs
_register_fix_function "_fix_var_mail_permissions"
@ -184,14 +161,10 @@ function register_functions
[[ ${ENABLE_CLAMAV} -eq 0 ]] && _register_fix_function "_fix_cleanup_clamav"
[[ ${ENABLE_SPAMASSASSIN} -eq 0 ]] && _register_fix_function "_fix_cleanup_spamassassin"
################### << fix funcs
################### >> misc funcs
_register_misc_function "_misc_save_states"
################### << misc funcs
################### >> daemon funcs
_register_start_daemon "_start_daemons_cron"
@ -209,14 +182,13 @@ function register_functions
_register_start_daemon "_start_daemons_postfix"
[[ ${ENABLE_SASLAUTHD} -eq 1 ]] && _register_start_daemon "_start_daemons_saslauthd"
[[ ${ENABLE_FAIL2BAN} -eq 1 ]] && _register_start_daemon "_start_daemons_fail2ban" # care :: needs to run after postfix
# care :: needs to run after postfix
[[ ${ENABLE_FAIL2BAN} -eq 1 ]] && _register_start_daemon "_start_daemons_fail2ban"
[[ ${ENABLE_FETCHMAIL} -eq 1 ]] && _register_start_daemon "_start_daemons_fetchmail"
[[ ${ENABLE_CLAMAV} -eq 1 ]] && _register_start_daemon "_start_daemons_clamav"
[[ ${ENABLE_LDAP} -eq 0 ]] && _register_start_daemon "_start_changedetector"
_register_start_daemon "_start_daemons_amavis"
################### << daemon funcs
}
##########################################################################
@ -224,9 +196,9 @@ function register_functions
##########################################################################
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, unless you exactly know what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !
# ! CARE BEGIN
# !
##########################################################################
@ -238,7 +210,6 @@ declare -a FUNCS_FIX
declare -a FUNCS_CHECK
declare -a FUNCS_MISC
declare -a DAEMONS_START
# declare -A HELPERS_EXEC_STATE
##########################################################################
# << CONSTANTS
@ -294,23 +265,22 @@ function display_startup_daemon
${1} &>/dev/null
local RES=${?}
if [[ ${DEFAULT_VARS["DMS_DEBUG"]} -eq 1 ]]
if [[ ${DMS_DEBUG} -eq 1 ]]
then
if [[ ${RES} -eq 0 ]]
then
_notify 'started' " [ OK ]"
_notify 'inf' " OK"
else
echo "false"
_notify 'err' " [ FAILED ]"
_notify 'err' " STARTUP FAILED"
fi
fi
return "${RES}"
}
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, except you know exactly what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !
# ! CARE END
# !
##########################################################################
@ -321,7 +291,7 @@ function display_startup_daemon
function check
{
_notify 'taskgrp' 'Checking configuration'
_notify 'tasklog' 'Checking configuration'
for FUNC in "${FUNCS_CHECK[@]}"
do
@ -336,16 +306,16 @@ function _check_hostname
{
_notify "task" "Check that hostname/domainname is provided or overridden (no default docker hostname/kubernetes) [in ${FUNCNAME[0]}]"
if [[ -n ${DEFAULT_VARS["OVERRIDE_HOSTNAME"]} ]]
if [[ -n ${OVERRIDE_HOSTNAME} ]]
then
export HOSTNAME=${DEFAULT_VARS["OVERRIDE_HOSTNAME"]}
export HOSTNAME=${OVERRIDE_HOSTNAME}
export DOMAINNAME="${HOSTNAME#*.}"
fi
_notify 'inf' "Domain has been set to ${DOMAINNAME}"
_notify 'inf' "Hostname has been set to ${HOSTNAME}"
if ( ! echo "${HOSTNAME}" | grep -E '^(\S+[.]\S+)$' > /dev/null )
if ( ! grep -E '^(\S+[.]\S+)$' <<< "${HOSTNAME}" >/dev/null )
then
_notify 'err' "Setting hostname/domainname is required"
kill "$(< /var/run/supervisord.pid)" && return 1
@ -373,7 +343,7 @@ function _check_environment_variables
function setup
{
_notify 'taskgrp' 'Configuring mail server'
_notify 'tasklog' 'Configuring mail server'
for FUNC in "${FUNCS_SETUP[@]}"
do
${FUNC}
@ -382,45 +352,75 @@ function setup
function _setup_default_vars
{
_notify 'task' "Setting up default variables [in ${FUNCNAME[0]}]"
_notify 'task' "Setting up default variables"
# update POSTMASTER_ADDRESS - must be done done after _check_hostname
DEFAULT_VARS["POSTMASTER_ADDRESS"]="${POSTMASTER_ADDRESS:=postmaster@${DOMAINNAME}}"
POSTMASTER_ADDRESS="${POSTMASTER_ADDRESS:="postmaster@${DOMAINNAME}"}"
# update REPORT_SENDER - must be done done after _check_hostname
DEFAULT_VARS["REPORT_SENDER"]="${REPORT_SENDER:=mailserver-report@${HOSTNAME}}"
DEFAULT_VARS["PFLOGSUMM_SENDER"]="${PFLOGSUMM_SENDER:=${REPORT_SENDER}}"
REPORT_SENDER="${REPORT_SENDER:="mailserver-report@${HOSTNAME}"}"
PFLOGSUMM_SENDER="${PFLOGSUMM_SENDER:=${REPORT_SENDER}}"
# set PFLOGSUMM_TRIGGER here for backwards compatibility
# when REPORT_RECIPIENT is on the old method should be used
# ! needs to be a string comparison
if [[ ${REPORT_RECIPIENT} == "0" ]]
then
DEFAULT_VARS["PFLOGSUMM_TRIGGER"]="${PFLOGSUMM_TRIGGER:="none"}"
PFLOGSUMM_TRIGGER="${PFLOGSUMM_TRIGGER:="none"}"
else
DEFAULT_VARS["PFLOGSUMM_TRIGGER"]="${PFLOGSUMM_TRIGGER:="logrotate"}"
PFLOGSUMM_TRIGGER="${PFLOGSUMM_TRIGGER:="logrotate"}"
fi
# expand address to simplify the rest of the script
if [[ ${REPORT_RECIPIENT} == "0" ]] || [[ ${REPORT_RECIPIENT} == "1" ]]
if [[ ${REPORT_RECIPIENT} == "0" ]] || [[ ${REPORT_RECIPIENT} == "0" ]]
then
REPORT_RECIPIENT="${POSTMASTER_ADDRESS}"
DEFAULT_VARS["REPORT_RECIPIENT"]="${REPORT_RECIPIENT}"
REPORT_RECIPIENT="${REPORT_RECIPIENT}"
fi
DEFAULT_VARS["PFLOGSUMM_RECIPIENT"]="${PFLOGSUMM_RECIPIENT:=${REPORT_RECIPIENT}}"
DEFAULT_VARS["LOGWATCH_RECIPIENT"]="${LOGWATCH_RECIPIENT:=${REPORT_RECIPIENT}}"
PFLOGSUMM_RECIPIENT="${PFLOGSUMM_RECIPIENT:=${REPORT_RECIPIENT}}"
LOGWATCH_RECIPIENT="${LOGWATCH_RECIPIENT:=${REPORT_RECIPIENT}}"
for var in "${!DEFAULT_VARS[@]}"
do
if ! echo "export ${var}=\"${DEFAULT_VARS[${var}]}\"" >>/root/.bashrc
then
_notify 'err' "Unable to set ${var}=${DEFAULT_VARS[${var}]}"
kill -15 "$(< /var/run/supervisord.pid)"
return 1
fi
_notify 'inf' "Set ${var}=${DEFAULT_VARS[${var}]}"
done
{
echo "DOVECOT_MAILBOX_FORMAT=${DOVECOT_MAILBOX_FORMAT}"
echo "DOVECOT_TLS=${DOVECOT_TLS}"
echo "ENABLE_CLAMAV=${ENABLE_CLAMAV}"
echo "ENABLE_FAIL2BAN=${ENABLE_FAIL2BAN}"
echo "ENABLE_FETCHMAIL=${ENABLE_FETCHMAIL}"
echo "ENABLE_LDAP=${ENABLE_LDAP}"
echo "ENABLE_MANAGESIEVE=${ENABLE_MANAGESIEVE}"
echo "ENABLE_POP3=${ENABLE_POP3}"
echo "ENABLE_POSTGREY=${ENABLE_POSTGREY}"
echo "ENABLE_QUOTAS=${ENABLE_QUOTAS}"
echo "ENABLE_SASLAUTHD=${ENABLE_SASLAUTHD}"
echo "ENABLE_SPAMASSASSIN=${ENABLE_SPAMASSASSIN}"
echo "ENABLE_SRS=${ENABLE_SRS}"
echo "FETCHMAIL_POLL=${FETCHMAIL_POLL}"
echo "LDAP_START_TLS=${LDAP_START_TLS}"
echo "LOGROTATE_INTERVAL=${LOGROTATE_INTERVAL}"
echo "LOGWATCH_INTERVAL=${LOGWATCH_INTERVAL}"
echo "MOVE_SPAM_TO_JUNK=${MOVE_SPAM_TO_JUNK}"
echo "NETWORK_INTERFACE=${NETWORK_INTERFACE}"
echo "ONE_DIR=${ONE_DIR}"
echo "OVERRIDE_HOSTNAME=${OVERRIDE_HOSTNAME}"
echo "POSTGREY_AUTO_WHITELIST_CLIENTS=${POSTGREY_AUTO_WHITELIST_CLIENTS}"
echo "POSTGREY_DELAY=${POSTGREY_DELAY}"
echo "POSTGREY_MAX_AGE=${POSTGREY_MAX_AGE}"
echo "POSTGREY_TEXT=${POSTGREY_TEXT}"
echo "POSTFIX_INET_PROTOCOLS=${POSTFIX_INET_PROTOCOLS}"
echo "POSTFIX_MAILBOX_SIZE_LIMIT=${POSTFIX_MAILBOX_SIZE_LIMIT}"
echo "POSTFIX_MESSAGE_SIZE_LIMIT=${POSTFIX_MESSAGE_SIZE_LIMIT}"
echo "POSTSCREEN_ACTION=${POSTSCREEN_ACTION}"
echo "REPORT_RECIPIENT=${REPORT_RECIPIENT}"
echo "SMTP_ONLY=${SMTP_ONLY}"
echo "SPAMASSASSIN_SPAM_TO_INBOX=${SPAMASSASSIN_SPAM_TO_INBOX}"
echo "SPOOF_PROTECTION=${SPOOF_PROTECTION}"
echo "SRS_SENDER_CLASSES=${SRS_SENDER_CLASSES}"
echo "SSL_TYPE=${SSL_TYPE}"
echo "TLS_LEVEL=${TLS_LEVEL}"
echo "VIRUSMAILS_DELETE_DELAY=${VIRUSMAILS_DELETE_DELAY}"
echo "DMS_DEBUG=${DMS_DEBUG}"
} >>/root/.bashrc
}
# File/folder permissions are fine when using docker volumes, but may be wrong
@ -631,11 +631,11 @@ function _setup_dovecot_quota
sed -i "s/mail_plugins = \$mail_plugin/mail_plugins = \$mail_plugins imap_quota/g" /etc/dovecot/conf.d/20-imap.conf
fi
message_size_limit_mb=$((DEFAULT_VARS["POSTFIX_MESSAGE_SIZE_LIMIT"] / 1000000))
mailbox_limit_mb=$((DEFAULT_VARS["POSTFIX_MAILBOX_SIZE_LIMIT"] / 1000000))
local MESSAGE_SIZE_LIMIT_MB=$((POSTFIX_MESSAGE_SIZE_LIMIT / 1000000))
local MAILBOX_LIMIT_MB=$((POSTFIX_MAILBOX_SIZE_LIMIT / 1000000))
sed -i "s/quota_max_mail_size =.*/quota_max_mail_size = ${message_size_limit_mb}$([[ ${message_size_limit_mb} -eq 0 ]] && echo "" || echo "M")/g" /etc/dovecot/conf.d/90-quota.conf
sed -i "s/quota_rule = \*:storage=.*/quota_rule = *:storage=${mailbox_limit_mb}$([[ ${mailbox_limit_mb} -eq 0 ]] && echo "" || echo "M")/g" /etc/dovecot/conf.d/90-quota.conf
sed -i "s/quota_max_mail_size =.*/quota_max_mail_size = ${MESSAGE_SIZE_LIMIT_MB}$([[ ${MESSAGE_SIZE_LIMIT_MB} -eq 0 ]] && echo "" || echo "M")/g" /etc/dovecot/conf.d/90-quota.conf
sed -i "s/quota_rule = \*:storage=.*/quota_rule = *:storage=${MAILBOX_LIMIT_MB}$([[ ${MAILBOX_LIMIT_MB} -eq 0 ]] && echo "" || echo "M")/g" /etc/dovecot/conf.d/90-quota.conf
if [[ ! -f /tmp/docker-mailserver/dovecot-quotas.cf ]]
then
@ -843,13 +843,13 @@ function _setup_postfix_postscreen
function _setup_postfix_sizelimits
{
_notify 'inf' "Configuring postfix message size limit"
postconf -e "message_size_limit = ${DEFAULT_VARS["POSTFIX_MESSAGE_SIZE_LIMIT"]}"
postconf -e "message_size_limit = ${POSTFIX_MESSAGE_SIZE_LIMIT}"
_notify 'inf' "Configuring postfix mailbox size limit"
postconf -e "mailbox_size_limit = ${DEFAULT_VARS["POSTFIX_MAILBOX_SIZE_LIMIT"]}"
postconf -e "mailbox_size_limit = ${POSTFIX_MAILBOX_SIZE_LIMIT}"
_notify 'inf' "Configuring postfix virtual mailbox size limit"
postconf -e "virtual_mailbox_limit = ${DEFAULT_VARS["POSTFIX_MAILBOX_SIZE_LIMIT"]}"
postconf -e "virtual_mailbox_limit = ${POSTFIX_MAILBOX_SIZE_LIMIT}"
}
function _setup_postfix_smtputf8
@ -909,8 +909,8 @@ function _setup_saslauthd
_notify 'inf' "Configuring Cyrus SASL"
# checking env vars and setting defaults
[[ -z ${SASLAUTHD_MECHANISMS} ]] && SASLAUTHD_MECHANISMS=pam
[[ ${SASLAUTHD_MECHANISMS} == ldap ]] && [[ -z ${SASLAUTHD_LDAP_SEARCH_BASE} ]] && SASLAUTHD_MECHANISMS=pam
[[ -z ${SASLAUTHD_MECHANISMS:-} ]] && SASLAUTHD_MECHANISMS=pam
[[ ${SASLAUTHD_MECHANISMS:-} == ldap ]] && [[ -z ${SASLAUTHD_LDAP_SEARCH_BASE} ]] && SASLAUTHD_MECHANISMS=pam
[[ -z ${SASLAUTHD_LDAP_SERVER} ]] && SASLAUTHD_LDAP_SERVER=localhost
[[ -z ${SASLAUTHD_LDAP_FILTER} ]] && SASLAUTHD_LDAP_FILTER='(&(uniqueIdentifier=%u)(mailEnabled=TRUE))'
@ -1109,6 +1109,7 @@ function _setup_ssl
_notify 'inf' "TLS configured with 'modern' ciphers"
;;
"intermediate" )
# Postfix configuration
sed -i -r 's/^smtpd_tls_mandatory_protocols =.*$/smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3/' /etc/postfix/main.cf
@ -1122,7 +1123,11 @@ function _setup_ssl
_notify 'inf' "TLS configured with 'intermediate' ciphers"
;;
* ) _notify 'err' 'TLS_LEVEL not found _setup_ssl' ;;
* )
_notify 'err' 'TLS_LEVEL not found [ in _setup_ssl ]'
;;
esac
# SSL certificate Configuration
@ -1265,7 +1270,7 @@ function _setup_ssl
fi
;;
'' )
# ${SSL_TYPE}=empty, no SSL certificate, plain text access
# no SSL certificate, plain text access
# Dovecot configuration
sed -i -e 's~#disable_plaintext_auth = yes~disable_plaintext_auth = no~g' /etc/dovecot/conf.d/10-auth.conf
@ -1304,10 +1309,11 @@ function _setup_docker_permit
_notify 'task' 'Setting up PERMIT_DOCKER Option'
local CONTAINER_IP CONTAINER_NETWORK
unset CONTAINER_NETWORKS
declare -a CONTAINER_NETWORKS
CONTAINER_IP=$(ip addr show "${DEFAULT_VARS['NETWORK_INTERFACE']}" | grep 'inet ' | sed 's/[^0-9\.\/]*//g' | cut -d '/' -f 1)
CONTAINER_IP=$(ip addr show "${NETWORK_INTERFACE}" | grep 'inet ' | sed 's/[^0-9\.\/]*//g' | cut -d '/' -f 1)
CONTAINER_NETWORK="$(echo "${CONTAINER_IP}" | cut -d '.' -f1-2).0.0"
while read -r IP
@ -1430,35 +1436,7 @@ function _setup_postfix_relay_hosts
{
_notify 'task' 'Setting up Postfix Relay Hosts'
# copy old AWS_SES variables to new variables
if [[ -z ${RELAY_HOST} ]]
then
if [[ -n ${AWS_SES_HOST} ]]
then
_notify 'inf' "Using deprecated AWS_SES environment variables"
RELAY_HOST="${AWS_SES_HOST}"
fi
fi
if [[ -z ${RELAY_PORT} ]]
then
if [[ -z ${AWS_SES_PORT} ]]
then
RELAY_PORT=25
else
RELAY_PORT=${AWS_SES_PORT}
fi
fi
if [[ -z ${RELAY_USER} ]]
then
if [[ -n ${AWS_SES_USERPASS} ]]
then
# NB this will fail if the password contains a colon!
RELAY_USER=$(echo "${AWS_SES_USERPASS}" | cut -f 1 -d ":")
RELAY_PASSWORD=$(echo "${AWS_SES_USERPASS}" | cut -f 2 -d ":")
fi
fi
[[ -z ${RELAY_PORT} ]] && RELAY_PORT=25
_notify 'inf' "Setting up outgoing email relaying via ${RELAY_HOST}:${RELAY_PORT}"
@ -1676,7 +1654,7 @@ function _setup_security_stack
sed -i "s/\$final_spam_destiny.*=.*$/\$final_spam_destiny = D_BOUNCE;/g" /etc/amavis/conf.d/49-docker-mailserver
sed -i "s/\$final_bad_header_destiny.*=.*$/\$final_bad_header_destiny = D_BOUNCE;/g" /etc/amavis/conf.d/49-docker-mailserver
if [[ ${DEFAULT_VARS['EXPLICITLY_DEFINED_SPAMASSASSIN_SPAM_TO_INBOX']} == "0" ]]
if ! ${SPAMASSASSIN_SPAM_TO_INBOX_IS_SET}
then
_notify 'warn' "Spam messages WILL NOT BE DELIVERED, you will NOT be notified of ANY message bounced. Please define SPAMASSASSIN_SPAM_TO_INBOX explicitly."
fi
@ -1799,7 +1777,7 @@ function _setup_logwatch
esac
}
function _setup_user_patches()
function _setup_user_patches
{
if [[ -f /tmp/docker-mailserver/user-patches.sh ]]
then
@ -1818,16 +1796,16 @@ function _setup_user_patches()
fi
}
function _setup_environment() {
function _setup_environment
{
_notify 'task' 'Setting up /etc/environment'
local banner="# docker environment"
local var
local BANNER="# Docker Environment"
if ! grep -q "${banner}" /etc/environment
if ! grep -q "${BANNER}" /etc/environment
then
echo "${banner}" >> /etc/environment
echo "VIRUSMAILS_DELETE_DELAY=${DEFAULT_VARS["VIRUSMAILS_DELETE_DELAY"]}" >> /etc/environment
echo "${BANNER}" >> /etc/environment
echo "VIRUSMAILS_DELETE_DELAY=${VIRUSMAILS_DELETE_DELAY}" >> /etc/environment
fi
}
@ -1924,7 +1902,7 @@ function _fix_cleanup_spamassassin
function misc
{
_notify 'taskgrp' 'Starting Misc'
_notify 'tasklog' 'Startin misc'
for FUNC in "${FUNCS_MISC[@]}"
do
@ -1992,7 +1970,7 @@ function _misc_save_states
function start_daemons
{
_notify 'taskgrp' 'Starting mail server'
_notify 'tasklog' 'Starting mail server'
for FUNC in "${DAEMONS_START[@]}"
do
@ -2129,32 +2107,25 @@ function _start_changedetector
supervisorctl start changedetector
}
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, unless you exactly know what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !
# ! CARE BEGIN
# !
# shellcheck source=./helper-functions.sh
. /usr/local/bin/helper-functions.sh
if [[ ${DEFAULT_VARS["DMS_DEBUG"]} -eq 1 ]]
if [[ ${DMS_DEBUG:-0} -eq 1 ]]
then
_notify 'taskgrp' ""
_notify 'taskgrp' "#"
_notify 'taskgrp' "#"
_notify 'taskgrp' "# ENV"
_notify 'taskgrp' "#"
_notify 'taskgrp' "#"
_notify 'taskgrp' ""
_notify 'none'
_notify 'tasklog' 'ENVIRONMENT'
_notify 'none'
printenv
fi
_notify 'taskgrp' ""
_notify 'taskgrp' "#"
_notify 'taskgrp' "#"
_notify 'taskgrp' "# docker-mailserver"
_notify 'taskgrp' "#"
_notify 'taskgrp' "#"
_notify 'taskgrp' ""
_notify 'none'
_notify 'tasklog' 'Welcome to docker-mailserver!'
_notify 'none'
register_functions
@ -2164,17 +2135,15 @@ fix
misc
start_daemons
_notify 'taskgrp' ""
_notify 'taskgrp' "#"
_notify 'taskgrp' "# ${HOSTNAME} is up and running"
_notify 'taskgrp' "#"
_notify 'taskgrp' ""
_notify 'none'
_notify 'tasklog' "${HOSTNAME} is up and running"
_notify 'none'
touch /var/log/mail/mail.log
tail -fn 0 /var/log/mail/mail.log
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# ! CARE --> DON'T CHANGE, unless you exactly know what you are doing
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !
# ! CARE END
# !
exit 0

@ -1 +1 @@
Subproject commit 03608115df2071fff4eaaff1605768c275e5f81f
Subproject commit dcaec03e32e0b152f8ef9cf14b75296cf5caeaff

View File

@ -2,8 +2,8 @@ load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
# load the helper function into current context
# shellcheck source=../target/helper-functions.sh
. ./target/helper-functions.sh
# shellcheck source=../target/scripts/helper-functions.sh
. ./target/scripts/helper-functions.sh
@test "check helper function: _sanitize_ipv4_to_subnet_cidr" {
output=$(_sanitize_ipv4_to_subnet_cidr 255.255.255.255/0)

View File

@ -1,5 +1,8 @@
ignored:
# disable explicit version for apt install
- DL3008
- DL3015
trustedRegistries:
- docker.io
- quay.io
- ghcr.io

View File

@ -1,7 +1,7 @@
#! /bin/bash
# version v0.1.2 stable
# executed by TravisCI / manually
# version v0.1.3 stable
# executed by CI / manually (via Make)
# task checks files agains linting targets
SCRIPT="lint.sh"
@ -10,7 +10,7 @@ function _get_current_directory
{
if dirname "$(readlink -f "${0}")" &>/dev/null
then
CDIR="$(cd "$(dirname "$(readlink -f "${0}")")" && pwd)"
CDIR="$(dirname "$(readlink -f "${0}")")"
elif realpath -e -L "${0}" &>/dev/null
then
CDIR="$(realpath -e -L "${0}")"
@ -188,13 +188,13 @@ function _shellcheck
function _main
{
case ${1:- } in
case ${1:-} in
'eclint' ) _eclint ;;
'hadolint' ) _hadolint ;;
'shellcheck' ) _shellcheck ;;
*)
__log_failure \
"${SCRIPT}: '${1}' is not a command nor an option. See 'make help'."
"${SCRIPT}: '${1}' is not a command nor an option."
exit 3
;;
esac

View File

@ -18,7 +18,7 @@ function setup_file() {
-e POSTGREY_DELAY=15 \
-e POSTGREY_MAX_AGE=35 \
-e POSTGREY_AUTO_WHITELIST_CLIENTS=5 \
-e POSTGREY_TEXT="Delayed by postgrey" \
-e POSTGREY_TEXT="Delayed by Postgrey" \
-e DMS_DEBUG=0 \
-h mail.my-domain.com -t "${NAME}"
# using postfix availability as start indicator, this might be insufficient for postgrey
@ -43,7 +43,7 @@ function teardown_file() {
run docker exec mail_with_postgrey /bin/bash -c "grep '^POSTGREY_OPTS=\"--inet=127.0.0.1:10023 --delay=15 --max-age=35 --auto-whitelist-clients=5\"$' /etc/default/postgrey | wc -l"
assert_success
assert_output 1
run docker exec mail_with_postgrey /bin/bash -c "grep '^POSTGREY_TEXT=\"Delayed by postgrey\"$' /etc/default/postgrey | wc -l"
run docker exec mail_with_postgrey /bin/bash -c "grep '^POSTGREY_TEXT=\"Delayed by Postgrey\"$' /etc/default/postgrey | wc -l"
assert_success
assert_output 1
}

View File

@ -3,8 +3,7 @@
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
# shellcheck disable=SC2034
NAME=tvial/docker-mailserver:testing
NAME=${NAME:-'docker.io/mailserver/testing:latest'}
# default timeout is 120 seconds
TEST_TIMEOUT_IN_SECONDS=${TEST_TIMEOUT_IN_SECONDS-120}
@ -180,6 +179,7 @@ function wait_for_service() {
function wait_for_changes_to_be_detected_in_container() {
local CONTAINER_NAME="${1}"
local TIMEOUT=${TEST_TIMEOUT_IN_SECONDS}
# shellcheck disable=SC2016
repeat_in_container_until_success_or_timeout "${TIMEOUT}" "${CONTAINER_NAME}" bash -c 'source /usr/local/bin/helper-functions.sh; cmp --silent -- <(_monitored_files_checksums) "${CHKSUM_FILE}" >/dev/null'
}
@ -187,5 +187,7 @@ function wait_for_changes_to_be_detected_in_container() {
function wait_for_empty_mail_queue_in_container() {
local CONTAINER_NAME="${1}"
local TIMEOUT=${TEST_TIMEOUT_IN_SECONDS}
# shellcheck disable=SC2016
repeat_in_container_until_success_or_timeout "${TIMEOUT}" "${CONTAINER_NAME}" bash -c '[[ $(mailq) == *"Mail queue is empty"* ]]'
}

View File

@ -1138,7 +1138,7 @@ EOF
# dovecot and postfix has been restarted
wait_for_service mail postfix
wait_for_service mail dovecot
sleep 5
sleep 10
# send some big emails
run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/quota-exceeded.txt"
@ -1151,6 +1151,7 @@ EOF
# check for quota warn message existence
run repeat_until_success_or_timeout 20 sh -c "docker exec mail sh -c 'grep \"Subject: quota warning\" /var/mail/otherdomain.tld/quotauser/new/ -R'"
assert_success
run repeat_until_success_or_timeout 20 sh -c "docker logs mail | grep 'Quota exceeded (mailbox for user is full)'"
assert_success
@ -1411,7 +1412,7 @@ EOF
@test "checking setup.sh: setup.sh debug inspect" {
run ./setup.sh -c mail debug inspect
assert_success
assert_line --index 0 "Image: tvial/docker-mailserver:testing"
assert_line --index 0 "Image: ${NAME}"
assert_line --index 1 "Container: mail"
}
@test "checking setup.sh: setup.sh debug login ls" {