Tag: RouterOS

Dude 6.x sprzątanie bazy danych

Ostatnio zacząłem mieć kłopoty z tworzeniem się kopii zapasowej. W logach pojawiały się wpisy na czerwono „timeout” w odniesieniu do skryptów. Sprawdziłem maszynę i rozmiar dude.db wynosił ponad 200MB. Faktycznie, z poziomu konsoli backup dało się zrobić, ale już aby skrypt wykonał kopię nie.

Przeglądając internet i stare wpisy na temat Dude 3.6 i 4.0 trafiłem na czyszczenie bazy. http://www.mtin.net/blog/cleaning-the-dude-database/

Dane w Dude trzymane są w bazie danych SQLite, można taką bazę otworzyć poprzez klienta i edytować. W czyszczeniu bazy najczęściej chodzi o usunięcie danych historycznych: czasów awarii oraz danych do wykresów.

Niestety pierwsze podejście było połowicznie udane, z 200MB udało mi się zmniejszyć bazę do 2,5MB. Polegało to na przekonwertowaniu bazy na plik tekstowy .sql, utworzenie w Dude nowej bazy dude.db i przeniesienie do niej tylko wpisów urządzeń. Są to linie zaczynające się od:

INSERT INTO “objs”

Wszystko wyglądało dobrze, Dude wstał z nową, lekką bazą. Nic nie zwiastowało problemów. Nastały one w północy, kiedy tworzy się kopia. Nie problemem było, że się nie zrobiła, problemem było, że zrobiła się na kilka tysięcy procent. Zapełniła całe dostępne miejsce na maszynie i zablokowała zapisywanie nowych zmian w bazie. Sprawdziłem kilkukrotnie, czy to ręcznie czy skryptem. Tak samo. Export mija magiczne 100% i przebiega dalej.

Powrót do starej bazy i dalsza analiza problemu. Jeżeli możemy dokonać obróbki bazy z poziomu wiersza poleceń sqlite, to zamiast edytować w notatniku plik sql wielkości ponad 600MB, zróbmy to tam.

Podejście numer dwa. Nowy jail na FreeBSD, dodanie pakietu sqlite3 i przesłanie pliku dude.db do niego.

Marcin@dude:/mnt# sqlite3 dude.db
SQLite version 3.30.1 2019-10-10 20:19:45
Enter ".help" for usage hints.
sqlite> .tables
chart_values_10min  chart_values_2hour  objs
chart_values_1day   chart_values_raw    outages

Jak widać, mamy tabele objs gdzie są nasze urządzenia, tabelę outages gdzie mamy wpisy z awariami naszych urządzeń oraz tabele chart_* gdzie są dane do wykresów. Choć możemy nie korzystać z wykresów to dane są i tak automatycznie zbierane dla wszystkich interfejsów, procesorów itp.

sqlite> delete from chart_values_10min;
sqlite> delete from chart_values_2hour;
sqlite> delete from chart_values_1day;
sqlite> delete from chart_values_raw;
sqlite> delete from outages;

Pozbywamy się niechcianych danych z tabel, jeżeli chcemy zostawić wpisy o awariach to nie usuwamy danych z tabeli outages.

Na koniec wykonujemy czyszczenie bazy poleceniem vacuum i zamykamy wiersz poleceń sqlite:

sqlite> vacuum;
sqlite> .quit;

Po tych zabiegach baza dude.db zajmowała tyle samo miejsca co według poradnika, ale nie stwarzała problemów z eksportem z linii poleceń czy poprzez skrypt.

Nie muszę chyba pisać o wykonaniu kopii zapasowej aby w razie niepowodzenia mieć plik dude.db sprzed zmian.

Dodatkowo można testować nową bazę danych zmieniając katalog główny Dude.

[Marcin@Dude] > dude set data-directory=dude2

Mikrotik 2XWAN 2XLAN Separacja i Failover

Trafiłem ostatnio zlecenie na użycie dwóch łącz internetowych dla dwóch podsieci. Każda podsieć korzysta z innego łącza. Ten konkretny przykład zrobiłem na RB2011, 10 portów elektrycznych. Port ETH1 jest portem WAN1, port ETH6 jest portem WAN2, porty 2-5 to LAN1, porty 7-10 to LAN2.

Topologia sieci wygląda następująco:

Network 2WAN 2LAN

Tworzymy na początek dwa bridge dla dwóch podsieci oraz dodajemy porty do odpowiednich sieci LAN:

/interface bridge
add name=LAN1
add name=LAN2
/interface bridge port
add bridge=LAN1 interface=ether2
add bridge=LAN1 interface=ether3
add bridge=LAN1 interface=ether4
add bridge=LAN1 interface=ether5
add bridge=LAN2 interface=ether7
add bridge=LAN2 interface=ether8
add bridge=LAN2 interface=ether9
add bridge=LAN2 interface=ether10

Nadajemy adresacje, gdzie IP ISP1 to 10.10.10.2 a brama to 10.10.10.1 maska 255.255.255.0, IP ISP2 to 10.10.20.2 a brama to 10.10.20.1 maska 255.255.255.0.

/ip address
add address=10.0.0.1/24 comment=LAN1 interface=LAN1 network=10.0.0.0
add address=10.0.2.1/24 comment=LAN2 interface=LAN2 network=10.0.2.0
add address=10.10.10.2/24 comment=WAN1 interface=ether1 network=\
    10.10.10.0
add address=10.10.20.2/24 comment=WAN2 interface=ether6 network=\
    10.10.20.0

Zajmiemy się teraz sieciami LAN, tworzymy serwery DHCP dla dwóch podsieci z osobnymi klasami adresowymi.

/ip pool
add name=LAN1 ranges=10.0.0.50-10.0.0.250
add name=LAN2 ranges=10.0.2.50-10.0.2.250
/ip dhcp-server
add add-arp=yes address-pool=LAN1 disabled=no interface=LAN1 lease-time=1h name=DHCP_LAN1
add add-arp=yes address-pool=LAN2 disabled=no interface=LAN2 lease-time=1h name=DHCP_LAN2
/ip dhcp-server network
add address=10.0.0.0/24 comment=LAN1 dns-server=208.67.220.220,208.67.222.222 gateway=10.0.0.1 ntp-server=193.219.28.2,194.29.130.252
add address=10.0.2.0/24 comment=LAN2 dns-server=208.67.220.220,208.67.222.222 gateway=10.0.2.1 ntp-server=193.219.28.2,194.29.130.252

Ustawiamy klienta czasu, serwer DNS oraz strefę czasową i nazwę urządzenia

/system ntp client
set enabled=yes primary-ntp=150.254.183.15 secondary-ntp=193.219.28.2
/ip dns
set servers=208.67.220.220,208.67.222.222
/system clock
set time-zone-name=Europe/Warsaw
/system identity
set name=2WAN2LAN

Przechodzimy teraz już do konfiguracji samego działania dwóch łącz oraz przełączenia się podsieci pomiędzy łącza w przypadku awarii jednego z nich.

Najpierw markujemy pakiety z odpowiednich podsieci na odpowiednie łącza internetowe

ip firewall mangle
add action=mark-routing chain=prerouting new-routing-mark=to_WAN1 passthrough=yes src-address=10.0.0.0/24
add action=mark-routing chain=prerouting new-routing-mark=to_WAN2 passthrough=yes src-address=10.0.2.0/24

Następnie dodajemy dodajemy maskradę, dając internet komputerom w podsieciach LAN1 i LAN2

/ip firewall nat
add action=masquerade chain=srcnat comment=WAN1 out-interface=ether1
add action=masquerade chain=srcnat comment=WAN2 out-interface=ether6

Następnie dodajemy bramy domyślne dla podsieci oraz główną bramę domyślną dla routera, w przypadku gdy jedna z bram przestanie odpowiadać sieć LAN która z niej korzysta przełączy się automatycznie na drugą podsieć

/ip route
add check-gateway=ping distance=1 gateway=10.10.10.1 routing-mark=to_WAN1
add check-gateway=ping distance=1 gateway=10.10.20.1 routing-mark=to_WAN2
add check-gateway=ping distance=2 gateway=10.10.10.1,10.10.20.1

Jeżeli dostajemy dwa łącza internetowe od jednego ISP zdarzyć się może, że będą one w jednej podsieci ze wspólną bramą. Np. IP1 10.10.10.2 oraz IP2 10.10.10.3 ze wspólną bramą 10.10.10.1 to należy oznaczyć taki ruch w sposób następujący

/ip route
add check-gateway=ping distance=1 gateway=10.10.10.1%ether1 routing-mark=to_WAN1
add check-gateway=ping distance=1 gateway=10.10.10.1%ether6 routing-mark=to_WAN2
add check-gateway=ping distance=2 gateway=10.10.10.1%ether6,10.10.10.1%ether1

Na koniec standardowo zabezpieczam takiego mikrotika wyłączając zbędne usługi oraz dając dostęp do zarządzania tylko z wewnętrznych podsieci

/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh disabled=yes
set api disabled=yes
set winbox address=10.0.0.0/24,10.0.2.0/24
set api-ssl disabled=yes

 

Mikrotik i backup codzienny

Tak jak w przypadku The Dude tak samo przydaje się mieć backup ustawień z urządzeń Mikrotik rozsianych po sieci. Po co utrudniać sobie życie jak można ułatwić, wykorzystując do tego samo urządzenie i automatyzując sam proces. Sam backup polega na wygenerowaniu pliku binarnego .backup oraz pliku tekstowego .rsc. Osobiście wolę mieć oba, pierwszy wgrywam, drugi mam do podglądu wszystkich ustawień.

/system script
add name=FTPBackup owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive source=":log info \"\
    Starting Automatic Backup Script Configure By cr0c0dil3\"\r\
    \n:log info \"Modyfikowany przez Marcin Morawiec\"\r\
    \n:global thisdate [/system clock get date]\r\
    \n:global datetimestring ([:pick \$thisdate 4 6] .\"-\" . [:pick \$thisdate 0 3\
    ] .\"-\" . [:pick \$thisdate 7 11])\r\
    \n\r\
    \n/system backup save name=\"\$[/system identity get name]_\$datetimestring\" \
    \r\
    \n:log info \"Backup Please wait...!!!\"\r\
    \nexport compact file=\"\$[/system identity get name]_\$datetimestring\"\
    \_\r\
    \n:log info \"Export Please wait...!!!\"\r\
    \n:delay 5s\r\
    \n:log info \"Sending Backup Mikrotik to FTP Server.............\"\r\
    \n/tool fetch address=ip_address src-path=\"\$[/system identity get name]_\$\
    datetimestring.backup\" user=user password=password port=21 upload=yes \
    ascii=no mode=ftp dst-path=\"/backup/\$[/system identity get name]_\$datetimest\
    ring.backup\"\r\
    \n:log info \"Sending Export Mikrotik to FTP Server.............\"\r\
    \n/tool fetch address=ip_address src-path=\"\$[/system identity get name]_\$\
    datetimestring.rsc\" user=user password=password port=21 upload=yes asc\
    ii=no mode=ftp dst-path=\"/backup/\$[/system identity get name]_\$datetimestrin\
    g.rsc\"\r\
    \n:delay 5s\r\
    \n:log info \"Deleting Backup Files\"\r\
    \n/file remove \"\$[/system identity get name]_\$datetimestring.rsc\"\r\
    \n/file remove \"\$[/system identity get name]_\$datetimestring.backup\"\r\
    \n:log info message=\"Successfully removed Temporary Backup Files\"\r\
    \n:delay 1\r\
    \n:log info \"Finished Backup Script...!!!!\""
  
/system scheduler
add interval=1d name=FTPBackupMT on-event="/system script run FTPBackup" policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive start-date=\
    apr/01/2016 start-time=00:00:15

Skrypt wzorowany jest na znalezionym w internecie tutaj. Przejrzysty, składa się z kilku poleceń. Łatwo można dostosować go do siebie. Pamiętać należy o podaniu swojego IP serwera FTP, użytkownika i hasła oraz ścieżki na serwerze gdzie ma być składowany backup. U mnie backup ląduje na serwerze NAS4FREE gdzie w odstępach tygodniowych protokołem rsync wędrują na kolejnego NASa. W planach jest jeszcze opcja szyfrowania archiwum i wysyłania go na pocztę aby mieć kolejną kopię w innej lokalizacji.

DudeRC i backup codzienny

Są admini którzy robią backup, i tacy którzy zaczną robić. Bardzo prawdziwe słowa, doceni je admin z tej drugiej grupy. Straciłem kiedyś bazę danych Mikrotikowego The Dude, normalna w świecie awaria sprzętu, dysk odmówił działania. Monitorowana sieć jest rozmiaru 300 hostów, syslog z kilkunastu urządzeń. Teraz The Dude stoi na maszynie wirtualnej, dysk jest na macierzy. Jednak przezorny zawsze ubezpieczony, w chwili wolnego czasu wolałem zabezpieczyć się przed jakimś błędem, który skasuje mi dane w programie. Zabezpieczenie przez awarią sprzętu to jedno, awaria przed utratą danych to drugie.

/system script
add name=Dude_backup owner=admin policy=\
 ftp,reboot,read,write,policy,test,password,sniff,sensitive source=":log in\
 fo \"Dude Backup Script by Marcin Morawiec\"\r\
 \n:global thisdate [/system clock get date]\r\
 \n:global datetimestring ([:pick \$thisdate 4 6] .\"-\" . [:pick \$thisdat\
 e 0 3] .\"-\" . [:pick \$thisdate 7 11])\r\
 \n\r\
 \n/dude export-db backup-file=\"Dude_\$datetimestring.backup\" \r\
 \n:log info \"Backup Please wait...!!!\"\r\
 \n:delay 30s\r\
 \n:log info \"Sending Dude Backup to FTP Server.............\"\r\
 \n/tool fetch address=10.0.0.10 src-path=\"Dude_\$datetimestring.backup\
 \" user=Dude password=zaq12wsxcde3 port=21 upload=yes ascii=no mode=ftp ds\
 t-path=\"Dude_\$datetimestring.backup\"\r\
 \n:delay 5s\r\
 \n:log info \"Deleting Backup Files\"\r\
 \n/file remove \"Dude_\$datetimestring.backup\"\r\
 \n:log info message=\"Successfully removed Temporary Backup Files\"\r\
 \n:delay 1\r\
 \n:log info \"Finished Backup Script...!!!!\""

Bazę danych na nowym The Dude w wersji na platformę ROS można optymalizować z racji tego, że jest to baza danych SQLite3, codziennie przed północą mam zaplanowaną optymalizację, a 30min później robiony jest export.

/system scheduler
add interval=1d name=Dude_vacuum-db on-event="/dude vacuum-db" policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive start-date=\
    apr/01/2016 start-time=23:00:00
add interval=1d name=Dude_Backup on-event="/system script run Dude_backup" \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive \
    start-date=apr/01/2016 start-time=23:30:00

Wyedytować trzeba sobie tylko skrypt aby łączyć się do swojego serwera FTP, podać IP, użytkownika i hasło. Oraz do jakiego katalogu ma być wrzucany plik.