2012
01.07

Od jakiegoś czasu używam varnisha jako cache dla mojego bloga i sprawdza się genialnie, dla rzeczy zcachowanych ( a przy odpowiednim configu to >90% ) czas odpowiedzi to właściwie RTT między klientem i serwerem. Nie jest skomplikowany w konfiguracji a przyśpiesza stronę paredziesięciokrotnie :).

Przygotowanie

Konfiguracja

Dp konfiguracji Varnish używa własnego minijęzyka zwanego VCL, odrobinę podobny do C. Pozwala on na grzebanie w nagłówkach zapytania i odpowiedzi oraz kierowanie requestu gdzie trzeba + parę innych akcji takich jak purgowanie obiektów w cache

VCLki mogą być przeładowywane w locie dzięki czemu nie traci się cache przy przeładowaniu configu.

Varnish domyślnie cachuje tylko w RAM, można mu wskazać cache dyskowy ale zostanie on zdiscardowany po restarcie (bo varnish go po prostu mmap()uje i traktuje jak kawałek pamięci, zostawiając OSowi co z tym fantem ma zrobić).

Istnieje opcja zapisywania cache na dysk, polega ona na tym że varnish podczas pracy streamuje obiekty na dysk a po restarcie zapełnia nimi cache, ale jest to rozdzielne z dyskowy cache – persisten storage podczas pracy jest tylko zapisywany, varnish nie serwuje z niego obiektów.

Konfig jakiego używam u siebie (pominąłem sekcje dot. backendów):

(more…)

2011
08.21

export DBI_TRACE=1=dbitrace.log
Gdzie 1 – debug lvl (1 całkowicie wystarcza, daje dane nt. wykonanych query i ich parametrów oraz create/destroy obiektów DBI) a dbitrace.log ofc plik do którego bedzie to logowane ;]

2011
08.12

Yes it works :]

W sumie jedna z tych rzeczy typu “Doh, czemu ja na to nie wpadłem” ;] Źródło: http://hackaday.com/2011/08/11/how-to-put-your-logo-in-a-qr-code. Tak kolorem też się da ;]

2011
08.02

Regexpy słyną z bycia językiem “tylko do zapisu”, często ciężko jest odcyfrować co autor regexpa miał na myśli. Jest (w perlowych i kompatybilnych) pewien ficzer który to ułatwia, mianowicie opcja x, powoduje ona że parser regexpów ignoruje komentarze, czyli taki np. dekoder daty (tak wiem że są liby, to tylko przykład ;))

my ($year, $mon, $mday, $hour, $min, $sec) = $date =~
  /(\d{1,4})\-(\d{1,2})\-(\d{1,2})\s+(\d{1,2})\:(\d{1,2})\:(\d{1,2}).*/;

można zapisać w formie:

my ($year, $mon, $mday, $hour, $min, $sec) = $date =~
  /(\d{1,4})\- # year-
   (\d{1,2})\- # month-
   (\d{1,2})\s+ # day + whitespace
   (\d{1,2})\: # hour:
   (\d{1,2})\: # min:
   (\d{1,2}) # sec:
   .* #rest of crap
  /x;

Trzeba tylko “wyescapować” wszystkie spacje (chociażby przez \s co oznacza “any whitespace” czyli też taby i \n)

Z innych przydatnych rzeczy to ściąga i edytor z tych “mniej znanych a przydatnych” :

  • (?:...) – pasywna grupa tzn matchuje ale nie będzie zwracane do zmiennych, czyli np (?:foo|bar)(.*) zwróci w zmiennej tylko zawartość bloku (.*) a nie foo/bar
  • \s i pokrewne, zamiast pisać \ (backslash spacja) czytelniej jest użyć \s które dodatkowo zmatchuje nam też taby i pare innych niewidocznych znaczków. \s+ jest przydatne, “matchuj jeden lub więcej whitespace”
  • {x,y} – zmatchuj od x do y znaków – np \d{3,} – więcej niż 3 cyfry, \S{5,9} – od 5 do 9 “nie-whitespace”
  • ? – powoduje że match będzie “ungreedy” czyli “zmatchuj minimalną liczbę znaków która będzie pasować, np gdy wrzucimy ciąg znaków “a:b:c” do regexpa (.*)\:(.*) to dostaniemy matche ‘a:b’ i ‘c’, gdy zrobimy matcha (.*?)\:(.*) na tym samym tekście to wynikiem będzie ‘a’ i ‘b:c’

Inną metodą na tworzenie regexpów jest “pokaż swojemu kotu jaki tekst chcesz zmatchować a potem posadź go na klawiaturze” ale to troszeczkę mniej czytelne ;]

2011
07.16

Po pierwsze – aptitude zamiast apt-get – ma trochę bardziej sensowne domyślne i przy instalacji wielu paczek łatwiej jest rozwiązać ew. konflikty na poziomie ncurses UI niż w CLI.

Chociażby dlatego że domyślnie nie usuwa “automatycznie” zainstalowanych paczek jak np. liby danej aplikacji ( nowa wersja apt-get informuje o tym z hintem żeby zamiast apt-get remove użyć apt-get autoremove – ale to troche mniej wygodne :)). O pinningu już pisałem

Polecam  http://www.debian.org/doc/FAQ/ch-customizing.en.html m.in jak podmienić plik z paczki na coś własnego tak żeby manager paczek go nie nadpisał podczas update paczki (p11.8) czy zarządzanie alternatywami

Z tego co używam na codzień w aptitude:

  • Wyszukiwanie ( klawisz / ) obsługuje regexpy (doh)
  • C pokaże changelog danej paczki
  • Po wejściu (Enter) w szczegóły paczki na dole można wybrać wersję (niby banał, ale widziałem ludzi klepiących apt-get po wyjściu z aptitude ;)
  • f (zapomnij o nowościach) wyczyści spamkategorie “Nowe pakiety”
  • Powyższe można zautomatyzować klikając w Opcje -> Preferencje ;)
  • Warto przejrzeć te menu – są tam tak przydatne funkcje jak np. “Anuluj zaplanowane zadania”

Oraz ofc etckeeper – od razu widać jakie zmiany w domyślnym configu wprowadziła paczka i czy to nasz fail czy paczki; można łatwo zrobić rollback/diffa poprzedniej “działającej” wersji.

Na koniec jeżeli używasz też (praca/testy/whatever) centosa lub pochodnych:

alias apt-cache=yum
alias apt-get=yum
alias aptitude=yum

bo inaczej będziesz klepał apt-get w centosie i yum w debianie ;].

2011
07.10

W życiu każdego admina przychodzi moment w którym trzeba umieścić cholernie niedorobiona niezbyt dobrze napisaną aplikację na serwerze i okazuje się że ta aplikacja po jakimś czasie zaczyna wariować. Czy to zwiecha czy wpada w pętlę i żre procesor jak szalona czy po prostu cieknie i po jakimś czasie zżera cały RAM i OOMkiller mówi “that’s a good day for you to die”, trzeba znaleźć sposób żeby dalej chodziła (bo nie ma alternatywy/nie da się naprawić/whatever).

Standardowym podejściem jest albo napisanie skryptu-niańki sprawdzającego czy działa poprawnie i zajmującego się resetem (w przypadku gdy app wpada w deadlock czy cieknie) lub prosty restart po padzie, czy używając while sleep 1 ;do /some/where/app ; done czy supervisora typu np. daemontools.

Gdy potrzebny jest prosty restart to nie jest problemem, schody zaczynają się gdy trzeba napisać więcej warunków.  Z czasem dochodzi potrzeba dodania więcej ficzerów np. alerty na maila w wypadku restartu, sprawdzanie danego URLa czy app działa, więcej testów itd. Potem pojawia się inna aplikacja, copy-paste starego skryptu, parę zmian, znowu dopisywanie nowych rzeczy (bo np. chcemy powiadamiać programistę o padzie ale tylko tej aplikacji, albo chcemy żeby dostawał maila tylko jeżeli restart się nie powiedzie). Jeżeli tego będzie wystarczająco dużo to pewnie nasz skrypcik spotka rewrite żeby obsługiwał pliki konfiguracyjne, stronę statusu, więcej testów itd.

Guess what ? Ktoś już to zrobił ;]

(more…)

2011
06.06

Mam sobie modem od tepsy, model ZXDSL 831A. Pewnego dnia postanowiłem zrobić mu autoreboot (żeby mi Neo nie rozłączało w środku dnia tylko w środku nocy) i po chwili wiresharkowania doszedłem do curl -u admin:admin http://10.254.254.1/rebootinfo.cgi , wrzuciłem do crona i zostawiłem modem w spokoju.

Ale gdy zacząłem grzebać przy nim podczas pisania tutoriala udało mi się znaleźć coś ciekawego, mianowicie modem można zresetować bez podawania hasła, curl http://10.254.254.1/rebootinfo.cgi owszem, zwraca Permission Denied, ale router i tak strzela reboot. ;]

Na szczęście resetowanie do ustawień fabrycznych w ten sposób nie działa (chociaż nie grzebałem długo) ale fail to fail. Prawdopodobnie inne modele tego samego producenta mają podobny fail, może ktoś potwierdzić

2011
06.06

(część 1sza)

Filtrowanie, ciąg dalszy.

Problem: Chcę żeby router ADSL restartował mi się o 4 w nocy (Neostrada rozłącza co 24h i jak akurat router wstał o 18.00 to następny disconnect będzie o tej samej porze) automatycznie.

Rozwiązanie: Router nie ma shella ani innej metody zdalnego rebootu więc muszę zesniffować jaki request powoduje reboot.

sniffing załatwia proste tcpdump -w dump -s 0 -i eth0 -n port 80 and host 10.254.254.1 i w rezultacie dostajemy dumpa z samymi requestami

Teraz chcemy z requestów wyciągnąć listę zapytań, z klikania przeglądarki wiemy że ma w sobie ciąg html:
http.request.uri contains "html"

Jeżeli nie jesteśmy pewni czego szukać to http.request da listę requestów, którą można potem wycinać przez eliminację np.
http.request and ! (http.request.uri contains ".gif" or http.request.uri contains ".css" or http.request.uri contains ".js" )
Rezultat powinien wyglądać mniej-więcej tak:

(more…)

2011
05.11

Wireshark jest jednym z najlepszych narzędzi do dyspozycji admina, nie jest tylko “graficznym tcpdumpem” jak niektórzy sądzą. Zamierzam opisać parę przydatnych zastosowań tego narzędzia w debugowaniu (nie)typowych problemów

Nie będzie to tutorial typu “jak kliknąć button ‘start capture’” albo “jak zrobić apt-get install” (w sumie jeżeli komuś potrzebne coś takiego powinien się poważnie zastanowić nad zmianą zawodu na np. zbieracz truskawek) tylko raczej “jak zdalnie nagrać rozmowy SIP” albo “jak zanalizować latencję łącza”.

Podstawy: Filtrowanie danych

Debugowanie czegokolwiek jest łatwiejsze gdy poziom “szumu” (części analizowanych danych która nas nie interesuje bo wiemy że jest dobra lub tyczy się innego fragmentu systemu) jest jak najniższy, dlatego zwykle robienie dumpu przez tcpdump -i any -s 0 -w dump na ruchliwym serwerze podczas gdy nas obchodzi parę requestów HTTP dobrym pomysłem nie jest ;]. Więcej info nt. filtrów tcpdumpa w manie ale podstawy:

  • not port 22
  • port 80 or port 8080 – np. gdy mamy proxy/lb które słucha na 80 i wysyła req. do backendu na
  • host 1.2.3.4

warto znać. Ofc. lepiej przechwycić za dużo niż za mało ;]

Podobne filtrowanie można zastosować potem w wiresharku, ale składnia jest inna. Oraz trzeba uważać na parę rzeczy np. ip.addr != 192.168.1.1 zadziała trochę inaczej niż podpowiada common sense. Naprawdę warto poznać te filtry (po kliknięciu w expression pokazuje się ładna lista po czym z każdego protokołu można filtrować) bo wtedy zamiast żmudnie przeglądać pakiety wystarczy wpisać np.

http.request.uri contains "admin" and http.request.method == POST and http.host == devrandom.pl

i od razu mamy to co potrzebujemy;]

Żeby nie było nudno (za dużo teorii jest nużące ;]) zróbmy mały eksperyment. Najpierw dump. Można odpalić lokalnie ale jeżeli masz własny serwer (ja zainstalowałem tcpdumpa na routerku z Tomato ;) ) pokażę jak robić zdalny live capture używając wireshark + ssh + tcpdump ;].

ssh root@192.168.1.1 /jffs/tcpdump -i vlan0 -s 0 -U -n -w - not port |tee /tmp/dump | wireshark -k -i -

czyli “ssh gdzieśtam, odpal tcpdump (ścieżka niekonieczna gdy to “normalny” serwer), ignoruj ruch na porcie 22 (WAŻNE inaczej będziemy nagrywać “sami siebie”), kopiuj dump do /tmp/dump, nakarm stdin wiresharka”

(more…)

2011
04.24

Podczas świątecznej nudy zdecydowałem wreszcie dodać IPv6 do mojego VPSa, + do geek karma i w końcu World IPv6 day się zbliża ;]. Żeby strona widoczna była przez IPv6 w sumie wiele nie trzeba,”wystarczy” adres i odpowiedni wpis do DNS.

Niestety niewiele hostingów (w tym mój VPS na linode.com) obsługuje natywnie IPv6 więc żeby mieć IPv6 trzeba sie gdzieś tunelować. Na szczęście sam serwer DNS w linode obsługiwał wpisy AAAA (mimo że same serwery ipv4 only) więc tu nie miałem problemu.

(more…)