Задача:
Необходимо отправить сообщение электронной почты (SMTP message) из командной строки.
Решение:
Для выполнения этой задачи нам необходимо будет подключаться утилитой Telnet к SMTP (обычно, 25-й) порту почтового сервера. Для удобства, будем запускать Telnet через PuTTY, поскольку, используя PuTTY можно, например, вставлять в сеанс Telnet буфер обмена (для этого нужно просто кликнуть правой кнопкой мыши в строке Telnet - и содержимое буфера вставится в эту строку), а так же русская версия PuTTY поддерживает сценарии, с помощью которых можно автоматизировать отправку почты из командной строки. Для использования сценариев в Telnet можно так же посоветовать клиент IVT: Telnet/Ssh VT220 emulator, либо тот же Plink - интерфейс командной строки для PuTTY. Я уже не говорю про PowerShell, где отправку SMTP можно реализовать гораздо интереснее.
Итак, запускаем PuTTY, указываем адрес SMTP сервера, порт и выбираем тип соединения Telnet:
Открывается окно Telnet клиента, в котором мы увидим приглашение от SMTP сервера, например:
220 smtp.server.ru ESMTP ready
Представляемся серверу, указывая полностью свой домен:
Код: Выделить всё
ehlo server.ru
Сервер покажет список поддерживаемых расширений ESMTP:
250-smtp.server.ru
250-AUTH CRAM-MD5 PLAIN LOGIN DIGEST-MD5 NTLM
250-SIZE 31457280
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-PIPELINING
250-ETRN
250-DSN
250 HELP
Если необходима авторизация, то вводим соответствующую команду:
Код: Выделить всё
auth login
На что сервер приглашает ввести имя пользователя, закодированное в формате base64 (о том как закодировать в base64 будет написано ниже):
334 VXNlcm5hbWU6
Вводим закодированное имя пользователя:
Код: Выделить всё
dGVzdEBtYW5hZWZmLnJ1
Сервер просит ввести пароль, опять же в формате base64:
334 UGFzc3dvcmQ6
Вводим пароль:
Код: Выделить всё
R2ZoamttMTU5
Сервер сообщает об успешной авторизации:
235 2.0.0 Authentication successfull
Указываем отправителя письма:
Код: Выделить всё
mail from: user@server.ru
Сервер принимает этого отправителя:
250 2.1.0 Sender <user@server.ru> ok
Указываем первого получателя:
Код: Выделить всё
rcpt to: receiver1@server.ru
Сервер принимает этого получателя и говорит, что получатель находится в локальном домене:
250 2.1.5 Recipient <receiver1@server.ru> ok (local)
Указываем второго получателя:
Код: Выделить всё
rcpt to: receiver2@otherserver.ru
Сервер принимает этого получателя и говорит, что получатель находится в удаленном домене:
250 2.1.5 Recipient <receiver2@otherserver.ru> ok (remote)
Начинаем вводить само письмо:
Код: Выделить всё
data
Сервер соглашается, и говорит, что по окончании вода нужно ввести следующую комбинацию: CRLF.CRLF (то есть ENTER, точка, ENTER)
354 Enter mail, end with CRLF.CRLF
Вводим отправителя письма - для того, чтобы получатель увидел что письмо пришло именно от нас. Если не указать это поле, то у отправителя письмо придет от MAILER-DAEMON и при ответе на письмо, в поле получатель будет пусто:
Код: Выделить всё
From: user@server.ru
Вводим тему письма:
Код: Выделить всё
subject: Test message
Вводим само тело письма (то есть само сообщение) - оно должно быть отделено от предыдущих полей одной пустой строкой:
Код: Выделить всё
Here is a body of message
Second string
Third String
......
......
......
......
Last String
В конце письма опять же должна быть пустая строка.
Далее, вводим признак окончания письма, как того требует сервер - CRLF.CRLF
Код: Выделить всё
.
Сервер ставит письмо в очередь на отправку:
250 2.0.0 53326d87-000001bb Message accepted for delivery
Выходим из сеанса Telnet:
Quit
Сервер сообщает об окончании сессии:
221 2.0.0 Bye
Connection closed by foreign host.
Это будет выглядеть примерно так:
Здесь выделены места, на которые нужно обратить внимание:
Имя пользователя и пароль должны быть в base64
В самом письме необходимо еще раз прописать отправителя (From)
Не забыть оставить пустые строки до и после тела письма
Теперь о том, как закодировать текст в base64.
Во-первых, существуют online кодировщики, например Base64 - шифрование online
Во-вторых, можно написать простенький сценарий на PowerShell:
Код: Выделить всё
$x = "test@manaeff.ru"
$x = [System.Convert]::ToBase64String([System.Text.Encoding]::Default.GetBytes($x))
write-host "My login encoded to Base64 is: " $x
$x = "Gfhjkm159"
$x = [System.Convert]::ToBase64String([System.Text.Encoding]::Default.GetBytes($x))
write-host "My password encoded to Base64 is: " $x
Который будет выдавать закодированные строки:
В итоге, если все выполнено правильно, получим примерно такое письмо: