piątek, 26 marca 2010

Instalacja i konfiguracja systemu Kerberos

Zaczynając swoją przygodę z oprogramowaniem Kerberos 5 Release 1.8 nie rozstawałem się z dokumentacją nawet na chwilę. Ku mojemu zdziwieniu, już przy pierwszej napotkanej przeszkodzie okazało się, że wszelkie zgromadzone przeze mnie informacje sprawiają wrażenie niewystarczających do rozwiązania problemu. Zanim jednak przedstawię więcej szczegółów na ten temat chciałbym opisać krok po kroku czynności niezbędne do wykonania przy instalacji i konfiguracji systemu kerberos.

1. Instalacja

Źródła do pobrania: krb-1.8-signed

Przed przystąpieniem do instalacji należy upewnić się, że system zawiera kompilator gcc oraz narzędzie yacc, co można sprawdzić poleceniem which, które zwraca pełną ścieżkę do programu (np. which yacc). U mnie na SUSE Enterprise Server 11 domyślnie zainstalowane oprogramowanie nie zawierało ani jednego ani drugiego, dlatego zmuszony byłem uzupełnić system o paczki rpm:
gcc oraz bison (które przeważnie można znaleźć na dvd z linuxem).

Po rozpakowaniu archiwum ze źródłami systemu kerberos powinniśmy przejść do wnętrza folderu krb5-1.8/src/ oraz wykonać następujące komendy:
./configure
make
make check (jeżeli chcemy przetestować skompilowany system)
make install

2. Konfiguracja

Przykładowa zawartość pliku /etc/krb5.conf dla hosta o nazwie linux-fi5z znajdującego się w domenie site wygląda następująco:


Realm wg obowiązującej konwencji powinien nosić taką samą nazwę jak domena i składać się wyłącznie z wielkich liter. Jak można zauważyć usługa Key Distribution Center oraz serwer administratora znajdują się pod adresem linux-fi5z.site a ich pliki log mieszczą się w /var/log/krb5/ .

Przykładowy plik konfiguracyjny usługi KDC /usr/local/var/krb5kdc/kdc.conf :


Tutaj staramy się nie zmieniać zbyt wiele bez wyraźnej potrzeby, pozostawiamy większość domyślnych wartości.

Informację o usługach kerberosa działających na danych portach powinniśmy umieścić w pliku /etc/services dodając do niego poniższe linie:


Kolejnym krokiem jest stworzenie bazy danych dla usługi KDC za pomocą polecenia /usr/local/sbin/kdb5_util create -r SITE -s

Dodawać administratorów będziemy za pomocą narzędzia /usr/local/sbin/kadmin.local . Polecenie mające na celu dodanie uzytkownika root do grupy administratorów wyglądać będzie następująco addprinc root/admin

Natomiast dodanie użytkownika, który będzie korzystać z usług za pomocą systemu kerberos przeprowadzamy poleceniem addprinc user_name

Dla nowo utworzonych użytkowników powinniśmy stworzyć listę uprawnień /usr/local/var/krb5kdc/kadm5.acl , w której na potrzeby przykładu nadamy każdemu administratorowi wszelkie dostępne uprawnienia: */admin@SITE *

Utworzenie pliku keytab umożliwi demonowi kadmind dekodowanie biletów Kerberosa w celu przyznania lub nie dostępu do bazy danych. Po uruchomieniu narzędzia /usr/local/sbin/kadmin.local wydajemy polecenie ktadd -k /usr/local/var/krb5kdc/kadmin5.keytab kadmin/admin kadmin/changepw

Po wykonaniu podstawowej konfiguracji systemu Kerberos możemy uruchomić usługi krb5kdc i kadmind (/usr/local/sbin/).

3. Napotkana przeszkoda

Chcąc sprawdzić czy system Kerberos działa poprawnie postanowiłem skorzystać z dołączonych przykładowych aplikacji. W tym celu dodałem do bazy danych pozycję sample/linux-fi5z.site@SITE oraz linijkę sample 13135/tcp do pliku /etc/services . Następnie uruchomiłem przykładowy serwer komendą sserver -p 13135 -S /usr/local/var/krb5kdc/kt.keytab .
Po uzyskaniu za pomocą kinit biletu TGT umożliwiającego dalsze działania postanowiłem połączyć się z serwerem komendą sclient linux-fi5z . Jak można zauważyć poniżej test zakończył się niepowodzeniem.


"Wrong principal in request" - nie jestem w stanie odgadnąć, co jest przyczyną błędu, za wszelkie pomysły na rozwiązanie zagadki będę bardzo wdzięczny.

sobota, 20 marca 2010

Podsumowanie ubiegłego tygodnia

Wreszcie nadszedł upragniony weekend! Teoretycznie powinienem przewracać się z boku na bok ciesząc się chwilą odpoczynku, ale dobrze wiem, że tym razem nie będę leniuchować. Mam zamiar opracować interfejs graficzny do kolejnego z ćwiczeń dotyczących wielowątkowości oraz bliżej zapoznać się z MIT Kerberos 5 Release 1.8.

Całe szczęście, że ubiegły tydzień mogę zaliczyć do udanych - utwierdziło mnie w tym przekonaniu przeprowadzone z Jackiem Laskowskim podsumowanie wykonanej pracy. Instalacja oprogramowania WebSphere Application Server 7 była równie intuicyjna co instalacja systemu SUSE Linux Enterprise Server 11, aczkolwiek nie obyło się bez drobnych przeszkód. Z pierwszą
- was7 nie rozpoznał SUSE, jako wspieranego systemu operacyjnego - poradziłem sobie bez problemu. Przed przystąpieniem do instalacji zapoznałem się z dokumentacją produktu stąd wiedziałem,
że wystarczy jedynie podmienić plik WAS/was.primary.pak/maintenance.xml na nowszą wersję, w tym przypadku dla architektury IA32. Plik służący do nadpisania maintenance.xml można pobrać tutaj.

Mniej zrozumiałym problemem okazał się być komunikat narzędzia IVT, uruchomionego przeze mnie po instalacji w celu zweryfikowania czy wszystko przebiegło zgodnie z planem. IVT nieczule poinformował mnie, że "IVTL0170I: Cannot find profile home. IVT cannot continue.". Dość mocno się zdziwiłem - przecież stworzyłem profil podczas instalacji, która zakończyła się sukcesem. Próba dodania profilu za pomocą Profile Management Tool nie przyniosła zamierzonego efektu. Rozwiązania problemu szukałem w InfoCenter dla was7, nie odnalazłem jednak żadnej istotnej z mojego punktu widzenia informacji.

Błędem, jaki popełniłem było szukanie odpowiedzi na nurtujące mnie pytanie z dala od źródła - wszystko, czego potrzebowałem znajdowało się w pliku /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/wsadmin.traceout zawierającym informację o zaistniałym wyjątku (java.net.UnknownHostException). Okazało się, że przyczyną kłopotów był brakujący wpis w /etc/hosts, którego brak istnienia zawdzięczam narzędziu YaST (oraz poniekąd swojej spostrzegawczości :), które domyślnie odznaczyło polecenie "Write Hostname to /etc/hosts" przy konfiguracji ustawień sieciowych.

Poprawnie utworzony profil dał mi możliwość uruchomienia przykładowej witryny sklepu internetowego "Plants by WebSphere"
co ostatecznie upewniło mnie, że tym razem wszystkie czynności zostały wykonane należycie.

Praca w korporacji ma swoje mocne dobre strony. Na początku tygodnia zwróciłem się z prośbą o przydział komputera z większą ilością pamięci RAM na pokładzie a już w piątek podczas kilkuminutowej rozmowy telefonicznej zostałem zapewniony,
że maszyna zostanie wysłana z Warszawy w poniedziałek. Podoba mi się podejście, które można krótko opisać w następujący sposób: "Damy Ci wszystko, czego potrzebujesz tylko przekonaj nas, że to,
co otrzymamy w zamian jest warte tego, o co prosisz"
. Gorzej, gdy nie wiesz, w jaki sposób uzasadnić swoje potrzeby, tutaj nie ma zmiłuj się - liczą się konkrety. Sprzęt to podstawa, ale jeszcze większe znaczenie mają narzędzia, którymi IBM nas obdarowuje. Łatwość komunikacji i dostęp do ogromnej bazy informacji
to z pewnością jedne z głównych zalet, które zrobiły na mnie wrażenie. Dostrzegam, że wraz z czasem coraz lepiej wykorzystuję dane mi narzędzia, co ma bezpośrednie przełożenie na fakt, iż coraz lepiej wykonuję swoją pracę.

wtorek, 16 marca 2010

Programowanie współbieżne

Poniedziałkowe laboratorium z przedmiotu "Programowanie współbieżne i rozproszone" zawsze zostawia w mojej głowie pewien mętlik. Zazwyczaj staram się wykonać jak najwięcej w czasie trwania zajęć, aby mieć mniej pracy w domu, fakt, iż jest to ostatnie laboratorium w danym dniu sprawia, że jedyną rzeczą na jakiej potrafię się skupić, jest myśl o powrocie do domowego zacisza. Ta czasowa nieprzydatność do pracy sprawia, że o wiele trudniej jest mi wpaść na prawidłowe rozwiązanie postawionego zadania, choć po dłuższej chwili namysłu okazuje się ono być całkiem banalne. Sytuacja zazwyczaj komplikuje się, gdy w głowie zaczynają pojawiać się dziesiątki pomysłów, a nie mam pewności, który jest tym właściwym.

Zabawne może wydawać się, że nie tylko ja mam wspomniany mętlik w głowie - cała grupa pozostaje z pracą do wykonania w domu. Co więcej, jeszcze ciekawiej robi się, gdy niejasności pojawiają się tuż przed terminem oddania pracy, a treść zadania mimo swojej prostoty opisu dopuszcza pozornie mnogość interpretacji. Doskonale zdaję sobie sprawę z faktu, iż sam proces planowania trwa znacznie dłużej niż kodowanie, dlatego zawsze próbuję zrobić małą burzę mózgów, w celu wyłonienia kilku najlepszych koncepcji oraz odrzucenia tych całkiem skrajnych, ale po chwili rozmowy odzywa się zmęczenie spowodowane niewyspaniem i wszystkie chęci zgłębienia tematu wnet gdzieś znikają. Wychodząc z założenia, że w programowaniu tak jak w życiu, nie zawsze liczy się fakt osiągnięcia celu, ale styl w jakim się tego dokonało, na weekend ponownie podchodzę do zadania tym razem wypoczęty i z otwartym umysłem.

Wyżej opisana historia powtarza się, co tydzień i wiem, że nie tylko ja zostawiam sobie pracę na jego koniec. Dla osób, które mimo szczerych chęci nie znalazły jednak czasu na dopracowanie swojego kodu, zamieszczam krótki opis moich pomysłów na realizację dwóch ostatnich ćwiczeń laboratoryjnych. Zaznaczam, że programy powstałe na ich bazie, zostały ocenione na ocenę bardzo dobrą, co świadczy o fakcie, iż koncepcja i wykonanie są co najmniej poprawne.

Pozornie skomplikowane zadanie, które byliśmy zobligowani wykonać na pierwszym laboratorium dotyczącym współbieżności, polegało na odwzorowaniu sytuacji mającej miejsce na parkingu. Samo rozwiązanie jest bardzo krótkie i proste, tym bardziej, że mogliśmy dopuścić do sytuacji, gdzie klienci nie honorują kolejki - najmniej zuchwały klient parkuje/wyjeżdża jako ostatni. Zuchwałość, o której piszę, to nic innego jak przydział czasu procesora, miejsce na parkingu oraz dwie bramy to zasoby, do których każdy wątek-samochód chce mieć dostęp. Jedyne wymagane na starcie programu wartości to ilość pojazdów oraz miejsc na parkingu, czas jazdy potencjalnego klienta poza parkingiem i czas jego postoju. Postanowiłem również założyć odpowiednią ilość zmian stanu pojazdów, aby generowany ruch nie był zbyt wielki, a jedynie przedstawiał mechanizm działania programu. Prostotę wykonania najważniejszych elementów tj. samochodu i obu bram ilustruje kod poniżej, na którym można dostrzec, że instrukcje informujące o zmianie stanu samochodów zawarte są w sekcjach krytycznych - w przeciwnym razie wyświetlane komunikaty nie odzwierciedlałyby chronologicznej kolejności zachodzących zdarzeń.

Klasa Parking:

Wątek:

Kolejne laboratorium było już bardziej wymagające. Tym razem zadanie polegało na odwzorowaniu sytuacji mającej miejsce na stacji benzynowej z trzema dystrybutorami. O zagłodzeniu wątków nie może być tutaj mowy - gra toczy się o dużą stawkę, brak benzyny w baku oznacza wyeliminowanie danego samochodu. Wartości liczbowe wymagane na starcie programu to maksymalna długość kolejek, ilość samochodów, ich czas tankowania oraz czas jazdy poza stacją. W przypadku zapełnienia wszystkich kolejek na stacji klient zmuszony jest do dalszej jazdy przez czas równy dwukrotności czasu tankowania, następnie może spróbować ponownie dostać się do kolejki. Samochody powinny dążyć do maksymalnego wykorzystania paliwa, dlatego założyłem, że z każdym kolejnym tankowaniem maksymalny poziom paliwa w baku się zmniejsza. Nie chciałem przecież dopuścić do sytuacji, gdzie w ruchu pozostają np. dwa samochody mające do dyspozycji całą stację dla siebie - mogłyby jeździć wtedy bez końca. Wybór do realizacji tego zadania struktury wyższego poziomu, jaką jest kolejka blokująca (w tym przypadku ArrayBlockingQueue), był dla mnie oczywisty, aczkolwiek do intensywniejszego myślenia zmusił mnie fakt, iż samochód wjeżdżający na stację, powinien wybrać najkrótszą kolejkę. Pierwszym pomysłem było wykorzystanie metod kolejek blokujących w sekcji krytycznej, która zlicza poziom ich zapełnienia i na żądanie klienta wybiera najkrótszą. Następnym krokiem przy założeniu, że pojazd został już przyporządkowany do jednej z kolejek, jest sprawdzenie, czy samochód zgłaszający chęć skorzystania z dystrybutora, jest pojazdem znajdującym się na czele kolejki - tu przychodzi z pomocą metoda peek(), która zwraca element z kolejki bez usuwania go. W przypadku zgodności wykonana zostaje metoda poll() (usuwa samochód z kolejki), po czym dany samochód uzyskuje dostęp do dystrybutora blokując go jednocześnie na czas użytkowania. W przeciwnym przypadku - stwierdzenia niezgodności - zostaje ponowiona weryfikacja, czy samochód zgłaszający chęć skorzystania z dystrybutora, jest pojazdem znajdującym się na czele kolejki. Pomysł ten sprawia wrażenie akceptowalnego, ale czy nie dałoby się zrobić tego subtelniej? Jestem otwarty na wszelkie sugestie.