Zetian.Storage.AmazonS3
1.0.4
Prefix Reserved
dotnet add package Zetian.Storage.AmazonS3 --version 1.0.4
NuGet\Install-Package Zetian.Storage.AmazonS3 -Version 1.0.4
<PackageReference Include="Zetian.Storage.AmazonS3" Version="1.0.4" />
<PackageVersion Include="Zetian.Storage.AmazonS3" Version="1.0.4" />
<PackageReference Include="Zetian.Storage.AmazonS3" />
paket add Zetian.Storage.AmazonS3 --version 1.0.4
#r "nuget: Zetian.Storage.AmazonS3, 1.0.4"
#:package Zetian.Storage.AmazonS3@1.0.4
#addin nuget:?package=Zetian.Storage.AmazonS3&version=1.0.4
#tool nuget:?package=Zetian.Storage.AmazonS3&version=1.0.4
Zetian.Storage.AmazonS3 - S3 Object Storage
Amazon S3 and S3-compatible storage provider for Zetian SMTP Server. Provides enterprise-grade object storage with features including server-side encryption, lifecycle management, versioning, transfer acceleration, intelligent tiering, and support for S3-compatible services like MinIO, Wasabi, and DigitalOcean Spaces. Perfect for organizations requiring scalable, durable, and cost-effective message storage with global accessibility.
⚡ Features
- 🚀 Transfer Acceleration - Fast global uploads
- 🌐 AWS S3 Native - Full Amazon S3 integration
- 📦 Versioning - Keep multiple versions of messages
- 📏 Intelligent Tiering - Automatic cost optimization
- 🏷️ Object Tagging - Organize and manage messages
- 📊 Lifecycle Rules - Automatic archival and expiration
- 🌍 Cross-Region Replication - Geographic redundancy
- ❄️ Storage Classes - Standard, IA, Glacier, Deep Archive
- 🔐 Encryption - SSE-S3, SSE-KMS, and client-side encryption
- 🔀 S3-Compatible - Works with MinIO, Wasabi, DigitalOcean Spaces
📦 Installation
# Install SMTP Server and Storage Provider
dotnet add package Zetian
dotnet add package Zetian.Storage.AmazonS3
🚀 Quick Start
Basic Configuration
using Zetian.Server;
using Zetian.Storage.AmazonS3.Extensions;
// Configure with AWS S3
var server = new SmtpServerBuilder()
.Port(25)
.WithS3Storage(
"AKIAIOSFODNN7EXAMPLE",
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"my-smtp-bucket")
.Build();
await server.StartAsync();
Advanced Configuration
var server = new SmtpServerBuilder()
.Port(25)
.WithS3Storage(
"AKIAIOSFODNN7EXAMPLE",
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"my-smtp-bucket",
config =>
{
config.Region = "us-west-2";
config.KeyPrefix = "messages/";
config.NamingFormat = S3NamingFormat.DateHierarchy;
config.StorageClass = S3StorageClass.Standard;
config.EnableServerSideEncryption = true;
config.CompressMessageBody = true;
config.EnableVersioning = true;
config.EnableLifecycleRules = true;
config.TransitionToIADays = 30;
config.TransitionToGlacierDays = 90;
config.ExpirationDays = 365;
})
.Build();
S3-Compatible Storage
// MinIO
var server = new SmtpServerBuilder()
.Port(25)
.WithS3CompatibleStorage(
"http://localhost:9000",
"minioadmin",
"minioadmin",
"smtp-messages",
config =>
{
config.ForcePathStyle = true; // Required for MinIO
config.Region = "us-east-1";
config.NamingFormat = S3NamingFormat.YearMonth;
config.CompressMessageBody = true;
})
.Build();
🛠️ Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
AccessKeyId |
string | - | AWS Access Key ID |
SecretAccessKey |
string | - | AWS Secret Access Key |
BucketName |
string | - | S3 bucket name (required) |
Region |
string | "us-east-1" | AWS region |
ServiceUrl |
string | - | Custom endpoint for S3-compatible services |
ForcePathStyle |
bool | false | Use path-style addressing |
KeyPrefix |
string | "smtp/" | Prefix for all object keys |
NamingFormat |
enum | DateHierarchy | Object naming format |
StorageClass |
enum | Standard | S3 storage class |
EnableServerSideEncryption |
bool | true | Enable server-side encryption |
KmsKeyId |
string | - | KMS key ID for encryption |
AutoCreateBucket |
bool | true | Create bucket if it doesn't exist |
EnableVersioning |
bool | false | Enable object versioning |
UseTransferAcceleration |
bool | false | Enable transfer acceleration |
EnableLifecycleRules |
bool | false | Configure lifecycle rules |
TransitionToIADays |
int | 30 | Days before moving to Infrequent Access |
TransitionToGlacierDays |
int | 90 | Days before moving to Glacier |
ExpirationDays |
int | 365 | Days before automatic deletion |
MaxMessageSizeMB |
double | 100 | Maximum message size in MB |
CompressMessageBody |
bool | false | Compress message bodies |
EnableRetry |
bool | true | Enable retry logic |
MaxRetryAttempts |
int | 3 | Maximum retry attempts |
RetryDelayMs |
int | 1000 | Delay between retries |
ConnectionTimeoutSeconds |
int | 30 | Connection timeout |
LogErrors |
bool | true | Whether to log errors |
🎯 Usage Examples
Storage Classes
// Standard storage class
config.StorageClass = S3StorageClass.Standard;
// Archive storage
config.StorageClass = S3StorageClass.Glacier;
config.StorageClass = S3StorageClass.DeepArchive;
// Intelligent Tiering (automatic)
config.StorageClass = S3StorageClass.IntelligentTiering;
// Infrequent Access
config.StorageClass = S3StorageClass.StandardInfrequentAccess;
Object Naming Strategies
// Date hierarchy: /2024/01/15/msg-123.eml
config.NamingFormat = S3NamingFormat.DateHierarchy;
// Year-Month: /2024-01/msg-123.eml
config.NamingFormat = S3NamingFormat.YearMonth;
// Hourly partition: /2024/01/15/14/msg-123.eml
config.NamingFormat = S3NamingFormat.HourlyPartition;
// Flat structure - all messages in prefix
config.NamingFormat = S3NamingFormat.Flat;
🔐 Authentication Methods
Access Keys
// Traditional authentication
.WithS3Storage(
accessKeyId: "AKIAIOSFODNN7EXAMPLE",
secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
bucketName: "my-smtp-bucket")
IAM Roles (EC2/ECS/Lambda)
// Use with IAM role (empty credentials)
.WithS3Storage(
"", // Empty access key for IAM role
"", // Empty secret key for IAM role
"my-smtp-bucket",
config =>
{
config.Region = "us-west-2";
})
AWS SSO/Identity Center
// With minimal configuration
.WithS3Storage(
"AKIAIOSFODNN7EXAMPLE",
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"my-smtp-bucket") // Uses default region and settings
🔀 S3-Compatible Services
MinIO
.WithS3CompatibleStorage(
serviceUrl: "http://localhost:9000",
accessKeyId: "minioadmin",
secretAccessKey: "minioadmin",
bucketName: "smtp-messages",
config =>
{
config.ForcePathStyle = true; // Required for MinIO
})
Wasabi
.WithS3CompatibleStorage(
serviceUrl: "https://s3.wasabisys.com",
accessKeyId: "WASABI_ACCESS_KEY",
secretAccessKey: "WASABI_SECRET_KEY",
bucketName: "smtp-messages",
config =>
{
config.Region = "us-east-1";
})
DigitalOcean Spaces
.WithS3CompatibleStorage(
serviceUrl: "https://nyc3.digitaloceanspaces.com",
accessKeyId: "DO_SPACES_KEY",
secretAccessKey: "DO_SPACES_SECRET",
bucketName: "smtp-messages",
config =>
{
config.Region = "nyc3";
})
Backblaze B2
.WithS3CompatibleStorage(
serviceUrl: "https://s3.us-west-000.backblazeb2.com",
accessKeyId: "B2_KEY_ID",
secretAccessKey: "B2_APPLICATION_KEY",
bucketName: "smtp-messages")
📊 Lifecycle Management
Configure Lifecycle Rules
config.EnableLifecycleRules = true;
// Transition rules
config.LifecycleRules = new[]
{
new S3LifecycleRule
{
Id = "MoveToIA",
DaysAfterCreation = 30,
Transition = S3StorageClass.StandardIA
},
new S3LifecycleRule
{
Id = "MoveToGlacier",
DaysAfterCreation = 90,
Transition = S3StorageClass.Glacier
},
new S3LifecycleRule
{
Id = "DeleteOld",
DaysAfterCreation = 365,
Expiration = true
}
};
🔒 Security Features
Server-Side Encryption
// SSE-S3 (AES-256)
config.EnableServerSideEncryption = true;
// SSE-KMS
config.EnableServerSideEncryption = true;
config.KmsKeyId = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";
Bucket Policies
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:user/smtp-app"},
"Action": ["s3:PutObject", "s3:GetObject"],
"Resource": "arn:aws:s3:::my-smtp-bucket/*"
}
]
}
📦 Versioning & Recovery
// Enable versioning
config.EnableVersioning = true;
// List all versions
var versions = await s3Client.ListObjectVersionsAsync(
new ListObjectVersionsRequest
{
BucketName = "my-smtp-bucket",
Prefix = "messages/"
});
// Restore specific version
await s3Client.CopyObjectAsync(
sourceBucket: "my-smtp-bucket",
sourceKey: "messages/msg-123.eml",
sourceVersionId: "versionId123",
destinationBucket: "my-smtp-bucket",
destinationKey: "messages/msg-123-restored.eml");
🚀 Performance Optimization
Transfer Acceleration
// Enable for faster global uploads
config.UseTransferAcceleration = true;
🔧 Troubleshooting
Common Issues
Access Denied
// Check IAM permissions
// Required: s3:PutObject, s3:GetObject, s3:DeleteObject
// For bucket creation: s3:CreateBucket, s3:PutBucketPolicy
Slow Uploads
// Enable transfer acceleration
config.UseTransferAcceleration = true;
// Use appropriate region
config.Region = "us-east-1"; // Same as bucket region
Glacier Retrieval
// Initiate restore
await s3Client.RestoreObjectAsync(new RestoreObjectRequest
{
BucketName = "my-smtp-bucket",
Key = "messages/msg-123.eml",
Days = 1,
RestoreRequest = new RestoreRequest
{
Days = 1,
Tier = RestoreTier.Expedited // 1-5 minutes
// Tier = RestoreTier.Standard // 3-5 hours
// Tier = RestoreTier.Bulk // 5-12 hours
}
});
📋 Requirements
- .NET 6.0, 7.0, 8.0, 9.0, or 10.0
- Zetian SMTP Server package
- For KMS: KMS key permissions
- AWSSDK.S3 package (included)
- AWS Account or S3-compatible service
- For Transfer Acceleration: Enabled on bucket
📚 Documentation & Support
- Issues: GitHub Issues
- Examples: GitHub Examples
- Discussions: GitHub Discussions
- Documentation: Zetian Documentation
- AWS S3 Docs: Amazon S3 Documentation
📄 License
MIT License - see LICENSE
Built with ❤️ for the .NET community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AWSSDK.S3 (>= 4.0.13.1)
- Zetian.Storage (>= 1.0.6)
-
net6.0
- AWSSDK.S3 (>= 4.0.13.1)
- Zetian.Storage (>= 1.0.6)
-
net7.0
- AWSSDK.S3 (>= 4.0.13.1)
- Zetian.Storage (>= 1.0.6)
-
net8.0
- AWSSDK.S3 (>= 4.0.13.1)
- Zetian.Storage (>= 1.0.6)
-
net9.0
- AWSSDK.S3 (>= 4.0.13.1)
- Zetian.Storage (>= 1.0.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
All changes are detailed at https://zetian.soferity.com/changelog.