Esempio n. 1
0
    def __init__(self, configpath):
        self.config = Config(configpath)
        self.loglevel = self.get_level(self.config.get_value("LOG", "level"))

        # create logger
        root = logging.getLogger()
        root.handlers.clear()  # workaround for default stdout handler
        root.setLevel(self.loglevel)

        # create formatter and add it to the handlers
        formatter = logging.Formatter(
            '[%(asctime)s] [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s')

        # create console handler -> logs are always written to stdout
        if bool(self.config.get_value("LOG", "to_stdout")):
            std_handler = logging.StreamHandler(stdout)
            std_handler.setLevel(self.loglevel)
            std_handler.setFormatter(formatter)
            root.addHandler(std_handler)

        # create file handler if enabled in configuration
        if bool(self.config.get_value("LOG", "to_files")):
            # create log filepath if not exists
            create_folder_if_not_exists(
                self.config.get_value("LOG", "filepath"))

            file_handler = logging.FileHandler(
                self.config.get_value("LOG", "filepath") + "/" +
                self.config.get_value("LOG", "filename")
            )
            file_handler.setLevel(self.loglevel)
            file_handler.setFormatter(formatter)
            root.addHandler(file_handler)
Esempio n. 2
0
    def __init__(self, debug: bool = False) -> None:
        """TODO: Doku."""
        self.cfg_log = Config(LOG_CONFIG_PATH)
        loglevel = self.cfg_log.get_value("LOG", "level")
        to_stdout = self.cfg_log.get_value("LOG", "to_stdout")
        to_files = self.cfg_log.get_value("LOG", "to_files")
        logpath = self.cfg_log.get_value("LOG", "filepath")
        logfile = self.cfg_log.get_value("LOG", "filename")
        self.log = Log(str(loglevel), bool(to_stdout), bool(to_files),
                       str(logpath), str(logfile))

        info("starting easywall-web")

        self.cfg = Config(CONFIG_PATH)

        if debug is True:
            info("loading Flask debug configuration")
            APP.config.from_object('easywall.web.__main__.DevelopmentConfig')
        else:
            info("loading Flask production configuration")
            APP.config.from_object('easywall.web.__main__.ProductionConfig')

        self.rules_handler = RulesHandler()

        self.login_attempts = self.cfg.get_value("WEB", "login_attempts")
        self.login_bantime = self.cfg.get_value("WEB", "login_bantime")
        self.ip_ban = IpBan(app=APP,
                            ban_count=self.login_attempts,
                            ban_seconds=self.login_bantime,
                            ipc=True)
        self.ip_ban.url_pattern_add('^/static.*$', match_type='regex')
Esempio n. 3
0
 def __init__(self):
     """the init function creates some class variables"""
     self.config = Config("config/easywall.ini")
     self.enabled = bool(self.config.get_value("ACCEPTANCE", "enabled"))
     self.filename = self.config.get_value("ACCEPTANCE", "filename")
     debug("Acceptance Process initialized. Status: " +
           str(self.enabled) + " Filename: " + self.filename)
Esempio n. 4
0
class TestFirstrun(unittest.TestCase):
    """TODO: Doku."""
    def setUp(self) -> None:
        """TODO: Doku."""
        prepare_configuration()
        self.config = Config(WEB_CONFIG_PATH)
        self.config.set_value("WEB", "username", "")
        self.config.set_value("WEB", "password", "")
        self.client = prepare_client()

    def tearDown(self) -> None:
        """TODO: Doku."""
        restore_configuration()

    def test_firstrun_logged_out(self) -> None:
        """TODO: Doku."""
        response = self.client.get('/')
        self.assertIn(b"username and password", response.data)

    def test_firstrun_save_logged_out(self) -> None:
        """TODO: Doku."""
        response = self.client.post('/firstrun',
                                    data={
                                        "username": "******",
                                        "password": "******",
                                        "password-confirm": "demo"
                                    },
                                    follow_redirects=True)
        self.assertIn(b"Username and password have been successfully saved",
                      response.data)
Esempio n. 5
0
class Passwd(object):
    """the class contains the password generation and saving"""

    def __init__(self):
        """the init function creates the config variable and calls the user input"""
        self.config = Config("config/web.ini")
        self.ask_user()

    def savepasswd(self, password):
        """the function saves the password into the config file using the config class"""
        hostname = platform.node().encode("utf-8")
        salt = hashlib.sha512(hostname).hexdigest()
        pw_hash = hashlib.sha512(
            str(salt + password).encode("utf-8")).hexdigest()
        self.config.set_value("WEB", "password", pw_hash)
        print("Password successfully saved.")

    def saveuser(self, username):
        """the function saves the username into the config file using the config class"""
        self.config.set_value("WEB", "username", username)
        print("Username successfully saved.")

    def ask_user(self):
        """the function asks the user for the username and password"""
        username = input("easywall Web Username: "******"easywall Web Password: ")
        self.savepasswd(password)
Esempio n. 6
0
    def __init__(self, debug: bool = False) -> None:
        self.cfg = Config(CONFIG_PATH)

        loglevel = self.cfg.get_value("LOG", "level")
        to_stdout = self.cfg.get_value("LOG", "to_stdout")
        to_files = self.cfg.get_value("LOG", "to_files")
        logpath = self.cfg.get_value("LOG", "filepath")
        logfile = self.cfg.get_value("LOG", "filename")
        self.log = Log(str(loglevel), bool(to_stdout), bool(to_files), str(logpath), str(logfile))

        self.login_attempts = self.cfg.get_value("WEB", "login_attempts")
        self.login_bantime = self.cfg.get_value("WEB", "login_bantime")
        self.ip_ban = IpBan(app=APP, ban_count=self.login_attempts,
                            ban_seconds=self.login_bantime, ipc=True)
        self.ip_ban.url_pattern_add('^/static.*$', match_type='regex')

        info("starting easywall-web")

        self.rules_handler = RulesHandler()
        self.rules_handler.ensure_files_exist()

        if debug is True:
            port = self.cfg.get_value("WEB", "bindport")
            host = self.cfg.get_value("WEB", "bindip")
            APP.config.from_object('easywall_web.__main__.DevelopmentConfig')
            APP.run(str(host), str(port))
        else:
            APP.config.from_object('easywall_web.__main__.ProductionConfig')
Esempio n. 7
0
    def __init__(self, debug: bool = False) -> None:
        self.cfg = Config(CONFIG_PATH)

        loglevel = self.cfg.get_value("LOG", "level")
        to_stdout = self.cfg.get_value("LOG", "to_stdout")
        to_files = self.cfg.get_value("LOG", "to_files")
        logpath = self.cfg.get_value("LOG", "filepath")
        logfile = self.cfg.get_value("LOG", "filename")
        self.log = Log(str(loglevel), bool(to_stdout), bool(to_files),
                       str(logpath), str(logfile))

        info("starting easywall-web")

        self.is_first_run = not folder_exists("rules")
        self.rules_handler = RulesHandler()
        if self.is_first_run:
            self.rules_handler.ensure_files_exist()

        if debug is True:
            port = self.cfg.get_value("WEB", "bindport")
            host = self.cfg.get_value("WEB", "bindip")
            APP.config.from_object('easywall_web.__main__.DevelopmentConfig')
            APP.run(str(host), str(port))
        else:
            APP.config.from_object('easywall_web.__main__.ProductionConfig')
Esempio n. 8
0
 def setUp(self) -> None:
     """TODO: Doku."""
     prepare_configuration()
     self.config = Config(WEB_CONFIG_PATH)
     self.config.set_value("WEB", "username", "")
     self.config.set_value("WEB", "password", "")
     self.client = prepare_client()
Esempio n. 9
0
 def test_init(self, input: Any, getpass: Any) -> None:
     """TODO: Doku."""
     input.return_value = "test"
     getpass.return_value = "test"
     from easywall.web.passwd import Passwd
     Passwd()
     self.config = Config(WEB_CONFIG_PATH)
     self.assertEqual(self.config.get_value("WEB", "username"), "test")
Esempio n. 10
0
class Log(object):
    """This class is a wrapper class around the logging module"""

    def __init__(self, configpath):
        self.config = Config(configpath)
        self.loglevel = self.get_level(self.config.get_value("LOG", "level"))

        # create logger
        root = logging.getLogger()
        root.handlers.clear()  # workaround for default stdout handler
        root.setLevel(self.loglevel)

        # create formatter and add it to the handlers
        formatter = logging.Formatter(
            '[%(asctime)s] [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s')

        # create console handler -> logs are always written to stdout
        if bool(self.config.get_value("LOG", "to_stdout")):
            std_handler = logging.StreamHandler(stdout)
            std_handler.setLevel(self.loglevel)
            std_handler.setFormatter(formatter)
            root.addHandler(std_handler)

        # create file handler if enabled in configuration
        if bool(self.config.get_value("LOG", "to_files")):
            # create log filepath if not exists
            create_folder_if_not_exists(
                self.config.get_value("LOG", "filepath"))

            file_handler = logging.FileHandler(
                self.config.get_value("LOG", "filepath") + "/" +
                self.config.get_value("LOG", "filename")
            )
            file_handler.setLevel(self.loglevel)
            file_handler.setFormatter(formatter)
            root.addHandler(file_handler)

    def close_logging(self):
        """This function gently closes all handlers before exiting the software"""
        root = logging.getLogger()
        for handler in root.handlers:
            handler.close()
            root.removeFilter(handler)

    def get_level(self, log_level):
        """This internal function determines the log_level of the logging class"""
        level = logging.NOTSET
        if log_level == "debug":
            level = logging.DEBUG
        elif log_level == "info":
            level = logging.INFO
        elif log_level == "warning":
            level = logging.WARNING
        elif log_level == "error":
            level = logging.ERROR
        elif log_level == "critical":
            level = logging.CRITICAL
        return level
Esempio n. 11
0
class Main():
    """TODO: Doku."""
    def __init__(self) -> None:
        """TODO: Doku."""
        self.cfg = Config(CONFIG_PATH)
        self.cfg_log = Config(LOG_CONFIG_PATH)

        loglevel = self.cfg_log.get_value("LOG", "level")
        to_stdout = self.cfg_log.get_value("LOG", "to_stdout")
        to_files = self.cfg_log.get_value("LOG", "to_files")
        logpath = self.cfg_log.get_value("LOG", "filepath")
        logfile = self.cfg_log.get_value("LOG", "filename")
        self.log = Log(str(loglevel), bool(to_stdout), bool(to_files),
                       str(logpath), str(logfile))

        info("starting easywall")

        self.easywall = Easywall(self.cfg)
        self.event_handler = ModifiedHandler(self.apply)
        self.observer = Observer()
        self.stop_flag = False

        info("easywall has been started")

    def apply(self, filename: str) -> None:
        """TODO: Doku."""
        info("starting apply process from easywall")
        delete_file_if_exists(filename)
        self.easywall.apply()

    def start_observer(self) -> None:
        """
        Keep the main process running until it should be stopped.

        if someone is pressing ctrl + C the software will initiate the stop process
        """
        self.observer.schedule(self.event_handler, ".")
        self.observer.start()

        try:
            while not self.stop_flag:
                sleep(2)
        except KeyboardInterrupt:
            info("KeyboardInterrupt received, starting shutdown")
        finally:
            self.shutdown()

    def shutdown(self) -> None:
        """Stop all threads and shut the software down gracefully."""
        info("starting shutdown")

        self.observer.stop()
        delete_file_if_exists(".acceptance")
        self.observer.join()

        info("shutdown completed")
        self.log.close_logging()
Esempio n. 12
0
 def set_username_password(self) -> None:
     """TODO: Doku."""
     self.config = Config(WEB_CONFIG_PATH)
     self.config.set_value("WEB", "username", "test")
     hostname = platform.node().encode("utf-8")
     salt = hashlib.sha512(hostname).hexdigest()
     pw_hash = hashlib.sha512(
         str(salt + "test").encode("utf-8")).hexdigest()
     self.config.set_value("WEB", "password", pw_hash)
Esempio n. 13
0
 def test_init(self, input, getpass):
     """
     TODO: Doku
     """
     input.return_value = "test"
     getpass.return_value = "test"
     from easywall_web.passwd import Passwd
     Passwd()
     self.config = Config(CONFIG_PATH)
     self.assertEqual(self.config.get_value("WEB", "username"), "test")
Esempio n. 14
0
def create_rule_files(cfg: Config):
    """
    the function checks if the rule files exist and creates them if they don't exist
    """
    filepath = cfg.get_value("RULES", "filepath")
    create_folder_if_not_exists(filepath)
    filename = ""

    for ruletype in ["blacklist", "whitelist", "tcp", "udp", "custom"]:
        filename = cfg.get_value("RULES", ruletype)
        create_file_if_not_exists("{}/{}".format(filepath, filename))
Esempio n. 15
0
    def setUp(self):
        content = """[TEST]
        teststring = string
        testboolean = true
        testint = 1
        testfloat = 1.1
        """
        create_file_if_not_exists("test.ini")
        write_into_file("test.ini", content)

        self.config = Config("test.ini")
Esempio n. 16
0
 def __init__(self):
     logging.info("Applying new configuration.")
     self.create_running_file()
     self.config = Config("config/easywall.ini")
     self.iptables = Iptables()
     self.acceptance = Acceptance()
     self.ipv6 = self.config.get_value("IPV6", "enabled")
     self.filepath = None
     self.filename = None
     self.date = None
     self.apply()
     self.delete_running_file()
Esempio n. 17
0
 def __init__(self, configpath: str):
     info("Applying new configuration.")
     self.create_running_file()
     self.config = Config(configpath)
     self.iptables = Iptables(configpath)
     self.acceptance = Acceptance(configpath)
     self.ipv6 = self.config.get_value("IPV6", "enabled")
     self.filepath = None
     self.filename = None
     self.date = None
     self.apply()
     self.delete_running_file()
Esempio n. 18
0
class TestLogin(unittest.TestCase):
    """
    TODO: Doku
    """
    def setUp(self):
        prepare_configuration()
        self.client = prepare_client()
        self.config = Config(CONFIG_PATH)

    def tearDown(self):
        restore_configuration()

    def test_login(self):
        """
        TODO: Doku
        """
        self.client.get('/login')

    def test_login_post(self):
        """
        TODO: Doku
        """
        self.log_in(self.client)

    def test_logout(self):
        """
        TODO: Doku
        """
        self.log_in(self.client)
        self.client.get('/logout', follow_redirects=True)

    def set_username_password(self):
        """
        TODO: Doku
        """
        self.config = Config(CONFIG_PATH)
        self.config.set_value("WEB", "username", "test")
        hostname = platform.node().encode("utf-8")
        salt = hashlib.sha512(hostname).hexdigest()
        pw_hash = hashlib.sha512(str(salt +
                                     "test").encode("utf-8")).hexdigest()
        self.config.set_value("WEB", "password", pw_hash)

    def log_in(self, client):
        """
        TODO: Doku
        """
        self.set_username_password()
        return client.post('/login',
                           data=dict(username="******", password="******"),
                           follow_redirects=True)
Esempio n. 19
0
    def __init__(self) -> None:
        """the init function creates the config variable and calls the user input"""
        self.config = Config(CONFIG_PATH)

        parser = argparse.ArgumentParser()
        parser.add_argument("--username", "-u", help="set username")
        parser.add_argument("--password", "-p", help="set password")
        args = parser.parse_args()

        if args.username and args.password:
            self.saveuser(args.username)
            self.savepasswd(args.password)
        else:
            self.ask_user()
Esempio n. 20
0
 def __init__(self):
     """the init function creates some useful class variables"""
     debug("Setting up iptables...")
     self.config = Config("config/easywall.ini")
     self.ipv6 = bool(self.config.get_value("IPV6", "enabled"))
     self.iptables_bin = self.config.get_value("EXEC", "iptables")
     self.iptables_bin_save = self.config.get_value("EXEC", "iptables-save")
     self.iptables_bin_restore = self.config.get_value(
         "EXEC", "iptables-restore")
     if self.ipv6 is True:
         debug("IPV6 is enabled")
         self.ip6tables_bin = self.config.get_value("EXEC", "ip6tables")
         self.ip6tables_bin_save = self.config.get_value(
             "EXEC", "ip6tables-save")
         self.ip6tables_bin_restore = self.config.get_value(
             "EXEC", "ip6tables-restore")
Esempio n. 21
0
    def setUp(self):
        self.config_file = "test_easywall.ini"
        content = """[LOG]
level = info
to_files = false
to_stdout = true
filepath =
filename =

[IPV6]
enabled = true

[ACCEPTANCE]
enabled = true
duration = 1

[EXEC]
iptables = /sbin/iptables
ip6tables = /sbin/ip6tables
iptables-save = /sbin/iptables-save
ip6tables-save = /sbin/ip6tables-save
iptables-restore = /sbin/iptables-restore
ip6tables-restore = /sbin/ip6tables-restore

[BACKUP]
filepath = ./backup
ipv4filename = iptables_v4_backup
ipv6filename = iptables_v6_backup
        """
        create_file_if_not_exists(self.config_file)
        write_into_file(self.config_file, content)
        self.cfg = Config(self.config_file)
        self.easywall = Easywall(self.cfg)
        self.easywall.rules.rules_firstrun()
Esempio n. 22
0
def run():
    """this is the main function of the program"""
    # Startup Process
    config = Config("config/easywall.ini")
    loglevel = config.get_value("LOG", "level")
    to_stdout = config.get_value("LOG", "to_stdout")
    to_files = config.get_value("LOG", "to_files")
    logpath = config.get_value("LOG", "filepath")
    logfile = config.get_value("LOG", "filename")
    log = Log(loglevel, to_stdout, to_files, logpath, logfile)
    info("Starting up easywall...")

    ensure_rules_files(config)
    event_handler = ModifiedHandler()
    observer = Observer()
    observer.schedule(event_handler, config.get_value("RULES", "filepath"))
    observer.start()
    info("easywall is up and running.")

    # waiting for file modifications
    try:
        while True:
            sleep(2)
    except KeyboardInterrupt:
        info("KeyboardInterrupt received, starting shutdown")
    finally:
        shutdown(observer, config, log)
Esempio n. 23
0
    def setUp(self) -> None:
        self.config_file = "test_easywall.ini"
        content = """[LOG]
level = info
to_files = no
to_stdout = yes
filepath = /var/log
filename = easywall.log

[IPTABLES]
log_blocked_connections = yes
log_blocked_connections_log_limit = 60
log_blacklist_connections = yes
log_blacklist_connections_log_limit = 60
drop_broadcast_packets = yes
drop_multicast_packets = yes
drop_anycast_packets = yes
ssh_brute_force_prevention = yes
ssh_brute_force_prevention_log = yes
ssh_brute_force_prevention_connection_limit = 5
ssh_brute_force_prevention_log_limit = 60
icmp_flood_prevention = yes
icmp_flood_prevention_log = yes
icmp_flood_prevention_connection_limit = 5
icmp_flood_prevention_log_limit = 60
drop_invalid_packets = yes
drop_invalid_packets_log = yes
drop_invalid_packets_log_limit = 60
port_scan_prevention = yes
port_scan_prevention_log = yes
port_scan_prevention_log_limit = 60

[IPV6]
enabled = true
icmp_allow_router_advertisement = yes
icmp_allow_neighbor_advertisement = yes

[ACCEPTANCE]
enabled = yes
duration = 1
timestamp =

[EXEC]
iptables = /sbin/iptables
ip6tables = /sbin/ip6tables
iptables-save = /sbin/iptables-save
ip6tables-save = /sbin/ip6tables-save
iptables-restore = /sbin/iptables-restore
ip6tables-restore = /sbin/ip6tables-restore

"""
        create_file_if_not_exists(self.config_file)
        write_into_file(self.config_file, content)
        self.cfg = Config(self.config_file)
        self.easywall = Easywall(self.cfg)
        self.easywall.rules.ensure_files_exist()
Esempio n. 24
0
class Acceptance(object):
    """
    the class contains function for checking the user acceptance after applying new firewall rules
    """

    def __init__(self):
        """the init function creates some class variables"""
        self.config = Config("config/easywall.ini")
        self.enabled = bool(self.config.get_value("ACCEPTANCE", "enabled"))
        self.filename = self.config.get_value("ACCEPTANCE", "filename")
        debug("Acceptance Process initialized. Status: " +
              str(self.enabled) + " Filename: " + self.filename)

    def reset(self):
        """the function is called then the user did not accept the changes"""
        if self.enabled:
            create_file_if_not_exists(self.filename)
            write_into_file(self.filename, "false")
            debug("Acceptance has been reset.")

    def check(self):
        """the function checks for acceptance and executes the next steps"""
        if self.enabled:
            seconds = int(self.config.get_value("ACCEPTANCE", "time"))
            debug(
                "Starting Acceptance Check... waiting for " + str(seconds) +
                " seconds")
            while seconds > 0:
                sleep(1)
                seconds = seconds - 1
            with open(self.filename, 'r') as accfile:
                accepted = accfile.read()
                accepted = accepted.replace("\n", "")
                if accepted == "true":
                    debug("Acceptance Process Result: Accepted")
                    return True
                else:
                    debug(
                        "Acceptance Process Result: Not Accepted (file content: " + accepted + ")")
                    return False
        else:
            debug("Acceptance is disabled. Skipping check.")
            return True
Esempio n. 25
0
    def setUp(self):
        content = """[ACCEPTANCE]
        enabled = true
        duration = 1
        """
        create_file_if_not_exists("acceptance.ini")
        write_into_file("acceptance.ini", content)

        self.config = Config("acceptance.ini")
        self.acceptance = Acceptance(self.config)
Esempio n. 26
0
def prepare_configuration() -> None:
    """
    TODO: Doku
    """

    if file_exists(CONFIG_PATH):
        rename_file(CONFIG_PATH, CONFIG_BACKUP_PATH)

    content = """[LOG]
level = info
to_files = no
to_stdout = yes
filepath = log
filename = easywall-web.log

[WEB]
username = demo
password = xxx
bindip = 0.0.0.0
bindport = 12227
login_attempts = 10
login_bantime = 1800

[VERSION]
version = 0.0.0
sha = 12345
date = 2020-01-01T00:00:00Z
timestamp = 1234

[uwsgi]
https-socket = 0.0.0.0:12227,easywall.crt,easywall.key
processes = 5
threads = 2
callable = APP
master = false
wsgi-file = easywall_web/__main__.py
need-plugin = python3
"""

    create_file_if_not_exists(CONFIG_PATH)
    write_into_file(CONFIG_PATH, content)
    config = Config(CONFIG_PATH)
    config.set_value("VERSION", "timestamp", str(int(time())))
Esempio n. 27
0
 def test_constructor_file_not_read(self) -> None:
     """TODO: Doku."""
     create_file_if_not_exists("test.ini")
     content = """[DEFAULT]
     goodcontent = test
     badcontent
     """
     write_into_file("test.ini", content)
     with self.assertRaises(ParsingError):
         Config("test.ini")
Esempio n. 28
0
 def get_config_version_mismatch(self) -> bool:
     """
     TODO: Docu
     """
     cfg1 = Config("config/easywall.sample.ini")
     cfg2 = Config("config/easywall.ini")
     for section in cfg1.get_sections():
         if section not in cfg2.get_sections():
             return True
         for key in cfg1.get_keys(section):
             if key not in cfg2.get_keys(section):
                 return True
     return False
Esempio n. 29
0
class Passwd(object):
    """the class contains the password generation and saving"""
    def __init__(self) -> None:
        """the init function creates the config variable and calls the user input"""
        self.config = Config(CONFIG_PATH)

        parser = argparse.ArgumentParser()
        parser.add_argument("--username", "-u", help="set username")
        parser.add_argument("--password", "-p", help="set password")
        args = parser.parse_args()

        if args.username and args.password:
            self.saveuser(args.username)
            self.savepasswd(args.password)
        else:
            self.ask_user()

    def savepasswd(self, password: str) -> None:
        """the function saves the password into the config file using the config class"""
        hostname = platform.node().encode("utf-8")
        salt = hashlib.sha512(hostname).hexdigest()
        pw_hash = hashlib.sha512(str(salt +
                                     password).encode("utf-8")).hexdigest()
        self.config.set_value("WEB", "password", pw_hash)
        print("Password successfully saved.")

    def saveuser(self, username: str) -> None:
        """the function saves the username into the config file using the config class"""
        self.config.set_value("WEB", "username", username)
        print("Username successfully saved.")

    def ask_user(self) -> None:
        """the function asks the user for the username and password"""
        username = input("easywall Web Username: "******"easywall Web Password: "******"easywall Web Password repeat: ")
        if password == password_repeat:
            self.savepasswd(password)
        else:
            print("password is not equal. password not saved!")
Esempio n. 30
0
    def __init__(self) -> None:
        """TODO: Doku."""
        self.cfg = Config(CONFIG_PATH)
        self.cfg_log = Config(LOG_CONFIG_PATH)

        loglevel = self.cfg_log.get_value("LOG", "level")
        to_stdout = self.cfg_log.get_value("LOG", "to_stdout")
        to_files = self.cfg_log.get_value("LOG", "to_files")
        logpath = self.cfg_log.get_value("LOG", "filepath")
        logfile = self.cfg_log.get_value("LOG", "filename")
        self.log = Log(str(loglevel), bool(to_stdout), bool(to_files),
                       str(logpath), str(logfile))

        info("starting easywall")

        self.easywall = Easywall(self.cfg)
        self.event_handler = ModifiedHandler(self.apply)
        self.observer = Observer()
        self.stop_flag = False

        info("easywall has been started")