Mikrotik addres-list в Home Assistant

Всем привет, понадобилось мне для домашней автоматизации Home Assistant управлять списком адресов в Mikrotik’е, поискав в гугле ничего внятного не нашел, пришлось писать самому

Зачем это нужно? Дома в сети есть девайсы (планшет, телефоны, телевизоры…) периодически есть необходимость лишать их доступа в интернет, молодые родители меня поймут 🙂

Что понадобится: 

  • Маршрутизатор Mikrotik
  • Home Assistant в моем случае hass.io
  • AppDaemon — это такая среда выполнения Python скриптов для автоматизаций, подробнее тут

Начнем.

Для начала сделайте адреса необходимых устройств статическими в DHCP сервере, это нужно для того что-бы IP адреса не изменялись. Далее нам нужно создать Address List в Mikrotik’е (IP > Firewall > Address Lists) Add New

  • Name: CHILDREN_BLOCK_INET (тут называете список как вам нравится, без пробелов)
  • Address: 192.168.0.51 (адрес устройства, который хотим блокировать)
  • Comment: iPad (ВАЖНО: здесь название устройства, будет отображаться в HA)

PS: Поле Comment важно заполнять уникальным т.к. на его основе будет создаваться сущность в данном случае switch.mtk_al_ipad 

Далее нам нужно создать правило фильтрации в Mikrotik’е (IP > Firewall > Filter Rules) Add New:

  • Enabled: Yes
  • Chain: forward
  • Protocol: 6 (tcp)
  • Out. Interface: ether1 (интерфейс который смотрит в интернет в моем случае это ether1)
  • Src. Address List: CHILDREN_BLOCK_INET (создавали ранее)
  • Action: reject
  • Reject With: tcp reset
  • Comment: CHILDREN_BLOCK_INET

Созданное правило перемещаем наверх, для того что бы оно отрабатывало как можно раньше, на этом этапе можно проверить работу правила, взять гаджет проверить интернет, зайти в (IP > Firewall > Address Lists) включить правило для устройства, интернет должен пропасть. Перейдите в System > User и создайте нового пользователя homeassistant, он нам понадобится для управления списком из HA.

С Mikrotik’ом всё, переходим в HA, у меня hass.io через него устанавливаем Add-on AppDaemon если у вас не hass.io, то AppDaemon скорее всего установить можно, каким то другим способом, но я не задавался таким вопросом 🙂

в AppDaemon прописываем в конфиг python_packages «librouteros==3.0.0» это модуль для взаимодействия с Mikrotik у меня получилось так:

{
  "disable_auto_token": false,
  "system_packages": [],
  "python_packages": [
    "librouteros==3.0.0"
  ],
  "init_commands": []
}

После перезапуска AppDaemon’а, установится librouteros и в папке конфигурации HA должна появится папка appdaemon, создаем папку appdaemon/apps/mikrotik это папка нашего приложения, в ней создаем два файла mikrotik.py и mikrotik.yaml

mikrotik.yaml:

Mikrotik:
 module: mikrotik
 class: Mikrotik
 host: '192.168.0.1'
 username: 'homeassistant'
 password: '__YOUR_PASSWORD__'
 addrlist: 'CHILDREN_BLOCK_INET'

mikrotik.py:

import datetime
import re
import appdaemon.plugins.hass.hassapi as hass
import time
import librouteros
from librouteros.login import plain, token

class Mikrotik(hass.Hass):
    def initialize(self):
        self.log("Mikrotik")
        self.handles = {}
        self.run_every(self.update, datetime.datetime.now(), 10)
        self.api = librouteros.connect(self.args["host"], self.args["username"], self.args["password"])
        self.listen_event(self.state_change, event = "call_service")

    def update_addr_list(self):
        lst = self.args["addrlist"]
        lists = self.api('/ip/firewall/address-list/print')
        for row in lists:
            if row['list'] != lst:
                continue
            addr_id = row['.id']
            sensor_name = 'switch.mtk_al_' + re.sub(r"\W ", "", row['comment'], flags=re.I).replace(" ", "_")
            self.log('sensor_name: {}'.format(sensor_name))
            sensor_name = sensor_name.lower()
            self.handles[sensor_name] = row
            self.handles[sensor_name]['addr_id'] = addr_id

    def update(self, kwargs):
        self.update_addr_list()
        for row in self.handles:
            state = "off"
            if self.handles[row]['disabled'] == True:
                state = "on"
            self.set_state(row, state = state, attributes = {"friendly_name": self.handles[row]['comment'], "address": self.handles[row]['address'], 'list': self.handles[row]['list'], 'icon': 'mdi:earth', 'addr_id': self.handles[row]['addr_id']})

    def state_change(self, event_name, data, kwargs):
        entity = data["service_data"]["entity_id"]
        if(data["service"] == "turn_off" and entity in self.handles):
            self.set_list_state(False, self.handles[entity]['addr_id'])
        if(data["service"] == "turn_on" and entity in self.handles):
            self.set_list_state(True, self.handles[entity]['addr_id'])

    def set_list_state(self, state, addr_id):
        params = {'disabled': state, '.id': addr_id}
        t = self.api('/ip/firewall/address-list/set', **params)
        tuple(t)
        self.update(None)

при копировании данного кода отсюда, могут поломаться отступы(особенность языка Python) имейте это ввиду. После сохранения AppDaemon увидет изменения и запустит приложение автоматически

Данный код писался с мобилки и на красоту не претендует 🙂 Надеюсь кому то будет полезно.

2 комментария на “Mikrotik addres-list в Home Assistant

  1. Не совсем работает код с последними HA и микротиком (6.46.6). Показывает то что есть в микротике, но не переключает.

Добавить комментарий для Сергей Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Закончите арифметическое действие * Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.