#!/usr/bin/env python
# -*- coding: utf-8 -*-

#***************************************************************************
#                           generateMalwareBlockScripts.py
#                             -------------------
#    copyright            : (c) 2016 by Robert Penz
#    license		  : GPL v3
#    email                : robert@penz.name
#    version		  : 0.1
#***************************************************************************

"""
    This script does following
    
    1. download various BlockLists (Domain and IP)
    2. generates a script which can be excuted by the Mikrotik RouterOS
    
    No error means no output - so you can use it via cron and get a mail on error

    usage: generateMalwareBlockScripts.py [-h]

    -h      print this text
    
    Written by Robert Penz <robert@penz.name>
"""


# Domain block lists

domainBlockListFile = "/var/www/html/addMalwareDomains.rsc"
domainBlockListsUrls = [{"name": "RW_DOMBL", "url": "https://ransomwaretracker.abuse.ch/downloads/RW_DOMBL.txt"},
                        {"name": "Feodo_DOMBL", "url": "https://feodotracker.abuse.ch/blocklist/?download=domainblocklist"},
                       ]
domainBlackListIPaddress = "10.255.255.255"

# IP address block lists

ipBlockListFile = "/var/www/html/addMalwareIPs.rsc"
ipBlockListsUrls = [{"name": "RW_IPBL", "url": "https://ransomwaretracker.abuse.ch/downloads/RW_IPBL.txt"},
                    {"name": "Feodo_IPBL", "url": "https://feodotracker.abuse.ch/blocklist/?download=ipblocklist"},
                   ]
     
import sys
import getopt
import requests
import traceback
import time
import re

# We only except valid domains and IP addresses
validIpAddressRegex = re.compile(r"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$", re.IGNORECASE)
validHostnameRegex = re.compile(r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$", re.IGNORECASE)


def logError(e):
    msg = "=========\n"
    # args can be empty
    if e.args:
        if len(e.args) > 1:
            msg += str(e.args) + "\n"
        else:
            msg += e.args[0] + "\n"
    else:
        # print exception class name
        msg += str(e.__class__) + "\n"
    msg += "---------" + "\n"
    msg += traceback.format_exc() + "\n"
    msg += "=========" + "\n"
    return msg

def doGenerateScripts():
    """ downloads and generates the RouterOS scripts """


    #### domains
    output = ["# This script adds malware domains to a block list via static dns entries (list created: %s)" % time.asctime(),
              "/ip dns static"]

    for entry in domainBlockListsUrls:
        resp = requests.get(url=entry["url"])
        for rawLine in resp.text.splitlines():
            domain = rawLine.strip()
            if not domain or domain[0] == "#":
                continue
            if not validHostnameRegex.match(domain):
                print >>sys.stderr, "%s contains invalid domain name %r - ignoring" % (entry["name"], domain)
                continue
            
            # all ok, we add the domain to the list
            output.append('add name="%s" address="%s" comment="addMalwareDomains %s"' % (domain, domainBlackListIPaddress, entry["name"]))
    
    f = open(domainBlockListFile,"w")
    for line in output:
        f.write(line + "\n")
    f.close()

    #### ip addresses
    output = ["# This scrip adds malware IP addresses to an address-list (list created: %s)" % time.asctime(),
              "/ip firewall address-list"]
    
    for entry in ipBlockListsUrls:
        resp = requests.get(url=entry["url"])
        for rawLine in resp.text.splitlines():
            ip = rawLine.strip()
            if not ip or ip[0] == "#":
                continue
            if not validIpAddressRegex.match(ip):
                print >>sys.stderr, "%s contains invalid ip address %r - ignoring" % (entry["name"], ip)
                continue
            
            # all ok, we add the domain to the list
            output.append('add list=addressListMalware address="%s" comment="addMalwareIPs %s"' % (ip, entry["name"]))
    
    f = open(ipBlockListFile,"w")
    for line in output:
        f.write(line + "\n")
    f.close()    


# Print usage message and exit
def usage(*args):
    sys.stdout = sys.stderr
    for msg in args: print msg
    print __doc__
    sys.exit(2)

def main():
    
    # parse the command lines
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'h')
    except getopt.error, msg:
        usage(msg)
    
    for o, a in opts:
        if o == '-h':
            print __doc__
            sys.exit()
        # may more options later
        
    doGenerateScripts()
    
    
if __name__ == '__main__':
    main()


