CactiEZ 0.7 i worek przygód

Do monitorowania sieci używam od dawien dawna oprogramowania Cacti. Na początku stawianego ręcznie na Debianie. Było to czasochłonne i wiązało się z powielaniem czynności. Na dodatek przy kolejnych wersjach Debiana instalacja różniła się w detalach. Zmieniały się wersje MySQL czy PHP.

Potem przyszedł z pomocą użytkownik cigamit z forums.cacti.net i stworzył CD z systemem CentOS 6 i skryptami instalującymi i konfigurującymi całość. Finalnie otrzymujemy gotową instalację z Cacti na pokładzie i kilkoma dodatkami, działającą od razu.

Niestety jak każdy “produkt” posiada większe i mniejsze błędy, ostatnia wersja to 0.7 czyli już po numerze widać, że nie jest to wersja stabilna, finalna itp. Nowszej już niestety nie było ale dla 99% instalacji jakie wykonałem Cacti 0.8.8b w zupełności wystarcza.

Procesu instalacji nie będę relacjonował bo jest ich kilka w sieci, nie ma co powielać treści. Jednak sposobu z jakiego sam korzystam nie widziałem nigdzie. CactiEZ domyślnie instaluje się na wybranym dysku podczas instalacji. Wybieramy jeden dysk i na nim kreator instalacji tworzy automatycznie partycje / i /home oraz partycję swap, rozmiar dobiera procentowo do pojemności dysku.

W instalacji CactiEZ katalog /home miałem praktycznie zawsze pusty, za to / zapełniał się szybko poprzez dodawanie urządzeń do monitorowania i tworzenia nowych plików .rra, które tworzą się od razu w przewidzianej w ustawieniach wielkości. Przeszukując instrukcję od CentOSa doszukałem się informacji, że w trybie tekstowym narzędzia do dysków są w okrojonej wersji i nie pozwalają na bardziej zaawansowane modyfikacje i ustawienia np. Software RAID ale instalując system poprzez VNC mamy dostęp do graficznego interfejsu i tym samym zaawansowanych narzędzi.

Aby zacząć instalację poprzez VNC podczas startu gdy pojawi się ekran CactiEZ Install screen wpisujemy w linii poleceń:

linux vnc

Dalej poprzez kilka pytań o ustawienia sieci przechodzimy dalej i pojawi się nam linijka na dole monitora:

13:14:47 Please manually connect your VNC viewer to 192.168.100.131:5901 to begin the install.

Oczywiście IP i port będzie inny, ale mamy podane dane do połączenia, za pomocą klienta VNC łączymy się do maszyny i postępujemy dalej z instalacją. Tworzymy macierze na dyskach i ustawiamy punkty montowania wg. potrzeb i kończymy instalację. Wydawałoby się, że to tak prosto ale jednak nie jest.

W pliku z listą pakietów do instalacji nie ma mdadm, bo standardowo instalacja wykonywana jest na jednym dysku z LVM i pakiet nie jest nam potrzebny po instalacji. Jeżeli mamy potrzebę utworzyć macierze za pomocą mdadm to instalujemy go po instalacji systemu i tworzymy macierze. Ale przecież my zainstalowaliśmy system na macierzy utworzonej przez mdadm ale nie mamy go w systemie. I podczas startu otrzymamy Kernel Panic. Nie wyciągamy CD z napędu tylko uruchamiamy instalator jeszcze raz, ale tym razem zamiast

linux vnc

wpisujemy

linux rescue

Uruchamiamy system z płyty, nasz system dyskowy zostanie podmontowany w katalogu

/mnt/sysimage

Należy wykonać polecenie

chroot /mnt/sysimage

I tym samym przełączyć się na naszą świerzą instalację tak jak byśmy byli w normalnie uruchomionym systemie. Teraz należy usunąć plik z repozytorium cactiez, które już niestety nie istnieje, potem zaktualizować listę pakietów ale nie uaktualniać ich na tą chwilę tylko wpisać N. Zainstalować pakiet mdadm i po tej operacji zaktualizować wszystkie pakiety.

rm /etc/yum.repos.d/cactiez.repo
yum update
yum install mdadm
yum upgrade

Dlatego w tej kolejności bo przy uaktualnieniu pakietów zostanie zainstalowany nowszy kernel linuksa, i tym samym zostanie wygenerowany nowy obraz initramfs już z obsługą mdadm i tym samym pozwoli już normalnie nam uruchomić system. Po tej operacji mamy gotowy system do pracy, zaktualizowany do CentOS 6.10 działający na SoftwareRAID.

[root@localhost ~]# cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 sdb1[1] sda1[0]
      255988 blocks super 1.0 [2/2] [UU]

md1 : active raid1 sdb2[1] sda2[0]
      30718908 blocks super 1.1 [2/2] [UU]
      bitmap: 1/1 pages [4KB], 65536KB chunk

md2 : active raid1 sda3[0] sdb3[1]
      2145272 blocks super 1.1 [2/2] [UU]

[root@localhost ~]# mount
/dev/md1 on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/md0 on /boot type ext2 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)

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

OpenWrt 18.06.1 + TP-Link WR841N = Czujnik temperatury cz.3

Jak pisałem w części 2 ostatnim krokiem będzie skonfigurowanie usługi SNMP na naszym czujniku abyśmy mogli monitorować temperaturę poprzez sieć.

Zaczynamy od konfiguracji SNMP. Edytujemy plik /etc/config/snmpd, interesuje nas sekcja

root@OpenWrt:~# nano /etc/config/snmpd
~
config system
        option sysLocation      'Monitorowana szafka' # Pole Location opisujące lokalizację czujnika
        option sysContact       'nasz@adres.email' # Pole Contact opisujące adres email, numer telefonu itp.
        option sysName          'OpenWrt_Temp' # Pole Name opisujęce nazwę urządzenia odczytywaną po SNMP
#       option sysServices      72
        option sysDescr         'OpenWrt Temperatura' # Pole Descryption z opisem urządzenia odczytywanym po SNMP
#       option sysObjectID      '1.2.3.4'
config exec
        option name     Temperatura
        option prog     /bin/cat
        option args     /etc/config/temp.txt
#       option miboid   1.2.3.4
~

Pod Windowsem korzystam z programu SNMPWalk od SolarWinds, jest to mały program pozwalający wykonać polecenie snmpwalk na urządzeniu i wynik zapisać do pliku tekstowego.snmpwalkJeżeli już wszystko ustawiliśmy wg. swoich danych zapisujemy i zamykamy edytor. Usługę snmpd uruchamiamy podobnie do usługi cron poleceniami:

root@OpenWrt:~# /etc/init.d/snmpd start
root@OpenWrt:~# /etc/init.d/snmpd enable

Po tych zabiegach możemy przetestować działanie naszego czujnika temperatury. Możemy przeskanować cały zakres OIDów lub tylko gałąź 1.3.6.1.4.1.2021.8.1, która zawiera dane odnośnie temperatury.

.1.3.6.1.4.1.2021.8.1.1.1 = INTEGER: 1
.1.3.6.1.4.1.2021.8.1.2.1 = STRING: "Temperatura"
.1.3.6.1.4.1.2021.8.1.3.1 = STRING: "/bin/cat /etc/config/temp.txt"
.1.3.6.1.4.1.2021.8.1.100.1 = INTEGER: 0
.1.3.6.1.4.1.2021.8.1.101.1 = STRING: "28"
.1.3.6.1.4.1.2021.8.1.102.1 = INTEGER: 0
.1.3.6.1.4.1.2021.8.1.103.1 = STRING: ""

Dalej możemy już dowolnie takimi danymi zarządzać, przetwarzać itp. U siebie mam dodaną taką czujkę jako urządzenie w Cacti, dodatkowo stworzony template odczytujący dany OID. Utworzony również template w pluginie Thold, monitorujący i alarmujący jeżeli temperatura wychodzi poza górny lub dolny zakres.

Cacti Tempratura SNMP

Cacti Tempratura SNMP

OpenWrt 18.06.1 + TP-Link WR841N = Czujnik temperatury cz.2

Witam w części drugiej, w niej zajmiemy się modyfikacją sprzętową. Dodamy jeden czujnik na jednej z dostępnych linii GPIO. Dostępne linie GPIO sprawdzimy poleceniem:

root@OpenWrt:~# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-31, parent: platform/ath79-gpio, ath79-gpio:
 gpio-3   (                    |tp-link:green:qss   ) out hi
 gpio-4   (                    |tp-link:green:wan   ) out hi
 gpio-11  (                    |tp-link:green:lan4  ) out hi
 gpio-12  (                    |Reset button        ) in  hi
 gpio-13  (                    |tp-link:green:wlan  ) out hi
 gpio-14  (                    |tp-link:green:lan3  ) out hi
 gpio-15  (                    |tp-link:green:lan2  ) out hi
 gpio-16  (                    |tp-link:green:lan1  ) out hi
 gpio-17  (                    |WIFI button         ) in  hi

gpiochip1: GPIOs 494-511, parent: platform/qca953x_wmac, ath9k-phy0:
 gpio-495 (                    |ath9k-phy0          ) in  lo

Sprawdzone i dostępne linie to 11,13,14,15,16. Testowałem linię GPIO3 ale router nie uruchamia się wcale. Innych jeszcze nie miałem czasu przetestować, choć planuję to w najbliższej przyszłości.

Ale wracamy do czujnika temperatury. Potrzebujemy czujnik temperatury DS18B20, zamieszczam kartę produktu: https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf. Do tego rezystor 3.3k przewlekany oraz kilka przewodów do podłączenia.

WR841N_V9 Top

WR841N_V9 Top

WR841N_V9 Bottom

WR841N_V9 Bottom

Wykorzystamy GPIO13 od diody WLAN, jest to druga dioda od lewej patrząc od dołu PCB. Na początek musimy usunąć diodę, można pomóc sobie małą ilością nowej cyny. Potrzebne są też trzy przewody o odpowiedniej długości, które cynujemy po obu stronach. Wszystko łączymy jak na zdjęciu poniżej:

WR841N_V9 DB18B20Jeżeli wszystko mamy przylutowane możemy złożyć router. Podpinamy zasilanie oraz łączymy się z naszym routerem po SSH. Teraz kilka poleceń aby odzyskać linie GPIO używane przez system i wykorzystać je do własnych celów.

Na początek dodajemy zawartość do pliku /etc/rc.local który jest uruchamiany przy starcie:

root@OpenWrt:~# cat /etc/rc.local
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
/bin/sh /etc/config/leds.sh
exit 0

Tworzymy plik /etc/config/leds.sh i wklejamy do niego zawartość oraz nadajemy mu bit wykonywalności:

root@OpenWrt:~# touch /etc/config/leds.sh
root@OpenWrt:~# cat /etc/config/leds.sh
/bin/echo "leds-gpio" > /sys/bus/platform/drivers/leds-gpio/unbind
/bin/sleep 5
/sbin/insmod w1-gpio-custom bus0=0,13,0
root@OpenWrt:~# chmod +x /etc/config/leds.sh

Plik ten będzie uruchamiany przy starcie systemu. Restartujemy nasz router. Jeżeli wszystko poszło ok to w katalogu /sys/bus/w1/drivers/w1_slave_driver/ powinien pojawić się katalog o nazwie XX-YYYYYYYYYY w moim przypadku jest to:

root@OpenWrt:~# ls -l /sys/bus/w1/drivers/w1_slave_driver/
lrwxrwxrwx    1 root     root             0 Sep 30 12:51 28-00ff984302e5 -> ../../../../devices/w1_bus_master1/28-00ff984302e5
--w-------    1 root     root          4096 Sep 30 13:11 bind
--w-------    1 root     root          4096 Sep 30 13:11 uevent
--w-------    1 root     root          4096 Sep 30 13:11 unbind

Temperaturę odczytujemy drugim skryptem, dodatkowo skrypt tworzy plik tekstowy temp.txt z aktualną temperaturą. Skrypt ten dodany został do crona i jest uruchamiany co pięć minut, częstotliwość można zmienić wg. własnego upodobania.

root@OpenWrt:~# touch /etc/config/temp.sh
root@OpenWrt:~# cat /etc/config/temp.sh
awk -F= '/t=/ {printf "%.0f\n", $2/1000}' /sys/bus/w1/drivers/w1_slave_driver/28-00ff984302e5/w1_slave > /etc/config/temp.txt
root@OpenWrt:~# chmod +x /etc/config/temp.sh

root@OpenWrt:~# touch /etc/crontabs/root
root@OpenWrt:~# cat /etc/crontabs/root
*/5 * * * * /etc/config/temp.sh
root@OpenWrt:~# /etc/init.d/cron start
root@OpenWrt:~# /etc/init.d/cron enable

W tym momencie możemy sprawdzić poprawność skryptów. Możemy uruchomić skrypt ręcznie lub poczekać pięć minut i sprawdzić czy pojawił się plik /etc/config/temp.txt i poleceniem cat /etc/config/temp.txt sprawdzić jego zawartość.

root@OpenWrt:~# cat /etc/config/temp.txt
28

W tym momencie kończymy drugą część, trzecia część będzie już krótka i opisywać będzie uruchomienie usługi SNMP. Konfiguracja i sprawdzenie poleceniem snmpwalk poprawności ustawień.

OpenWrt 18.06.1 + TP-Link WR841N = Czujnik temperatury cz.1

Ostatnio wpadł mi pomysł do głowy na monitorowanie kilku lokalizacji. Chodziło głównie o temperaturę w pomieszczeniu, szafie serwerowej czy wewnątrz skrzyni powieszonej na ścianie czy maszcie. Przeglądając internet i szukając trafiłem na sondy temperatury odczytywanej po SNMP, jednak koszt 300zł był dla mnie mało atrakcyjny. Ilość jakiej potrzebowałem to kilkanaście sztuk, może i więcej. Zainteresowałem się tematem, zmalałem wiele opisów takich sond opartych o routery z wgranym OpenWrt i podpiętym pod USB konwerterem na RS232 i do tego czujnik DS18B20 1-wire. Gra warta świeczki bo koszt takiej czujki spadł nam już w okolice 100zł. Jest o co walczyć, w cenie jednej sondy mamy trzy. Ale dalej wgłębiałem się w temat. OpenWrt jest projektem o wielu możliwościach, może być nie tylko routerem ale też dyskiem sieciowym czy kontrolerem z podpiętymi przekaźnikami na liniach GPIO. Zgłębiając dalej temat znalazłem informację, że na linii GPIO mogę również podłączyć czujnik 1-wire. Zapaliła się lampka w mojej głowie, mam jeden wolny router w szufladzie, jest to wspomniany w temacie WR841N.

Pierwszą sprawą było przygotowanie sobie obrazu OpenWrt dla tego modelu routera. Można skorzystać z gotowego obrazu, jednak nie ma on w standardzie paczek 1-wire a ilość wolnego miejsca jest bardzo skromna. Router jaki posiadam to v9.1, 550MHz, 4MB FLASH oraz 32MB RAM.

Do stworzenia takiego obrazu potrzebujemy środowiska Linuksowego x64. Czy jest to fizyczna maszyna czy wirtualna nie ma znaczenia. Jak zapewnić sobie takie środowisko odsyłam do źródła: Image Builder

Przechodzimy do katalogu ze źródłami. Do budowania obrazów OpenWrt posiłkuję się skryptem:

make -j2 image PROFILE=tl-wr841-v9 PACKAGES="kmod-w1 kmod-w1-master-gpio kmod-w1-gpio-custom kmod-w1-slave-therm terminfo libnetsnmp snmpd libncurses nano base-files busybox dnsmasq dropbear -firewall fstools -ip6tables -iptables kernel kmod-ath9k kmod-gpio-button-hotplug libc libgcc logd mtd netifd -odhcp6c -odhcpd-ipv6only opkg -ppp -ppp-mod-pppoe swconfig uboot-envtools uci uclient-fetch wpad-mini"

Krótkie wyjaśnienie parametrów w skrypcie:

  • -j2 oznacza kompilowanie w dwóch wątkach jednocześnie, w zależności od ilości rdzeni/procesorów na maszynie gdzie budujemy obrazy
  • image PROFILE=tl-wr841-v9 oznacza pod jaki router budujemy obraz, bez tego parametru będziemy budować obrazy dla każdego rodzaju routera co znacząco wydłuży czas budowy i będzie marnotrawieniem czasu
  • lista PACKAGES zawiera jakie pakiety będą dodane lub usunięte (te z – na początku nazwy) z budowanego obrazu

W katalogu bin/targets/ar71xx/tiny/ znajdują się nasze obrazy:

marcin@openwrt:~/openwrt1806_wr841n$ ls -l bin/targets/ar71xx/tiny/
razem 22012
-rw-r--r-- 1 marcin users    1678 wrz 28 14:31 openwrt-18.06.1-ar71xx-tiny-device-tl-wr841-v9.manifest
-rw-r--r-- 1 marcin users 2490368 wrz 28 14:31 openwrt-18.06.1-ar71xx-tiny-root.squashfs
-rw-r--r-- 1 marcin users 3932160 wrz 28 14:31 openwrt-18.06.1-ar71xx-tiny-tl-wr841-v9-squashfs-factory.bin
-rw-r--r-- 1 marcin users 3538948 wrz 28 14:31 openwrt-18.06.1-ar71xx-tiny-tl-wr841-v9-squashfs-sysupgrade.bin
-rw-r--r-- 1 marcin users 1348203 wrz 28 14:31 openwrt-18.06.1-ar71xx-tiny-uImage-lzma.bin
-rwxr-xr-x 1 marcin users 4234996 wrz 28 14:31 openwrt-18.06.1-ar71xx-tiny-vmlinux.bin
-rwxr-xr-x 1 marcin users 4240120 wrz 28 14:31 openwrt-18.06.1-ar71xx-tiny-vmlinux.elf
-rw-r--r-- 1 marcin users 1376256 wrz 28 14:31 openwrt-18.06.1-ar71xx-tiny-vmlinux.lzma
-rwxr-xr-x 1 marcin users 1358324 wrz 28 14:31 openwrt-18.06.1-ar71xx-tiny-vmlinux-lzma.elf
-rw-r--r-- 1 marcin users    1027 wrz 28 14:31 sha256sums

Jeżeli mamy router z fabrycznym oprogramowaniem to wybieramy obraz *-factory.bin, jeżeli mamy już wgranego OpenWrt to wybieramy obraz *-sysupgrade.bin. W nowych fabrycznych firmware jest ograniczenie ilości znaków w nazwie wgrywanego obrazu, przed wybraniem go trzeba sobie skrócić jego nazwę. Jeżeli dodajemy jakieś paczki do budowanego obrazu to przed wgrywaniem go na router należy sprawdzić jego rozmiar, powinien być zawsze 3932160, jeżeli jest więcej to przesadziliśmy z ilością pakietów i taki obraz nie wgra się poprawnie.

Jeżeli wszystko poszło ok to router rozdziela adresy IP na portach LAN, na porcie WAN jest klient DHCP czekający na adres. Po instalacji router ma aktywny telnet. Należy za jego pomocą zalogować się jako root do routera, nie ma hasła, i ustawić hasło poleceniem passwd. Jeżeli ustawimy hasło, serwer telnet zostanie wyłączony i zarządzamy naszym routerem poprzez klienta SSH.

Dla ww. wersji użycie pamięci FLASH ma się jak poniżej:

root@OpenWrt:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                 2.0M      2.0M         0 100% /rom
tmpfs                    13.6M     60.0K     13.6M   0% /tmp
/dev/mtdblock3          512.0K    240.0K    272.0K  47% /overlay
overlayfs:/overlay      512.0K    240.0K    272.0K  47% /
tmpfs                   512.0K         0    512.0K   0% /dev

Mamy przygotowany system do pracy z sensorami na 1-wire, w tym czujnikiem temperatury DS18B20. W części drugiej będzie o tym jak podłączyć czujnik pod jedną diodę LED routera i wykorzystać GPIO do odczytu temperatury z czujnika.

Debian 9.0 oraz AirControl 2.1 Beta6

Ostatnio miałem potrzebę przenieść instalację AC2 z jednej maszyny na drugą. Dodatkowo zrobić uaktualnienie do najnowszej wersji beta.

Potrzebujemy maszynę z zainstalowanym podstawowym systemem Debian 9.0, jest to najnowsze stabilne wydanie na obecną chwilę.

Logujemy się na konto root i wydajemy polecenie zainstalowania potrzebnych zależności:

apt-get install default-jdk iperf

W drugim kroku pobieramy binarny pakiet AirControl2.

wget https://fw-download.ubnt.com/data/airControl/680a-unix64-v2.1.0-beta6-7a3591a4c8f646988255f12caa6dac58.bin
mv 680a-unix64-v2.1.0-beta6-7a3591a4c8f646988255f12caa6dac58.bin aircontrol2.1-beta6.bin
chmod +x aircontrol2.1-beta6.bin

Uruchamiamy binarkę i przystępujemy do instalacji serwera AirControl2.

./aircontrol2.1-beta6.bin

Na większość pytań odpowiadamy w domyślnych ustawieniach, instalujemy załączoną bazę danych Postgresql, podajemy hasło dla bazy danych oraz nazwę użytkownika i hasło.

Aby przenieść kopię zapasową ze starej instalacji na nową, na starym serwerze z poziomu klienta AC2 wykonujemy kopię zapasową. Znajduje się ona w folderze

/opt/Ubiquiti/AirControl2/lib/db/

Przenosimy ją za pomocą scp na drugą maszynę i kopiujemy do takiego samego katalogu. Ustawiamy prawa dla pliku aby AC2 ją widział.

chown root:root /opt/Ubiquiti/AirControl2/lib/db/dbbackups/v2.1.0.BETA6_*.pgdmp

Łączymy się za pomocą klienta do nowego serwera i przywracamy za jego pomocą przesłaną kopię zapasową. Serwer AC2 uruchomi się ponownie z przywróconymi danymi.

The Dude + Ubiquity SNMP

Ostatnio upiększałem Dude aby pokazywał trochę więcej informacji niż standardowo jest widoczne dla urządzeń Ubiquity. Efekt widać na załączonym obrazku:

Informacje wyciągane po SNMP z urządzeń z firmware 6.x jednak większość OIDów jest dostępna na urządzeniach z serii A/B,G/AC. Potrzebujemy dodać MIB od Ubiquity do Dude, znaleźć go można na stronie ubnt.com.

Za każdą linijkę odpowiada inna funkcja. Funkcje dodajemy do etykiety urządzenia, lokalnie dla danej mapy w jej ustawieniach albo globalnie dla wszystkich etykiet.

Kolejno zamieszczam zawartość Code.

ubnt_airmax

if (oid_raw("1.3.6.1.4.1.41112.1.4.6.1.3.1")>1,
concatenate("AirMaxQ: ", oid("1.3.6.1.4.1.41112.1.4.6.1.3.1"),"%","/ AirMaxC: ", oid("1.3.6.1.4.1.41112.1.4.6.1.4.1"),"%"),"")
ubnt_cpuload

if (string_size(oid("1.3.6.1.4.1.10002.1.1.1.4.2.1.3.1")),
concatenate("CPU Load: ", oid("1.3.6.1.4.1.10002.1.1.1.4.2.1.3.1"),"%"),"")
ubnt_dfs

if (oid_raw("1.3.6.1.4.1.41112.1.4.1.1.5.1")=1,
"DFS: ON   ","DFS: OFF")
ubnt_kanal

if (string_size(oid("1.3.6.1.4.1.41112.1.4.1.1.4.1")),
concatenate("Kanał: ", oid("1.3.6.1.4.1.41112.1.4.1.1.4.1"),"/", oid("1.3.6.1.4.1.41112.1.4.5.1.14.1"),"MHz", " CC",oid("1.3.6.1.4.1.41112.1.4.1.1.3.1"),""),"")
ubnt_modulacje

if (string_size(oid("1.3.6.1.4.1.41112.1.4.5.1.9.1")),
concatenate("RX/TX: ", string_substring(oid("1.3.6.1.4.1.41112.1.4.5.1.9.1")/1000000,0,4),"Mbps","/", string_substring(oid("1.3.6.1.4.1.41112.1.4.5.1.10.1")/1000000,0,4),"Mbps"),"")
ubnt_sygnaly

if (string_size(oid("1.3.6.1.4.1.41112.1.4.5.1.5.1")),
concatenate("Sygnał: ", oid("1.3.6.1.4.1.41112.1.4.5.1.5.1"), "(", oid("1.3.6.1.4.1.41112.1.4.1.1.6.1"), "dBm)", "/", oid("1.3.6.1.4.1.41112.1.4.5.1.8.1"),"dBm", ""),"")
ubnt_eth0

if (oid_raw("1.3.6.1.2.1.2.2.1.5.2")=10000000,
"LAN Speed:   10MBit/s",if (oid_raw("1.3.6.1.2.1.2.2.1.5.2")=100000000,
"LAN Speed:   100MBit/s",if (oid_raw("1.3.6.1.2.1.2.2.1.5.2")=1000000000,
"LAN Speed:   1GBit/s","unknown")))
ubnt_ssid

if (string_size(oid("1.3.6.1.4.1.41112.1.4.5.1.2.1")),
concatenate("SSID: ", oid("1.3.6.1.4.1.41112.1.4.5.1.2.1"),""),"")
ubnt_stacje

if (string_size(oid("1.3.6.1.4.1.41112.1.4.5.1.15.1")),
concatenate("Stations: ", oid("1.3.6.1.4.1.41112.1.4.5.1.15.1")),"")

 

FreeBSD + Rancid + ViewVC = Backup

FreeBSD czyli NAS4Free ciąg dalszy, czyli jak wykorzystać możliwości systemów BSD, zamiast wirtualizować całe systemy można oddzielać środowiska od siebie.

Potrzebujemy NAS4Free + The Brig, czyli manager jaili, albo surowy system FreeBSD zainstalowany na maszynie fizycznej lub w ostateczności na wirtualnej.

Do zapoznania się czym jest RANCID zapraszam na stronę autora: http://www.shrubbery.net/rancid/

1.Instalacja i konfiguracja RANCID

Tworzymy naszego jaila, w większości sprowadza się to do podania jego ID, nazwy oraz przydzielenia adresu IP na wybrany interfejs. Startujemy go i łączymy się po IP jaila albo IP systemu podając dane user/pass z systemu głównego. Podnosimy uprawnienia komendą su, listujemy jaile komendą jls, i łączymy się do wybranego poleceniem jexec:

nas4free.local: /# jls
   JID  IP Address      Hostname                      Path
     1  10.0.0.3     rancid.local                  /mnt/ZFS/jails/rancid
nas4free.local: /# jexec 1 /bin/csh
root@rancid:/ #

Jesteśmy zalogowani jako root w naszym podsystemie. Pierwsze co to potrzebujemy pobrać zarządcę pakietami pkg:

root@rancid:/ # pkg
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:11:amd64/quarterly, please wait...
Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done
[rancid.local] Installing pkg-1.10.1...
[rancid.local] Extracting pkg-1.10.1: 100%
pkg: not enough arguments
Usage: pkg [-v] [-d] [-l] [-N] [-j <jail name or id>|-c <chroot path>|-r <rootdir>] [-C <configuration file>] [-R <repo config dir>] [-o var=value] [-4|-6] <command> [<args>]

For more information on available commands and options see 'pkg help'.
root@rancid:/ #

Uaktualniamy bazę poleceniem pkg update:

root@rancid:/ # pkg update
Updating FreeBSD repository catalogue...
pkg: Repository FreeBSD load error: access repo file(/var/db/pkg/repo-FreeBSD.sqlite) failed: No such file or directory
[rancid.local] Fetching meta.txz: 100%    944 B   0.9kB/s    00:01
[rancid.local] Fetching packagesite.txz: 100%    6 MiB 498.7kB/s    00:12
Processing entries: 100%
FreeBSD repository update completed. 26289 packages processed.
All repositories are up to date.

Instalujemy RANCID poleceniem pkg install rancid3, zostanie pobrany pakiet łącznie ze wszystkimi zależnościami.

Kopiujemy plik konfiguracyjny posiłkując się dołączonym samplem takiego pliku przez autora:

cp /usr/local/etc/rancid/rancid.conf.sample /usr/local/etc/rancid/rancid.conf

Z przyzwyczajenia używam edytora nano, jeżeli nie masz go w systemie możesz go doinstalować poleceniem pkg install nano, albo korzystać z wbudowanego w system vi.

RANCID może tworzyć grupy urządzeń i katalogować je w osobnych miejscach, na potrzeby poradnika skupimy się na razie na przypadku jednej grupy. W pliku /usr/local/etc/rancid/rancid.conf odnajdujemy, zmieniamy i usuwany znak # komentarza:

#LIST_OF_GROUPS="sl joebobisp" => LIST_OF_GROUPS="backup"

Teraz logujemy się poprzez su rancid na użytkownika rancid aby utworzyć poprawnie struktury katalogów i konfigurację z poprawnymi uprawnieniami

root@rancid:/ # su rancid
$

Tworzymy plik z loginami i hasłami do urządzeń. Niestety w pliku RANCID przechowuje je otwartym tekstem, jeżeli to tylko możliwe warto stosować logowanie za pomocą kluczy SSH, jak nie ma możliwości bo urządzenie obsługuje tylko telnet, odseparować sieć aby nie było możliwe przechwycenie transmisji hasła. Zawartość pliku wygląda następująco:

$ touch /usr/local/var/rancid/.cloginrc
$ nano /usr/local/var/rancid/.cloginrc

add user 10.0.0.5 admin # dla urządzenia 10.0.0.5 dodajemy użytkownika admin
add password 10.0.0.5 hasło hasłogłówne # dla urządzenia 10.0.0.5 dodajemy hasło logowania i hasło podniesienia uprawnień jak w urządzeniach Cisco
add method 10.0.0.5 ssh # dla urządzenia 10.0.0.5 dodajemy metodę logowania, tutaj ssh
add user 10.0.0.* admininny # możemy wykorzystać gwiazdkę aby rozszerzyć zakres na więcej urządzeń, tutaj cała podsieć /24
add method mikrotik1 ssh # możemy używać nazw bardziej ludzkich albo domenowych, urządzenia muszą być albo dopisane w pliku /etc/hosts albo rozwiązywane przez serwer DNS

$ chmod 600 /usr/local/var/rancid/.cloginrc

$ ls -l /usr/local/var/rancid/.cloginrc
-rw-------  1 rancid  rancid  88 May 20 20:33 /usr/local/var/rancid/.cloginrc

Zawartość chronimy ustawiając prawa tylko do odczytu i zapisu przez właściciela pliku. Jeżeli używany swoich nazw dopisanych do pliku /etc/hosts to zalecam stosowanie tylko małych liter.

Tworzymy pliki i katalogi ręcznie uruchamiając polecenia:

$ /usr/local/bin/rancid-run
$ /usr/local/bin/rancid-cvs

No conflicts created by this import

cvs checkout: Updating backup
Directory /usr/local/var/rancid/CVS/backup/configs added to the repository
cvs commit: Examining configs
cvs add: scheduling file `router.db' for addition
cvs add: use 'cvs commit' to add this file permanently
RCS file: /usr/local/var/rancid/CVS/backup/router.db,v
done
Checking in router.db;
/usr/local/var/rancid/CVS/backup/router.db,v  <--  router.db
initial revision: 1.1
done

Przechodzimy do katalogu gdzie pojawiły się nasze pliki, nazwa będzie różna, w zależności od nazwy grupy czy grup jakie podawaliśmy w pliku /usr/local/etc/rancid/rancid.conf.

$ cd /usr/local/var/rancid/backup

Edytujemy plik router.db, gdzie podajemy urządzenia które mają odpytane o konfigurację. Ma on składnię IP;rodzaj_urządzenia;status(up,down)

10.0.250.1;mikrotik;up # urządzenie typu mikrotik, kopia będzie wykonana
10.0.250.2;Cisco;up # urządzenie typu Cisco, kopia będzie wykonana
10.0.250.3;mikrotik;down # urządzenie typu mikrotik, kopia nie będzie wykonana

Ostatnim krokiem będzie dodanie wpisu do crona, aby kopie były tworzone regularnie o równej godzinie co godzinę:

$ crontab -e
Wciskamy klawisz i
Wklejamy zawartość poniżej:
0 * * * * /usr/local/bin/rancid-run

Wciskamy klawisz ESC
Wpisujemy :wq i zatwierdzamy ENTER
/tmp/crontab.pcMtf5FHDq: 1 lines, 36 characters.
crontab: installing new crontab
$

Log dla odpowiedniej grupy znajduje się w katalogu: /usr/local/var/rancid/logs/, gdzie można sprawdzić jak przebiega proces tworzenia kopii zapasowych i rozwiązywać występujące problemy.

2.Instalacja ViewVC do przeglądania konfiguracji poprzez przeglądarkę WWW.

Aby wygodniej przeglądać zmiany w konfiguracji zainstalujemy w systemie ViewVC poleceniem pkg install viewvc.

root@rancid:~ # pkg install viewvc

Doinstaluje się nam serwer WWW apache jako zależność, jednak w zupełności wystarczy nam serwer WWW wbudowany.

Konfiguracja ViewVC znajduje się w pliku: /usr/local/viewvc/viewvc.conf edytujemy go i zmieniamy podane linie.

root@rancid:~ # nano /usr/local/viewvc/viewvc.conf

cvs_roots = backup: /usr/local/var/rancid/backup/CVS/
root_parents = /usr/local/var/rancid/CVS/ : cvs
default_root = backup
use_localtime = 1

Dodajemy do pliku /etc/rc.conf polecenia dla ViewVC:

root@rancid:~ # nano /etc/rc.conf

viewvc_enable="YES"
viewvc_user="rancid"
viewvc_flags="-h 10.0.0.3 -p 10080"

Czyli uruchamiamy ViewVC jako użytkownik rancid, serwer WWW będzie uruchomiony na IP 10.0.0.3 i porcie 10080

ViewVC startujemy poleceniem:

root@rancid:~ # /usr/local/etc/rc.d/viewvc start
Starting viewvc.

I uruchamiamy przeglądarkę i przechodzimy na adres: http://10.0.0.3:10080/viewvc

 

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

 

Cacti 1.0.4 + Spine 1.0.4 na Ubuntu 16.04 LTS

Jakiś czas temu wydano Cacti 1.0. Poczekałem chwilę aby wszystkie bolączki wieku dziecięcego zostały usunięte i przystąpiłem do aktualizacji już posiadanych.

Każda aktualizacja wygląda inaczej dlatego przedstawię instalację nowego Cacti + kompilacja Spine.

Jest to instalacja manualna z racji, że cacti mamy 0.8.8f a spine 0.8.8b.

Potrzebne pakiety na nowej czystej instalacji Ubuntu 16.04 LTS:

apt install gcc apache2 libapache2-mod-php snmpd snmp snmp-mibs-downloader libsnmp-base libsnmp-dev libssl-dev libc-dev libc6-dev make php php-snmp php-xml php-gd php-common php-gmp php-ldap php-mbstring php-mysql mysql-server mysql-client libmysqlclient-dev help2man rrdtool git

Po instalacji php ustawiamy timezone

timedatectl set-timezone Europe/Warsaw
nano /etc/php/7.0/apache2/php.ini
date.timezone = Europe/Warsaw

Pobieramy Cacti z oficjalnej strony cacti.net i nadajemy uprawnienia dla serwera Apache

wget http://www.cacti.net/downloads/cacti-1.0.4.tar.gz
tar xvzf cacti-1.0.4.tar.gz
mv cacti-1.0.4 /var/www/html/cacti
chown -R www-data:www-data /var/www/html/cacti

Dodajemy konfigurację dla serwera www

nano /etc/apache2/conf-enabled/cacti.conf

Zawartość pliku:

Alias /cacti /var/www/html/cacti
<Directory /var/www/html/cacti>
        Options +FollowSymLinks
        AllowOverride None
        <IfVersion >= 2.3>
                Require all granted
        </IfVersion>
        <IfVersion < 2.3>
                Order Allow,Deny
                Allow from all
        </IfVersion>

        AddType application/x-httpd-php .php

        <IfModule mod_php.c>
                php_flag magic_quotes_gpc Off
                php_flag short_open_tag On
                php_flag register_globals Off
                php_flag register_argc_argv On
                php_flag track_vars On
                # this setting is necessary for some locales
                php_value mbstring.func_overload 0
                php_value include_path .
        </IfModule>

        DirectoryIndex index.php
</Directory>

Ustawiamy bazę mysql, użytkownika i hasło. Pierwszy krok to ustawienie hasła mysql dla root’a

mysqladmin password
cd /var/www/html/cacti
nano include/config.php
mysql -p

logujemy się ustawionym przed chwilą hasłem do serwera mysql i wydajemy polecenia

> CREATE DATABASE cacti
> grant all privileges on cacti.* to user@'localhost' identified by 'password';
> grant select on mysql.time_zone_name to user@'localhost' identified by 'password';

Edytujemy plik konfiguracyjny serwera mysql i dodajemy w sekcji [mysqld]

#
# Cacti Server
#

collation-server = utf8mb4_unicode_ci
character-set-server = utf8mb4
max_heap_table_size = 256M
max_allowed_packet = 16777216
tmp_table_size = 64M
join_buffer_size = 64M
innodb_file_per_table = on
innodb_doublewrite = off
innodb_buffer_pool_size = 512M
innodb_flush_log_at_trx_commit = 2

Tworzymy strukturę bazy danych oraz dodajemy strefy czasowe do bazy danych

mysql -p cacti < cacti.sql
mysql_tzinfo_to_sql  /usr/share/zoneinfo | mysql -p mysql

Na koniec pobieramy i kompilujemy spine, kompilacja powinna potrwać chwilę.

wget http://www.cacti.net/downloads/spine/cacti-spine-1.0.4.tar.gz
tar xvzf cacti-spine-1.0.4.tar.gz
cd cacti-spine-1.0.4
./configure
make
make install

Teraz kończymy instalację przez przeglądarkę wchodząc na stronę http://adres.ip/cacti/ i akceptujemy warunki licencji, przechodzimy dalej, jeżeli brakuje nam wymienionych modułów dodajemy je poprzez apt.