A complete private email server implementation in C++20 with POP3, IMAP, and SMTP support.
-
POP3 Server (RFC 1939)
- Ports: 110 (plain), 995 (TLS)
- Commands: USER, PASS, STAT, LIST, RETR, DELE, NOOP, RSET, QUIT, TOP, UIDL, CAPA, STLS
- STARTTLS support
-
IMAP Server (RFC 3501)
- Ports: 143 (plain), 993 (TLS)
- Commands: LOGIN, LOGOUT, SELECT, EXAMINE, CREATE, DELETE, RENAME, LIST, STATUS, FETCH, STORE, COPY, SEARCH, EXPUNGE, UID, CAPABILITY, NOOP, STARTTLS
- Message flags and mailbox management
-
SMTP Server (RFC 5321)
- Ports: 25 (MTA), 587 (submission), 465 (TLS)
- Commands: HELO, EHLO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT, VRFY, AUTH, STARTTLS
- AUTH PLAIN and AUTH LOGIN
- Local delivery and relay support
-
Common Features
- TLS/SSL encryption (STARTTLS and implicit TLS)
- SQLite-based user authentication
- Maildir storage format
- Configurable via INI-style config file
- Comprehensive logging
- C++20 compatible compiler (GCC 10+, Clang 12+)
- CMake 3.20+
- Boost 1.74+ (Asio)
- OpenSSL 1.1.1+
- SQLite 3.35+
- Catch2 3.0+ (for tests, automatically fetched if not found)
Ubuntu/Debian:
sudo apt update
sudo apt install build-essential cmake libboost-all-dev libssl-dev libsqlite3-devmacOS (Homebrew):
brew install cmake boost openssl sqlite3Fedora:
sudo dnf install gcc-c++ cmake boost-devel openssl-devel sqlite-devel# Clone the repository
git clone https://github.com/yourusername/email_server.git
cd email_server
# Create build directory
mkdir build && cd build
# Configure
cmake .. -DCMAKE_BUILD_TYPE=Release
# Build
cmake --build . -j$(nproc)
# Run tests
ctest --output-on-failure
# Install (optional)
sudo cmake --install .-DBUILD_TESTS=ON|OFF- Build test programs (default: ON)-DBUILD_TOOLS=ON|OFF- Build utility tools (default: ON)-DENABLE_TLS=ON|OFF- Enable TLS/SSL support (default: ON)-DCMAKE_BUILD_TYPE=Debug|Release- Build type
- Copy the example configuration:
sudo mkdir -p /etc/email_server
sudo cp config/server.conf.example /etc/email_server/server.conf- Edit the configuration file:
sudo nano /etc/email_server/server.confKey settings to configure:
[tls]- SSL certificate and key paths[database]- User database location[storage]- Maildir root directory[smtp]- SMTP server settings including hostname and local domains
./tools/generate_certs.sh mail.example.com /etc/ssl/email_server# Install certbot
sudo apt install certbot
# Obtain certificate
sudo certbot certonly --standalone -d mail.example.com
# Update configuration
# certificate = /etc/letsencrypt/live/mail.example.com/fullchain.pem
# private_key = /etc/letsencrypt/live/mail.example.com/privkey.pemUse the create_user tool to manage users:
# Add a domain
./bin/create_user domain add example.com
# Add a user
./bin/create_user add [email protected]
# List users
./bin/create_user list
# Change password
./bin/create_user passwd [email protected]
# Show user info
./bin/create_user info [email protected]
# Delete user
./bin/create_user delete [email protected]# SMTP server
./bin/smtp_server -c /etc/email_server/server.conf
# POP3 server
./bin/pop3_server -c /etc/email_server/server.conf
# IMAP server
./bin/imap_server -c /etc/email_server/server.confCreate systemd service files for production deployment:
/etc/systemd/system/email-smtp.service:
[Unit]
Description=Email SMTP Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/smtp_server -c /etc/email_server/server.conf
Restart=always
User=mail
Group=mail
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl enable email-smtp email-pop3 email-imap
sudo systemctl start email-smtp email-pop3 email-imapConfigure the following DNS records for your domain:
| Type | Name | Value | Priority |
|---|---|---|---|
| A | mail.example.com | YOUR_IP | - |
| MX | example.com | mail.example.com | 10 |
| TXT | example.com | v=spf1 mx -all | - |
| PTR | YOUR_IP | mail.example.com | - |
For SPF (prevents email spoofing):
v=spf1 mx -all
For DMARC (optional but recommended):
_dmarc.example.com TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
Open the required ports:
# UFW
sudo ufw allow 25/tcp # SMTP
sudo ufw allow 465/tcp # SMTPS
sudo ufw allow 587/tcp # Submission
sudo ufw allow 110/tcp # POP3
sudo ufw allow 995/tcp # POP3S
sudo ufw allow 143/tcp # IMAP
sudo ufw allow 993/tcp # IMAPS
# iptables
sudo iptables -A INPUT -p tcp --dport 25 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 465 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 587 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 110 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 995 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 143 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 993 -j ACCEPTIncoming Mail (IMAP):
- Server: mail.example.com
- Port: 993
- Security: SSL/TLS
- Authentication: Normal password
Incoming Mail (POP3):
- Server: mail.example.com
- Port: 995
- Security: SSL/TLS
- Authentication: Normal password
Outgoing Mail (SMTP):
- Server: mail.example.com
- Port: 587
- Security: STARTTLS
- Authentication: Normal password
- Add Account > Other Mail Account
- Enter your name, email, and password
- Configure manually:
- IMAP: mail.example.com:993 (SSL)
- SMTP: mail.example.com:587 (STARTTLS)
- File > Add Account
- Manual setup > POP or IMAP
- Configure:
- Account type: IMAP
- Incoming: mail.example.com:993 (SSL)
- Outgoing: mail.example.com:587 (TLS)
SMTP:
telnet mail.example.com 25
EHLO client.example.com
AUTH PLAIN <base64-credentials>
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: Test
This is a test.
.
QUITPOP3:
telnet mail.example.com 110
USER [email protected]
PASS password
STAT
LIST
RETR 1
QUITopenssl s_client -connect mail.example.com:993
openssl s_client -connect mail.example.com:995
openssl s_client -starttls smtp -connect mail.example.com:587/var/mail/ # Maildir root
example.com/ # Domain
username/ # User maildir
cur/ # Read messages
new/ # New messages
tmp/ # Temporary
.Sent/ # Sent folder
.Drafts/ # Drafts folder
.Trash/ # Trash folder
/var/lib/email_server/ # Server data
users.db # User database
/etc/email_server/ # Configuration
server.conf # Main config file
/var/log/email_server/ # Logs
smtp.log
pop3.log
imap.log
- Check if the server is running:
systemctl status email-smtp - Check firewall rules:
sudo ufw status - Verify ports are listening:
ss -tlnp | grep -E '(25|110|143|465|587|993|995)'
- Verify user exists:
./bin/create_user info [email protected] - Check password:
./bin/create_user passwd [email protected] - Check logs:
tail -f /var/log/email_server/smtp.log
- Verify certificate:
openssl x509 -in /etc/ssl/email_server/server.crt -text - Check certificate chain:
openssl verify -CAfile ca.crt server.crt - Ensure key matches certificate
- Check maildir permissions:
ls -la /var/mail/example.com/username/ - Verify local_domains in config
- Check SMTP logs for delivery errors
- Always use TLS - Enable STARTTLS on all ports
- Require authentication - Set
require_auth = truefor SMTP - Use strong passwords - Enforce via user management
- Regular updates - Keep the system and dependencies updated
- Firewall - Only open necessary ports
- SPF/DKIM/DMARC - Configure email authentication
- Monitoring - Set up log monitoring for suspicious activity
- Backups - Regularly backup /var/mail and user database
MIT License - See LICENSE file for details.
Contributions are welcome! Please submit pull requests or open issues on GitHub.