Documentation/Configuration

Configuration

Configure Zetian SMTP Server according to your needs.

Fluent Builder Pattern

Zetian uses fluent builder pattern for readable and chainable configuration. You can configure all settings in a single expression.

Basic Configuration

Configure your server with SmtpServerBuilder:

ServerConfiguration.cs
using Zetian.Server;

var server = new SmtpServerBuilder()
    // Basic Settings
    .Port(587)                           // Port number
    .ServerName("My SMTP Server")        // Server name
    .MaxMessageSizeMB(25)                // Max message size (MB)
    .MaxRecipients(100)                  // Max number of recipients
    .MaxConnections(50)                  // Max number of connections
    .MaxConnectionsPerIP(10)             // Max connections per IP
    
    // Security
    .RequireAuthentication()             // Authentication required
    .RequireSecureConnection()           // TLS/SSL required
    .Certificate("cert.pfx", "password") // SSL certificate
    
    // SMTP Features
    .EnableSmtpUtf8()                    // UTF-8 support
    .EnablePipelining()                  // Pipeline support
    
    // Timeout Settings
    .ConnectionTimeout(TimeSpan.FromMinutes(5))
    .CommandTimeout(TimeSpan.FromSeconds(30))
    
    .Build();

Basic Settings

  • Port - SMTP port number
  • ServerName - Server name
  • MaxMessageSizeMB - Max message size
  • MaxRecipients - Max number of recipients

Connection Limits

  • MaxConnections - Total connection limit
  • MaxConnectionsPerIP - Limit per IP
  • ConnectionTimeout - Connection timeout
  • CommandTimeout - Command timeout

Authentication Configuration

Configure different authentication methods:

AuthConfiguration.cs
using Zetian.Models;
using Zetian.Server;

// Simple authentication
.SimpleAuthentication("admin", "password123")

// Custom authentication
.AuthenticationHandler(async (username, password) =>
{
    // Database check
    var user = await GetUserAsync(username);
    if (user != null && VerifyPassword(password, user.PasswordHash))
    {
        return AuthenticationResult.Succeed(username);
    }
    return AuthenticationResult.Fail("Invalid credentials");
})

// Multiple authentication mechanisms
.AddAuthenticationMechanism("PLAIN")
.AddAuthenticationMechanism("LOGIN")

PLAIN Auth

Simple username/password

LOGIN Auth

Legacy auth

Custom Auth

Custom handler

Filtering Configuration

Two different filtering approaches:

FilterConfiguration.cs
using Zetian.Server;
using Zetian.Extensions;

// Protocol-Level Filtering (at SMTP command level)
var server = new SmtpServerBuilder()
    .Port(25)
    // Domain filtering
    .WithSenderDomainWhitelist("trusted.com", "partner.org")
    .WithSenderDomainBlacklist("spam.com", "junk.org")
    .WithRecipientDomainWhitelist("mydomain.com")
    
    // Message size limit
    .MaxMessageSizeMB(10)
    
    // Message storage
    .WithFileMessageStore(@"C:\smtp_messages", createDateFolders: true)
    .Build();

// Event-Based Filtering (after message is received)
server.AddSpamFilter(new[] { "spam.com", "junk.org" });
server.AddSizeFilter(10 * 1024 * 1024); // 10MB
server.AddAllowedDomains("example.com");

Protocol-Level Filtering

Early rejection during SMTP commands. More efficient, saves bandwidth.

  • • At MAIL FROM/RCPT TO level
  • • Bandwidth savings
  • • Fast rejection

Event-Based Filtering

Filtering after message is received. More flexible, can check content.

  • • Full message content check
  • • Complex logic support
  • • Dynamic filters

Rate Limiting

Speed limiting for spam protection:

RateLimiting.cs
using Zetian.Server;
using Zetian.Models;
using Zetian.Extensions;

// Rate limiting configuration
var rateLimitConfig = new RateLimitConfiguration
{
    MaxRequests = 100,             // Maximum number of requests
    UseSlidingWindow = false,      // Fixed or sliding window
    Window = TimeSpan.FromHours(1) // Time window
};

server.AddRateLimiting(rateLimitConfig);

// Alternative: Ready-made configurations
server.AddRateLimiting(RateLimitConfiguration.PerDay(1000));  // 1000 per day
server.AddRateLimiting(RateLimitConfiguration.PerHour(100));  // 100 per hour
server.AddRateLimiting(RateLimitConfiguration.PerMinute(10)); // 10 per minute

Important Note

Rate limiting works based on IP. Be careful in localhost tests. You can keep limits high in development environment.

Health Check Configuration

Monitor your SMTP server's health with built-in HTTP endpoints:

HealthCheck.cs
using Zetian.Server;
using Zetian.HealthCheck.Models;
using Zetian.HealthCheck.Options;
using Zetian.HealthCheck.Extensions;

// Simple health check setup
var server = new SmtpServerBuilder()
    .Port(25)
    .Build();

// Enable health check on port 8080 (localhost)
var healthCheck = server.EnableHealthCheck(8080);

// Or bind to all interfaces
var healthCheck = server.EnableHealthCheck("0.0.0.0", 8080);

// Or with custom service options
var serviceOptions = new HealthCheckServiceOptions
{
    // Define HTTP prefixes to listen on
    Prefixes = new() { "http://+:8080/health/" },  // Listen on all interfaces
    DegradedStatusCode = 200  // HTTP status code for degraded state
};

// SMTP health check options
var smtpOptions = new SmtpHealthCheckOptions
{
    CheckMemoryUsage = true,          // Include memory metrics
    DegradedThresholdPercent = 60,    // 60% utilization = degraded
    UnhealthyThresholdPercent = 85    // 85% utilization = unhealthy
};

var healthCheck = server.EnableHealthCheck(serviceOptions, smtpOptions);

// Start server with health check and custom checks
await server.StartWithHealthCheckAsync(8080, healthService =>
{
    // Add custom health checks
    healthService.AddHealthCheck("database", async (ct) =>
    {
        try
        {
            // Check database connection
            await CheckDatabaseAsync();
            return HealthCheckResult.Healthy("Database connected");
        }
        catch (Exception ex)
        {
            return HealthCheckResult.Unhealthy("Database unavailable", ex);
        }
    });
});

/health

Overall health status with details about all checks

/livez

Liveness probe for Kubernetes - is the service alive?

/readyz

Readiness probe - is the service ready for traffic?