Amazon S3¶
This document covers configuration specific to the Amazon Web Services S3 (Simple Storage Service). See also the base S3 configuration in S3-compatible Storages.
plugin {
# Basic configuration (v2.3.10+):
obox_fs = aws-s3:https://BUCKETNAME.s3.REGION.amazonaws.com/?auth_role=s3access®ion=REGION¶meters
# Basic configuration (old versions):
#obox_fs = s3:https://ACCESSKEY:SECRET@BUCKETNAME.s3.REGION.amazonaws.com/?region=REGION¶meters
}
Parameter |
Description |
---|---|
See S3-compatible Storages for all S3 parameters. |
IAM authentication¶
New in version 2.3.10.
Dovecot supports AWS Identity and Access Management (IAM) for authenticating requests to AWS S3 using the AWS EC2 Instance Metadata Service (IMDS), solely version 2 of IMDS (IMDSv2) is supported.
Using IAM allows running Dovecot with S3 Storage while not keeping the credentials in the configuration.
A requirement for using IMDSv2 is that Dovecot is running on an AWS EC2
instance, otherwise the IMDS will not be reachable. Additionally an IAM role
must be configured which allows trusted entities, EC2 in this case, to
assume that role. The role (for example s3access
) that will be assumed must
have the AmazonS3FullAccess
policy attached.
The auth_role
can be configured as a URL parameter which specifies the IAM
role to be assumed. If no auth_role
is configured, no IAM lookup will be
done.
plugin {
obox_fs = aws-s3:https://mails.s3.eu-central-1.amazonaws.com/?auth_role=s3access®ion=eu-central-1
}
When using IAM you must ensure that the fs-auth
service has proper
permissions/owner. Configure the user for the fs-auth listener to be the same
as for mail_uid
.
mail_uid = vmail
service fs-auth {
unix_listener fs-auth {
user = vmail
}
}
For more information about IAM roles for EC2 please refer to: IAM roles for Amazon EC2
For general information about IAM: IAM UserGuide
Manual authentication¶
Get ACCESSKEY and SECRET from www.aws.amazon.com
-> My account -> Security credentials -> Access credentials. Create the
BUCKETNAME
from AWS Management Console -> S3 -> Create Bucket.
If the ACCESSKEY
or SECRET
contains any special characters, they can be
%hex-encoded.
Note
dovecot.conf
handles %variable expansion internally as well, so % needs
to be escaped as %% and ‘:’ needs to be escaped as %%3A. For example if the
SECRET is “foo:bar” this would be encoded as
https://ACCESSKEY:foo%%3Abar:s3.example.com/
. This double-%% escaping is
needed only when the string is read from dovecot.conf
- it doesn’t apply
for example if the string comes from a userdb lookup.
Dispersion prefix¶
mail_location = obox:%8Mu/%u:INDEX=~/:CONTROL=~/
As also explained in S3-compatible Storages, AWS can internally shard data much more efficiently by including a dispersion prefix in all S3 paths. Without this the S3 bucket may not scale above a certain limit in the number of S3 requests/second.
We recommend implementing the dispersion prefix by using the first 8 characters of the hex representation of the MD5 hash of the username at the beginning of each object path.
When a S3 bucket is created, AWS creates a single shared partition for the bucket with a default limit of 3,500 requests/second for PUTs/DELETEs/POSTs and 5500 requests/second for GETs (see Best Practices Design Patterns: Optimizing Amazon S3 Performance).
This 3,500 TPS limit is generally too small and quickly surpassed by Dovecot
which results in a spike of 503: Slow Down
log events. It is strongly
recommended to contact AWS to request they manually set up at least 1 layer of
hex partitioning (0-9a-f
), to create 16 dedicated partitions for your
bucket. This “1 hex” layer of partitioning means a theoretical capacity of
56,000 PUTs/DELETEs/POSTs and 88,000 GETs per second.
Per AWS, you can go pretty deep in the number of layers, but most customers do not need more than 2 layers of partitioning, (2 layers = 16x16 = 256 partitions = this would theoretically provide you up to ~896,000 PUT/DELETE/POST TPS and 1,408,000 GET TPS if requests are distributed evenly across the partitions).
DNS¶
AWS instances are known to react badly when high packets per second network traffic is generated by e.g. DNS lookups. Please see Domain Name System lookups.
AWS Signature version¶
S3 driver uses the AWS signature version 2 method by default, but version 4 can be used by adding the region parameter to the S3 URL:
plugin {
obox_index_fs = https://ACCESSKEY:SECRET@BUCKETNAME.s3.eu-central-1.amazonaws.com/?region=eu-central-1
}
aws-s3 scheme¶
New in version 2.3.10.
Using the aws-s3
scheme is a simpler way to configure the S3 driver for
AWS. Currently it’s the same as using the s3
scheme with the following
URL parameters (see HTTP-Based Object Storages):
addhdrvar=x-amz-security-token:%{auth:token}
- Enable using security token if returned by IAM lookup.
loghdr=x-amz-request-id
andloghdr=x-amz-id-2
- Include the these headers’ values in all log messages related to the request. This additional information helps when Troubleshooting Amazon S3 See https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html
Example debug log message, which shows how the x-amz-* headers are included:
Debug: http-client: conn 1.2.3.4:443 [1]: Got 200 response for request [Req1: GET https://test-mails.s3-service.com/?prefix=user%2Fidx%2F]: OK (x-amz-request-id:AABBCC22BB7798869, x-amz-id-2:DeadBeefanXBapRucWGAD1+aWwYMfwmXydlI0mHSuh4ic/j8Ji7gicTsP7xpMQz1IR9eydzeVI=) (took 63 ms + 140 ms in queue)
Example configuration¶
With IAM:
mail_location = obox:%8Mu/%u:INDEX=~/:CONTROL=~/
plugin {
obox_fs = fscache:512M:/var/cache/mails/%4Nu:compress:zstd:3:aws-s3:https://dovecot-mails.s3.eu-central-1.amazonaws.com/?region=eu-central-1&auth_role=s3access
obox_index_fs = compress:zstd:3:aws-s3:https://dovecot-mails.s3.eu-central-1.amazonaws.com/?region=eu-central-1&auth_role=s3access
fts_dovecot_fs = fts-cache:fscache:512M:/var/cache/fts/%4Nu:compress:zstd:3:aws-s3:https://dovecot-mails.s3.eu-central-1.amazonaws.com/%8Mu/%u/fts/?region=eu-central-1&auth_role=s3access
obox_max_parallel_deletes = 1000
}
mail_uid = vmail
service fs-auth {
unix_listener fs-auth {
user = vmail
}
}
Without IAM:
mail_location = obox:%8Mu/%u:INDEX=~/:CONTROL=~/
plugin {
obox_fs = fscache:512M:/var/cache/mails/%4Nu:compress:zstd:3:aws-s3:https://ACCESSKEY:SECRET@dovecot-mails.s3.eu-central-1.amazonaws.com/?region=eu-central-1&auth_role=s3access
obox_index_fs = compress:zstd:3:aws-s3:https://ACCESSKEY:SECRET@dovecot-mails.s3.eu-central-1.amazonaws.com/?region=eu-central-1&auth_role=s3access
fts_dovecot_fs = fts-cache:fscache:512M:/var/cache/fts/%4Nu:compress:zstd:3:aws-s3:https://ACCESSKEY:SECRET@dovecot-mails.s3.eu-central-1.amazonaws.com/%8Mu/%u/fts/?region=eu-central-1&auth_role=s3access
obox_max_parallel_deletes = 1000
}