Ad Widget

Collapse

How to Monitor Email Arrival and Content in Zabbix

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MoreBit
    Junior Member
    • Feb 2024
    • 1

    #1

    How to Monitor Email Arrival and Content in Zabbix

    Hello everyone,

    I'm seeking guidance on setting up a monitoring mechanism within Zabbix that can reliably check for the receipt of an email from an external service and also verify its content. The main goal is to have Zabbix generate an alert if a specific email is not received within a given timeframe or if the content of the email does not meet certain criteria.

    Here are the specific requirements I'm trying to achieve:
    1. Monitor an email inbox for messages from a specified external service.
    2. Verify the content of the email to ensure it contains specific information or meets certain conditions.
    3. Trigger an alert in Zabbix if the email is not received by a certain deadline or if the email content verification fails.

    Could anyone provide insights or share their experience on how to configure Zabbix for this type of monitoring? I am particularly interested in any templates, scripts, or third-party tools that integrate well with Zabbix for email monitoring and content verification purposes.

    Thank you in advance for your help and suggestions!
  • blackbasket
    Junior Member
    • Jan 2025
    • 13

    #2
    Hi MoreBit,

    did you find a solution?

    Regards,
    Marcel

    Comment

    • Blevar
      Member
      • Jan 2025
      • 68

      #3
      Hi,
      This is an interesting problem. Zabbix itself doesnt offer monitoring e-mail accounts. However it could be done by writing and running your own script. You can create an item 'External Check' which would run your own for example python script: `check_email.py`. This script could return values on the run depending on if the required e-mail appeared in the inbox like: 0 - email recieved, 1 - not recieved, 2 - error and so on. Then based on that value you can create a trigger
      Code:
      `{your_host:check_email.py.last()}=1`

      Comment

      • blackbasket
        Junior Member
        • Jan 2025
        • 13

        #4
        Hi Blevar, thank you... I created a script based on some examples, I found... it parses the content of the last matching mail...

        Comment

        • msz@kommunekredit.dk
          Junior Member
          • Jun 2024
          • 7

          #5
          Originally posted by blackbasket
          Hi Blevar, thank you... I created a script based on some examples, I found... it parses the content of the last matching mail...
          Would You share an example with all us NOOBS knowing nothing?

          Comment

          • blackbasket
            Junior Member
            • Jan 2025
            • 13

            #6
            sure but it's really simple... no LLDP or anything...

            Code:
            #!/usr/bin/python3
            import argparse
            import imaplib
            import email
            from email.header import decode_header
            import webbrowser
            import os
            import json
            import datetime
            
            # parse parameters
            parser = argparse.ArgumentParser()
            
            parser.add_argument('-t', '--timedelta', type=int)
            parser.add_argument('-s', '--sender')
            parser.add_argument('-b', '--body')
            
            args = parser.parse_args()
            
            # account credentials
            username = "xxx"
            password = "xxx"
            imap_server = "xxx"
            
            def clean(text):
                # clean text for creating a folder
                return "".join(c if c.isalnum() else "_" for c in text)
            
            # create an IMAP4 class with SSL, use your email provider's IMAP server
            imap = imaplib.IMAP4_SSL(imap_server)
            # authenticate
            imap.login(username, password)
            
            # select a mailbox (in this case, the inbox mailbox)
            # use imap.list() to get the list of mailboxes
            status, messages = imap.select("INBOX")
            
            date = datetime.datetime.now()
            #resp, items = conn.uid("search",None, 'All')
            dateFilter = (datetime.datetime.now() - datetime.timedelta(args.timedelta)).strftime("%d-%b-%Y")
            senderFilter = args.sender
            bodyFilter = args.body
            filter = '(SENTSINCE "' + dateFilter + '" FROM "' + senderFilter + '" BODY "' + bodyFilter + '")'
            resp, items = imap.uid("search" ,None, filter)
            
            tdata=[]
            
            items = items[0].split()
            for emailid in items:
                resp, msg = imap.uid("fetch",emailid, "(RFC822)")
                if resp == 'OK':
                  for response in msg:
                    if isinstance(response, tuple):
                        # parse a bytes email into a message object
                        msg = email.message_from_bytes(response[1])
                        # decode the email date
                        date, encoding = decode_header(msg["Date"])[0]
                        if isinstance(date, bytes):
                            # if it's a bytes, decode to str
                            date = date.decode(encoding)
                        #print("Date:", date)
                        # decode the email subject
                        subject, encoding = decode_header(msg["Subject"])[0]
                        if isinstance(subject, bytes):
                            # if it's a bytes, decode to str
                            subject = subject.decode(encoding)
                        #print("Subject:", subject)
                        # decode email sender
                        From, encoding = decode_header(msg.get("From"))[0]
                        if isinstance(From, bytes):
                            From = From.decode(encoding)
                        #print("From:", From)
                        # if the email message is multipart
                        if msg.is_multipart():
                            # iterate over email parts
                            for part in msg.walk():
                                # extract content type of email
                                content_type = part.get_content_type()
                                content_disposition = str(part.get("Content-Disposition"))
                                try:
                                    # get the email body
                                    body = part.get_payload(decode=True).decode()
                                except:
                                    pass
            #                    if content_type == "text/plain" and "attachment" not in content_disposition:
                                    # print text/plain emails and skip attachments
                                    #print(body)
            #                    elif "attachment" in content_disposition:
                                    # download attachment
            #                        filename = part.get_filename()
            #                        if filename:
            #                            folder_name = clean(subject)
            #                            if not os.path.isdir(folder_name):
                                            # make a folder for this email (named after the subject)
            #                                os.mkdir(folder_name)
            #                            filepath = os.path.join(folder_name, filename)
                                        # download attachment and save it
            #                            open(filepath, "wb").write(part.get_payload(decode=True))
                        else:
                            # extract content type of email
                            content_type = msg.get_content_type()
                            # get the email body
                            body = msg.get_payload(decode=True).decode()
            #                if content_type == "text/plain":
                                # print only text email parts
                                #print(body)
                #create LLD JSON output
                tdata.clear()
                tdata.append({'JOB':subject,'DATE':date,'RESULT':body})
            #print(tdata)
            #print(json.dumps(tdata))
            print(json.dumps({"data": tdata}, indent=1))
            
            
            # close the connection and logout
            imap.close()
            imap.logout()
            never got it working with macros... but not use to much time for it...
            Click image for larger version

Name:	grafik.png
Views:	715
Size:	11.0 KB
ID:	503453
            Click image for larger version

Name:	grafik.png
Views:	637
Size:	11.2 KB
ID:	503454
            Click image for larger version

Name:	grafik.png
Views:	633
Size:	7.4 KB
ID:	503455

            Comment

            • blackbasket
              Junior Member
              • Jan 2025
              • 13

              #7
              Click image for larger version

Name:	grafik.png
Views:	621
Size:	12.3 KB
ID:	503457
              Click image for larger version

Name:	grafik.png
Views:	629
Size:	12.4 KB
ID:	503458
              Code:
              var string = value
              var parts = string.match(/(\w*), (\d{2}) (\w*) (\d{4}) (\d{2})\:(\d{2})\:(\d{2})/);
              var month = "JanFebMarAprMayJunJulAugSepOctNovDec".indexOf(parts[3]) / 3 + 1
              var date = new Date(parts[4], month, parts[2],parts[5], parts[6], parts[7])
              return(date)​
              Click image for larger version

Name:	grafik.png
Views:	625
Size:	24.6 KB
ID:	503459

              Comment

              • blackbasket
                Junior Member
                • Jan 2025
                • 13

                #8
                Click image for larger version

Name:	grafik.png
Views:	627
Size:	10.8 KB
ID:	503461
                Click image for larger version

Name:	grafik.png
Views:	631
Size:	7.2 KB
ID:	503462
                Click image for larger version

Name:	grafik.png
Views:	626
Size:	27.0 KB
ID:	503463

                and this one

                Comment

                Working...