Wczoraj w firmie przeżyliśmy chwilę grozy. Zaczęło się niewinnie. Nie mogłem
commitnąć zmian w systemie zarządzania użytkownikami. svn commit
zawisał, strace pokazywało, że na dostępie do /dev/random
. Nie
było to pilne, więc bardzo się tym nie przejąłem. Potem dzwonił gościu, że
poczty nie może odebrać. Chwila śledztwa wykazała, że zacina się na autoryzacji
DIGEST-MD5. Od razu skojarzyłem to z problemami z /dev/random
.
Potem było już tylko gorzej — przy niedziałającym /dev/random posłuszeństwa
odmówił też PostgreSQL. A ja ciągle nie wiedziałem co się dzieje.
/proc/sys/kernel/random/entropy_avail
pokazywało 0 i nie chciało
nawet drgnąć. Nie pomogło też wybicie procesów korzystających z /dev/random i
/dev/urandom. Wyglądało na to, że coś się zacieło. Ten serwer już długo działał,
a jeszcze nie było takich problemów.
Pomyślałem o sprzętowym generatorze liczb losowych — podobno niektóre płyty
takie coś mają. find /lib/modules -name "*rng*"
pokazało dwa
moduły. Jeden (amd768_rng
) miał nazwę podobną do chipsetu płyty.
Załadowałem i nawet działa — cat /dev/misc/amd768_rng
pokazywało
krzaczki. Jednak aplikacje odwoływały się do /dev/random
, a tam
dalej bez zmian. Spróbowałem ln -s /dev/misc/amd768_rng /dev/random
— Permission denied
, mv /dev/random /dev/random.orig
— to
samo. Cholerny devfs – próbuje być mądrzejszy ode mnie! Zawsze lubiłem ideę
devfs — w /dev/
jest tylko to co mam w komputerze, a dysk o
konkretnym SCSI-id podłączony do konkretnego kontrolera ma zawsze tę samą nazwę,
a nie zależną od tego co jeszcze jest podłączone. Jednak implementacja jest
fatalne, a ten przypadek przeważył — devfs wyleciał z tego serwera. I tak
robiliśmy reboot, bo innych pomysłów nie było.
Po reboocie okazało się, że /dev/amd768_rng
nie jest całkiem
zgodny z /dev/random
— po podlinkowaniu niektóre aplikacje (w
szczególności SVN) zawisały przy próbie korzystania z tegoż. Jednak
/proc/sys/kernel/random/entropy_avail
było już większe od zera,
więc problem chwilowo zniknął. Jednak nie na długo — entropy_avail
zaczęło się zmniejszać i znowu doszło do zera blokując wiele usług. Zamiany
/dev/random
na /dev/urandom
nie brałem pod uwagę – po
to używam SSL, SASL itp. żeby było bezpiecznie, a /dev/urandom
bez
entropii generuje liczby bardzo pseudolosowe, a więc do kryptografii
niespecjalnie się nadające. Na szczęście kumpel znalazł winowajcę —
iptables -m random
. Jedna taka regułka była w naszym firewallu i po
podłączeniu któregoś klienta najwyraźniej zabrakło na nią entropii. Po zamianie
tego na coś innego entropy_avail
urosło do sensownej wartości i
wszystko zaczęło znowu działać. Ufff…
W PyXMPP i CJC obsługa MUC zaczyna działać. Można już wejść na takiego czata
i pogadać. Ale pierwszym felerem, który się rzuca w oczy, są niewłaściwe czasy
przy wiadomościach z historii pokoju. Jest tam czas aktualny, zamiast tego
podanego w <x xmlns="jabber:x:delay"/>
. JEP-91 jest banalnie prosty,
więc postanowiłem go od razu zaimplementować. Oczywiste było, że przydałby się
typ opisujący czas, którego w Pythonie zawsze brakowało. Zwykle używałem
mx.Datetime
, ale nie chciałem dla takiej dupereli do PyXMPP dodawać
kolejnej zależności. Więc użyłem modułu time
, ale on jest do bani.
Można pobrać aktualny czas, przedstawić ją w postaci UTC, czy czasu lokalnego,
czy skonwertować tekst o znanym formacie na czas — ale tylko w czasie lokalnym.
Na zamianę czasu UTC w postaci tekstowej na czas lokalny nie znalazłem sposobu.
Poczytałem dokumentację — z niej wynikało że
w formacie%Z
dla time.strptime
czasem może działać — u mnie nie działa.
Pogooglałem i okazało się że moje wiadomości na temat braku typu dla czasu są
nieaktualne. W Pythonie 2.3 jest moduł datetime
, który daje
wszystko co potrzebuję wraz z sensownym interfejsem. Dotychczas jednak PyXMPP
działało także na pythonie 2.2.x. Chyba przestanie — już dawno zastanawiałem się
nad porzuceniem wsparcia dla Pythona 2.2 — chociażby dlatego, że nie ma w nim
obsługi stringprep, czy IDN (oba standardy wymagane przez XMPP). Teraz PyXMPP
zawiera moją własną implementację stringprep dla Pythona 2.2 (wraz z wymaganą przez nią
normalizacją Unicode — to było sporo roboty), a IDN po prostu nie są obsługiwane gdy używany jest Python 2.2
(użycie znaku nie-ASCII w domenie JID powoduje bład). Ciekawe dla ilu
użytkowników takie podniesienie wymagań będzie dużym kłopotem. A może w ogóle
się tym nie przejmować? W końcu już teraz użytkownicy Debiana muszą kombinować,
żeby z PyXMPP skorzystać, bo standardowo mają historyczne wersje Pythona i
libxml2. Chyba jednak wywalę obsługę pythona 2.2 — kodowi wyjdzie to tylko na
dobre.
niegrzeczne chłopaki, -m random? udajecie komuś loss na łączu? 😛
PolubieniePolubienie
Jak ktoś ma powyżej 500 połączeń z jednego kompa, to trzeba mu trochę utrudnić otwieranie kolejnych. Dla jego własnego dobra 😉
PolubieniePolubienie
A jak? -m limit na każdego usera czy masz coś co hashuje?
PolubieniePolubienie
Dokładnie nawet nie wiem, bo drugi admin się tym zajmuje (w końcu nie wszystko musi być na mojej głowie), raczej nie na każdego user – maszyna by tego raczej nie wytrzymała. Zdaje się że -m connlimit samo ogranicza hashuje po userach.
PolubieniePolubienie
Ano tak. Swoją drogą fajnie mieć drugiego admina. Ja się nie dorobiłem :).
PolubieniePolubienie
Niektórzy emulują moduł funkcje modułu datetime we wcześniejszych Pythonach przy użyciu mx.DateTime. Ale to chyba rzeźba w klocku niewarta zachodu — zwłaszcza, że 2.4 ma się pojawić w ciągu niespełna miesiąca.
PolubieniePolubienie
Taaa… Nie ma wyraźnych powodów, by nie używać 2.3, więc myślę, że możesz go wymagać. Ja tam się raczej nie zastanawiam i jade ciągle na cutting edge.
PolubieniePolubienie