Receiving email (online)

This is a follow up (part 3) to Receiving email.

Now that the groundwork for receiving email (with SMTP) and storage email (with the Maildir format) is established, I want to see if we can actually store mail in the wild.

To run the server online, I am renting a VPS from Linode. The VPS is running Debian 13 and has the following (minimal) configuration:

Plan Monthly Hourly RAM CPUs Storage Transfer Network In/Out
Nanode 1 GB $5 $0.0075 1 GB 1 25 GB 1 TB 40 Gbps / 1 Gbps

This is a very lightweight, single-user experimental service so I believe this should be sufficient.

When I started up the server, I was greeted this with warning message:

SMTP ports may be restricted on this Linode. Need to send email? Review our mail server guide, then open a support ticket.

Before choosing Linode, I read through their aforementioned mail server guide which states that "outbound connections on ports 25, 465, and 587 are blocked by default… for some new accounts". Given that, at least at this time, I am only interested in in-bound traffic, I'm hoping this won't be an issue.

Now, I could simply ssh into the remote server and run the code, but I first need to make the service discoverable with DNS records, so that mail assigned to "mail.pokey.onl" can be properly routed to this VPS.

Configuring DNS records and PTR record

This comes in two parts, configured at the domain/DNS level:

  1. A record: maps "mail.pokey.onl" to VPS IP
  2. MX record: maps mail to "mail.pokey.onl"

In my case, my email-specific DNS configuration looks like this:

Type Host Answer Priority
A mail.pokey.onl 96.126.120.46  
MX pokey.onl mail.pokey.onl 10

I also want to configure a PTR Record at the VPS provider level. This is designed to work in the reverse direction of the A record by mapping the VPS IP to the mail server's domain name. With Akamai, I navigated to my Linode, then Network > IP Addresses > Edit RDNS > insert "mail.pokey.onl".

Testing records

After defining the routing information, I took a break to wait for the necessary propagation. Now, we can see that the records are set properly.

Using dig mail.pokey.onl (checking A record):

mail.pokey.onl.		600	IN	A	96.126.120.46

Using dig MX pokey.onl (checking MX record):

pokey.onl.		600	IN	MX	10 mail.pokey.onl.

Using dig -x 96.126.120.46 (checking PTR record):

46.120.126.96.in-addr.arpa. 295	IN	PTR	mail.pokey.onl.

Surprisingly, it was the PTR record which took the longest to propagate in my case.

Getting online

Finally, we can begin running the actual SMTP server. I transferred my files to the VPS, installed gcc through the build-essentials package, and then compiled the project.

I ran the server for the first time using the following command:

./server & echo $! > mves.pid

Then, from my laptop terminal, trying to telnet into the SMTP server (telnet mail.pokey.onl 25) gives me Trying 96.126.120.46..., but this never connects even though (on the VPS) I see the expected entry using socket statistics (ss -tulnp | grep :25).

As a result, I am fairly certain that these ports were being blocked prior to reaching my VPS. Following the warning message I received from Linode at the VPS creation, I filed a ticket to remove the SMTP port restriction early in the morning on March 27, 2026.

After less than 6 hours, my ticket was approved, but I still couldn't telnet into the server. As it turns out, the issue here was with my local machine: my home network was apparently blocked from sending on port 25, but as soon as I switched to a mobile hotspot, my requests to the server could go through.

With this setup and issues resolved, I was now able to send my first email over the internet to the email server:

% telnet mail.pokey.onl 25
Trying 96.126.120.46...
Connected to mail.pokey.onl.
Escape character is '^]'.
220 mail.pokey.onl Simple Mail Transfer Service Ready
EHLO mail.pokey.onl
250-mail.pokey.onl greets mail.pokey.onl
250-SIZE 100000
250 VRFY
MAIL FROM:<alice@pokey.onl>
250 OK
RCPT TO:<bob@pokey.onl>
250 OK
DATA
354 Start mail input; end with <CRLF>.<CRLF>
Hello Bob, this is a test message over the internet!
.
250 OK
QUIT
221 mail.pokey.onl Service closing transmission channel
Connection closed by foreign host.

As a result of this communication, the email server wrote "1774645958.10644.mail.pokey.onl" to "./mail/bob/Maildir/new". This is a important milestone for this project!

Here is a summary of the progress so far:

Capability Standard/support Status
Receive mail SMTP (RCC 5321) Implemented
  IMF (RFC 5322) Supported*
  MIME (RFC 2045-2049) Unimplemented
Store mail Local user accounts Implemented (manual)
  Maildir Implemented
Read mail IMAP (RFC 3501) Unimplemented
Send mail SMTP Submission (RFC 6409) Unimplemented
  STARTTLS (RFC 3207) Unimplemented
  SPF, DKIM, DMARC, TLS Unimplemented

*The Internet Message Format is a standard for headers and content sent within DATA of SMTP. This is supported but only as arbitrary data at this point.


Last updated March 28, 2026