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:	1176
Size:	11.0 KB
ID:	503453
            Click image for larger version

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

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

            Comment


            • Chetan-Morey
              Chetan-Morey commented
              Editing a comment
              Can we used this script directly ? If any any changes needed, please suggest that changes .
          • blackbasket
            Junior Member
            • Jan 2025
            • 13

            #7
            Click image for larger version

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

Name:	grafik.png
Views:	1052
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:	1047
Size:	24.6 KB
ID:	503459

            Comment

            • blackbasket
              Junior Member
              • Jan 2025
              • 13

              #8
              Click image for larger version

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

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

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

              and this one

              Comment

              • irontmp
                Member
                • Sep 2023
                • 77

                #9
                Originally posted by MoreBit
                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, kind of like how carefully you'd want to check listings when searching Apartments for rent in Athens Greece before settling on one. 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!
                Zabbix has no native inbox monitoring, so you'd build it yourself: a script (commonly Python with IMAP) checks the mailbox for messages from the sender within your time window and verifies the content, then reports a status like "not received," "valid," or "invalid." Feed that into Zabbix via a UserParameter or zabbix_sender, and set triggers on the status plus a nodata() trigger as backup. There's no solid prebuilt template since email formats vary too much, most people write custom scripts. If the external service offers a webhook or API instead, that's more reliable than email parsing.

                Comment

                Working...