mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-12 00:26:13 +01:00
c236e4ad72
Summary: This allows you to configure a single mailbox for all mail sent by phabricator, so you can keep a mailaddress like bugs@example.com and don't need a catchall on your domain/subdomain. Test Plan: Enabled and disabled suffix. Saw mails generated have to correct prefix. Also piped raw mails into the scripts/mail/mail_handler.php and ensured comments went into phabricator for both maniphest and differential. Reviewers: epriestley Reviewed By: epriestley CC: aran, epriestley Differential Revision: 815
230 lines
10 KiB
Text
230 lines
10 KiB
Text
@title Configuring Inbound Email
|
|
@group config
|
|
|
|
This document contains instructions for configuring inbound email, so users
|
|
may update Differential and Maniphest by replying to messages and create
|
|
Maniphest tasks via email.
|
|
|
|
= Preamble =
|
|
|
|
This can be extremely difficult to configure correctly. This is doubly true if
|
|
you use sendmail.
|
|
|
|
There are basically a few approaches available:
|
|
|
|
- Use SendGrid (<http://sendgrid.com/>), which is very easy but is not free.
|
|
- Run your own MTA, which can be quite harrowing to configure but is free.
|
|
- Tell the Phabricator devteam about another service you'd like support for,
|
|
this stuff is seriously terrible to configure on your own.
|
|
|
|
= Configuring Phabricator =
|
|
|
|
By default, Phabricator uses a "noreply@example.com" email address as the 'From'
|
|
(configurable with ##metamta.default-address##) and sets 'Reply-To' to the
|
|
user generating the email (e.g., by making a comment), if the mail was generated
|
|
by a user action. This means that users can reply (or reply-all) to email to
|
|
discuss changes, but the conversation won't be recorded in Phabricator and users
|
|
will not be able to take actions like claiming tasks or requesting changes to
|
|
revisions.
|
|
|
|
To change this behavior so that users can interact with objects in Phabricator
|
|
over email, set these configuration keys:
|
|
|
|
- ##metamta.differential.reply-handler-domain##: enables email replies for
|
|
Differential.
|
|
- ##metamta.maniphest.reply-handler-domain##: enables email replies for
|
|
Maniphest.
|
|
|
|
Set these keys to some domain which you configure according to the instructions
|
|
below, e.g. "##phabricator.example.com##". You can set these both to the same
|
|
domain, and will generally want to. Once you set these keys, emails will use a
|
|
'Reply-To' like "##T123+273+af310f9220ad@example.com##", which -- when
|
|
configured correctly, according to the instructions below -- will parse incoming
|
|
email and allow users to interact with Maniphest tasks and Differential
|
|
revisions over email.
|
|
|
|
If you don't want phabricator to take up an entire domain (or subdomain) you
|
|
can configure a general prefix so you can use a single mailbox to receive mail
|
|
on. To make use of this set ##metamta.single-reply-handler-prefix## to the
|
|
prefix of your choice, and phabricator will prepend this to the 'Reply-To'
|
|
mail address. This works because everything up to the first (optional) '+'
|
|
character in an email-address is considered the receiver, and everything
|
|
after is essentially "ignored".
|
|
|
|
You can also set up a task creation email address, like ##bugs@example.com##,
|
|
which will create a Maniphest task out of any email which is set to it. To do
|
|
this, set ##metamta.maniphest.public-create-email## in your configuration. This
|
|
has some mild security implications, see below.
|
|
|
|
= Security =
|
|
|
|
The email reply channel is "somewhat" authenticated. Each reply-to address is
|
|
unique to the recipient and includes a hash of user information and a unique
|
|
object ID, so it can only be used to update that object and only be used to act
|
|
on behalf of the recipient.
|
|
|
|
However, if an address is leaked (which is fairly easy -- for instance,
|
|
forwarding an email will leak a live reply address, or a user might take a
|
|
screenshot), //anyone// who can send mail to your reply-to domain may interact
|
|
with the object the email relates to as the user who leaked the mail. Because
|
|
the authentication around email has this weakness, some actions (like accepting
|
|
revisions) are not permitted over email.
|
|
|
|
This implementation is an attempt to balance utility and security, but makes
|
|
some sacrifices on both sides to achieve it because of the difficulty of
|
|
authenticating senders in the general case (e.g., where you are an open source
|
|
project and need to interact with users whose email accounts you have no control
|
|
over).
|
|
|
|
If you leak a bunch of reply-to addresses by accident, you can change
|
|
##phabricator.mail-key## in your configuration to invalidate all the old hashes.
|
|
|
|
You can also set ##metamta.public-replies##, which will change how Phabricator
|
|
delivers email. Instead of sending each recipient a unique mail with a personal
|
|
reply-to address, it will send a single email to everyone with a public reply-to
|
|
address. This decreases security because anyone who can spoof a "From" address
|
|
can act as another user, but increases convenience if you use mailing lists and,
|
|
practically, is a reasonable setting for many installs. The reply-to address
|
|
will still contain a hash unique to the object it represents, so users who have
|
|
not received an email about an object can not blindly interact with it.
|
|
|
|
If you enable ##metamta.maniphest.public-create-email##, that address also uses
|
|
the weaker "From" authentication mechanism.
|
|
|
|
NOTE: Phabricator does not currently attempt to verify "From" addresses because
|
|
this is technically complex, seems unreasonably difficult in the general case,
|
|
and no installs have had a need for it yet. If you have a specific case where a
|
|
reasonable mechanism exists to provide sender verification (e.g., DKIM
|
|
signatures are sufficient to authenticate the sender under your configuration,
|
|
or you are willing to require all users to sign their email), file a feature
|
|
request.
|
|
|
|
= Testing =
|
|
|
|
You can view a log of received mail by going to MetaMTA -> Received in the
|
|
Phabricator web interface. This can help you determine if mail is being
|
|
delivered to Phabricator or not.
|
|
|
|
You can also use the "Test Receiver" button, but note that this just simulates
|
|
receiving mail and doesn't send any information over the network. It is
|
|
primarily aimed at developing email handlers: it will still work properly
|
|
if your inbound email configuration is incorrect or even disabled.
|
|
|
|
= SendGrid =
|
|
|
|
To use SendGrid, you need a SendGrid account with access to the "Parse API" for
|
|
inbound email. Provided you have such an account, configure it like this:
|
|
|
|
- Configure an MX record according to SendGrid's instructions, i.e. add
|
|
##phabricator.example.com MX 10 mx.sendgrid.net.## or similar.
|
|
- Go to the "Parse Incoming Emails" page on SendGrid
|
|
(<http://sendgrid.com/developer/reply>) and add the domain as the
|
|
"Hostname".
|
|
- Add the URL ##https://phabricator.example.com/mail/sendgrid/## as the "Url",
|
|
using your domain (and HTTP instead of HTTPS if you are not configured with
|
|
SSL).
|
|
- If you get an error that the hostname "can't be located or verified", it
|
|
means your MX record is either incorrectly configured or hasn't propagated
|
|
yet.
|
|
- Set ##metamta.maniphest.reply-handler-domain## and/or
|
|
##metamta.differential.reply-handler-domain## to
|
|
"##phabricator.example.com##" (whatever you configured the MX record for),
|
|
depending on whether you want to support email replies for Maniphest,
|
|
Differential, or both.
|
|
|
|
That's it! If everything is working properly you should be able to send email
|
|
to ##anything@phabricator.example.com## and it should appear in the "Received"
|
|
tab of MetaMTA within a few seconds.
|
|
|
|
= Installing Mailparse =
|
|
|
|
If you're going to run your own MTA, you need to install the PECL mailparse
|
|
extension. In theory, you can do that with:
|
|
|
|
$ sudo pecl install mailparse
|
|
|
|
You may run into an error like "needs mbstring". If so, try:
|
|
|
|
$ sudo yum install php-mbstring # or equivalent
|
|
$ sudo pecl install -n mailparse
|
|
|
|
If you get a linker error like this:
|
|
|
|
COUNTEREXAMPLE
|
|
PHP Warning: PHP Startup: Unable to load dynamic library
|
|
'/usr/lib64/php/modules/mailparse.so' - /usr/lib64/php/modules/mailparse.so:
|
|
undefined symbol: mbfl_name2no_encoding in Unknown on line 0
|
|
|
|
...you need to edit your php.ini file so that mbstring.so is loaded **before**
|
|
mailparse.so. This is not the default if you have individual files in
|
|
##php.d/##.
|
|
|
|
= MTA: Configuring Sendmail =
|
|
|
|
Before you can configure Sendmail, you need to install Mailparse. See the
|
|
section "Installing Mailparse" above.
|
|
|
|
Sendmail is very difficult to configure. First, you need to configure it for
|
|
your domain so that mail can be delivered correctly. In broad strokes, this
|
|
probably means something like this:
|
|
|
|
- add an MX record;
|
|
- make sendmail listen on external interfaces;
|
|
- open up port 25 if necessary (e.g., in your EC2 security policy);
|
|
- add your host to /etc/mail/local-host-names; and
|
|
- restart sendmail.
|
|
|
|
Now, you can actually configure sendmail to deliver to Phabricator. In
|
|
##/etc/aliases##, add an entry like this:
|
|
|
|
phabricator: "| /path/to/phabricator/scripts/mail/mail_handler.php <ENV>"
|
|
|
|
...where <ENV> is the PHABRICATOR_ENV the script should run under. Run
|
|
##sudo newaliases##. Now you likely need to symlink this script into
|
|
##/etc/smrsh/##:
|
|
|
|
sudo ln -s /path/to/phabricator/scripts/mail/mail_handler.php /etc/smrsh/
|
|
|
|
Finally, edit ##/etc/mail/virtusertable## and add an entry like this:
|
|
|
|
@yourdomain.com phabricator@localhost
|
|
|
|
That will forward all mail to @yourdomain.com to the Phabricator processing
|
|
script. Run ##sudo /etc/mail/make## or similar and then restart sendmail with
|
|
##sudo /etc/init.d/sendmail restart##.
|
|
|
|
= MTA: Configuring Lamson =
|
|
|
|
Before you can configure Lamson, you need to install Mailparse. See the section
|
|
"Installing Mailparse" above.
|
|
|
|
In contrast to Sendmail, Lamson is relatively easy to configure. It is fairly
|
|
minimal, and is suitable for a development or testing environment. Lamson
|
|
listens for incoming SMTP mails and passes the content directly to Phabricator.
|
|
|
|
To get started, follow the provided instructions
|
|
(<http://lamsonproject.org/docs/getting_started.html>) to set up an instance.
|
|
One likely deployment issue is that binding to port 25 requires root
|
|
privileges. Lamson is capable of starting as root then dropping privileges, but
|
|
you must supply ##-uid## and ##-gid## arguments to do so, as demonstrated by
|
|
Step 8 in Lamson's deployment tutorial (located here:
|
|
<http://lamsonproject.org/docs/deploying_oneshotblog.html>).
|
|
|
|
The Lamson handler code itself is very concise; it merely needs to pass the
|
|
content of the email to Phabricator:
|
|
|
|
import logging, subprocess
|
|
from lamson.routing import route, stateless
|
|
from lamson import view
|
|
|
|
PHABRICATOR_ROOT = "/path/to/phabricator"
|
|
PHABRICATOR_ENV = "custom/myconf"
|
|
LOGGING_ENABLED = True
|
|
|
|
@route("(address)@(host)", address=".+")
|
|
@stateless
|
|
def START(message, address=None, host=None):
|
|
if LOGGING_ENABLED:
|
|
logging.debug("%s", message.original)
|
|
process = subprocess.Popen([PHABRICATOR_ROOT + "scripts/mail/mail_handler.php",PHABRICATOR_ENV],stdin=subprocess.PIPE)
|
|
process.communicate(message.original)
|