Exécuter le script à la réception de l'e-mail

8

Je gère un serveur de messagerie Postfix / Dovecot pour un usage personnel. Il n'y a qu'une poignée de boîtes aux lettres réelles, essentiellement juste [email protected]et [email protected].

J'utilise fréquemment le virtualfichier pour créer des boîtes aux lettres virtuelles transmises à [email protected]. J'en ai un certain nombre pour les comptes jetables comme les achats uniques dans les magasins en ligne, les jeux en ligne que je veux essayer sans me soucier du spam en cours, etc. Pour ce faire, je SSH et exécute les commandes suivantes:

sudo vim /etc/postfix/virtual
# add a line that looks like:
# # [email protected]      [email protected]
sudo postmap virtual
sudo service postfix restart

Je le fais avec une fréquence suffisante pour que j'automatise le processus dans une certaine mesure. J'ai envisagé d'écrire simplement un script shell qui prenait la boîte aux lettres virtuelle et la vraie boîte aux lettres comme arguments et apportait les modifications lui-même, mais j'espère quelque chose de plus encore.

Je voudrais pouvoir envoyer un e-mail depuis [email protected]à une autre boîte aux lettres sur le serveur avec le nom de la boîte aux lettres virtuelle comme corps du message. Le problème serait les sudoappels mais je peux créer un nouvel utilisateur dont la seule responsabilité est de gérer ce qui devrait gérer cela.

La question est principalement la suivante: comment créer un événement déclenché par un e-mail? Y a-t-il un service quelque part qui fait cela? Puis-je configurer Postfix ou Dovecot pour écouter cet e-mail et exécuter des commandes sur cet événement?

Adam Smith
la source
Avez-vous vérifié ce lien ?
kirill-a
@ kirill-a non, je ne l'avais pas fait. Il semble que cela puisse être envisagé pour résoudre ce problème, et maintenant j'ai enfin une bonne raison d'apprendre PHP
Adam Smith
Vous n'avez pas besoin d'apprendre PHP: remplacez simplement votre propre script shell par le script PHP, et vous avez terminé.
MariusMatutiae
@MariusMatutiae si vous ou kirill-a souhaitez rédiger une réponse sur le sujet, alors (en supposant que cela fonctionne), je remettrai volontiers la prime
Adam Smith
@ kirill-un ping de courtoisie pour mon commentaire, ci-dessus.
Adam Smith

Réponses:

8

La procédure correcte pour exécuter un script (j'utilise un script shell) à la réception d'un message électronique est la suivante. Cela implique de modifier le fichier de configuration de postfix , master.cf (qui, dans mon Debian, se trouve dans / etc / postfix ) en ajoutant la ligne suivante:

 my_shell_script unix - n n - - pipe flags=F user=MY_USERNAME argv=/path/to/my/shell/script ${sender} ${size} ${recipient}

qui demande à postfix d'exécuter le script (vous devez le rendre exécutable) lorsqu'un événement se produit.

Pour spécifier quand exécuter le script, procédez comme suit: supposez que vous voulez qu'il soit exécuté lorsque [email protected] reçoit un message. Placez la ligne suivante

 [email protected] FILTER my_shell_script:dummy

à l'intérieur du fichier /etc/postfix/address.txt ; vous devrez créer une base de données appropriée pour postfix pour utiliser ce fichier, ce que vous accomplissez au moyen de

  postmap /etc/postfix/address.txt

qui produit en sortie un fichier appelé /etc/postfix/address.db . Revenez maintenant au fichier /etc/postfix/main.cf et ajoutez la ligne suivante:

 smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/access, permit_mynetworks, reject_unauth_destination

Maintenant, redémarrez postfix ,

  postfix reload

et vous devriez être prêt à partir.

MariusMatutiae
la source
2
Ne voulez-vous pas dire 'hachage check_recipient_access: / etc / postfix / address' ici? Vous avez utilisé "accès" où je pense que vous vouliez dire "adresse", sur la base de vos instructions.
Lee Fuller
3
Est-ce la même chose si vous exécutez des boîtes aux lettres virtuelles pour différents domaines virtuels? J'ai suivi ces instructions textuellement - et si je ne déclare pas de virtual_alias, j'obtiens un rebond. Si je le fais, il remet le message à la boîte aux lettres mais ne déclenche pas le script.
Lee Fuller
Je ne l'ai pas fait fonctionner. Cette réponse a fonctionné: serverfault.com/questions/322657/…
jlh
D'après ce que je comprends, cette solution a également le problème qu'elle ne déclenchera que pour les messages reçus via SMTP. sendmaildirect sur le serveur ne déclenchera pas cela.
Philip Couling
@PhilipCouling Voir cette réponse: unix.stackexchange.com/a/179407 . Vous pouvez utiliser l' pickupoption.
Stephan
4

Je peux voir deux solutions évidentes.

Si vous utilisez procmail comme MDA sur votre serveur, ou si vous êtes prêt à le convertir, vous pouvez exécuter n'importe quel script arbitraire sur n'importe quel courrier électronique arbitraire via l' |action de recette de procmail (pipe). Espérons qu'il ne sera pas démarré en tant que root, mais il devrait être facile de créer un script qui exécute la magie requise et qui peut être invoqué sans mot de passe en tant que root par un utilisateur pertinent. La sortie du script pourrait même être réinjectée dans le même e-mail et l'e-mail remis ultérieurement en faisant de la recette une action de filtrage.

Une alternative (qui devrait nécessiter moins de maintenance pratique) consiste à créer une seule boîte aux lettres et à configurer Postfix$recipient_delimiter pour qu'il ne soit pas normalement utilisé à cette fin; par exemple, .ou -. Notez que recipient_delimeter est un paramètre à l'échelle du serveur. Disons que vous avez configuré la boîte aux lettres [email protected]et défini $recipient_delimeter = .. Cela permettra alors dummy.<anything>@example.comqui sera livré à la boîte aux lettres locale correspondant à [email protected]. Pour désactiver l'un d'eux, ajoutezdummy.<whatever>@example.comà une table de destinataires appropriée avec une action de rejet. L'inconvénient est qu'il s'agira d'une boîte aux lettres fourre-tout pour le préfixe, vous voudrez donc rendre le préfixe difficile à trouver par accident ou par des attaques de dictionnaire. L'avantage est que dans le cas normal (l'expéditeur respecte vos souhaits et ne revend pas votre adresse e-mail), cette approche ne nécessite aucune maintenance, et vous pouvez toujours modifier votre préfixe plus tard et répertorier explicitement les combinaisons que vous souhaitez conserver lors de la réception de courrier pour .

un CVn
la source
Je ne suis pas lié à Postfix pour une raison autre que celle que j'ai actuellement. Je préférerais cependant trouver une solution qui fonctionnerait avec mon MDA / MTA actuel. En ce qui concerne les délimiteurs: j'ai à peine confiance que l'expéditeur respectera mes souhaits et ne revendra pas mon adresse e-mail, ou je leur donnerais l'adresse permanente :)
Adam Smith
@AdamSmith La différence est que, avec quelque chose comme ma deuxième alternative, vous pouvez désactiver l'adresse que vous avez donnée à une entité particulière sans causer de problèmes ailleurs, et les adresses semblent raisonnables même pour les vérificateurs automatisés stupides. En ce qui concerne la conservation du MDA / MTA, procmail peut être utilisé en remplacement du MDA de Postfix; pas besoin de remplacer Postfix comme MTA.
un CVn du
procmail n'est plus maintenu: voir lwn.net/Articles/416901 , un article intitulé: Les rapports sur la mort de procmail ne sont pas terriblement exagérés. Mieux vaut jouer prudemment et suivre la suggestion de @ kirill-a.
MariusMatutiae
procmail est encore largement utilisé et (à mon humble avis) reste la meilleure solution pour le filtrage ad hoc. @ MariusMatutiae note qu'il est effectivement mort s'applique uniquement à son développement. Je ne peux penser à aucun bogue de procmail que j'ai jamais rencontré, et j'ai fait des choses ridicules comme y implémenter des listes de diffusion complètes. Il n'a peut-être pas encore été développé car la seule direction à prendre serait au-delà de sa portée (par exemple, anti-spam, mieux servi par SpamAssassin ou par exemple milter-greylist ).
Adam Katz
Et vous me dites cela parce que ...?
MariusMatutiae
2

Si le lien tombe en panne, voici un résumé.

Tout d'abord, accédez à master.cfet enregistrez votre script "myhook" en ajoutant la ligne suivante:

myhook unix - n n - - pipe flags=F user=www-data argv=/path/to/script.sh ${sender} ${size} ${recipient}

Modifiez également la ligne smtp pour indiquer à Postfix d'exécuter le filtre pour tout courrier arrivant via la remise SMTP:

smtp inet n - - - - smtpd -o content_filter=myhook:dummy

Veuillez noter que si vous envoyez des e-mails à l'aide de la commande "sendmail", le filtre ne se déclenchera pas. Dans ce cas, ajoutez l'option après la méthode de livraison "enlèvement":

pickup fifo n - - 60 1 pickup -o content_filter=myhook:dummy

Redémarrez le suffixe: postfix reload

Rendez votre script lisible et exécutable par n'importe qui: chmod +rx script.sh

Notez que le script est toujours déclenché pour tout courrier arrivant. Pour spécifier l'adresse exacte, voir la réponse @MariusMatutiae.

kirill-a
la source
qui m'a fait "erreur de transport de courrier inconnu" ...
user1133275