Skip to content

You are not logged in. Register orLog In

start:

Polska Planeta OpenOffice.org

14.03.2010

Morfologik

Testy segmentacji

Do niedawna nie było dla polszczyzny korpusu, w którym ręcznie zweryfikowano by podział na zdania (a przynajmniej ja nic o dostępności takiego zasobu nie wiedziałem). Całe szczęście, trwają prace nad Narodowym Korpusem Języka Polskiego – i obejmują one także ręczne oznaczenie tekstu, w tym podział go na zdania. Uzyskałem do testów próbkę obecnie opracowywanego tekstu, aby móc przetestować swoje reguły.
Okazało się, że stosujemy nieco inne konwencje – np. ja uznawałem, że liczby porządkowe na początku zdań są osobnym elementem, a nie fragmentem zdania (w OpenOffice.org takie liczby generowane automatycznie nie są w ogóle widoczne dla LanguageTool). Ale po ujednoliceniu takich konwencji przystąpiłem do testów. Wykryłem trochę usterek w regułach SRX, usunąłem je i wyniki są obecnie następujące.
W próbce było 42426 znaczników podziału (dalej oznaczone jako Z). Dokładność (precision) podziału wyniosła 0,993234. Kompletność (recall) 0,998353. Poprawność (accuracy) 0,991609. (Wszystkie te parametry liczyłem jako ilorazy, odpowiednio Z oraz sumy Z i podziałów dodanych przez SRX; Z oraz sumy Z i podziałów brakujących w pliku posegmentowanym przez SRX; wreszcie Z oraz sumy Z i podziałów dodanych przez SRX i brakujących w SRX).
Nie da się dojść, rzecz jasna, mechanicznymi środkami typu reguły SRX, do poziomu 1, bo niektóre podziały zależą od analizy znaczeniowo-logicznej zdania. Ale jest całkiem już nieźle! :)

AKTUALIZACJA: przy właściwym ustawieniu segmentacji na końcach wierszy udało się uzyskać kompletność równą 1 (to trochę artefakt wynikający z przetwarzania danych wejściowych) i dokładność 0,996933.

Marcin Miłkowski (noreply@blogger.com), 14.03.2010 18:11

13.03.2010

JakiLinux.org

Domowe środowisko chroot z usługami

Celem tego artykułu będzie wyjaśnienie zasady działania środowiska chroot, przedstawienie proponowanej konfiguracji sprzętowej, jak i programowej dla domowego serwera. Ważne dla nas będzie oczywiście nie tylko stworzenie środowiska chroot, ale udostępnienie w nim użytkownikom takich usług jak ssh, ftp czy www dostępnych z poziomu sieci Internet.

ol {list-style-type:none;}

Spis treści:

  1. 0. Czym jest chroot
  2. 1. Przygotowanie środowiska
  3. 2. Make Chroot Jail
  4. 3. Dodawanie nowych aplikacji
    1. 3.1. Standardowy proces dodawania nowych aplikacji
    2. 3.2. Dodawanie specyficznych aplikacji
    3. 3.3. Dodawanie programu passwd i automatyzacja zmiany haseł.
  5. 4. Zarządzanie użytkownikami
  6. 5. Konfiguracja usług
    1. 5.1. SSH
    2. 5.2. ProFTPd
    3. 5.3. Apache
  7. 6. Czynienie serwera widocznym w sieci Internet
    1. 6.1. Przekierowanie portów
    2. 6.2. Konfigurowanie DynDNS
    3. 6.3. Konfigurowanie /etc/hosts
  8. 7. Zakończenie

0. Czym jest chroot

Chroot to polecenie uniksowe, pozwalające uruchomić dany program ze zmienionym korzeniem (root) – katalogiem głównym systemu plików. Wykorzystanie tego typu mechanizmu w konfiguracji domowego serwera ma wiele zalet. Nie jest to raczej metoda, która mogłaby być z powodzeniem użyta na serwerach dużych korporacji – w takich przypadkach znacznie lepiej sprawdzają się techniki wirtualizacyjne. Wirtualizowaniem zasobów na pewno nie będą się jednak zajmować osoby, które korzystają z jednego domowego serwera średniej klasy, często komputera zabytkowego. W przypadku wirtualizacji najważniejszym punktem, od którego trzeba zacząć, to konieczność posiadania odpowiednich zasobów do wirtualizowania. Serwery na zabytkowych komputerach klasy Pentium III lub podobne nie są stworzone dla tak nowoczesnych metod, ale jednocześnie ich los nie jest przekreślony. Odpowiedni system operacyjny bez zbędnych dodatków takich jak środowisko graficzne, jest w stanie umożliwić nie tylko uruchomienie na tego typu komputerze serwera www, serwera ftp czy dostępu przez powłokę secure shell, ale także zwiększyć bezpieczeństwo całej konfiguracji poprzez zastosowanie wcale zasobożernego środowiska chroot.

Stosując środowisko chroot, wydzielamy użytkownikom specjalną przestrzeń dyskową, najczęściej w podfolderze folderu /home. W zależności od zasobów sprzętowych, możemy wykorzystać ten fakt w różny sposób. Jednym z ciekawszych pomysłów jest odseparowanie danych użytkowników i środowiska chroot od danych właściwego systemu. W moim przypadku wykorzystane zostały dwa dyski twarde. Jeden z nich, o pojemności dziesięciu gigabajtów, posłużył za magazyn dla plików właściwego sytemu oraz strony głównej serwera. Drugi, czterdziestogigabajtowy dysk twardy, został w całości przeznaczony na dane środowiska chroot. W zależności od naszej konfiguracji, folder ze środowiskiem chroot może mieć różną nazwę, dla przykładu /home/jail. Folder ten możemy zamontować na osobny dysk twardy. Jeśli posiadamy już zainstalowany system operacyjny, nie musimy go przeinstalowywać, by osiągnąć wyżej wymieniony efekt. Wszystko co należy w tym momencie zrobić, to podpiąć dysk twardy do płyty głównej, po czym utworzyć na nim partycję, a następnie dopisać ją do pliku /etc/fstab. Nową partycję najlepiej utworzyć za pomocą takich narzędzi jak cfdisk. O konfiguracji partycji przy pomocy pliku fstab można przeczytać w internecie.

cfdisk
cfdisk z widokiem na pierwszy dysk twardy

cfdisk1
cfdisk z widokiem na drugi dysk twardy

To, na co należy się przygotować, przystępując do konfiguracji serwera do pracy w środowisku chroot, to potencjalne problemy. Aplikacje uruchamiane w środowisku chroot są odseparowane od prawdziwego systemu. O ile korzystamy z prostych, podstawowych poleceń systemu Linux, problemy nie powinny się pojawiać. Kłopoty sprawiają natomiast bardziej zaawansowane aplikacje takie jak nano, dla których trzeba wyszukiwać odpowiednie biblioteki, które następnie ręcznie należy przekopiowywać do folderów środowiska chroot. Nie jest to takie łatwe, nie zawsze wiadomo, który plik trzeba skopiować, jednak takie działające środowisko ma ogromną zaletę – użytkownik teoretycznie nie może wydostać się poza środowisko chroot. W dodatku, przy konfiguracji dyskowej opisywanej przeze mnie powyżej, dane systemu właściwego są jeszcze lepiej odseparowane od danych użytkowników w środowisku chroot. Nawet gdyby udało się użytkownikom zapełnić plikami cały dysk twardy, dysk prawdziwego systemu pozostanie nieruszony. Nawet gdyby użytkownikom udało się usunąć jakieś pliki systemowe środowiska chroot, nie wpłynie to w żaden sposób na funkcjonowanie właściwego systemu. Najciekawsze jest jednak to, iż przy odpowiednim podejściu do sprawy, można środowisko chroot uczynić tak podobne do prawdziwego, iż użytkownik nie będzie w stanie stwierdzić czy pracuje na prawdziwym systemie.

chroot_fs
Domyślny układ folderów w środowisku chroot

1. Przygotowanie środowiska

Z naszego domowego serwera ma się nam korzystać wygodnie. Z racji trybu, w którym pracuje system operacyjny naszego serwera – trybu tekstowego – nie jest potrzebne posiadanie do niego monitora. Można nim zarządzać zdalnie i, w przeciwieństwie do zarządzania zdalnego Pulpitem, jest banalne. Wystarczy, że zainstalujemy w systemie usługę ssh i nie będziemy musieli posiadać osobnej klawiatury i osobnego monitora dla naszego serwera, gdyż będziemy mogli zarządzać nim z naszego domowego komputera, z poziomu terminala. Wystarczy, że przydzielimy naszemu serwerowi statyczny adres (nie jest to konieczne, ale znacznie ułatwi nam pracę w przyszłości), czego dokonuje się poprzez edycję pliku /etc/network/interfaces:

network
Widok pliku /etc/network/interfaces po zamianie domyślnych ustawień adresu IP pobieranego z DHCP na adres statyczny

Adres może być dowolny, pod warunkiem, że obsługiwany i nie zajęty przez inne urządzenie, bądź nie wchodzący w zakres usług takich jak DHCP (czytaj punkt szósty). Po takiej konfiguracji możemy logować się na nasz serwer komendą ssh -l [nazwa użytkownika] [adres serwera]. Gdyby zdażyło się nam zapomnieć adresu serwera – korzystamy z komendy nmap, by przeskanować sieć lokalną w celu znalezienia podłączonych do sieci urządzeń – nmap -sP 192.168.1.0/24 lub inny adres odpowiedni dla naszej sieci lokalnej:

connection
Wyszukiwanie serwera przy pomocy komendy nmap

2. Make Chroot Jail

Istnieją różne metody tworzenia środowiska chroot w systemie. Jedną z nich, która najbardziej przypadła mi do gustu, polega na wykorzystaniu skryptu autorstwa Wolfganga Fuschlbergera o nazwie make_chroot_jail.sh. Jest to jednocześnie najłatwiejsza moim zdaniem metoda. Przed wdrożeniem jakiegoś rozwiązania, warto zastanowić się w jaki sposób nam pomoże, w jaki sposób działa, jakie wady i zalety posiada. Postaram się zatem pokrótce to wszystko omówić.

Skrypt Make Chroot Jail jest dostosowany do czterech dystrybucji systemu operacyjnego GNU/Linux: Debianie, Suse, Fedorze i RedHacie. W skrypcie istnieje odpowiedni mechanizm wykrywający uruchomiony system operacyjny i stosujący odpowiednie czynności dla niego. W przypadku kiedy posiadamy system nie zaliczany do tego grona – podejmowane są domyślne czynności. Mowa jest tutaj głównie o bibliotekach kopiowanych do środowiska chroot, specyficznych dla danego systemu. W przypadku, gdy skrypt nie obsługuje danej dystrybucji i ustawienia domyślne się nie sprawdzają – można go edytować, dodając odpowiednie parametry, specyficzne dla tej dystrybucji systemu.

source
Wycinek kodu źródłowego skryptu makre_chroot_jail.sh

Za pomocą skryptu możemy dodawać nowych użytkowników w środowisku chroot, modyfikować istniejące konta użytkowników, dostarczać im środowisko chroot dla połączeń ssh czy też ftp. Skrypt nie zajmuje się tworzeniem specjalnej grupy dla użytkowników chrootowanych, dostarcza im natomiast specjalnie przygotowaną, sztuczną powłokę, którą tak na prawdę jest bash – domyślna powłoka wielu systemów Linuksowych i nie tylko – jednak uruchomiony na innych prawach. W celu osiągnięcia takiego stanu konieczne jest zainstalowanie w systemie pakietu sudo, którego konfiguracją natomiast w całości zajmuje się skrypt.

Skryptu można używać tylko posiadając prawa roota. Sugeruję pobranie go i wrzucenie do jednego z folderów ze ścieżki PATH

mv make_chrot_jail.sh /usr/bin/mk_jail

aby móc uruchamiać go jednym poleceniem, wraz z wykorzystaniem funkcji bash polegającej na dopełnianiu nazwy polecenia po naciśnięciu klawisza TAB. Oprócz tego należy nadać skryptowi uprawnienia wykonywania, ale tylko dla roota, czyli rwx—— (700):

chmod 700 /usr/bin/mk_jail

Domyślna konfiguracja skryptu make_chroot_jail.sh tworzy jedynie folder dla użytkownika z prawami rwx——. My, chcąc umożliwić użytkownikom publikowanie swoich własnych stron internetowych i plików, musimy zmienić tę konfigurację. Ręczna zmiana atrybutów folderu za każdym razem z pewnością nie jest wygodna, dlatego lepiej wyedytować skrypt tak, by robił to za nas. Dla leniwych lub niezaawansowanych użytkowników udostępniam zmodyfikowaną przeze mnie wersję skryptu, która tworzy folder dla użytkownika z prawami rwxr-xr-x, a w nim dwa podfoldery: public_html o atrybutach takich jak folder powyższy, z przeznaczeniem dla stron internetowych oraz folder private o uprawnieniach rwx——, w którym użytkownicy będą mogli umieszczać swoje prywatne dokumenty bez obaw, że zobaczy je ktoś inny. Zainteresowani mogą porównać oba pliki.

3. Dodawanie nowych aplikacji

3.1. Standardowy proces dodawania nowych aplikacji

Przed rozpoczęciem procesu dodawania nowych użytkowników, bądź też migrowania obecnych do środowiska chroot, warto zadbać by już na starcie posiadali odpowiednie aplikacje, potrzebne do codziennej pracy. W domyślnej konfiguracji skryptu w naszym systemie pojawią się jedynie takie programy jak: bash, cp, dircolors, ls, mkdir, mv, rm, rmdir, sh, su, groups, id, netcat, rsync, ssh, scp, unix_chkpwd. Jak można zatem zauważyć – jest to niesamowicie minimalistyczny zestaw oprogramowania, przy pomocy którego zdziałać nie można zbyt wiele. W tym zestawie nie ma nawet programu touch, umożliwiającego tworzenie plików. Warto zatem zastanowić się jakie programy chcemy udostępnić naszym użytkownikom. Osobiście proponuję udostępnić całą zawartość folderu /bin. Zdawałoby się, że możliwość zmiany hasła w systemie jest oczywistością, jednak jak widać po powyższym zestawie podstawowych aplikacji – wcale nie musi tak być. Nie musimy umożliwiać użytkownikom zmiany hasła, jednak to co najmniej szaleństwo. Program odpowiedzialny za zmianę hasła to /usr/bin/passwd.

Programy, które mają zostać skopiowane do środowiska chroot, wpisujemy do skryptu. Ważne, by pamiętać, iż należy podawać pełne ścieżki do programów. Skąd jednak wiedzieć gdzie znajduje się dany program? Do tego celu stosujemy polecenie wbudowane w powłokę bash – type:

type
Działanie komendy type przedstawione na przykładach

Oprogramowanie mające pojawić się w chroocie wpisujemy do zmiennej APPS do odpowiedniego punktu instrukcji warunkowej if. Jeśli korzystamy ze skryptu na Debianie – ścieżki programów wpisujemy przy warunku “$DISTRO” = DEBIAN:

apps
Zmienna APPS w kodzie źródłowym make_chroot_jail.sh

Po dodaniu programów, komendą:

mk_jail update

dokonujemy aktualizacji zawartości środowiska chroot.

3.2. Dodawanie specyficznych aplikacji

Większość podstawowych programów, na przykład te z /bin działają na standardowych bibliotekach Linuksa, które skrypt make_chroot_jail.sh kopiuje do chroota automatycznie.

libs
Wycinek kodu źródłowego skryptu make_chroot_jail.sh

Dzięki takiej konfiguracji skryptu, podczas pracy ze standardowymi programami nie pojawiają się problemy wynikające z natury zależności aplikacji od bibliotek. Cuda zaczynają się jednak dziać w przypadku specyficznych aplikacji takich jak nano – konsolowy edytor tekstu. Nawet po jego zainstalowaniu w chroocie, nie jest możliwe uruchomienie go na domyślnej konfiguracji:

zosia@byisk-server:~$ nano
Error opening terminal: xterm.

Ta aplikacja wymaga do działania m.in. bibliotek, które nie są domyślne, dlatego należy je skopiować własnoręcznie. Po raz kolejny pojawia się pytanie – skąd wiedzieć które? Do wykrywania zależności programów od bibliotek stosujemy komendę ldd. Tym poleceniem wskazujemy na plik w danym miejscu na dysku – należy podawać całą ścieżkę jako parametr polecenia, bądź, oczywiście, po prostu przejść do danego folderu i wskazać na konkretny plik z aplikacją. W przypadku nano, polecenie ldd zwraca taki wynik:

ldd_nano
Wyszukiwanie potrzebnych bibliotek przy pomocy komendy ldd

Jak zatem widzimy – komenda ldd dokładnie wypunktowuje nam biblioteki, które musimy skopiować do środowiska chroot.

byisk-server:~# cp /lib/libncursesw.so.5 /home/jail/lib/libncursesw.so.5
byisk-server:~# cp /lib/i686/cmov/libc.so.6 /home/jail/lib/i686/cmov/libc.so.6
byisk-server:~# cp /lib/i686/cmov/libdl.so.2 /home/jail/lib/i686/cmov/libdl.so.2
byisk-server:~# cp /lib/ld-linux.so.2 /home/jail/lib/ld-linux.so.2
cp: cannot create regular file `/home/jail/lib/ld-linux.so.2': Text file busy

W kwestii nano i innych edytorów – to jeszcze nie wszystko. Warto zawczasu dodać sobie biblioteki terminfo. Mimo, że komenda ldd nie wykazała takiej konieczności, nie da się bez tego uruchomić takich aplikacji jak nano. Terminfo przyda się nam z pewnością także dla innych aplikacji, chyba, że szczytem wymagań naszych użytkowników jest możliwość tworzenia i kasowania nowych plików i folderów :)

byisk-server:/etc/terminfo# mkdir -p /home/jail/usr/share/terminfo
byisk-server:/etc/terminfo# cp -R /usr/share/terminfo/ /home/jail/usr/share/terminfo/
byisk-server:/etc/terminfo# mkdir -p /home/jail/lib/terminfo
byisk-server:/etc/terminfo# cp -R /lib/terminfo /home/jail/lib/terminfo/
cp -R /lib/terminfo /home/jail/lib/terminfo
byisk-server:/etc/terminfo# cd !$
cd /home/jail/lib/terminfo
byisk-server:/home/jail/lib/terminfo/terminfo# ls
a c d E h l m p r s v w  x
byisk-server:/home/jail/lib/terminfo/terminfo# mv * ..
byisk-server:/home/jail/lib/terminfo# cd /usr/share/terminfo/
byisk-server:/usr/share/terminfo# ls
1 2 3 4 5 6 7 8 9 a  A b c d e E f g h i  j k l L m M n N o p P q Q r s t u  v w  x X z

Po tych wszystkich czynnościach, nano powinno uruchamiać się i działać bez problemu.

nano
Program nano uruchomiony w środowisku chrootowanym

3.3. Dodawanie programu passwd i automatyzacja zmiany haseł.

W taki sam sposób, jaki opisałem w punkcie 3.1, dodajemy do listy dostępnych dla użytkownika programów program passwd, służący zmianie hasła. Z racji tego, iż system główny, jak i ten chrootowany, pracują na osobnych wersjach plików, pojawiają się problemy. Po zainstalowaniu passwd, chrootowany użytkownik ma możliwość zmiany hasła, jednak zmiana następuje jedynie w obrębie środowiska chrootowanego, które to nie ma wpływu na pliki systemu głównego, na czym nam przecież zależy. Użytkownik zmienia zatem hasło jedynie w pliku /home/jail/etc/passwd i /home/jail/etc/shadow, a do logowania do systemu używane są pliki /etc/passwd i /etc/shadow. Należy zatem poinstruować system, by automatycznie co jakiś czas porównywał pliki z systemu głównego do tych z systemu chrootowanego i, w razie konieczności, wprowadzał potrzebne zmiany. Zasadniczo, ze względów bezpieczeństwa nie pozwalamy sobie na trzymanie haseł w pliku /etc/passwd, dlatego nawet po zmianie hasła, wpis w tym pliku pozostanie taki sam – x sygnalizuje, iż hasło zawiera się w pliku /etc/shadow. Z tego powodu porównywać będziemy jedynie pliki /etc/shadow i /home/jail/etc/shadow. Standardowy cron dostępny w wielu systemach często sprawia problemy, w moim przypadku w ogóle nie chce uruchamiać poleceń, nawet tak prostych jak tworzenie plików. Proponuję wykorzystać do automatyzacji program bcron, który nastawiony jest głównie na bezpieczeństwo, zastępuje system drop-in z vixie-cron, posiada natywne wsparcie dla czasu letniego i potrafi wiele innych ciekawych rzeczy. W zależnościach pakietu wpisane jest, iż nie może on współgrać z cronem, dlatego pakiet cron zostanie usunięty. Po instalacji bcrona możemy przejść do edycji crontab. W tym celu otwieramy w dowolnym edytorze tekstu, np. nano, plik /etc/crontab i dodajemy do niego wpisy

* * * * * diff -u /etc/shadow /home/jail/etc/shadow > /etc/shadow.patch
* * * * * patch -b /etc/shadow /etc/shadow.patch

lub podobne, w zależności od tego, jak często funkcja synchronizacji plików z hasłami powinna być uruchamiana. Ogrom informacji na temat konfiguracji pliku crontab można znaleźć przy pomocy Google.

Po wykonaniu tych operacji użytkownicy nie będą mieli problemów ze zmianą hasła w środowisku chroot.

4. Zarządzanie użytkownikami

Skrypt jest banalny w użyciu. Najczęściej uruchamiamy go tylko z jednym parametrem. W przypadku tworzenia nowego i przenoszenia obecnego użytkownika do środowiska chroot – przy uruchomieniu skryptu podajemy tylko jego nazwę. W przypadku gdy użytkownik już istnieje – przed rozpoczęciem migrowania jego folderu i ustawień do środowiska chroot – zostaniemy poproszeni o potwierdzenie operacji.

usr_exist
Działanie skryptu w przypadku migracji użytkownika do środowiska chroot

Zatem za pomocą komendy mk_jail jakilinux utworzymy w systemie użytkownika jakilinux. Istnieje jeszcze opcja zastosowania trzech parametrów, w tym przypadku wywołujemy skrypt w taki sposób: mk_jail [nazwa użytkownika] [ścieżka do powłoki] [ścieżka do folderu domowego]

Proces usuwania użytkownika nie jest niestety aż tak zautomatyzowany. Użytkownika wymazujemy z systemu poprzez zastosowanie kilku komend. Wpierw wywołujemy program odpowiedzialny za usuwanie użytkowników – userdel <nazwa użytkownika>. Następnie kopiujemy zmodyfikowane wersje plików /etc/shadow i /etc/passwd do folderu /home/jail/etc, zastępując obecne. Na sam koniec usuwamy ręcznie wpisy o danym użytkowniku z pliku /etc/sudoers

Jeśli w przyszłości będziemy chcieli pozbyć się całego mechanizmu jail – oprócz wyżej wymienionych czynności usuwamy plik /usr/bin/mk_jail, folder /home/jail oraz “powłokę” /bin/chroot-shell

5. Konfiguracja usług

5.1. SSH

Połączenia przez Secure Shell są domyślnie skonfigurowane tak, by wszystko mogło działać w kooperacji z chrootem. Warto jednak wprowadzić kilka zabezpieczeń. Użytkownik chrootowany nie może wejść nam do głównego systemu, pozmieniać plików, a ewentualne zawalenie partycji przeznaczonej dla /home/jail/ nie spowoduje problemów z działaniem systemu właściwego. Może on jednak ubić nasz serwer w inny sposób. Warto zapoznać się z materiałem, do którego hiperłącze zamieściłem w poprzednim zdaniu, by zyskać świadomość, że to, co jest akceptowalne na komputerze biurkowym, często nie może mieć miejsca na serwerze. W Twojej głowie na pewno nie ma takich pomysłów jak ubijanie swojego własnego systemu, pośród użytkowników spotkasz różnych ludzi, którym psucie Twojej pracy może sprawiać przyjemność. Zobaczmy zatem co możemy zdziałać w kwestii bezpieczeństwa udostępnianej użytkownikom usługi Secure Shell.

Jednym z ważniejszych plików, w którym konfigurujemy limity dla użytkowników jest plik /etc/security/limits.conf. Założenie limitów na maksymalną liczbę uruchomionych na raz procesów jest obowiązkowe, by nie doznać na własnej skórze ataku typu bash fork() bomb. W samym pliku znajduje się zahaszowane wytłumaczenie jego konfiguracji wraz z przykładami.

limits
Widok na plik konfiguracyjny usługi Secure Shell

Jak można wyczytać, wpis limitujący ilość procesów do dziesięciu dla wszystkich użytkowników, powinien wyglądać tak:

* hard nproc 10

Liczba procesów, na jaką możemy przyzwolić, zależy od tego ilu użytkowników spodziewamy się na naszym serwerze oraz od tego, jak wydajny jest serwer. Za konfigurację samego daemona sshd odpowiedzialny jest /etc/ssh/sshd_config. By nie powtarzać raz dobrze wykonanej roboty, po informacje na temat konfiguracji, którą można osiągnąć za pomocą tego pliku odsyłam do źródeł tutu. Jeden z podpunktów mówi o możliwości podpięcia pliku tekstowego, którego zawartość będzie wyświetlana użytkownikom podczas łączenia się z naszym serwerem przez usługę Secure Shell. Linia w konfiguracji odpowiedzialna za zdefiniowanie pliku, który ma brać udział w tym przedsięwzięciu to:

Banner /etc/issue.net

Mam ciekawą propozycję, która co prawda nie zwiększy bezpieczeństwa serwera, jednak uprzyjemni korzystanie z usług przez niego udotępnianych. W pliku /etc/issue.net można zamieścić jakiś obrazek wykonany techniką ASCII ART, których to niesamowita kolekcja znajduje się na stronie Christophera Johnsona. Efekt nie powala może na kolana, ale niejednemu z naszych użytkowników z pewnością pojawi się uśmiech na twarzy.

issue
Przykładowy komunikat powitalny usługi SSH, czerpiący motwywem z Futuramy

Dodatkowe metody zabezpieczenia zostały niedawno opisane w serwisie Jakilinux.org.

5.2. ProFTPd

Konfiguracja tej usługi również zależy głównie od naszych upodobań. W celu poszerzenia swojej wiedzy, zachęcam do odwiedzenia rozdziału dotyczącego ProFTPd w polskiej dokumentacji PLD. Koniecznością w przypadku chrootowanego FTP za pomocą opisywanej przeze mnie metody jest dodanie (lub odhaszowanie) w pliku /etc/proftpd/proftpd.conf linii

RequireValidShell off

Ma to ogromne znaczenie ze względu na to w jaki sposób działa skrypt. Make Chroot Jail tworzy specjalną “powłokę”, która nie jest autoryzowana w pliku /etc/shells ze względu na to, że gdyby tak było – chroot nie spełniałby swojej funkcji. Powłoka /bin/chroot-shell to prosty skrypt, w którym zawiera się taka komenda:

/usr/bin/sudo /usr/sbin/chroot /bin/su - $USER "$@"

Jak zatem możemy zauważyć – cała sztuczka polega na tym, iż przy logowaniu się na konto korzystające z chroot-shella, z poziomu roota (przez sudo) uruchamiany jest program chroot, po czym następuje przełączenie się na danego użytkownika. ProFTPd, jak sama nazwa wskazuje, jest profesjonalnym serwerem FTP :) W program wbudowano mechanizm zabezpieczający przed potencjalnym niebezpieczeństwem związanym z użyciem fałszywej powłoki – właśnie z tego powodu musimy dodać wyżej wymienioną linię do pliku konfiguracyjnego.

5.3. Apache

Również w dokumentacji PLD można odnaleźć ciekawe informacje na temat podstaw konfiguracji Apache. To, co nas interesuje, to konfiguracja serwera Apache by pozwalał na umieszczanie stron przez wszystkich użytkowników. Jest to banalne, cytując źródło:

Swobodne publikowanie stron internetowych przez użytkowników jest możliwe dzięki pakietowi apache-mod_userdir. Opcja UserDir w pliku 16_mod_userdir.conf definiuje nazwę katalogu przechowującego strony użytkowników wewnątrz ich katalogów domowych.

UserDir public_html

Przykład: Użytkownik Jan Kowalski posiada konto o nazwie: jan. W /home/users/jan jest jego katalog domowy. Swoją stronę internetową umieszcza w katalogu /home/users/jan/public_html, zaś dostęp do niej uzyskuje za pomocą adresu http://example.net/~jan.
Aby strona się wyświetliła należy ustawić odpowiednie prawa dostępu – tak by Apache (domyślnie z prawami użytkownika http) miał prawo do odczytu. Katalog domowy jan powinien mieć ustawione prawa 711. Katalog przechowujący jego stronę czyli public_html powinien mieć 755. Każdy katalog zawierający elementy strony powinien mieć również uprawnienia 755. Pliki strony natomiast 644.

UserDir wskazuje na folder public_html, czyli ten, który jest tworzony przez zmodyfikowaną przeze mnie wersję skryptu.

6. Czynienie serwera widocznym w sieci Internet

6.1. Przekierowanie portów

Aby umożliwić pracę naszego domowego serwera w sieci WAN, będziemy musieli skorzystać z mechanizmu przekierowania portów. Tego typu mechanizmy stosuje się w routerach. Jeśli na naszym serwerze będzie działać np. serwer www, musimy ustawić przekierowanie portu 80 na konkretny adres IP w sieci lokalnej.

Domyślna konfiguracja większości routerów bazuje na protokole DHCP, który przydziela adresy dynamicznie. Nie jest to dobre rozwiązanie, gdyż przy każdej zmianie adresu przez DHCP, musielibyśmy zmieniać adres IP, na który przekierowane miałyby być dane porty. By wprowadzić poprawną konfiguracę do pliku interfaces, należy zorientować się jakie adresy IP w sieci lokalnej są wolne, a jakie są zarezerwowane dla działania protokołu DHCP. Całość jest możliwa do skonfigurowania w routerze. Spostrzegawczy użytkownicy zorientowali się już na pewno, iż stosując mechanizm przekierowania portów, można posiadać osobny serwer dla każdej usługi. Można posiadać także kilka serwerów dla jednej usługi, dzięki mechanizmowi klastrowania I równoważenia obciążenia, jednak tematyka ta nie wchodzi w zakres tego artykułu.

router1
Strona konfiguracyjna routera

router2
Strona konfiguracyjna routera

Warto w tym momencie również wspomnieć, z racji popularności urządzenia, że cześć usług oferowanych przez serwer w sieci Internet, np. WWW, wymaga do działania tzw. strefy zdemilitaryzowanej, której z pewnością nie posiadają routery oferowane przez Telekomunikację Polską – liveboksy. DMZ posiada większość routerów dostępnych na rynku.

6.2. Konfigurowanie DynDNS

Żyjemy w erze domen, wpisywanie adresów IP serwerów jest obecnie uznawane za coś niebywałego i kompletnie niewygodnego. Warto zaopatrzeć się w domenę dla naszego serwera, nawet w darmową. W przypadku gdy korzystamy z sieci, w której zewnętrzny adres IP jest przydzielany dynamicznie – np. z Neostrady – domena to konieczność. W celu współpracy z dynamicznie zmiennymi IP powstała darmowa usługa DDNS (Dynamic Domain Name Server) DynDNS.com. Korzystając z tej usługi możemy ustawić domenę zarówno dla statycznego, jak i dynamicznego adresu. Na dodatek wielu producentów dostrzegło tę możliwość i umożliwiła w swoich routerach automatyczną synchronizację z usługą DynDNS. Wystarczy w panelu administracji routera podać swój login i hasło do usługi DDNS, aby router, przy każdej zmianie adresu IP, wysyłał informację do DynDNS, by ten zaktualizował wpisy na swoich serwerach. Całość działa naprawdę świetnie, a w dodatku za darmo, dlatego warto z tego skorzystać.

W celu założenia konta i usługi w serwisie DynDNS, należy udać się na stronę usługi. Na stronie głównej, w pobliżu panelu logowania, wybieramy opcję Create Account.

1
Widok na stronę główną usługi DynDNS

W dalszej części wypełniamy kolejne formularze, aż w końcu kończymy rejestrację, logujemy się do serwisu, znajdujemy zakładkę My Services, gdzie w części usług hostingowych (Host Services) wybieramy opcję Add Hostname.

4
Konfiguracja nazwy domenowej w DynDNS

W następnej części wpisujemy nazwę domenową dla naszego serwera, wybieramy opcję Host with IP Adress, po czym klikamy na “Use auto detected IP Address x.x.x.x”

51
Konfiguracja nazwy domenowej w DynDNS

Następnie udajemy się do panelu konfiguracyjnego routera, gdzie podajemy nasze dane dostępowe do usługi, zapisujemy ustawienia i od teraz usługi oferowane przez nasz serwer są widoczne spoza naszej sieci lokalnej. Tak, nasz serwer stał się teraz serwerem widocznym w Internecie.

dyndns
Konfiguracja synchronizacji routera z DynDNS

6.3. Konfigurowanie /etc/hosts

W pewnych przypadkach możliwość korzystania z domeny w przypadku łączenia się w sieci lokalnej jest przydatna. Taka możliwość przypadnie do gustu osobom, które posiadają nie jeden, lecz kilka domowych serwerów, a spamiętywanie ich adresów IP nie jest rzeczą przyjemną. W obecnych czasach możliwości usługi www znacznie się rozwinęły i w przypadku niektórych skryptów, np. blogowego systemu WordPress, nie możemy pozwolić sobie na korzystanie z adresu IP. WordPress wymaga ustawienia konkretnej nazwy domeny dla bloga. Możemy wpisać tam adres domenowy, jednak w większości przypadków nie będziemy w stanie połączyć się z serwerem przy pomocy domeny, gdyż będziemy przekierowywani na stronę konfiguracyjną routera. Przy próbie łączenia się z serwerem poprzez wpisanie adresu IP, posypie się nam WordPress, gdyż większość elementów skrypt próbował będzie pobierać ze skonfigurowanego wcześniej adresu domenowego, jednak nie otrzyma ich, gdyż jego zapytania zatrzymaja się na routerze. W takich i innych przypadkach wystarczy w swoim komputerze biurkowym zastosować sztuczkę polegającą na dodaniu nazwy domenowej serwera do pliku /etc/hosts:

hosts
Widok na plik /etc/hosts

Po wykonaniu tej prostej czynności wszystkie zapytania kierowane na domenowy adres naszego serwera będą zamieniane na zapytania na adres IP w sieci lokalnej.

7. Zakończenie

Mam nadzieję, iż przedstawiony przeze mnie w tym artykule sposób pomoże początkującym administratorom zwiększyć bezpieczeństwo serwerów przez nich zarządzanych. Jak już mówiłem, w dobie dzisiejszych mocy obliczeniowych bezpieczeństwo znacznie efektywniej zwiększa się przy pomocy wirtualizacji. Znajdzie się jednak nie jeden użytkownik, który z ogromną chęcią weźmie swojego starego peceta i postawi na nim serwer. Mam nadzieję, że dzięki mojemu artykułowi serwer będzie choć odrobinkę bezpieczniejszy.

Autor: b.yisk
Skład: Swamper

b.YISK, 13.03.2010 00:39

12.03.2010

OSNews.pl

OpenOffice.org nie sprawdziło się w urzędzie gminy

Jak donoszą rożne źródła w holenderskich mediach, projekt wdrożenia OpenOffice.org w jednym z urzędów gminnych zakończył się fiaskiem.

Przez cztery lata urząd fryzyjskiego miasta i gminy Heerenveen próbował przejść z MS Office 97 na OpenOffice.org. Główną przyczyna niepowodzenia były problemy z integracją OpenOffice.org z innymi aplikacjami stosowanymi w urzędzie.
Z 50 rożnych systemów które muszą współpracować z pakietem biurowym nie udało się połączyć piętnastu. Większość systemów nie ma standardowej wtyczki dla OpenOffice.org, a ich budowa nie zawsze była możliwa z uwagi na brak odpowiedniej dokumentacji lub niechęci producentów. Niektórych systemów, na przykład Centric w żaden sposób nie udało się nakłonić do współpracy z OpenOffice.org. Problemy pojawiały się podczas importowania danych z serwera Microsoft SQL. Również informacje z innych programów administracyjnych nie zawsze mogły być odczytane za pomocą OpenOffice.org. Kłopotliwe były nie tylko łącza, także program Calc (odpowiednik MS Excel) nie dawał sobie rady z większymi arkuszami kalkulacyjnymi.

Wiele problemów udało się rozwiązać, zbudowano wiele nowych wtyczek i rozwiązań systemowych. Nowe środowisko oparte na OpenOffice.org stało się jednak tak skomplikowane, że jego utrzymanie prawdopodobnie przekroczyłoby przewidziany budżet. Szef projektu podsumował niepowodzenie mówiąc: “W pewnym momencie doszliśmy do wniosku ze nowe MS Office nie działa u nas tak jak się spodziewaliśmy”.

Pracownicy urzędu w ciągu ostatnich tygodni przesiedli się na Microsoft Office. Pakiet Microsoftu zwykle dysponuje odpowiednimi wtyczkami, a jeżeli nie to producenci systemów biurowych zwykle budują swoje programy tak by współpracowały z MS Office. Szef wydziału ICT w urzędzie z Heerenveen zaznacza, że nie zrezygnowano z oprogramowania open source, nadal stosuje się te systemy tam gdzie się sprawdzają.

W licznych komentarzach na holenderskich portalach ICT specjaliści zastanawiają się czy najnowsze MS Office będzie dobrze współpracować ze starymi systemami. Czytelnicy zwracają tez uwagę na to, że najpierw należałoby wymienić blokujące systemy a później przystąpić do wymiany pakietu biurowego. Pojawiły się również informacje o tym, że producenci niektórych systemów nie byli chętni do współpracy podczas wymiany pakietu biurowego powołując się na prawa autorskie nie pozwalające na publikowanie własnego kodu źródłowego w celu umożliwienia łączności z OpenOffice.org.

goudacaster, 12.03.2010 22:56

10.03.2010

OSNews.pl

Simon Phipps odchodzi z Suna

Simon Phipps, kierownik działu Open Source w Sunie, poinformował na swoim blogu o odejściu z Suna, a raczej już z Oracle.

Nie ujawnił powodów decyzji, co oczywiście daje otwartą drogę do spekulacji, jak i nie powiedział nic o planach, co zamierza robić dalej.

Dziękując za współpracę i wspominając swoje 10 lat w Sunie, wymienił sukcesy jak i rzeczy które najzwyczajniej nie wyszły. Sukcesami przygody w Sunie są:

  • uwolnienie licencji Java, Uniksa (chodzi pewnie o OpenSolarisa), architektury SPARC i czołowych elementów Linuksa;
  • wspieranie działań na rzecz formatu OpenDocument;
  • zapoczątkowanie blogowej rewolucji na blogs.sun.com;
  • zmianę sposobu podejścia i postrzegania przez Sun samego Open Source- na lepsze oczywiście;
  • możliwość udzielania się w działaniach społeczności, FSF itp. (między innymi prace dla GPL3);
  • pracę w niesamowitym i jedynym w swoim rodzaju zespole.

Lista porażek, czy rzeczy jakie nie udały się do końca to nieotrzymanie przez Apache licencji TCK, nieuwolnienie dla społeczności niektórych projektów czy nieosiągnięciu harmonii samego współtworzenia z priorytetami produktów. Najsmutniejsze jednak wydaje się to, że mimo sukcesu firm Open Source nie udało się uratować Suna. Mimo tego, Simon pozostaje pod wrażeniem osiągnięć zespołu Open Source Suna.

Jakie będzie miejsce Open Source w oraclowskiej wizji Suna- czas pokaże. Póki co odchodzi ważny człowiek a sam Oracle wprowadza opłaty za dostęp do aktualizacji bezpieczeństwa w OpenSolarisie. Widocznie pewna epoka w firmie dobiega końca.

Tomasz Woźniak, 10.03.2010 15:31

06.03.2010

Przemek Rumik

PROPFIND, czyli jak przechytrzyć HttpURLConnection

Próbuję dodać do OOo2GD możliwość pobierania dokumentów z serwerów WebDAV [dzięki temu możliwe by było używanie OOo2GD do pracy z dokumentami, które nie ulegałyby konwersji, pracuję nad tym bo to co robi OpenOffice.org z WebDAVem to ludzkie pojęcie przechodzi, nie dość, że angażuje do tego system operacyjny i działa przeraźliwie wolno, to jeszcze tworzy później pliki tymczasowe na serwerze WebDAV] i właśnie próbuję zaimplementować pobieranie listy dokumentów, do czego potrzebuję metody PROPFIND z WebDAV.

Standardowo chciałem użyć HttpURLConnection, ale złośliwie Sun zabronił korzystania z metod innych niż wielka 7, czyli "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE" i "TRACE".

Wrrr... Logika jakaś za tym stoi, w końcu to HttpURLConnection, ale jednak miło by było gdyby pozwalała ta klasa na proste jej wykorzystanie do niecnych celów.

Na razie w celach testowych postanowiłem to obejść w bardzo nieelegancki sposób ;-)
Zamiast:

conn.setRequestMethod("PROPFIND");

Które powoduje wylecenie wyjątku "java.net.ProtocolException: Invalid HTTP method: PROPFIND" używam takiej brzydkiej plomby:


try {
Field field = conn.getClass().getDeclaredField("method");
field.setAccessible(true);
field.set(conn, "PROPFIND");
} catch (Exception e) {

}


Jak na razie działa, dostaję od serwera XMLa, już zaczynam go nawet "obrabiać" choć chyba wcześniej pójdę spać ;-)

Sposób ma wadę bo jest przywiązany do konkretnej maszyny wirtualnej, ale działa, a to mi jest potrzebne do testów :-)


Podobne postybeta
Sztuczki tropiciela błędów, part 2 ;-)
Ile to jest 1+1 w Java'ie?
Sortujemy JTable gdy się da ;-)
Sekrety klasy String ;-)
CONNECT i tunele

RMK (noreply@blogger.com), 06.03.2010 22:19

05.03.2010

DobreProgramy.pl

Nietypowe edytory tekstu na Maka

Dawno już minęły czasy, kiedy edytor tekstu służył jedynie do pisania. Dzisiaj użytkownicy pragną bardziej zaawansowanych, uwzględniających ich indywidualne potrzeby narzędzi. Oprócz popularnych pakietów jak Microsoft Office, iWork, OpenOffice czy NeoOffice, w Internecie można znaleźć sporo interesujących programów. W dodatku większość z nich jest darmowa. Są to przede wszystkim niszowe i...

Redakcja, 05.03.2010 10:57

Przemek Rumik

Najnowszy Chrome nie lubi chyba Gmaila ;-)

Dziś zaktualizował mi się Chrome do wersji 5.0.342.1 i zachorował na ciekawą przypadłość ;-) Nie lubi już GMAILa.
Każda próba wejścia na GMAILa kończy się padem przeglądarki, co widać na filmie :-)



Co ciekawe korzystanie z konta jest nadal możliwe gdy używam konta na Google Apps :-)

Trzeba jednak pamiętać, że ja używam wersji developerskiej, a ona ma prawo zachowywać się dziwnie.


Podobne postybeta
OOo2GD 2.1.0 - filtrowanie, sortowanie [dla niektórych ;-)] i bardziej *nixowe nazwy
O zaletach JNLP/Java Web Start :-)
OpenOffice.org2GoogleDocs 1.0.1
Kalendarz i GMAIL w jednym okienku ;-)
Kino, a w nim Harry Potter i Książę Półkrwi ;-)

RMK (noreply@blogger.com), 05.03.2010 02:06

04.03.2010

OpenOffice.org w praktyce

Tworzymy i publikujemy blog z poziomu OpenOffice.org.

Co prawda OpenOffice.org jest przede wszystkim pakietem biurowym, możemy jednak wykorzystać jego zdolność łączenia się z zewnętrznymi systemami zarządzania bazami danych, jak MySQL, by stworzyć wygodne rozwiązania, rozszerzające jego funkcje poza zwyczajne redagowanie dokumentów. Możemy na przykład połączyć OpenOffice’a z bazą danych aplikacji do blogowania, co pozwoli pisać i publikować posty bezpośrednio z Writera. Brzmi to może jak zadanie dla zawodowego programisty, ale w rzeczywistości wystarczy kilka prostych makr.

Rysunek 1: Doskonałym kandydatem do naszego zadania będzie Bilboblog.

Elementy układanki

By ułatwić zrozumienie działania tego projektu, podzielę jego wykonanie na kilka kroków. Najpierw powinniśmy zainstalować i skonfigurować aplikację do blogowania. Teoretycznie do naszych celów nada się każda z nich, o ile korzysta z bazy danych MySQL. W praktyce powinniśmy jednak wybrać niezbyt skomplikowany program, posługujący się prostą bazą danych. W naszym przykładzie użyjemy nieco zmodyfikowanej wersji aplikacji do blogowania Bilboblog (Rysunek 1) [1]. Przechowuje ona treści w prostej tabeli z zaledwie trzema polami, dzięki czemu nadaje się idealnie do wykorzystania w naszym projekcie.

Będziemy również potrzebować serwera PHP / MySQL lub konta na odpowiednim serwisie, gdzie będziemy mogli zainstalować Bilbobloga. By to zrobić, wystarczy stworzyć bazę danych MySQL (na przykład bilboblog), pobrać najnowszą wersję aplikacji, rozpakować archiwum i przenieść jego zawartość (katalog bilboblog) do katalogu głównego na serwerze. Nadajemy mu prawa zapisu i poprzez przeglądarkę przechodzimy do http://twojserwer/bilboblog. Tu wypełniamy wymagane pola i klikamy Install.

Rysunek 2: Konfiguracja połączenia z MySQL-em za pomocą aplikacji Database Wizard.

Następnie musimy połączyć OpenOffice’a z bazą danych Bilbobloga. W tym celu potrzebujemy rozszerzenia Sun MySQL Connector dla OpenOffice.org [2], które integruje się bezpośrednio z naszym pakietem biurowym i umożliwia połączenie z bazą danych (Rysunek 2). By go zainstalować, pobierzmy najnowszą wersję rozszerzenia. W OpenOffice.org wchodzimy w Narzędzia | Menedżer rozszerzeń, wciskamy przycisk Dodaj i wybieramy pobrany plik .oxt. Teraz wystarczy zrestartować OpenOffice – i gotowe.

Rysunek 3: Struktura bazy danych bilboblog.

Na koniec tworzymy prosty plik bazy danych (Base), łączący pakiet biurowy z bazą danych Bilbobloga (domyślnie bilboblog). W tym celu w OpenOffice.org wybieramy Plik | Nowy | Baza danych, zaznaczamy opcję Połącz z istniejącą bazą danych i wyszukujemy na liście rozwijanej MySQL. Teraz wciskamy Dalej i zaznaczamy opcję Connect native. W kolejnym kroku określamy ustawienia połączenia z bazą danych i nazwę użytkownika, a następnie zaznaczamy pole Wymagane hasło.

By sprawdzić, czy połączenie funkcjonuje prawidłowo, wciskamy przycisk Testuj połączenie, po czym upewniamy się, że zaznaczona jest opcja Tak, zarejestruj bazę danych, odznaczamy pole Otwórz bazę danych do edycji i zapisujemy efekt końcowy jako Bilboblog.odb. Powstały plik nie tylko łączy się z bazą danych bilbobloga, ale też pozwala przyjrzeć się jej strukturze. Otwórzmy Bilboblog.odb i przejdźmy do sekcji Tabele. Jeśli klikniemy dwukrotnie na bazę danych bilboblog, powinna pojawić się tabela articles (Rysunek 3). Jej strukturę także możemy podejrzeć poprzez podwójne kliknięcie.

Piszemy makra

Tabela articles składa się z trzech pól: num_article, gdzie znajdują się numery ID postów, article_pub z czasem publikacji oraz article_content, przechowująca treść postów. Na początek musimy napisać proste makro w języku OpenOffice.org Basic. Będzie ono tworzyć rekord w tabeli articles i zapisywać zawartość otwartego dokumentu Writer w polu article_content. Makro ma wykonywać trzy czynności: pobierać tekst z otwartego dokumentu Writer, łączyć się z bazą danych bilboblog i zapisywać tekst w polu article_content tabeli articles. Pierwszy krok – pobranie zawartości aktywnego dokumentu – wymaga trzech prostych linii kodu:

ThisDoc=ThisComponent
ThisText=ThisDoc.Text
Article=ThisText.String


Teraz musimy połączyć się z bazą danych. Tu również wystarczą trzy instrukcje:

DBContext=createUnoService ("com.sun.star.sdb.DatabaseContext")
DataSource=DBContext.getByName ("Bilboblog")
DB=DataSource.GetConnection ("użytkownik", "hasło")

W miejscu ciągów “użytkownik” i “hasło” wpisujemy nazwę użytkownika i hasło do bazy danych. Podanie tych elementów na stałe sprawia, że makro staje się mniej elastyczne (jeśli zmienimy któreś z nich, musimy ręcznie edytować makro), możemy więc pokusić się o zmodyfikowanie go tak, by samo pytało o dane do logowania. W takim wypadku kod umożliwiający połączenie z bazą danych przybierze następującą postać:

DBContext=createUnoService ("com.sun.star.sdb.DatabaseContext")
DataSource=DBContext.getByName("Bilboblog")
UserName=InputBox ("Użytkownik MySQL", "Attention")
UserPassword=InputBox ("Hasło", "Attention")
DB=DataSource.GetConnection (UserName, UserPassword)

Do manipulowania bazą danych OpenOffice.org Basic wykorzystuje zapytania SQL, więc aby zapisać pobrany tekst w polu article_content, makro posługuje się zapytaniem opartym na poleceniu INSERT INTO o następującym formacie:

INSERT INTO articles (pole1, pole2) VALUES ('wartość1', 'wartość2')

W naszym przypadku zapytanie INSERT INTO wyglądać będzie tak:

SQLQuery="INSERT INTO articles (article_content) VALUES ('" + Article + "')"

W języku OpenOffice.org Basic po zapytaniu INSERT INTO następują dwie instrukcje, służące do jego wykonania:

SQLStatement=DB.createStatement
Result=SQLStatement.executeQuery (SQLQuery)

Kiedy kwerenda zostanie już wykonana, makro sprząta po sobie, zamykając połączenie z bazą danych:

DB.close
DB.dispose

Cały kod przedstawiony jest w Listingu 1.

Sub PostToBilboblog
ThisDoc=ThisComponent
ThisText=ThisDoc.Text
Article=ThisText.String
DBContext=createUnoService("com.sun.star.sdb.DatabaseContext")
DataSource=DBContext.getByName("Bilboblog")
UserName=InputBox("Użytkownik MySQL", "Attention")
UserPassword=InputBox("Hasło", "Attention")
DB=DataSource.GetConnection (UserName, UserPassword)
SQLQuery="INSERT INTO articles (article_content) VALUES ('" + Article + "')"
SQLStatement=DB.createStatement
Result=SQLStatement.executeQuery (SQLQuery)
DB.close
DB.dispose
End Sub
Listing 1: Makro w języku OpenOffice.org Basic

Wszystko pięknie, ale powstałe makro ma jedno poważne ograniczenie: odziera tekst z wszelkiego formatowania, więc jeśli chcemy, by zachowane zostały pogrubienia, kursywa, podkreślenia i inne style tekstowe, będziemy potrzebować trochę więcej kodu. Bilboblog formatuje tekst za pomocą podzbioru znaczników BBCode, w tym pogrubienia (znaczniki [b] i [/b]), kursywy ([i] i [/i]) oraz podkreślenia ([u] i [/u]). Możemy oczywiście użyć tychże znaczników w trakcie pisania tekstu w Writerze, ale byłoby znacznie wygodniej, gdyby makro potrafiło przetworzyć tekst automatycznie, w momencie wstawiania jego zawartości do tabeli articles. W tym celu musimy zmodyfikować makro, aby odnajdywało wszystkie fragmenty sformatowane za pomocą pogrubienia, kursywy i podkreślenia i otaczało je odpowiednimi znacznikami. Bez zbędnych ceregieli przyjrzyjmy się Listingowi 2, który zawiera przykładowe makro wyszukujące pogrubione fragmenty tekstu i oznaczające je znacznikami [b] i [/b].

Sub ReplaceBold
Dim SearchAttributes(0) As New com.sun.star.beans.PropertyValue
ThisDoc=ThisComponent
SearchAttributes(0).Name="CharWeight"
SearchAttributes(0).Value=com.sun.star.awt.FontWeight.BOLD
ReplaceObj=ThisDoc.createReplaceDescriptor
ReplaceObj.SearchStyles=false
ReplaceObj.SearchAll=true
ReplaceObj.SearchRegularExpression=true
ReplaceObj.SetSearchAttributes(SearchAttributes)
ReplaceObj.SearchString=".*"
ReplaceObj.ReplaceString="[b]&[/b]"
ThisDoc.replaceAll(ReplaceObj)
End Sub
Listing 2: Makro zachowujące pogrubienie

Makro zaczyna się od określenia atrybutów wyszukiwania name i value i stworzenia obiektu ReplaceObj. Jego parametry definiują operacje wyszukania i zastąpienia. Ustawienie opcji SearchStyles na false zapobiega wyszukiwaniu przez makro konkretnych stylów, zaś aktywowanie parametru SearchAll pozwala na przeszukanie całego dokumentu. SearchRegularExpression umożliwia wykorzystanie wyrażeń regularnych, więc makro może posłużyć się wartością .* opcji SearchString, by przeszukać cały tekst. Parametr ReplaceString definiuje ciąg, którym zostanie zastąpiony odnaleziony fragment tekstu. Następnie ThisDoc.replaceAll(ReplaceObj) przeprowadza operację wyszukania i zamiany.

By tak samo postąpić z tekstem kursywą, wystarczy następująco zmodyfikować wartości SearchAttributes(0).Name, SearchAttributes(0).Value i ReplaceObj.ReplaceString:

SearchAttributes(0).Name="CharPosture"
SearchAttributes(0).Value=com.sun.star.awt.FontSlant.ITALIC
ReplaceObj.ReplaceString="[i]&[/i]"

Zamiast pisać kilka podprocedur dla każdego stylu, możemy z łatwością zmienić makro w funkcję i wywołać ją z podprocedury głównej – wystarczy, że zastąpimy wartości zmiennymi (Listing 3).

Function MarkupStr(SearchAttrName, SearchAttrValue, ReplaceStr)
Dim SearchAttributes(0) As New com.sun.star.beans.PropertyValue
ThisDoc=ThisComponent
SearchAttributes(0).Name=SearchAttrName
SearchAttributes(0).Value=SearchAttrValue
ReplaceObj=ThisDoc.createReplaceDescriptor
ReplaceObj.SearchStyles=false
ReplaceObj.SearchAll=true
ReplaceObj.SearchRegularExpression=true
ReplaceObj.SetSearchAttributes(SearchAttributes)
ReplaceObj.SearchString=".*"
ReplaceObj.ReplaceString=ReplaceStr
ThisDoc.replaceAll(ReplaceObj)
End Function
Listing 3: Zmieniamy podprocedurę w funkcję

Teraz możemy wywołać funkcję w głównej podprocedurze i podać odpowiednie wartości. Poniższy fragment kodu wyszukuje pogrubione, podkreślone i przekreślone fragmenty tekstu oraz kursywę za pomocą funkcji MarkupStr i stosuje w nich odpowiednie znaczniki.

MarkupStr("CharWeight", com.sun.star.awt.FontWeight.BOLD, "[b]&[/b]")
MarkupStr("CharPosture", com.sun.star.awt.FontSlant.ITALIC, "[i]&[/i]")
MarkupStr("CharUnderline", com.sun.star.awt.FontUnderline.SINGLE, "[u]&[/u]")
MarkupStr("CharStrikeout", com.sun.star.awt.FontStrikeout.SINGLE, "[s]&[/s]")

Makro jest prawie gotowe, powinniśmy jednak naprawić jeszcze jeden niewielki mankament. Bilboblog zapisuje datę i czas w tak zwanym uniksowym formacie czasowym, określanym jako liczba sekund, które upłynęły od północy 1 stycznia 1970 roku. Jeśli wrzucimy do tabeli articles rekord bez podania właściwego znacznika czasu, domyślnie wyświetlony zostanie właśnie 1 stycznia 1970 roku, co nie jest zbyt praktyczne. By uniknąć tego problemu, powinniśmy dodać instrukcję, która przypomina o podaniu daty i czasu:

Timestamp=InputBox ("Podaj znacznik czasu", "Attention")

Musimy również zmodyfikować zapytanie SQL, by wpisywało pobraną wartość znacznika czasu w polu article_pub:

SQLQuery="INSERT INTO articles (article_content, article_pub) VALUES ('" + Article + "', '" + Timestamp + "')"

Sub PostToBilboblog
MarkupStr("CharWeight", com.sun.star.awt.FontWeight.BOLD, "[b]&[/b]")
MarkupStr("CharPosture", com.sun.star.awt.FontSlant.ITALIC, "[i]&[/i]")
MarkupStr("CharUnderline", com.sun.star.awt.FontUnderline.SINGLE, "[u]&[/u]")
MarkupStr("CharStrikeout", com.sun.star.awt.FontStrikeout.SINGLE, "[s]&[/s]")
ThisDoc=ThisComponent
ThisText=ThisDoc.Text
Article=ThisText.String
DBContext=createUnoService("com.sun.star.sdb.DatabaseContext")
DataSource=DBContext.getByName("Bilboblog")
UserName=InputBox("Użytkownik MySQL", "Attention")
UserPassword=InputBox("Hasło", "Attention")
DB=DataSource.GetConnection (UserName, UserPassword)
Timestamp=InputBox("Podaj znacznik czasu", "Attention")
SQLQuery="INSERT INTO articles (article_content, article_pub) VALUES ('" + Article + "', '" + Timestamp + "')"
SQLStatement=DB.createStatement
Result=SQLStatement.executeQuery (SQLQuery)
DB.close
DB.dispose
End Sub
Function MarkupStr(SearchAttrName, SearchAttrValue, ReplaceStr)
Dim SearchAttributes(0) As New com.sun.star.beans.PropertyValue
ThisDoc=ThisComponent
SearchAttributes(0).Name=SearchAttrName
SearchAttributes(0).Value=SearchAttrValue
ReplaceObj=ThisDoc.createReplaceDescriptor
ReplaceObj.SearchRegularExpression=true
ReplaceObj.searchStyles=false
ReplaceObj.searchAll=true
ReplaceObj.SetSearchAttributes(SearchAttributes)
ReplaceObj.SearchString=".*"
ReplaceObj.ReplaceString=ReplaceStr
ThisDoc.replaceAll(ReplaceObj)
End Function

Listing 4: Makro i funkcja

Na Listingu 4 znajduje się ostateczna wersja makra i dołączonej do niego funkcji. Pytanie brzmi: jak wyliczyć wartość znacznika czasu? Możemy wprawdzie napisać kod konwertujący bieżącą datę i czas na znacznik czasu w formacie uniksowym, ale może to być problematyczne. Najprostszym rozwiązaniem jest skorzystanie z polecenia date %s w terminalu lub zainstalowanie rozszerzenia TimeStamp Converter dla Firefoksa [3].

Ostateczny szlif

Na koniec przyjrzyjmy się makru, które analizuje linki w dokumencie Writer i nadaje im formatowanie Bilbobloga. W odróżnieniu od funkcji zajmującej się formatowaniem tekstu, makro przetwarzające hiperłącza wykorzystuje obiekt Enumeration, za pomocą którego możemy po kolei przejrzeć paragrafy dokumentu, pobrać wartości parametru HyperlinkURL, a następnie zastosować określone formatowanie (Listing 5).

Sub MarkupURL
ThisDoc=ThisComponent
ThisText=ThisDoc.Text
ParaEnum=ThisText.createEnumeration
While ParaEnum.hasmoreElements
Para=ParaEnum.nextElement
PortionEnum=Para.createEnumeration
While PortionEnum.hasMoreElements
Portion=PortionEnum.nextElement
If Portion.HyperlinkURL
"" then
Portion.String = "[url=" + Portion.HyperlinkURL +"]" +Portion.String + "[/url]"
End if
Wend
Wend
End Sub

Listing 5: Analiza i formatowanie hiperłączy

By przetworzyć hiperłącza za pomocą tego makra, wystarczy wywołać je z głównej podprocedury PostToBilboblog.

Info


Artykuł znaleziono w serwisie czytelnia.ubuntu.pl. Jego autorem jest Dmitri Popov, a sam tekst jest przedrukiem z gazety Linux Magazine 1(71)/2010 i został opublikowany za zgodą redakcji.

Mateusz Zasuwik (noreply@blogger.com), 04.03.2010 20:06

03.03.2010

Morfologik

morfologik-stemming 1.3.0

Wydaliśmy dziś nową wersję biblioteki morfologik-stemming. Zawiera ona trochę usprawnień związanych z wydajnością, w tym m.in. możliwość innego binarnego przekodowania automatu fsa (CFSA), umożliwiającą uzyskanie mniej więcej 10% mniejszego pliku, który jest obsługiwany szybciej.
API wysokiego poziomu nie uległo zmianie.

Marcin Miłkowski (noreply@blogger.com), 03.03.2010 00:50

02.03.2010

Przemek Rumik

ePubGenerator v0.0.3 - tytuł, obrazki i inne takie

Niewielki [o takie -> . -] siły z siebie wysupłałem i mamy wersję 0.0.3 ePubGeneratora.

Ta wersja potrafi już:
  • osadzać obrazki w ebookach
  • użyć tytułu, opisu, tematyki, twórcy i identyfikatora podanych przez użytkownika
  • sprawdzić czy nie ma nowszej wersji

Nadal jednak nie potrafi ustawić daty [która jest na sztywno ustawiona na 1 marca 2010 :-)], oraz języka, który jest ustawiony na polski.

Następne wyzwanie to wielorozdziałowość i jedyny pomysł jaki mi przyszedł do głowy to wrzucanie kolejnych rozdziałów do podkatalogów. I idea jest taka by najpierw tworzyło się 1 rozdział, a później można by było dodawać następne generowane z kolejnych dokumentów, tudzież by od razu tworzyć ebooka z wieloma rozdziałami i każdy z nich byłby w innym pliku........ To na razie pomysły bo szczerze to nawet nie wiem jak w OpenOffice.org robi się rozdziały :-)

Obsługa jest podobna do tego co opisałem pisząc o wersji 0.0.1, czyli klikamy na ePubGenerator, ale tym razem ujrzymy okienko:



klikamy Generate i po chwili ujrzymy okienko:



wskazujące gdzie szukać naszego ebooka w formacie EPUB.

Jak widzę parę osób pobrało poprzednią wersję, ale jak na razie jedyny komentarz to stwierdzenie, że nazwa "ePubGenerator jest lepsza od OpenOffice.org2GoogleDocs" ;-)


Podobne postybeta
ePubGenerator v0.0.2
Generowanie plików ePub z OpenOffice.org :-)
Dalsze zabawy z ePubGeneratorem :-)
OOo2GD 1.9.0 w kierunku bezszwowości ;-)
Wpisy z Bloggera jako eventy w Google Calendar, odsłona 3 - Aplikacja ;-)

RMK (noreply@blogger.com), 02.03.2010 00:26

Dalsze zabawy z ePubGeneratorem :-)

Moja chytrość mnie przeraża ;-) [chytrość w sensie przebiegłości ;p]

Dalej bawię się w pisanie wtyczki do generowania plików EPUB, i dziś walczyłem między innymi z tym by wynikowy ebook miał w sobie obrazki jeśli takowe były w oryginalnym pliku.

Problemem okazało się to, że OpenOffice.org w trakcie zapisywania dokumentu jako XHTML zapisuje obrazki w pliku XHTML w postaci osadzonej.

Gdy to zauważyłem to poczułem, że to jednak lekka "amba".... Ale po chwili doznałem olśnienia ;-) Przecież nic nie stoi na przeszkodzie temu by takie osadzone obrazki wyrzucić do zewnętrznych plików, a w miejsce osadzonych danych można spokojnie wstawić nazwy plików wynikowych.

W tym celu wystarczy stworzony plik XHTML wczytać jako dokument XML, a następnie przejść przez wszystkie tagi typu img i dla każdego z nich pobrać zawartość atrybutu src, wyekstrahować z tej zawartości dane w Base64, przekodować je na bajty [tutaj jest problem, bo Java nie daje takiego ficzera sama z siebie, tzn. w przypadku Java'y od Suna jest coś takiego w bibliotekach, choć nie powinno się tego używać bo to tajny ficzer ;-)], zapisać do pliku i w miejsce danych w src wstawić nazwę pliku, teraz już tylko nagrać taki nowy plik XML w miejsce oryginalnego i voilà! :-)

Teraz stoi przede mną konieczność zbudowania GUI i chyba napisania własnego dekodera Base64 bo nie chciałbym dla 1 głupiej funkcji dodawać jakiejś dużej biblioteki do rozszerzenia.

Jak widzę w logach obecnie rozszerzenie do generowania EPUBów nie jest jakoś szczególnie pobierane ;-) [przodują tutaj Boty Google i Yahoo ;-)] ale liczę, że w momencie gdy dodam do niego GUI to wrzucę je do katalogu rozszerzeń OpenOffice.org i zawsze jest szansa, że znajdzie jakichś użytkowników :-) [bym za 2 lata gdy pobierze je powiedzmy 50 tysięcy osób pluł sobie w brodę, że głupi ja, przecież mogłem je sprzedawać nawet po 1 Euro i jaki byłbym bogaty ;p]

Ciągle nie umiem wymyślić jakiejś ładnej nazwy dla rozszerzenia, ale bądźmy szczerzy, od czasów Gadacza żadna nazwa mi jakoś nie wyszła ;-) Sam jak sobie przypomnę nazywam ten projekt "topeszem" [od "nietopesz" ;-)]


Podobne postybeta
ePubGenerator v0.0.2
RDrive w działaniu ;-) czyli kolejny raport z prac nad Kolczatką ;-)
User Interface... jak ja tego nie lubię...
ePubGenerator v0.0.3 - tytuł, obrazki i inne takie
Generowanie plików ePub z OpenOffice.org :-)

RMK (noreply@blogger.com), 02.03.2010 00:26

ePubGenerator v0.0.2

Poprzednia wersja działała, ale dziwnie ;-) Po prostu pliki EPUB, które generowała nie były zgodne ze standardem.

Teraz mamy wersję 0.0.2, której "produkty" to już coś bliższego pełnoprawnych dokumentów EPUB.
Wcześniejsza wersja miała problem polegający na tym, że katalog OPS w którym znajdują się pliki umieszczany był zawsze w katalogu META-INF, a nie powinien. Dodatkowo poprzednia wersja używała HTMLa do przechowywania treści, a to jest niezgodne ze specyfikacją, wg. której treść przechowywać należy w XHMTL.
Na szczęście OpenOffice.org potrafi nagrywać XHTMLa [choć z jakimiś błędami ;-)] i dzięki temu możliwe jest tworzenie plików EPUB.
Obecnie generowane pliki można już otwierać np. w androidowym Aldiko :-)
Okazuje się również, że pliki EPUB to wcale nie "zwykłe pliki ZIP", a pliki ZIP, których pierwszym plikiem musi być plik mimetype, który nie może być skompresowany tak by w pliku bajty od 30 do 37 miały wartość mimetype, a następne od 38 by miały wartość application/epub+zip.

Wygenerowane przez ePubGenerator pliki nie są niestety w pełni poprawne, ale z tego co widzę w logach wyrzucanych przez epubcheck winne jest to, że XHMTL wygenerowany przez OpenOffice.org nie jest poprawny.

Zapraszam do pobierania ePubGenerator 0.0.2.

Może ktoś się podzieli pomysłem na nazwę? :-)
Wersja 0.0.2 ma dokładnie takie same ograniczenia jak wersja 0.0.1. Także wersja 0.0.2 strasznie "brudzi" na dysku w katalogu użytkownika i pozostawia katalogi wraz z zawartością, które są używane do tworzenia dokumentów EPUB. Kolejne wersje powinny ten problem wyeliminować.

Z ciekawostek, po przejściu z HTML na XHTML czytnik Stanza odmówił współpracy ;-)


Podobne postybeta
Generowanie plików ePub z OpenOffice.org :-)
ePubGenerator v0.0.3 - tytuł, obrazki i inne takie
Dalsze zabawy z ePubGeneratorem :-)
CosmoPlayer w Google Chrome
OOo2GD 1.5.0 - drżyjcie arkusze! ;-)

RMK (noreply@blogger.com), 02.03.2010 00:26

Generowanie plików ePub z OpenOffice.org :-)

Czytniki e-booków, jak i same e-booki stają się coraz popularniejsze. Coraz więcej się wydaje książek w taki sposób.
Ale co ma zrobić biedny żuczek, użytkownik, który chciałby np. swoje dokumenty "wydać" jako plik w formacie ePub rozpoznawalnym przez wiele [jeśli nie większość] czytników?

Może skorzystać z dostępnych w sieci konwerterów, ale nie zawsze chcemy by nasz dokument wyszedł poza nasz komputer....

I tu może wejść coś co nazwałem jak na razie ePubGenerator, a co jest dzieckiem ostatnich 3-4 godzin kodowania i wtyczką do OpenOffice.org ;-)

Jak na razie jest to głupiutkie maleństwo z dużą ilością obostrzeń:
  • tytuł e-booka to zawsze "Test"
  • autor to zawsze "Przemysław Rumik" (dokładniej Przemys³aw Rumik)
  • opis to "Opis EPUB"
  • data utworzenia to 27 lutego 2010 [czyli dziś ;-)]
  • brak wsparcia dla obrazków [choć są umieszczone w samym pliku]

Wszystko powstało w oparciu o strukturę i opis formatu EPUB stworzony przez Pawła Wimmera. [OK, czuję, że mi coś gramatyka siada, nie żeby normalnie była na wysokim poziomie, ale teraz już siada kompletnie, może to że jest 4:28 nad ranem coś tłumaczy ;-)].
Jak na razie wygenerowane pliki EPUB testowałem z MobipocketReader'em i działają, do Androidowego Aldiko nie udało mi się ich zaimportować.

Obsługa jest banalnie prosta, instalujemy rozszerzenie [standard, pobrać, gdy mamy szczęście przeglądarka za nas odpali Extensions Managera, jeśli tego nie zrobi musimy sami, gdy zobaczymy że już się rozszerzenie zainstalowało to wyłączamy OO.org], otwieramy plik w OpenOffice.org, klikamy na napisie ePubGenerator na pasku rozszerzenia.
Po chwili gdzieś na ekranie [możliwe, że pod oknem OpenOffice.org] dostaniemy informację, że plik został stworzony i namiary na jego lokalizację [jest w katalogu domowym użytkownika, na WinXP c:\Documents and Settings\user\] i ma nazwę w stylu folder1267240546631.epub.

ePubGenerator w Extension Managerze:


Guziczek do generowania:


Konwersja skończona:


Wygenerowany dokument w Modipocket Reader:



Jak już chyba pisałem, jest to wersja 0.0.1, czyli bardziej niż wczesna :-) Ale jeśli ktoś jest zainteresowany to zapraszam do pobierania [teraz wersji 0.0.2] i testowania :-)
Ciekawi mnie głównie feedback dotyczący tego czy inne czytniki sobie radzą z plikami wygenerowanymi przez rozszerzenie i ogólne opinie na temat rozszerzenia :-)
Tutaj poprzedni wpis z bloga jako EPUB.

Nie dam głowy, ale chyba konieczna jest jak na razie Java 1.6 by móc uruchomić rozszerzenie.


Podobne postybeta
ePubGenerator v0.0.2
ePubGenerator v0.0.3 - tytuł, obrazki i inne takie
I bądź tu przedsiębiorczy
Dalsze zabawy z ePubGeneratorem :-)
Gadające Gadu-Gadu

RMK (noreply@blogger.com), 02.03.2010 00:26