receiving email / inbound smtp

Sorry, can’t help there! I’m using haraka.

oh, haha. me too, I just assumed you were using postfix and was going to try to adapt it to haraka. Would you be able to share what you have for haraka? Thanks :slight_smile:

Hah, that makes it easy. I’m running more or less stock config.

tls.ini: key and cert are set
smtp.ini: listen=0.0.0.0:25 to match internal_port
plugins: tls is included

My dockerfile installs haraka and then runs a script that copies my cert over from secrets:

mkdir -p /var/lib/acme/devnull.noreply.zone/
echo "${DEVNULL_KEY}" | base64 -d > /var/lib/acme/devnull.noreply.zone/key.pem
echo "${DEVNULL_CRT}" | base64 -d > /var/lib/acme/devnull.noreply.zone/fullchain.pem

exec npx --no-install haraka -c /app/devnull

I’ve also since switched my fly.toml from the earlier example to use port 465 without the tls handler. This makes it do starttls with my cert rather than smtp-over-tls with fly’s. I’m not sure it really matters since that port seems to be deprecated for smtp usage.

1 Like

@simon-weber how do you set up your MX records for Haraka? Just point them at your fly domain?

I’ve got A/AAAA records to my fly ips and an MX record pointing at the domain of the A/AAAA records. It’s been a while since I set it up so I don’t remember if there was any big tradeoff involved here, but it seems to work fine.

Is this working for people with v2? My config looks like this:

[[services]]
  internal_port = 25
  protocol = "tcp"

  [[services.ports]]
    port = 25

  [[services.ports]]
    handlers = ["tls"]
    port = 465

  [[services.ports]]
    port = 587

[[services]]
  internal_port = 8080
  protocol = "tcp"

  [[services.ports]]
    handlers = ["http"]
    port = "80"
    force_https = true  # optional

  [[services.ports]]
    handlers = ["tls", "http"]
    port = "443"

Then to test:

> telnet example.com 25
Connected to example.com
Connection closed by foreign host

Note that this is the same response you get from any random port so I’m pretty sure it’s not getting to my app (also not seeing anything in the logs).

Also tested telnet with port 80 and that is getting through.

Here’s some very simple Go code:

	l, err := net.Listen("tcp", ":25")
	if err != nil {
		panic(err)
	}

	for {
		c, err := l.Accept()
		fmt.Printf("Got a connection - %v - %v\n", c, err)
	}

Where the print never occurs. Pretty sure it’s not getting to my app. Any pointers are appreciated.

For me (using Elixir and Phoenix ) I have to make sure the internal port is 2525 (below 1024), then mapping it to external 25 etc.

[[services]]
  # have to use 2525 otherwise will get this error
  # o]"Starting SMTP server at port 25"
  # 2023-09-29T17:41:58Z app[683d3d6f777528] lax [info]17:41:58.656 
  # [error] Failed to start Ranch listener :gen_smtp_server in :ranch_tcp:listen([{:cacerts, :...}, {:key, :...}, {:cert, :...}, {:port, 25}, {:ip, {0, 0, 0, 0}}, {:keepalive, true}, :inet]) for reason :eacces (permission denied)
  internal_port = 2525
  protocol = "tcp"

  # mapping these three ports ALL to internal 25
  # https://community.fly.io/t/receiving-email-inbound-smtp/1033/24
  [[services.ports]]
    port = 25

  [[services.ports]]
    handlers = ["tls"]
    port = 465

  [[services.ports]]
    port = 587

Maybe that’s a constraint when using shared IP? Not tested if I can do 25 directly using dedicated IP.

1 Like

Can someone confirm what is the best configuration for a node ts server with gmail smtp? I’ve been struggling a lot with this and I’ve been getting a connection refused error.

I’ve got a similar configuration which I’ve used on a mail server with both a shared and dedicated IP. I can’t connect to the server on port 25 or 587 with the shared IP but all works fine using the dedicated IP address. Same app, both types of IPs. It seems those ports are blocked when accessing services with shared IPs