Introduisez postfix dans WSL pour relayer le courrier adressé à Office365 et le traiter avec Python

introduction

J'avais besoin d'enquêter, j'ai donc essayé une méthode pour relayer le courrier envoyé, le traiter, puis le transmettre à Office365.

WSL → telnet → Envoyer un mail → postfix → Traiter avec Python → sendmail → C'est comme Office365.

J'utilise WSL (Ubuntu 18.04 LTS) de Windows 10 comme environnement car il ne s'agit que d'une confirmation de la méthode d'implémentation. Les e-mails sont également envoyés à partir de WSL (localhost), et les paramètres de postfix sont prioritaires pour le contrôle de fonctionnement.

environnement

Je suis parti d'un environnement où WSL (Ubuntu 18.04 LTS) peut être utilisé sur Windows 10 Pro.

Installation de WSL (sous-système Windows pour Linux) et paramètres initiaux d'Ubuntu

Informations référencées

http://www.postfix.org/FILTER_README.html https://qiita.com/kanedaq/items/aab362e20bdafea83fff

Installation de Postfix et paramètres de relais pour WSL (Ubuntu 18.04 LTS)

$ sudo apt install postfix
$ sudo cp /etc/postfix/main.cf.proto /etc/postfix/main.cf
$ sudo vi /etc/postfix/main.cf
#Nom d'hôte du système de messagerie (FQDN)
myhostname = hostname.example.jp
#Nom de domaine du système de messagerie
mydomain = example.jp
#Nom de domaine (nom de domaine) qui est automatiquement complété lors de la livraison d'un e-mail
myorigin = $mydomain
#Interface réseau pour recevoir du courrier (tous)
inet_interfaces = all
#Plage de réseau autorisée
mynetworks = 127.0.0.0/8

#Chemin complet de la commande sendmail de Postfix
sendmail_path = /usr/sbin/sendmail
#Chemin complet de la commande newaliases de Postfix
newaliases_path = /usr/bin/newaliases
#Chemin complet de la commande mailq de Postfix
mailq_path = /usr/bin/mailq
#Groupe d'envoi de courrier et de gestion des files d'attente
setgid_group = postdrop
#Emplacement du document HTML de Postfix
html_directory = no
#Emplacement manuel de Postfix
manpage_directory = /usr/share/man
#Emplacement de l'exemple de fichier de configuration de Postfix
sample_directory = /etc/postfix
#Emplacement du fichier README de Postfix
readme_directory = /usr/share/doc/postfix

#Ajouter d'ici au bas du fichier de paramètres
#Serveur de messagerie principal de la destination de transfert (Office365 cette fois)
relayhost = [smtp.office365.com]:587
# SMTP-Activer AUTH
smtp_sasl_auth_enable = yes
#Un fichier qui décrit l'adresse du serveur de destination du transfert ainsi que le nom d'utilisateur et le mot de passe à authentifier.
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
#Ne pas autoriser la connexion anonyme
smtp_sasl_security_options = noanonymous
#Filtre pour mécanisme SASL du serveur de destination
smtp_sasl_mechanism_filter = LOGIN
#Cryptage TLS si possible
smtp_tls_security_level = may
#Certificat CA (ca-certificates)
smtp_tls_CApath = /etc/ssl/certs/ca-certificates.crt
$ sudo vi /etc/postfix/sasl_passwd
[smtp.office365.com]:587 Nom d'utilisateur (adresse e-mail):mot de passe
$ sudo chmod 600 /etc/postfix/sasl_passwd
$ sudo postmap hash:/etc/postfix/sasl_passwd
$ sudo service postfix restart
$ tail -f /var/log/mail.log
$ cat /var/log/mail.err
#Vérifiez le processus
$ ps aux|grep rsyslog|grep -v grep
#Vérifier les paramètres
$ sudo /usr/sbin/rsyslogd -n -d
$ cat /etc/rsyslog.d/50-default.conf
#Vérifiez l'état
$ sudo /etc/init.d/rsyslog status
#Démarrez le processus
$ sudo /etc/init.d/rsyslog start

error: open database /etc/aliases.db: No such file or directory

#Arrêtez Postfix et reconstruisez et démarrez la base de données d'alias de messagerie
$ sudo service postfix stop
$ sudo newaliases
$ sudo service postfix start
#Confirmation de l'existence de la base de données d'alias de messagerie
$ ls /etc/aliases.db

Confirmation pour relayer le courrier envoyé et le transférer vers Office365

$ telnet hostname.example.jp 25
Trying 127.0.1.1...
Connected to hostname.example.jp.
Escape character is '^]'.
220 hostname.example.jp ESMTP Postfix (Ubuntu)
(contribution) HELO hostname.example.jp
250 hostname.example.jp
(contribution) MAIL From:Adresse e-mail de l'expéditeur
250 2.1.0 Ok
(contribution) RCPT To:Adresse e-mail de destination
250 2.1.5 Ok
(contribution) DATA
354 End data with <CR><LF>.<CR><LF>
(contribution) This is test mail.
(contribution) .
250 2.0.0 Ok: queued as EAD291C000000084498
(contribution) quit
221 2.0.0 Bye
Connection closed by foreign host.
$ tail -f /var/log/mail.log
$ cat /var/log/mail.err

Filtrer avec le programme Python en utilisant Postfix content_filter

$ sudo apt install python3
$ sudo apt install python3-pip
$ python3 -V
$ pip3 -V
$ cd ~
$ mkdir postfix
$ cd postfix
$ touch transfer_mail.py
$ chmod 755 transfer_mail.py
#!/usr/bin/python3

import sys
import os
import email
import email.parser
from os.path import join, dirname
from subprocess import Popen, PIPE

#Obtenir à partir d'une entrée standard
mime_str = sys.stdin.read()
# mime_str = open(sys.argv[4]).read()
#Analyser comme e-mail
message = email.parser.Parser().parsestr(mime_str)
#Fichier qui crache le contenu de l'e-mail
filepath = join(dirname(__file__), 'result.txt')
#Expirez le contenu de l'e-mail dans un fichier
with open(filepath, mode='w') as f:
    #Paramètres
    for arg in sys.argv:
        f.write(f"{arg}\n")
    #En-tête de courrier
    for key in message.keys():
        value = message.get(key)
        f.write(f"{key} : {value}\n")
    #le contenu de l'e-mail
    payload = message.get_payload()
    f.write(payload)
#Définir la source, la destination, le sujet
message["From"] = sys.argv[1]
message["To"] = sys.argv[2]
message["Subject"] = "Test mail !!!"
#Transférer le courrier
command = ["/usr/sbin/sendmail", "-t", "-oi"]
stdout = ''
stderr = ''
retval = 0
process = Popen(command, stdin=PIPE)
(stdout, stderr) = process.communicate(message.as_string().encode())
retval = process.wait()
if retval == 0:
    sys.exit(0)
else:
    sys.exit(1)
$ sudo vi /etc/postfix/master.cf
# content_Spécifier le filtre
smtp      inet  n       -       n       -       -       smtpd -o content_filter=filter:dummy

# content_Définir un filtre (utilisateur en cours d'exécution, programme en cours d'exécution, expéditeur, destinataire, taille)
filter    unix  -       n       n       -       10      pipe
  flags=Rq user=Argv utilisateur=/home/utilisateur/postfix/transfer_mail.py ${sender} ${recipient} ${size}
$ sudo service postfix restart
$ tail -f /var/log/mail.log
$ cat /var/log/mail.err

Confirmation que le courrier envoyé est relayé, traité avec Python et transmis à Office365

$ telnet hostname.example.jp 25
Trying 127.0.1.1...
Connected to hostname.example.jp.
Escape character is '^]'.
220 hostname.example.jp ESMTP Postfix (Ubuntu)
(contribution) HELO hostname.example.jp
250 hostname.example.jp
(contribution) MAIL From:Adresse e-mail de l'expéditeur
250 2.1.0 Ok
(contribution) RCPT To:Adresse e-mail de destination
250 2.1.5 Ok
(contribution) DATA
354 End data with <CR><LF>.<CR><LF>
(contribution) This is test mail.
(contribution) .
250 2.0.0 Ok: queued as EAD291C000000084498
(contribution) quit
221 2.0.0 Bye
Connection closed by foreign host.
$ cat ~/postfix/result.txt
/home/utilisateur/postfix/transfer_mail.py ← programme exécuté
Adresse e-mail de l'expéditeur ← Paramètre de filtre 1
Adresse e-mail de destination ← Paramètre de filtre 2
Taille ← Filtre paramètre 3
Return-Path : <Adresse e-mail du relais>
Received : from hostname.example.jp (localhost [127.0.0.1])
	by hostname.example.jp (Postfix) with SMTP id 923AE9E00000003FBF1
	for <Adresse e-mail de destination>; Fri,  9 Oct 2020 23:55:00 +0900 (JST)
Message-Id : <[email protected]>
Date : Fri, 10 Oct 2020 23:55:00 +0900 (JST)
From :Adresse e-mail de l'expéditeur
This is test mail.(Texte)
$ tail -f /var/log/mail.log
Oct 10 23:55:00 hostname postfix/qmgr[10858]: 923AE9E00000003FBF1: from=<Adresse e-mail de l'expéditeur>, size=362, nrcpt=1 (queue active)
Oct 10 23:55:00 hostname postfix/pipe[10951]: 923AE9E00000003FBF1: to=<Adresse e-mail de destination>, relay=filter, delay=591, delays=591/0.01/0/0.08, dsn=2.0.0, status=sent (delivered via filter service)
Oct 10 23:55:00 hostname postfix/qmgr[10858]: 923AE9E00000003FBF1: removed
Oct 10 23:55:00 hostname postfix/pickup[10857]: 2047A9F00000003FBF1: uid=1000 from=<utilisateur>
Oct 10 23:55:00 hostname postfix/cleanup[10955]: 2047A9F00000003FBF1: message-id=<[email protected]>
Oct 10 23:55:00 hostname postfix/qmgr[10858]: 2047A9F00000003FBF1: from=<[email protected]>, size=567, nrcpt=1 (queue active)
Oct 10 23:55:00 hostname postfix/smtp[10957]: warning: vstream_tweak_tcp: getsockopt TCP_MAXSEG: Protocol not available
Oct 10 23:55:00 hostname postfix/smtp[10957]: 2047A9F00000003FBF1: to=<Adresse e-mail de destination>, relay=smtp.office365.com[XXX.XXX.XXX.XXX]:587, delay=1.6, delays=0.03/0.02/1.1/0.4, dsn=2.0.0, status=sent (250 2.0.0 OK <[email protected]> [Hostname=XXXXXXXXXXXXX.xxxxxxxx.xxxx.outlook.com])
Oct 10 23:55:00 hostname postfix/qmgr[10858]: 2047A9F00000003FBF1: removed

en conclusion

Je suis curieux de connaître l'avertissement vstream_tweak_tcp dans le journal, mais j'ai pu relayer le courrier envoyé, le traiter, puis le transmettre à Office365. Il semble qu'il puisse être utilisé pour la coopération avec d'autres services et des enquêtes au moment du développement.

Recommended Posts

Introduisez postfix dans WSL pour relayer le courrier adressé à Office365 et le traiter avec Python
Recevoir des e-mails de Gmail et étiqueter avec Python3
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
Traitez le fichier gzip UNLOADed avec Redshift avec Python de Lambda, gzipez-le à nouveau et téléchargez-le sur S3
Fractal pour faire et jouer avec Python
Lisez le fichier CSV avec Python et convertissez-le en DataFrame tel quel
J'ai essayé de faire un processus périodique avec CentOS7, Selenium, Python et Chrome
Comment démarrer le projet Python en 2020 (Windows WSL et Mac commun)
Grattage de la nourriture avec python et sortie en CSV
MessagePack-Try pour lier Java et Python avec RPC
[Introduction au trading système] J'ai dessiné un oscillateur stochastique avec python et joué avec ♬
Créez rapidement un tableau de bord d'analyse de données Python avec Streamlit et déployez-le sur AWS
Il est facile d'exécuter SQL avec Python et de générer le résultat dans Excel
Procédure pour charger MNIST avec python et sortie en png
Python Ver. Présentation de WebPay avec un peu de code
Je veux gérer l'optimisation avec python et cplex
Introduire l'opérateur pipe et la composition de fonction à Python (provisoire)
Installez le sélénium sur votre Mac et essayez-le avec python
Essayez le fonctionnement de la base de données avec Python et visualisez avec d3
Lire le fichier json avec Python, le formater et générer le json
E-mail hipchat avec postfix, fluentd et python sur Azure
Obtenez de manière récursive la liste Excel dans un dossier spécifique avec python et écrivez-la dans Excel.
J'ai créé un serveur avec socket Python et ssl et j'ai essayé d'y accéder depuis le navigateur
Renvoyez les données d'image avec Flask of Python et dessinez-les dans l'élément canvas de HTML
[Python / Ruby] Comprendre le code Comment obtenir des données en ligne et les écrire au format CSV
[Python] Qu'est-ce qu'un tuple? Explique comment utiliser sans toucher et comment l'utiliser avec des exemples.
Précautions lors de la saisie à partir de CSV avec Python et de la sortie vers json pour faire exe
API Nifty Cloud facile à utiliser avec botocore et python
Essayez de le faire avec GUI, PyQt en Python
Après tout, il est faux de chat avec le sous-processus python.
écran et écran partagé avec connexion python et ssh au serveur distant
J'ai essayé différentes méthodes pour envoyer du courrier japonais avec Python
Associez Python Enum à une fonction pour la rendre appelable
[Python] Comment jouer avec les variables de classe avec décorateur et métaclasse
Essayez d'ouvrir une sous-fenêtre avec PyQt5 et Python
Comment convertir Youtube en mp3 et le télécharger en toute sécurité [Python]
[Jouons avec Python] Traitement d'image en monochrome et points
Le processus de création et d'amélioration du code Python orienté objet
Orienté objet en langage C: "○ ✕ game" a été refacturé et porté en Python
Convertir une vidéo en noir et blanc avec ffmpeg + python + opencv
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
C'est Halloween donc je vais essayer de le cacher avec Python
Installez CaboCha dans l'environnement Ubuntu et appelez-le avec Python.
Obtenez des données supplémentaires vers LDAP avec python (Writer et Reader)
Comment se connecter à AtCoder avec Python et soumettre automatiquement
Vue d'ensemble de l'environnement virtuel Python et comment le créer
[Python] Qu'est-ce que pip? Expliquez la liste des commandes et comment l'utiliser avec des exemples réels