gotthardp/rabbitmq-email

Correct Installation of plugin

alexmtv opened this issue · 22 comments

Hi!
I have Rabbit 3.6.6 with Erlang R16B03-1 on Centos-7
No selinux or firewall enabled
I built plugins with make 4.2.1
I don't use Forked and patched gen_smtp
I copied complied plugins (gen_smtp*.ez and rabbitmq_email*.ez) in /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.6/plugins

I set up config

[{rabbit, 
[
{loopback_users,[]},
{rabbitmq_email, [
    {server_config, [
        [{port, 2525}, {protocol, tcp}, {domain, "mydomain.int.local"}, {address,{0,0,0,0}}]
    ]},
    {server_auth, false},
    {server_starttls, false},
    {email_domains,
        [{<<"mydomain.int.local">>, {<<"/">>, <<"email-in">>}}
    ]},
    {email_queues,
        [{{<<"/">>, <<"email-out">>}, <<"mydomain.int.local">>}
    ]},
    {email_from, <<"noreply">>},
    {client_sender, "rabbitmq1@mydomain.int.local"},
    {client_config, [
        {relay, "smtp.rabbit1.int.local"}
    ]}
]}
]}
].

and do

rabbitmq-plugins enable rabbitmq_email

netstat -plnt | grep:2525 show:
tcp 0 0 0.0.0.0:2525 0.0.0.0:* LISTEN PID/beam.smp

rabbitmq-server is running and works fine with amqp-connections

Telnet says
220 example.com ESMTP rabbit_email_handler
EHLO mydomain.com
250-example.com
250-AUTH PLAIN LOGIN
250-SIZE 10485670
250-8BITMIME
250 PIPELINING
MAIL FROM:user@mydomain.com
530 SMTP authentication is required

All mail relay from postfix also don't put anything in queue ("email-out" queue was created automatically)

In web ui /connections:

Overview Details Network +/-
Name
User name
State
SSL / TLS
Protocol
Channels
From client
To client
rabbit@rabbit1.1.853.0
none Direct 0-9-1

Any suggestions welcome!

Hello. Did you bind the queue? Please note the <<"email-in">> is an exchange, where as the <<"email-out">> is a queue. To get the e-mails received via SNMP you have to bind <<"email-in">> to some queue (other than <<"email-out">>, of course).

Hi gotthardp!
Thank you for reply. Yes, i bind the queue. With no effect. How to debug this?

Also, i have a question. Compiled plugins can be transferred to another machine with equal versions of rabbit and erlang?

Another question is can this plugin be used in high load environment with 30-50 emails per second?

What exchange type do you use and how did you bind the queue?

The plug-in is producing logs. The best way to debug is to have a look if the e-mail was successfully processed and where it was published.

Yes, if the erlang&rabbit version is the same, it is safe to transfer the plug-in.

I never tested performance limits. Give it a try and see for much it can handle. ;-)

Exchange type is topic. It's auto-created, i suppose. I do bind this way http://imgur.com/a/o7ufL
Also i noticed high load of cpu when i start send mails to it http://imgur.com/a/3n3sC

Except for the pre-created amq.* exchanges, there is no such thing as automatically created exchanges.

Your binding doesn't use a routing key, or rather uses a blank one, which is critically important for topic routing. I highly recommend investing some time into learning about AMQP 0-9-1 concepts and going through the tutorials before further attempts to investigate this.

You can also enable message tracing and use a plugin that logs tracing messages to a text file to help with debugging.

Except for the pre-created amq.* exchanges, there is no such thing as automatically created exchanges.

You are wrong. Try following steps:

  1. rabbitmq-plugins disable rabbitmq_email.
  2. Delete email-in exchange manually.
  3. rabbitmq-plugins enable rabbitmq_email
  4. Start sending email to rabbitmq
  5. Now you can see auto-created "email-in" exchange with type "topic"

@michaelklishin
Anyway, thanks for the info, i'll look at this again

@alexmtv that's not an "automatically" created exchange. It's an exchange that this plugin creates on start, just like any other application that uses RabbitMQ. Anyhow, "automatic" means different things to different people and it has nothing to do with this question.

Due to documentation of this plugin,

the mailbox name is mapped to an AMQP routing key

and from concepts

The routing algorithm behind a direct exchange is simple - a message goes to the queues whose binding key exactly matches the routing key of the message

for direct type exchange
Is those mean i need a separate queue for each email address with unique binding key?

You can have multiple bindings between an exchange and a queue. Or you could use e.g. a topic exchange. In any case, binding with a blank routing key isn't going to route anything with this plugin.

So i need to add routing key for every mailbox for the chosen queue? Is it possible to use the wildcards for mail domains?
Also, why in Connections tab, under rabbitmq_email connection shows user name "none"? It's refers to {server_auth, false}, in config?
And mailbox (routing key) mean user@domain or just user or just domain?

Well, similar to this issue my problem probably is "530 SMTP authentication is required". It is necessary to use server_auth?

With enabled server_auth, plugin is work now. Partially. At least i lost full day to find plugin bug with server_auth=false. Also i got many "421 example.com is too busy to accept mail right now" error in my mail server logs.

The server_auth is for incoming SMTP connections only, i.e. it will help if the 530 is generated by the gen_smtp.

I believe the routing key is the entire user@domain. With a topic exchange you could use wildcards the standard way.

The plug-in connects via a "direct" connection, where user name doesn't have to be specified. Hence "none" in the Connections tab.

Yes, without {server_auth, rabbitmq} gen_smtp reject all incoming connections with 530 error. Even with telnet. So config option {server_auth, false} is useless or don' work. A least in my case.

"Direct" above means an Erlang client feature where it uses Erlang distribution directly instead of using AMQP 0-9-1 protocol serialization over a separate TCP connection. The Erlang client can also use "regular" network connections much like e.g. Java or Ruby clients but not limited to that.

@alexmtv see (and post) server log files, including the SASL log. This plugin may need rebuilding against a recent RabbitMQ version, for example.

And please refrain from making bold claims that something is useless or you've found a bug unless you have hard evidence to back them (such as server logs and documented repro steps).

@michaelklishin
What exactly i need to see/post ?

Example from rabbitmq.log when settins is {server_auth, false}
=INFO REPORT==== 12-Apr-2017::12:31:11 ===
example.com SMTP connection from {ip of my smtp server}

=ERROR REPORT==== 12-Apr-2017::12:31:11 ===
SMTP authentication is required

Example from sasl.log
=SUPERVISOR REPORT==== 12-Apr-2017::12:31:11 ===
Supervisor: {<0.16695.140>,amqp_channel_sup_sup}
Context: shutdown_error
Reason: shutdown
Offender: [{nb_children,1},
{name,channel_sup},
{mfargs,
{amqp_channel_sup,start_link,
[direct,<0.16733.140>,
<<"rabbit@rabbit1.2.16733.140">>]}},
{restart_type,temporary},
{shutdown,brutal_kill},
{child_type,supervisor}]

Even, when config set to {server_auth, rabbitmq}
gen_smtp seems to feel bad on load
=ERROR REPORT==== 13-Apr-2017::10:23:11 ===
** Generic server <0.2345.1> terminating
** Last message in was {tcp,#Port<0.29353>,
<<"AUTH PLAIN b64:002:File Error Opening/Creating Files.\r\n">>}
** When Server state == {state,#Port<0.29353>,rabbit_email_handler,
{envelope,undefined,[],<<>>,0,{<<>>,<<>>}},
[{"AUTH","PLAIN LOGIN"},
{"SIZE","10485670"},
{"8BITMIME",true},
{"PIPELINING",true}],
false,undefined,false,false,
{state,undefined,<0.2346.1>,[]},
[{hostname,"example.com"},{sessioncount,2}]}
** Reason for termination ==
** {{badarg,58},
[{base64,decode_binary,2,[{file,"base64.erl"},{line,191}]},
{gen_smtp_server_session,handle_request,2,
[{file,"src/gen_smtp_server_session.erl"},
{line,360}]},
{gen_smtp_server_session,handle_info,2,
[{file,"src/gen_smtp_server_session.erl"},
{line,199}]},
{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,604}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]}
=CRASH REPORT==== 13-Apr-2017::10:23:11 ===
crasher:
initial call: gen_smtp_server_session:init/1
pid: <0.2345.1>
registered_name: []
exception exit: {{badarg,58},
[{base64,decode_binary,2,
[{file,"base64.erl"},{line,191}]},
{gen_smtp_server_session,handle_request,2,
[{file,"src/gen_smtp_server_session.erl"},
{line,360}]},
{gen_smtp_server_session,handle_info,2,
[{file,"src/gen_smtp_server_session.erl"},
{line,199}]},
{gen_server,handle_msg,5,
[{file,"gen_server.erl"},{line,604}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,239}]}]}
in function gen_server:terminate/6 (gen_server.erl, line 744)
ancestors: [<0.323.0>,<0.322.0>,<0.321.0>]
messages: []
links: [<0.323.0>,<0.2346.1>]
dictionary: []
trap_exit: true
status: running
heap_size: 987
stack_size: 27
reductions: 1286
neighbours:

@alexmtv according to your config it seems you have the rabbitmq_email configuration inside rabbit section, which is wrong

You should have it directly in the top-level structure, so

case application:get_env(rabbitmq_email, server_auth) of
is evaluated correctly

(just a note to all others who will find this issue :) )

Closing due to inactivity.