Skip to content

OpenBox zamiast AwesomeWM, czyli dlaczego Awesome nie jest taki awesome.

2 komentarzy

Słowem wstępu.

Do tej pory namiętnie używałem AwesomeWM jako menedżera okien do codziennej pracy. Nie mam wielkich wymagań, oczekuję głównie dobrego (i działającego!) wsparcia wielu ekranów oraz wygodnego poruszania się pomiędzy oknami bez konieczności używania myszy. Zazwyczaj pracuję na zestawie składającym się z laptopa podłączonego do zewnętrznego monitora przez HDMI oraz z bezprzewodowej klawiatury i myszy. Taki układ umożliwia wygodną pracę jak przy desktopie, natomiast w potrzebie większej mobilności wystarczy odpiąć wszelkie kable od laptopa i można ruszać w teren.

Jeszcze do niedawna AwesomeWM w pełni zaspokajał moje potrzeby dzięki wygodnemu poruszaniu się pomiędzy oknami za pomocą skrótów klawiszowych na wzór Vima oraz idealnej dla mnie obsłudze wielu ekranów. Od razu odrzucam konfiguracje X-ów wykorzystującą Xinerama oraz TwinView. Posiadam na pokładzie technologię NVIDIA Optimus, która działa u mnie wystarczająco dobrze dzięki Bumblebee. W takiej konfiguracji działa instancja serwera X obsługująca jeden wirtualny obszar podzielony na dwa ekrany. I właśnie w sposobie zarządzania tymi ekranami pojawia się spora różnica pomiędzy AwesomeWM a większością innych menedżerów okien.

Awesome wykorzystuje podejście, w którym dla każdego ekranu są tworzone odrębne, niezależne pulpity robocze, dzięki czemu zmiana pulpitu na jednym ekranie nie powoduje zmiany pulpitu na drugim. Jest to bardzo wygodne rozwiązanie pozwalające rozmieszczać okna na poszczególnych pulpitach bez przywiązania ich do drugiego ekranu, na którym nie są wcale wyświetlane. To podejście jest charakterystyczne dla Tiling window managerów w przeciwieństwie do Floating window managerów, do których należą wszystkie najpopularniejsze i najlepiej wspierane menadżery okien, takie jak Mutter (GNOME3), KWin (KDE), Muffin (Cinnamon), Xfwm (XFCE) czy OpenBox (LXDE). Niestety w tych drugich standardem jest rozwiązanie, w którym zmiana pulpitu na jednym ekranie, zmienia również odpowiednio pulpit na drugim ekranie. Znalazłem dwa częściowe obejścia tego problemu. Pierwszym jest wyświetlanie danego okna na wszystkich pulpitach jednocześnie, wówczas na drugi ekran można wrzucić okno, które będzie cały czas widoczne niezależnie od numeru pulpitu na pierwszym ekranie. Drugim rozwiązaniem dostępnym jedynie w wybranych menadżerach okien (np. Muffin) jest wyświetlanie pulpitów jedynie na pierwszym ekranie, podczas gdy drugi posiada jeden statyczny pulpit.

Zatem dlaczego nie AwesomeWM skoro świetnie radzi sobie z oknami, pulpitami i ekranami?

W życiu nic nie jest idealne, a już szczególnie oprogramowanie. Korzystając z AwesomeWM napotkałem trochę problemów raczej nie spotykanych w większych menedżerach okien. Warto w tym momencie wspomnieć, iż Awesome został napisany w niecałych 20000 linii kodu tworzących w pełni funkcjonalne środowisko pracy wpierające wiele standardów i technologii takich jak EWMH, XRandR czy D-Bus.

Sporo problemów było związanych z wyświetlaniem aplikacji napisanych w Javie, co szczególnie dawało znać o sobie odkąd bardziej zainteresowałem się tą technologią. Mianowicie w świeżo uruchomionych aplikacjach Intellij oraz Oracle SQL Developer, bądź po przeniesieniu ich okien na inny pulpit, występowało przesunięcie kursora objawiające się wskazywaniem przez niego punktu znajdującego się w przybliżeniu 20 px nad nim. Jest to znany problem związany z aplikacjami Javy w non-reparenting window menedżerach. Jednakże żadne z proponowanych rozwiązań, również znajdujących się na stronach wiki AwesomeWM, nie odniosły pożądanego skutku. Jak się okazuje, nie tylko w moim systemie te hacki nie działają.

Kolejną uciążliwością jest brak natywnego wsparcia rozszerzenia X Composite, co samo w sobie nie jest problemem, gdyż można podpiąć compositing window manager pod inny menedżer okien. Wspomniane rozszerzenie jest wymagane do obsługi bardziej zaawansowanych metod rysowania okien, czego oczekuje m.in. JavaFX Scene Builder. Niestety AwesomeWM nie chciał u mnie poprawnie współpracować z Compton’em, czego efektem była niemożność korzystania z tego kawałka oprogramowania. Nie sprawdzałem czy inny compositing window manager działałby poprawnie.

Na tym nie koniec problemów. Zakładki w przeglądarce Chrome nie działały poprawnie na drugim ekranie. Nie funkcjonowało na nim łączenie ze sobą dwóch okien z pojedynczymi zakładkami w jedno okno ze wszystkimi zakładkami, jak również sama zamiana kolejności zakładek powodowała przeniesienie trzymanej zakładki do nowego okna. Te niedogodności nie występowały na pierwszym ekranie. Również tutaj nie wnikałem w przyczynę takiego działania okien przeglądarki ale na pewno jest to powiązane z menedżerem okien.

Przesiadka na OpenBox’a

Dlaczego OpenBox? Po drodze odwiedziłem kilka środowisk graficznych takich jak GNOME3, Cinnamon, MATE, XFCE, licząc, że przekonają mnie swoją kompletnością oraz łatwością konfiguracji i obsługi. Z pewnością dla wielu użytkowników dostarczają odpowiednie warunki do pracy, jednakże w tym przypadku nie zaspokoiły mojej potrzeby dostosowywania środowiska, prostoty i minimalizmu. OpenBox, będący tylko menedżerem okien, okazał się rozwiązaniem najbliższym ideału. Do kompletu mogącego stanowić kompletne środowisko potrzebowałem dorzucić kilka aplikacji:

  • tint2 – panel systemowy dostarczający również tray oraz widget minitorujący stan baterii
  • nitrogen – aplikacja do zarządzania tapetą na pulpicie
  • compton – compositing window manager dostarczający rozszerzenie X Composite jak również kilka miłych dla oka efektów podczas przełączania okien
  • volumeicon – podręczna ikona w tray’u do obsługi poziomu głośności, obsługująca również część klawiszy multimedialnych
  • conky – monitor dostarczający na pulpicie informacje o systemie
  • redshift – aplikacja zmieniająca temperaturę światła ekranu w zależności od pory dnia
  • xfce-notifyd – demon obsługujący powiadomienia systemowe poprzez D-Bus
  • xfce-appfinder – podręczny launcher do aplikacji
  • xfce-screenshooter – przydaje się do wygodnego robienia zrzutów ekranu po zbindowaniu do klawisza Print

W tym momencie można postawić pytanie, po co instalować OpenBoxa wraz z powyższymi aplikacjami skoro te wszystkie funkcjonalności dostarczają środowiska graficzne. Dla mnie odpowiedzią jest pełna kontrola nad takim środowiskiem graficznym, które stworzyłem samemu od podstaw.

Wymiana przyzwyczajeń na nowsze

Przesiadka na OpenBoxa wiązała się ze zmianą przyzwyczajeń związanych z organizacją okien pośród wielu pulpitów. W przypadku AwesomeWM na dwóch ekranach posiadałem odrębne, niezależne pulpity dzięki czemu zazwyczaj mogłem pracować w konfiguracji, gdzie na głównym ekranie na poszczególnych pulpitach trzymałem okna, w których aktywnie pracowałem, podczas gdy na drugim ekranie okna związane z dodatkowymi informacjami np. przeglądarka internetowa z pomocnym artykułem. Taki sposób pracy nie jest możliwy w OpenBoxie, który narzuca konfigurację wykorzystującą przestrzenie robocze (ang. workspace).

Wydajna praca w menedżerze okien udostępniającym przestrzenie robocze opiera się na przydzieleniu każdej przestrzeni oddzielnego zadania, nawet pomimo pracy wymagającej większej liczby okien niż liczba fizycznie posiadanych monitorów. Wówczas przełączanie pomiędzy poszczególnymi oknami opiera się nie na zmianie pulpitu jak to było w przypadku AwesomeWM, lecz na wyświetleniu wybranego okna z pośród wielu innych dostępnych na danym ekranie w przestrzeni roboczej. Standardowym skrótem klawiszowym używanym do tego celu jest powszechnie znany alt + tab. Początkowo taki sposób pracy sprawiał wrażenie niekomfortowego i mniej wydajnego, lecz już po tygodniu mogłem poczuć się jak w domu. Zapewne w przyspieszeniu tego procesu spory udział miało zbindowanie skrótów klawiszowych do obsługi okien i przestrzeni roboczych na wzór AwesomeWM, gdzie domyślna konfiguracja jest bardzo przemyślana i wydajana, szczególnie dla wytrawnych użytkowników Vima.

Ostatecznie mogę powiedzieć, że trud związany ze zmianą menedżera okien opłacił się. Moje aktualne środowisko graficzne jak bardziej kompletne i dopracowane. Nie doświadczam już problemów w przypadku uruchamiania aplikacji napisanych w Javie. Pomimo tego, że AwesomeWM jest już dla mnie przeszłym doświadczeniem, nadal uważam iż jest to świetny menedżer okien pomimo kilku problemów z nim związanych. Co więcej, jeśli chciałbyś spróbować innego podejścia do zarządzania oknami na wzór tiling window managerów, AwesomeWM będzie idealnym wyborem.

Prelekcja „Exploity w praktyce”

Brak komentarzy

Wczoraj na ramach koła naukowego IT Security Group miałem okazję przeprowadzić prelekcję pt. „Exploity w praktyce”, której celem było przedstawienie działania exploitów u podstaw na przykładzie przepełnienia stosu. W nowym roku będzie kontynuacja tematu w postaci warsztatów, na których zaprezentowaną wiedzę wykorzystamy w praktyce.

Zarys prelekcji:

  • Powtórka assembly x86.
  • Pamięć uruchamianych programów.
  • Prosty stack overflow exploit.
  • Tworzenie shellcode i jego uruchomienie.
  • Wstrzykiwanie shellcode wykorzystując stack overflow.
  • Inne błędy umożliwiające exploitowanie. Jak sytuacja wygląda dzisiaj.
  • Analiza oprogramowania zamkniętego oraz otwartego. Techniki i narzędzia.

Slajdy z prezentacji: PDF

Zapraszam również do śledzenia IT Security Group na Facebook’u, aby być na bieżąco z organizowanymi wydarzeniami.

Jabber, OTR, GPG

Brak komentarzy

Podczas wieczornego przeglądania internetów dowiedziałem się o istnieniu OTR. Jest to interesująca alternatywa dla GnuPG w przypadku komunikatorów internetowych zapewniająca dodatkowo brak powiązania zaszyfrowanej wiadomości z nadawcą (nie można udowodnić takiego powiązania) oraz w przypadku utraty klucza, brak możliwości odszyfrowania wszystkich wiadomości poprzedzających wykorzystanie tego klucza (jest to możliwe ponieważ poszczególne wiadomości są szyfrowane tymczasowymi kluczami).

Niestety komunikator, którego dotychczas używałem (psi) nie zapewniał obsługi OTR, jednakże wystarczył niewielki upgrade do psi-plus, aby móc korzystać z OTR dostępnego za pomocą pluginu.

gpg-agent

Brak komentarzy

Czym jest gpg-agent?

gpg-agent zarządza dostępem do kluczy prywatnych. Używając gpg do podpisów cyfrowych oraz do odszyfrowania wiadomości zaszyfrowanych kluczem publicznym potrzebny jest dostęp do klucza prywatnego, który zazwyczaj jest zabezpieczony hasłem. Częste korzystanie z gpg, a tym samym częste wpisywanie hasła jest bardzo nieporęczne. Rozwiązaniem jest powyższy program dołączony w zestawie z gpg. gpg-agent może być również skonfigurowany do zarządzania kluczami ssh.

Uruchomienie gpg-agent’a

Uruchomienie gpg-agent wydaje się mało intuicyjne, jednakże nie jest trudne. Należy zwrócić uwagę aby uruchomić tylko jedną instancję. Osobiście uruchamiam go przy starcie X’sów, jednak nie będzie różnicy jeśli gpg-agent zostanie uruchomiony podczas startu systemu. Wówczas należy tylko zadbać o późniejsze ustawienie zmiennych środowiskowych, które są istotne aby aplikacje korzystające z gpg widziały gpg-agent’a.

Uruchomienie gpg-agent przy starcie serwera X opiera się na pliku .xinitrc. Przez poleceniem uruchamiającym WM należy dostać następujący kod:

pgrep gpg-agent || gpg-agent --daemon --write-env-file "${HOME}/.gpg-agent-info"

if [ -f "${HOME}/.gpg-agent-info" ]; then
    . "${HOME}/.gpg-agent-info"
    export GPG_AGENT_INFO
fi

Pierwsza linia uruchamia demona gpg-agent jeśli jeszcze nie ma takiego procesu. Opcja --write-env-file zapisuje kod ustawiający zmienną GPG_AGENT_INFO do pliku. W kolejnych liniach zmienna zostaje wyeksportowana, aby była widoczna dla wszystkich programów uruchomionych w WM.

Należy również w pliku .bashrc lub innym jemu odpowiadającym umieścić następujące linie:

GPG_TTY=$(tty)
export GPG_TTY

Konfiguracja

Konfiguracja gpg-agent’a opiera się na configu ~/.gnupg/gpg-agent.conf, ale wypada zacząć od dodania linii w pliku ~/.gnupg/gpg.conf wymuszającej korzystanie z agenta:

use-agent

gpg w wersji 2.x domyślnie korzysta z gpg-agent’a, jednakże dodatkowy wpis w niczym nie przeszkadza.

Plik konfiguracyjny gpg-agent.conf zawiera ustawienia, które odzwierciedlają jego opcje w manualu, wymaganiem jest korzystanie z nieskróconych nazw opcji oraz pominięcie początkowych dwóch minusów. Najważniejsze ustawienia znajdują się poniżej:

no-grab
pinentry-program /usr/bin/pinentry
default-cache-ttl 86400
max-cache-ttl 259200

Pierwsza linia jest opcjonalna, przydaje się jedynie gdy korzystamy z menedżera haseł, np. keepassx. pinentry-program określa program pinentry wykorzystywany do wpisywania haseł. Jest kilka popularnych wersji dostępnych z interfejsem GTK, Qt oraz curses. default-cache-ttl ustala maksymalny czas w sekundach przechowywania hasła od ostatniego jego użycia. Po przekroczeniu limitu czasu będzie konieczne ponowne podanie hasła przy kolejnym korzystaniu z klucza prywatnego. max-cache-ttl określa maksymalny czas przechowywania hasła od momentu jego podania.

Po wprowadzeniu zmian w pliku konfiguracyjnym, należy poinformować gpg-agent’a o zaistniałym fakcie:

gpg-connect-agent <<<RELOADAGENT

Ponowne wczytanie configu powoduje wyczyszczenie cache, dlatego będzie konieczne ponowne podanie hasła przy następnym odniesieniu do klucza prywatnego.

gpg-preset-passphrase

DISCLAIMER: Podanie hasła do klucza prywatnego za pomocą gpg-preset-passphrase, sprawia, że hasło jest pamiętane do momentu, w którym sami go nie usuniemy, bądź gpg-agent nie zostanie zrestartowany. Należy podchodzić ostrożnie do tego rozwiązania.

Domyślnie gpg-preset-passphrase nie znajduje się pod ścieżkami ustalonymi przez zmienną $PATH. Przeglądając pliki wykonywalne instalowane przez pakiet gnupg znajdziemy ścieżkę, pod którą znajduje się powyższy program. Ponadto należy zezwolić na korzystanie z niego w configu gpg-agent’a dodając linię:

allow-preset-passphrase

Za pomocą polecenia możemy podać hasła do kluczy prywatnych zanim jeszcze będą one potrzebne. Służą do tego następujące opcje:

gpg-preset-passphrase --passphrase PASSPHRASE --preset CACHE_ID

O ile PASSPHRASE znamy, gdyż jest to hasło, to ustalenie odpowiedniej wartości CACHE_ID jest momentem, w którym robi się trudniej. Należy uruchomić gpg-agent z flagami --debug 1024 --log-file gpg-agent.log a następnie analizować logi pojawiające podczas podawania hasła gdy potrzebne jest użycie klucza prywatnego. W liniach zawierających zwrot „GET_PASSPHRASE” znajdziemy CACHE_ID. Dostęp do klucza prywatnego może odbywać się zarówno po jego ID, jak również od ID odpowiadającego mu klucza publicznego, dlatego dla tego samego hasła możemy uzyskać dwa monity o podanie hasła, a tym samym dwie wartości CACHE_ID, które należy ustawić poleceniem gpg-preset-passphrase.

Szyfrowanie dla każdego dzięki GnuPG

1 komentarz

GnuPG umożliwia w prosty sposób korzystanie z siły nowoczesnej kryptografii w postaci szyfrowania oraz podpisów cyfrowych. Opiszę tutaj głównie zagadnienia dotyczące kryptografii asymetrycznej wykorzystującej dwa klucze: publiczny oraz prywatny. Za pomocą klucza prywatnego możemy podpisać dokument, a inni ludzie będą mogli zweryfikować podpis odpowiadającym kluczem publicznym. Z kolei w przypadku szyfrowania, treść zaszyfrowana z wykorzystaniem klucza publicznego może być odczytana tylko przy pomocy klucza prywatnego.

Korzystanie z kryptografii zapewnia naszym informacjom poufność (szyfrowanie) oraz integralność (podpisy cyfrowe). Ponadto techniki kryptograficzne umożliwiają uwierzytelnianie stron, jak również niezaprzeczalne potwierdzenie wykonanych działań. Wszystkie te aspekty są szeroko wykorzystywane w bankowości elektronicznej, uwierzytelnianiu użytkowników i zapewnianiu bezpieczeństwa ich danym. Wykorzystujemy techniki kryptograficzne na każdym kroku, również używając sieci mobilnych czy WiFi.

Wstępna konfiguracja GPG

Zanim wygenerujemy klucze, warto dodać na koniec pliku ~/.gnupg/gpg.conf poniższe opcje. Najważniejszą z nich jest wykorzystywanie mocniejszych funkcji hashujących zamiast domyślnej SHA1 oraz używanie domyślnie długiego id klucza.

keyid-format long
cert-digest-algo SHA512
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
verify-options show-uid-validity
list-options show-uid-validity

Generowanie kluczy

Generując parę kluczy należy wybrać odpowiednio mocne szyfrowanie, minimum RSA 2048 bitów. Wskazane jest również ustawienie „expiration date”, aby w przypadku zagubienia klucza prywatnego i braku „revocation certificate” para kluczy stała się automatycznie nieważna po przekroczeniu określonej daty. Istnieje możliwość przedłużania daty wygaśnięcia, więc nie stanowi to żadnego kłopotu. Ponadto koniecznie należy ustawić mocne hasło dla wygenerowanych kluczy. W przypadku ich przejęcia przez trzecią stronę, nie będzie wielkiego ryzyka nieuprawnionego wykorzystania naszych kluczy.

Parę kluczy można wygenerować za pomocą poniższego polecenia. Wystarczy tylko odpowiedzieć na kilka intuicyjnych pytań.

$ gpg --gen-key

Aby inni mogli łatwiej odnaleźć nasz klucz publiczny, warto go wgrać na serwer. Potrzebujemy znać tylko id klucza. Wywołanie polecenia $ gpg --list-keys wypisze wszystkie dostępne klucze publiczne. Id klucza znajduje się w linii oznaczonej pub po ukośniku, przed którym jest oznaczony rodzaj klucza. Następnie klucz publiczny możemy wyeksportować na serwer poleceniem:

$ gpg --send-keys ID_KLUCZA

W przypadku jeśli chcemy wysłać nasz klucz publiczny mailem w załączniku jako plik tekstowy, wyeksportujemy go poleceniem:

$ gpg --armor --export ID_KLUCZA >some_public_key.pub

Używanie GPG

Wiele programów na wbudowaną obsługę GPG, zarówno natywnie (np. gajim) jak i za pomocą pluginów (np. thunderbird). Posiadając wygenerowaną parę kluczy możemy odczytać wiadomości zaszyfrowane kluczem publicznym, które zostały do nas wysłane. Jeśli jednak to my chcemy wysłać zaszyfrowaną wiadomość, potrzebujemy klucz publiczny odbiorcy. Jeśli znamy id klucza, możemy go zaimportować z serwera:

$ gpg --recv-key ID_KLUCZA

Natomiast jeśli posiadamy plik z kluczem publicznym, można go analogicznie zaimportować:

$ gpg --import my_key.pub

Następnie nowo pobrane klucze publiczne powinniśmy podpisać własnym kluczem zanim zaczniemy je używać. Służy do tego kolejne polecenie:

$ gpg --edit-key ID_KLUCZA

Ten proces jest jednak interaktywny i dalej należy podać komendę sign, a przy wyjściu z edycji dla zachowania zamian komendę save. Tak przygotowane klucze możemy wykorzystywać w każdym programie wspierającym obsługę GPG i cieszyć się zapewnianą poufnością oraz integralnością informacji.

Dobre praktyki

$ gpg --refresh

Bazę kluczy publicznych powinno się regularnie odświeżać. Jest to istotne, ponieważ w przypadku gdy jakiś klucz zostanie unieważniony, dowiemy się o tym fakcie dopiero po odświeżeniu bazy kluczy. Proponuje nawet dodać wywołanie gpg --refresh do crona. Skoro jest już mowa o unieważnianiu kluczy. Co robić jeśli ktoś przejmie nasz klucz prywatny? W tym celu można wcześniej wygenerować „revocation certificate”, który służy do odwołania pary kluczy. Taki certyfikat należy trzymać w innym miejscu niż klucz prywatny, w końcu nie chcemy stracić ich obu na raz. Jednakże inni użytkownicy GPG dowiedzą się o fakcie odwołania certyfikatu dopiero po odświeżeniu ich bazy. Wygenerowanie takiego certyfikatu wykonujemy w następujący sposób:

gpg --output revoke.asc --gen-revoke ID_KLUCZA_PRYWATNEGO

GPG istnieje dzięki sieci zwanej „Web of Trust”. Aby wspierać tę idee, należy budować własną sieć zaufania, w której podpisujemy klucze publiczne innych osób oraz określamy stopień „zaufania” do nich. Służy temu interaktywne polecenie:

$ gpg --update-trustdb