3

I've seen many blogs and stack overflow questions about setting up nodejs to use a pre-existing smtp server, especially through modules like nodemailer etc. Some of what I've already seen:

https://www.zeolearn.com/magazine/sending-and-receiving-emails-using-nodejs

Use smtp client to send email without providing password

How can I create a custom smtp server to send out notification emails in Nodejs?

Sending emails in Node.js? (DON'T KNOW WHY IT IS CLOSED)

Use smtp client to send email without providing password

Nodemailer with Gmail and NodeJS

Nodemailer send email without smtp transport -- this is a tiny bit closer to what I want

How can I create a custom smtp server to send out notification emails in Nodejs? -- this one is so close yet no answers

Sending email via Node.js using nodemailer is not working

SmtpJs API not working! is there any way to send emails using SMTP server with JavaScript or JQuery

Email NodeJS cannot send

Any suggestion for smtp mail server in nodejs? -- this one may be the only one that even attempts to answer it, although from the docs for the service mentioned there (smtp-server), I don't see where the actual makings of the SMTP server from scratch are, i.e. I don't see the part that shows how to make your own myemail@mydomain.com using nodeJS (assuming the NodeJS server is configured on some kind of linux VM like google compete engine).

All of these answers and blogs only addressed sending emails via some other email client.

I am not interested in any other email servers.

I don't believe in gmail -- or any other 3rd party email providers.

I want to host my own.

From my own computer.

Don't question my intentions.

It's a perfectly valid programming question:

How do I create, from absolute scratch (i.e., only using the "net" built-in library in nodeJS, no external dependencies at all) create a SMTP mail server (assuming I have my own domain registered at an HTTPS virtual machine somewhere), that has the ability to receive mails at myemail@mydomain.com, and send emails from myemail@mydomain.com, without any 3rd party servers at all.

How can I at least start to do this? Any possible reference or tutorial that deals with the SMTP socket protocols would be a great start.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

6

Some friendly advice -- you probably want to use an off-the-shelf MTA like postfix, exim4, or sendmail if you just want to receive mail on your local machine.

I say this because I have literally spent a good hunk of my career implementing MTAs and feel I should warn you that this is a solved problem that allows you to have complete control over your mail traffic, and there are some very tricky issues to solve to write an MTA that works at scale with large mail volumes.

That said, SMTP (note spelling) is a very simple protocol, and a great "first protocol" to implement if you're interested in that stuff. It would be very easy to write one in NodeJS.

The first edition you'd be interested in was released some time around 1982, as RFC-821, aka IETF STD-10. It was then updated over the years to RFC-2821 and a bunch of related specs, but basic RFC-821 support will get you what you need to talk to 99% of hosts on the Internet today. (That number will go down as you need ESMTP support for TLS - but this is not much harder nor much different).

Your daemon will need to listen on port 25, and need to process commands like this:

YOU:  220 my.computer.com SMTP Service Ready
THEM: EHLO blah blah
YOU:  500 Syntax Error. Try again using SMTP.
THEM: HELO blah blah
YOU:  250 G'day mate
THEM: MAIL FROM: <billg@microsoft.com>
YOU:  250 Sender Okay
THEM: RCPT TO: <steve@apple.com>
YOU:  250 OK
THEM: DATA
YOU:  354 Enter mail, end with "." on a line by itself...
THEM: <BUNCH OF STUFF>
      .
YOU:  250 Mail accepted
THEM: QUIT
YOU:  221 Goodbye

Obviously there is more here wrt error handling etc -- read the spec -- but this is the gist of it. The numbers are response codes and have specific meanings. The lines are separated by \r\n and are supposed to be less than 1024 bytes wide.

<BUNCH OF STUFF> is an email message, and will not have a line which is just a dot in it. If the email had a dot like that, the other end will send an extra dot. This is in the spec.

Finally, write <XXXX><BUNCH OF STUFF> into your $MAIL file (probably /var/mail/username or /var/spool/mail/username) and point your MUA at it. Pine, Alpine, Elm, or mutt would make a good MUA for sorting this stuff out.

<XXXX> needs to start with From (NO colon) and end with \n. This is the Berkeley mbox file format. It should reflect the MAIL FROM header in the SMTP transaction.

This file format is very common and supported by most POP3 and IMAP4 servers. You can probably also read it with Mozilla Thunderbird. I know Netscape Mail supported it back in the day.

Wes
  • 950
  • 5
  • 12
  • Thanks, its good to find *actual* answers to questions on here instead of just "don't do that.." this is really good, so basically just implement https://tools.ietf.org/html/rfc821 ? And also do you know how to handle multiple users, i.e. guyone@mydomain.com, guytwo@mydomain.com (or is it in the spec somewhere)? – B''H Bi'ezras -- Boruch Hashem Apr 30 '20 at 23:47
  • No problem -- and yes, implementing that spec will let you send and receive Internet e-mail. Note that the spec covers the transfer, not the format of the e-mail, which is in RFC-2822 / STD-11 and a LOT of other documents. At least 10 relevant ones. Multiple users is simply multiple RCPT-TO: lines in the envelope. Piece of cake! Also, re-read my message; I forgot to escape some <entites> when I wrote it. Good luck, and have fun! – Wes May 01 '20 at 02:16