Send email with netcat
Asked Answered
S

2

7

I try to send emails from my ESXI servers but for a reason I don't know I get errors.

this is the command I use to send the email :

nc -Cv smtp.relay.us 25 < /vmfs/volumes/Vcloud-Datatstore/Tools/mail.txt

And this is the file mail.txt:

HELO smtp.relay.us
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
From: [Log Server] <maillog@gkmonitor>
To: <[email protected]>
Date: Mon, 29 May 2017 20:25:38 +0000
Subject: Resultat de la restauration de GED
blabla
blabla

.

I get these output :

220-*****************************
220 *****************************
250 smtp.relay.us
250 2.1.0 Ok
250 2.1.5 Ok
503 5.5.0 <DATA>: Data command rejected: Improper use of SMTP command pipelining
502 5.5.2 Error: command not recognized
...
...

I don't understand what I'm doing wrong. Many thanks by advance.

Sternpost answered 29/5, 2017 at 20:42 Comment(0)
S
8

Finally made it work.

I don't know why but nc sends to much information at one time once reached DATA part of the mail. Even introducing interval between each line with -i option did not helped.

So this is how I made it works (massively inspired by GhettoVCB script):

 cat "mail.txt" |while read L; do sleep "1"; echo "$L"; done | "nc" -C -v "smtp.relay.us" "25"

Nothing changed in mail.txt

Bye

Sternpost answered 30/5, 2017 at 10:17 Comment(0)
F
8

The reason the sleeps are needed is that SMTP is "conversational". After the server receives a line, it replies with something. The client replies, and the server replies. However, TCP doesn't care about the content. (Of special importance here is the line breaks.) TCP gets a stream of data and a destination. It chops off a negotiated (at a lower level than your application so this is out of your control) number of octets of data and sends them. And repeat until done.

The problem is that when the server receives a TCP segment that has the linebreak, odds are (negotiated_octet_count to 1) that some amount of the next line is going to be included. At which point the server says, "You are not letting me speak, so this is not a conversation, and we are not going to continue."

So, that is why your first attempt failed. The reason your 2nd attempt succeeded is that netcat doesn't require that every TCP segment be full. It works on streams, not files. So netcat doesn't work upto EOF. It works until stdin closes (or timeout is reached if you specify one). And when the stdin "delays", it sends what it has. This ensures that your server gets a TCP segment that ends in a line break. You will probably find that your server can handle a much smaller than 1 second sleep. I us .05, but you might want to use .1 to give it some safety.

I gave an example here but I'm going to repeat it because your quoting is very irregular to me.

$ cat email_msg.txt
HELO localhost
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
From: [IES] <[email protected]>
To: <[email protected]>
Date: Fri, 27 Oct 2017 06:14:11 +0000
Subject: Test Message

Hi there! This is supposed to be a real email...

Have a good day!
-- System


.
QUIT

$ function slowcat(){ cat "$1" | while read; do sleep .05; echo "$REPLY"; done; }

$ slowcat email_msg.txt | nc localhost 25
220 et3 ESMTP Exim 4.89 Fri, 27 Oct 2017 06:18:14 +0000
250 et3 Hello localhost [::1]
250 OK
250 Accepted
354 Enter message, ending with "." on a line by itself
250 OK id=1e7xyA-0000m6-VR
221 et3 closing connection
Flan answered 1/5, 2018 at 15:11 Comment(1)
You could make that function a little smarter, like smtp() { cat "$1" |while read; do sleep .05; echo "$REPLY"; done |nc "${2:-localhost}" "${3:-25}"; }. This will default to localhost on port 25 but can be changed. Syntax is smtp FILE [server [port]]Patricapatrice

© 2022 - 2024 — McMap. All rights reserved.