Standards & Reference

Mail Server

Self-hosted mail server running Stalwart on DigitalOcean.

Server Details

SettingValue
ProviderDigitalOcean
Droplet ID548284048
Droplet Namemail-server
IP Address192.241.158.87
RegionNYC1
Sizes-1vcpu-2gb (1 vCPU, 2GB RAM, 50GB disk)
OSUbuntu 24.04 LTS
Mail ServerStalwart 0.11.8

SSH Access

Root login is disabled. Use the deploy user:

ssh deploy@192.241.158.87

SSH key: ~/.ssh/id_ed25519 (ed25519, fingerprint: 54:29:7c:94:e2:70:f5:0c:1a:8c:4f:46:a3:7f:c4:21)

Admin Access

SettingValue
Web UIhttps://192.241.158.87
APIhttp://192.241.158.87:8080/api
Admin Useradmin
Admin PasswordlfA791f9gk

Credentials are also stored on the server at /root/.email-creds.

Configured Domains

epicflowstate.ai

EmailPassword
help@epicflowstate.aiwyppdHbXfVeOw1P4

epicdigital.team

EmailPassword
help@epicdigital.teamqs6LC9LsdKaP6Ebb

Email Client Settings

ProtocolServerPortSecurity
IMAP192.241.158.87993SSL/TLS
POP3192.241.158.87995SSL/TLS
SMTP192.241.158.87465SSL/TLS
SMTP192.241.158.87587STARTTLS

Ports

PortServiceStatus
22SSHOpen
25SMTP (inbound)Blocked by DO (pending support ticket)
110POP3Open
143IMAPOpen
443HTTPS (Web UI)Open
465SMTPSOpen
587SubmissionOpen
993IMAPSOpen
995POP3SOpen
4190ManageSieveOpen
8080Management APIOpen

DNS Records

epicflowstate.ai (Cloudflare)

Type    Name                      Value
A       mail                      192.241.158.87 (proxy OFF)
MX      @                         10 mail.epicflowstate.ai
TXT     @                         v=spf1 mx -all
TXT     default._domainkey        v=DKIM1; k=rsa; h=sha256; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsP0qn3TF4bdhcBCz4HoiZWhmizWxqcSJQLCXFU4zeauXpBf/UuCJdO7UW4l8XRsIdRxdcvlAgXZ0y6n8PVSN7bQT94l5zVNRKek/xHvDTQkxXZZ25y5GPpZWwZGd7PNu0UzxxE8MIjpP+gpjaFdVwVrIagiE36jnc4dUAHccdDhtdMpeWRjR79RJwLu3e+X3Wjq5C+pMzsxS6u6FpZ9oL7Mcqyq00MtpJbCblOC7svwOmma224VB+BWxS7B/dfE5fdLjfT5NZYEWEejHJm7kMriBzUz4M+7pMhs38fNIz2isPiSb9G1rdN3kYPIANcv76fUc0MVmOohPBiw+RDDlrQIDAQAB
TXT     _dmarc                    v=DMARC1; p=reject; rua=mailto:postmaster@epicflowstate.ai

epicdigital.team

Type    Name                      Value
A       mail                      192.241.158.87
MX      @                         10 mail.epicdigital.team
TXT     @                         v=spf1 mx -all
TXT     default._domainkey        v=DKIM1; k=rsa; h=sha256; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn3y5w83aIdTxVFaG1E97aaBLOwtJ3gfbxwk3fOUAbJhdVVsXjC+DDM32zcYEgVbbvgOaVMnWL7U+5XvZur3DUL9MoKwFqCplJy7NeDvlHwVwCPAU/YUMlv32KgUvBfAFtAeMespatUfvDZKodY04svT8nqgixrWRqfC7MEWdq9UQFUSxqPSszSLg0J8C5tUDLCoo29awudgTM+g3MxWfm8hdL6MIk9BVEFYIWLWuAD47zp7/EnHwik78rAKDxaBgV49V1KGxQFoN7hTM3KYElzUDztTXqDNuEVKcCqd89eJXXSEh2QjsIER2qCLcE+HfEmdQCvazZ+AD3prQr5er1wIDAQAB
TXT     _dmarc                    v=DMARC1; p=reject; rua=mailto:postmaster@epicdigital.team

Security Hardening

SSH Hardening

  • Root login: Disabled
  • Password authentication: Disabled
  • Key-based auth: Required
  • Max auth tries: 3
  • Allowed users: deploy only

Config: /etc/ssh/sshd_config.d/hardening.conf

fail2ban

Active jails:

  • sshd - Bans IPs after 3 failed attempts for 1 hour

Config: /etc/fail2ban/jail.local

Check status:

sudo fail2ban-client status
sudo fail2ban-client status sshd

Automatic Security Updates

Enabled via unattended-upgrades. Config: /etc/apt/apt.conf.d/20auto-upgrades

Firewall (UFW)

sudo ufw status

Open ports: 22, 25, 80, 110, 143, 443, 465, 587, 993, 995, 4190, 8080

Service Management

# Check status
sudo systemctl status stalwart-mail

# Restart
sudo systemctl restart stalwart-mail

# View logs
sudo journalctl -u stalwart-mail -f

# Stalwart logs
ls /opt/stalwart-mail/logs/

Stalwart Configuration

  • Config file: /opt/stalwart-mail/etc/config.toml
  • Data directory: /opt/stalwart-mail/data
  • Logs directory: /opt/stalwart-mail/logs

REST API Examples

Authentication

Use Basic Auth with admin credentials:

AUTH=$(echo -n "admin:lfA791f9gk" | base64)
curl -H "Authorization: Basic $AUTH" http://192.241.158.87:8080/api/principal

List all accounts

curl -s -H "Authorization: Basic $AUTH" http://192.241.158.87:8080/api/principal | jq .

Create a new mailbox

curl -X POST http://192.241.158.87:8080/api/principal \
  -H "Authorization: Basic $AUTH" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "individual",
    "name": "user@epicflowstate.ai",
    "secrets": ["SecurePassword123"],
    "emails": ["user@epicflowstate.ai"],
    "quota": 1073741824
  }'

Get DNS records for a domain

curl -s -H "Authorization: Basic $AUTH" \
  http://192.241.158.87:8080/api/dns/records/epicflowstate.ai | jq .

Pending Tasks

  • [ ] DigitalOcean support ticket to unblock port 25 for inbound mail
  • [ ] Set up TLS certificates with Let's Encrypt
  • [ ] Configure reverse DNS (PTR record) via DigitalOcean

Resources

Previous
Nightly Automation