Amazon S3 Storage Provider
Highly scalable object storage with S3 and S3-compatible services support.
Universal S3 Support
AWS S3MinIOWasabiKMS EncryptionLifecycle Rules
Installation
dotnet add package Zetian
dotnet add package Zetian.Storage.AmazonS3Quick Start
QuickStart.cs
using Zetian.Server;
using Zetian.Storage.AmazonS3.Extensions;
// Basic S3 setup
var server = new SmtpServerBuilder()
.Port(25)
.WithS3Storage(
"AKIAIOSFODNN7EXAMPLE",
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"my-smtp-bucket")
.Build();
await server.StartAsync();S3-Compatible Services
Works with MinIO, Wasabi, DigitalOcean Spaces, and more:
S3Compatible.cs
// MinIO, Wasabi, or other S3-compatible services
var server = new SmtpServerBuilder()
.Port(25)
.WithS3CompatibleStorage(
"http://localhost:9000", // MinIO endpoint
"minioadmin",
"minioadmin",
"smtp-messages",
config =>
{
config.ForcePathStyle = true; // Required for MinIO
config.Region = "us-east-1";
})
.Build();
// Wasabi example
var server = new SmtpServerBuilder()
.Port(25)
.WithS3CompatibleStorage(
"https://s3.wasabisys.com",
"accessKey",
"secretKey",
"my-bucket",
config =>
{
config.Region = "us-east-1";
})
.Build();MinIO
Self-hosted S3 alternative
Wasabi
80% cheaper than S3
Backblaze B2
Cost-effective storage
Advanced Configuration
AdvancedConfig.cs
var server = new SmtpServerBuilder()
.Port(25)
.WithS3Storage(
accessKeyId: Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID"),
secretAccessKey: Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY"),
bucketName: "smtp-messages",
config =>
{
config.Region = "us-west-2";
config.KeyPrefix = "emails/";
// Server-side encryption
config.EnableServerSideEncryption = true;
config.KmsKeyId = "alias/my-kms-key";
// Versioning
config.EnableVersioning = true;
// Storage class
config.StorageClass = S3StorageClass.StandardInfrequentAccess;
// Performance
config.UseTransferAcceleration = true;
config.CompressMessageBody = true;
})
.Build();Lifecycle Management
Automatically transition objects between storage classes:
Lifecycle.json
// Lifecycle rules for automatic management
{
"Rules": [{
"Id": "ArchiveOldEmails",
"Status": "Enabled",
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
"Days": 90,
"StorageClass": "GLACIER"
},
{
"Days": 365,
"StorageClass": "DEEP_ARCHIVE"
}
],
"Expiration": {
"Days": 730
}
}]
}
// Apply lifecycle policy
var lifecycleConfig = new LifecycleConfiguration
{
Rules = new List<LifecycleRule>
{
new LifecycleRule
{
Id = "EmailArchiving",
Status = LifecycleRuleStatus.Enabled,
Transitions = new List<Transition>
{
new Transition { Days = 30, StorageClass = S3StorageClass.StandardInfrequentAccess },
new Transition { Days = 90, StorageClass = S3StorageClass.Glacier }
}
}
}
};Storage Classes
• Standard: Frequently accessed data
• Standard-IA: Infrequent access (30+ days)
• Glacier Instant: Archive with millisecond retrieval
• Glacier Flexible: 1-12 hour retrieval
• Glacier Deep Archive: 12-48 hour retrieval
Encryption Options
Encryption.cs
// KMS encryption for sensitive data
var putRequest = new PutObjectRequest
{
BucketName = "smtp-messages",
Key = "email-123.eml",
ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS,
ServerSideEncryptionKeyManagementServiceKeyId = "arn:aws:kms:us-west-2:111122223333:key/abc123"
};
// Customer-provided encryption keys
var putRequest = new PutObjectRequest
{
BucketName = "smtp-messages",
Key = "email-123.eml",
ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,
ServerSideEncryptionCustomerProvidedKey = "base64-encoded-256-bit-key",
ServerSideEncryptionCustomerProvidedKeyMD5 = "base64-encoded-md5"
};Configuration Options
| Option | Default | Description |
|---|---|---|
| BucketName | required | S3 bucket name |
| Region | "us-east-1" | AWS region |
| KeyPrefix | "smtp/" | Object key prefix |
| StorageClass | Standard | Default storage class |
| EnableServerSideEncryption | true | Encryption method |
| EnableVersioning | false | Enable object versioning |
Security Best Practices
Use IAM Roles
Avoid hardcoding credentials
Enable Encryption
Use KMS for sensitive data
Bucket Policies
Restrict access properly
Enable Versioning
Protect against overwrites
Cost Optimization
💡
Use appropriate storage classes
Standard-IA for infrequent access saves 45%
💡
Set lifecycle policies
Automatically transition to cheaper tiers
💡
Consider S3-compatible alternatives
Wasabi or Backblaze B2 for lower costs
💡
Enable compression
Reduce storage and transfer costs