How to add IMQ patch to Ubuntu 10.04 Lucid Lynx

Those of you, who are having problems adding IMQ support to recent Ubuntu/Debian release, might consider this blog entry useful :)

I will not discuss what IMQ is and wheater is it good or bad – I will describe how to prepare kernel, iptables packages and how to deploy them to our Debian/Ubuntu system including taking care of making them immune to accidential system upgrade packages replacement.

Kernel package with IMQ support

Before we start – we need few packages that will might be required:

sudo aptitude install fakeroot build-essential kernel-package ncurses-dev

Now we are ready to start: first, we need our current kernel with distro patches. For desktop instance I would use -generic instead of -server:

apt-get source linux-image-2.6.32-22-server

Now, we download imq patch, apply it and compile kernel:

wget http://linuximq.net/patchs/linux-2.6.32-imq-test2.diff

cd linux-2.6.32/

patch -p1 < ../linux-2.6.32-imq-test2.diff

fakeroot time make-kpkg --initrd --append_to_version=imq linux-image

During the compilation process, make-kpkg script will discover unanswered features that we need to check as modules:

  "IMQ" target support (NETFILTER_XT_TARGET_IMQ) [N/m/?] (NEW) m

  IMQ (intermediate queueing device) support (IMQ) [M/y/?] (NEW) M

    IMQ behavior (PRE/POSTROUTING)

      1. IMQ AA (IMQ_BEHAVIOR_AA) (NEW)

    > 2. IMQ AB (IMQ_BEHAVIOR_AB) (NEW)

      3. IMQ BA (IMQ_BEHAVIOR_BA) (NEW)

      4. IMQ BB (IMQ_BEHAVIOR_BB) (NEW)

    choice[1-4?]: 2

    Number of IMQ devices (IMQ_NUM_DEVS) [16] (NEW)

Finally... in parent directory we will find:

linux-image-2.6.32.11+drm33.2imq_2.6.32.11+drm33.2imq-10.00.Custom_i386.deb

If everything went fine and our package is present - we can clean up compiled object files that will not be required anymore, recovering few GB of hard disk space:

./debian/rules clean

in case You forget to generate initrd file, it always might be generated by hand:

sudo -i

cd /boot/

mkinitramfs-kpkg -o initrd.img-2.6.32.11+drm33.2imq 2.6.32.11+drm33.2imq

update-grub

Iptables package with IMQ support

First, the patch - there is no iptables-1.4.4 imq patch available on linuximq.net I'm afraid. I have used iptables-1.4.6-imq patch and fixed it to compile with iptables-1.4.4.

Original patch can be found here.

Changes:

diff -Naurw iptables-1.4.6-imq.diff iptables-1.4.4-imq.diff
--- iptables-1.4.6-imq.diff	2010-01-27 11:53:22.000000000 +0100
+++ iptables-1.4.4-imq.diff	2010-05-08 13:18:21.000000000 +0200
@@ -43,7 +43,7 @@
 +
 +	switch(c) {
 +	case '1':
-+		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
++		if (xtables_check_inverse(optarg, &invert, 0, argv))
 +			xtables_error(PARAMETER_PROBLEM,
 +				   "Unexpected `!' after --todev");
 +		mr->todev=atoi(optarg);

Ready to use patch can be downloaded from here using command below:

wget http://nme.pl/pub/patches/iptables-1.4.4-imq.diff

Ok, now since we got patch ready, we can download iptables sources and compile our deb package:

apt-get source iptables
cd iptables-1.4.4

cp ../iptables-1.4.4-imq.diff debian/patch/1009-iptables-1.4.4-imq.diff
echo "1009-iptables-1.4.4-imq.diff" >>debian/patch/series

patch -p0 < ../iptables-1.4.4-imq.diff

dpkg-buildpackage -rfakeroot -uc -b

In case You are recompiling for some reason, one of the distro patches might fail - in this case edit debian/patches/series using Your favourite editor and comment out the following patch:

0902-docs-version-reference.diff    ->    #0902-docs-version-reference.diff

Operation above might be archived by in place edition of debian/patch/series using command below:

sed -i 's/^0902/#0902/' debian/patch/series

When compilation ends, You should get two packages in parent directory: iptables and iptables-dev.

Installation & freezing our changes

Now we can install our packages:

dpkg -i *.deb

It will install following packages:

iptables_1.4.4-2ubuntu2_i386.deb
linux-image-2.6.32.11+drm33.2imq_2.6.32.11+drm33.2imq-10.00.Custom_i386.deb
iptables-dev_1.4.4-2ubuntu2_i386.deb

You might also consider holding packages to be sure that they will not be replaced during standard regular-basis upgrade:

aptitude hold linux-image iptables iptables-dev

IMQ development, status and replacement discussion

It is not true that recent IMQ patches are not stable as I have read on some web pages. Since Jussi joined the IMQ team, problems I have had with 2.6.18-24 kernels have gone to past.

Kernel 2.6.28.9 with iptables 1.4.0 works perfectly stable taking care of huge loads of network traffic. I think that current patch described above will work the same (im making before-production tests currently and it seems to work fine).

On the other hand - IFB - which is meant as replacement for IMQ - as for me - it does not offer the same functionality for bridge environment I need... Of course - I might be mistaken. Thats why - if anyone of You have replaced IMQ with IFB for bridge devices with ingress and egress traffic shaping - I'm very interested in the solution.

Dodatkowy wolumin Ext3 jako plik na Fat32

Wielu użytkowników Linuxa ma zinstalowane dwa systemy operacyjne na notebookach i komputerach stacjonarnych. Nie jestem tutaj wyjątkiem. Jak już mam naklejkę licencyjną to przecież jej nie zdrapię ;) Mojemu Linuxowemu LVM’owi dałem 30 GB, Windowsowi również, a resztę stanowi wolumin FAT32. Kiedyś reszty nie było, ale cóż – musiałem kupić nowego twardziela z powodu podejścia producentów do „ekonomicznego” trybu pracy dysków twardych ;)

Co jednak można zrobić w sytuacji, gdy nagle potrzebujemy trochę więcej przestrzeni dyskowej z obsługą Linuxowych uprawnień? Odpowiedź jest prosta – możemy wykorzystać trochę wolnej przestrzeni FAT32, aby stworzyć sobie na nim wolumin ext3 w postaci zwykłego pliku.

Tworzenie woluminu ext3 w pliku

Aby utworzyć 15 GB wolumin ext3, przechodzimy w linii komend na dysk FAT32 i wydajemy polecenie:

cd /media/[nasz podmontowany wolumin FAT32]/

dd if=/dev/zero of=volume bs=1G count=15

Chwilkę to potrwa, ale ostatecznie powstaje wolumin:

15+0 przeczytanych recordów
15+0 zapisanych recordów
skopiowane 16106127360 bajtów (16 GB), 957,413 s, 16,8 MB/s

Sprawdzamy nasz plik:

du -sh volume
15G	volume

Wszystko się zgadza. Tak przygotowany plik należy teraz sformatować:

mke2fs -j volume

Zostaniemy zapytani, czy napewno chcemy formatować urządzenie które nie jest blokowe – potwierdzamy nasze intencje.

mke2fs 1.41.11 (14-Mar-2010)
volume nie jest specjalnym urządzeniem blokowym.
Kontynuować mimo to? (t,n) t
warning: Unable to get device geometry for volume
Etykieta systemu plików=
Typ OS: Linux
Rozmiar bloku=4096 (log=2)
Rozmiar fragmentu=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
983040 i-węzłów, 3932160 bloków
196608 bloków (5.00%) zarezerwowanych dla superużytkownika
Pierwszy blok danych=0
Maksymalna liczba bloków systemu plików=4026531840
120 grup bloków
32768 bloków w grupie, 32768 fragmentów w grupie
8192 i-węzłów w grupie
Kopie zapasowe superbloku zapisane w blokach:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

Zapis tablicy i-węzłów: zakończono
Tworzenie kroniki (32768 bloków): wykonano
Zapis superbloków i podsumowania systemu plików: wykonano

Ten system plików będzie automatycznie sprawdzany co każde 39 montowań
lub co 180 dni, zależnie co nastąpi pierwsze. Można to zmienić poprzez
tune2fs -c lub -i.

Montowanie woluminu plikowego

Teraz możemy już podmontować sobie tak stworzony wolumin:

sudo mkdir /mnt/tmp

sudo mount -o loop volume /mnt/tmp

df -h
System plików            rozm. użyte dost. %uż. zamont. na
/dev/mapper/sys-root   22G   11G  9,8G  52% /
[...]
/dev/loop0             15G  166M   14G   2% /mnt/tmp

I to wszystko – wolumin jest już gotowy do użycia :)

Wydajna i bezpieczna zdalna synchronizacja katalogów w Ubuntu

Będąc między innymi developerem, który pracuję na różnych maszynach, potrzebuje mieć swój kod dostępny na każdej stacji przy której zasiadam.

Przez jakiś czas sprawdzał się rozproszony system kontroli wersji. Wystarczyło robić push i pull poprzez ssh. Z czasem, kiedy np. miałem rozgrzebany kod, nie chciałem robić commita, tworzyć odgałęzienia – zacząłem pakować kod i przesyłać w tej postaci. Przez jakiś czas to znosiłem. Nie było to jednak zbyt przyjemne. Kilka drobnych zmian, a okazywało się, że muszę przesyłać kilka MB danych. Nie narzekałbym, gdybym nie miał w domu łącza niesymetrycznego :)

Z czasem, kiedy ilość projektów nad którymi pracowałem wzrosła, poczułem pewien dyskomfort (prawie jak pani Żanet Kaleta ;) ). Tym większy, że zdarzało mi się pracować nad aplikacją i biblioteką jednocześnie w ramach jednego projektu, gdzie oba kody miały swoje indywidualne drzewa kontroli wersji. Nawet jeśli jedno było w podgałęzi drugiego – Mercurial, bo z tego systemu kontroli wersji korzystam – zdawał sobie sprawe, że dany katalog należy już do innego drzewa kontroli wersji.

Co począć w takiej sytuacji? Rozwiązanie przypadkowo podsunął kolega, jednocześnie przypominając mi jak to rozwiązanie efektywnie spisywało się w dystrybucji Gentoo, z której miałem okazję jakiś czas temu przez dłuższy nawet czas korzystać. Chodzi oczywiście o rsync’a.

Niżej przedstawioną metodę praktykuję już od jakiegoś czasu. Synchronizuję się do/z jednej centralnej maszyny. Synchronizuję katalog zawierający 300 MB kodu, źródeł grafik, duże drzewa hg. Nie zdarzyło mi się jeszcze, mimo wykonywania dość drastycznych zmian w podstrukturze, żeby trwało to dłużej niż wcześniej trwało przesłanie spakowanej paczki o rozmiarze 1 czy 2 MB.

Załóżmy, że w katalogu domowym /home/user/dev mam swoje repozytorium. Na maszynie centralnej, dane trzymane będą w katalogu /srv/archive/dev.

Aby wysłać dane z notebooka, na serwer, wydajemy polecenie:

rsync -azv --delete -e ssh /home/user/dev MASZYNA_CENTRALNA:/srv/archive

Aby pobrać dane z serwera na notebooka wydajemy:

rsync -azv --delete -e ssh MASZYNA_CENTRALNA:/srv/archive/dev /home/user

Jeśli nie jesteśmy pewni, czy efekty komendy będą zadowalające, warto dodać parametr --dry-run, który sprawi, że zostanie nam wyświetlona jedynie lista zmian, a nic tak naprawdę nie zostanie zmienione.

Myślę, że warto poświęcić kilka minut aby wewnątrz swojej biblioteczki stworzyć katalog sync, a w nim dwa skrypty sendrecv które będą wykonywać te czynności, a gwarantuje, że w zamian zaoszczędzicie znacznie więcej czasu w przyszłości.

Generowanie losowych haseł w Ubuntu

Hasła, każdy ma ich przynajmniej kilka w pamięci, ale życie uczy, że nie warto stosować takich samych do autoryzacji bankowych, kont na naszej-klasie, gadu czy na roota ;)

Chciałbym Wam przedstawić bardzo proste narzędzie z którego korzystam z powodzeniem od kilku lat – nazywa się apg (Automated Password Generator) i służy do wygodnego generowania haseł.

Narzędzie oferuje dwa rodzaje haseł – mniej zaawansowane, ale znacznie łatwiejsze do zapamiętania dla osób znających język angielski oraz bardziej zaawansowane (zawierające poza literami dodatkowe krzaczki). Za pomocą dodatkowych parametrów możemy wpłynąć na zawartość dużych, małych liter lub liczb.

Instalacja jest standardowa:

aptitude install apg

Help

Wygląda tak:

apg -h

apg   Automated Password Generator
Copyright (c) Adel I. Mirzazhanov

apg   [-a algorithm] [-r file]
[-M mode] [-E char_string] [-n num_of_pass] [-m min_pass_len]
[-x max_pass_len] [-c cl_seed] [-d] [-s] [-h] [-y] [-q]

-M mode         new style password modes
-E char_string  exclude characters from password generation process
-r file         apply dictionary check against file
-b filter_file  apply bloom filter check against filter_file
(filter_file should be created with apgbfm(1) utility)
-p substr_len   paranoid modifier for bloom filter check
-a algorithm    choose algorithm
1 - random password generation according to
password modes
0 - pronounceable password generation
-n num_of_pass  generate num_of_pass passwords
-m min_pass_len minimum password length
-x max_pass_len maximum password length
-s              ask user for a random seed for password
generation
-c cl_seed      use cl_seed as a random seed for password
-d              do NOT use any delimiters between generated passwords
-l              spell generated password
-t              print pronunciation for generated pronounceable password
-y              print crypted passwords
-q              quiet mode (do not print warnings)
-h              print this help screen
-v              print version information

A teraz praktyka

Wystarczy znajomość kilku parametrów:

Generowanie 5-ciu haseł: -n

apg -n 5

ookyopIack
berpAxEr
DusEphac
yomlipvog~
weehacir

Generowanie haseł o minimalnej długości: -m

apg -n 5 -m 10

BlysBicWeo
fefimvesBa
CuAtecHeoc
crejvibred
CynfiShnoi

Generowanie haseł z wymową (aby łatwiej było je zapamiętać): -t

apg -n 5 -m 10 -t

WaigJocWig (Waig-Joc-Wig)
Geagsyinau (Geags-yin-au)
Cunefkalt9 (Cun-ef-kalt-NINE)
Pemyidyish (Pem-yid-yish)
agsirasuk7 (ags-ir-as-uk-SEVEN)

Generowanie bardziej zaawansowanych haseł: -a 1

apg -a 1 -n 5 -m 10

N;%5RWNM|B
$48+HGvlac
{@M!yPMa-y
jyI<{\3;{i
t)nThAUw?~

Skrypt ten jest bardzo przydatny, kiedy musimy wygenerować komuś hasło ponieważ nie jest w stanie sobie czegoś wymyślić (i pewnie wymyślił by ostatecznie nazwę swojego psa lub imię małżonki) lub stawiamy następny z kolei serwer mysql, a nie chcemy zostawiać takiej dziury jak nie tak dawno ktoś z ekipy Wykopu, kiedy to wykradziono im hasła użytkowników.

Wirtualni userzy ftp w Ubuntu

Poniżej znajduje się instrukcja opisująca jak skonfigurować krok po kroku bardzo prosty i bezpieczny serwer ftp obsługujący wirtualne konta – użytkowników, których fizycznie nie ma zdefinowanych w systemie. Jako serwer ftp wykorzystany zostanie vsftpd (very secure ftp daemon).

Założenia: potrzebujemy prostego serwera ftp do którego możemy zdefiniować kilku użytkowników, gdzie każdy ma dostęp do tego samego katalogu (opis jak należy to skonfigurować, aby każdy użytkownik miał swój własny katalog znajduje się we wpisie źródłowym, którego adres zamieściłem na końcu wpisu).

Najpierw instalujemy serwer ftp oraz narzędzie do obsługi bazy użytkowników:

aptitude install vsftpd db4.2-util

Tworzymy katalog ftp:

mkdir /home/ftp
chown ftp:ftp /home/ftp

(aplikacja domyślnie podczas instalacji zakłada katalog /srv/ftp)

Podmieniamy plik /etc/vsftpd.conf na następujący:

# /etc/vsftpd.conf
listen=YES
listen_ipv6=NO
#listen_port=2121

anonymous_enable=NO
local_enable=YES
guest_enable=YES

virtual_use_local_privs=YES
pam_service_name=vsftpd-virtual

guest_username=ftp

local_root=/home/ftp

local_umask=022
write_enable=YES
hide_ids=YES
dirmessage_enable=YES

use_localtime=YES
xferlog_enable=YES
log_ftp_protocol=YES
setproctitle_enable=YES

connect_from_port_20=YES

chroot_local_user=YES
chroot_list_enable=NO
secure_chroot_dir=/var/run/vsftpd/empty

W razie potrzeb – zmieniamy ustawienia – np. jeśli chcemy zmienić port na którym aplikacja ma nasłuchiwać – usuwamy znak komentarza z linii listen_port i zmieniamy numer portu.

Przygotowujemy plik /etc/pam.d/vsftpd-virtual:

auth required pam_userdb.so db=/etc/vsftpd-virtual
account required pam_userdb.so db=/etc/vsftpd-virtual

Przygotowujemy plik z użytkownikami i hasłami /etc/vsftpd-konta:

uzytkownik1
haslo1
uzytkownik2
haslo2

umieszczamy hasła w bazie:

db4.2_load -T -t hash -f /etc/vsftpd-konta /etc/vsftpd-virtual.db

a następnie restartujemy usługę:

service vsftpd restart

Możemy już zalogować się do serwera, przykładowo:

lftp -p 2121 -u uzytkownik1,haslo1 localhost
lftp test1@localhost:~> ls
lftp test1@localhost:/>

Źródło: http://linuxforfun.net/2008/04/05/vsftpd-virtual-users/

ACL dla plików i katalogów w Ubuntu

Unixowy system uprawnień dla plików i katalogów został naprawdę dobrze przemyślany i świetnie się sprawdza. Każdy jednak prędzej czy później może trafić na sytuację, w której możliwość stosowania rozszerzonych uprawnień dałaby znacznie większą swobodę i wygodę.

Kogo temat może zainteresować?

Wydaje mi się, że użytkownicy zwykłych desktopów nie będą ACL’i potrzebować. Jeśli jednak jakiś developer umieszcza przykładowo serwer z repozytorium u siebie albo jest administratorem jakiegoś serwera – myślę, że warto się zapoznać z poniższą tematyką.

Krok po kroku

Access Control Lists (ang. ACL), czyli listy kontroli dostępu są w jądrze Ubuntu wkompilowana domyślnie już od jakiegoś czasu. Niewiele stoi zatem nam na przeszkodzie, aby aktywnie zacząć z nich korzystać. ACL należy traktować jako rozszerzenie Unixowego systemu uprawnień plików i katalogów, dlatego zestaw komend takich jak chown czy chmod nadal obowiązuje.

Czego zatem potrzebujemy? Musimy uświadomić nasz system, że będziemy wykorzystywać ACL’e dla konkretnych systemów plików. No i przede wszystkim – musimy mieć narzędzia do zarządzania ACL’ami oraz wiedzieć, jak się ich używa :)

Zatem po kolei.

Sprawdźmy, czy mamy narzędzia do obsługi ACL’i. Narzędzia nazywają się setfacl, getfacl oraz chacl.

desktop repos # getfacl
Program getfacl nie jest obecnie zainstalowany.  Można go zainstalować wpisując:
apt-get install acl
getfacl: command not found
desktop repos #

Więc go sobie instalujemy:

sudo aptitude install acl

Spróbujmy ustawić jakąś rozszerzoną listę dostępu. Przejdźmy do katalogu domowego, załóżmy katalog test oraz nadajmy uprawnienia rwx użytkownikowi nobody.

cd
mkdir test
setfacl -R -m u:nobody:rwX test
setfacl: test: Operation not supported

Komunikat Operation not supported oznacza nic innego jak brak obsługi ACL w systemie plików. Jeśli nasz katalog domowy znajduje się na odrębnym systemie plików home, możemy aktywować obsługę ACL komendą:

sudo mount -o remount,acl /home

Teraz ustawianie rozszerzonych uprawnień powinno już działać. Ponowne wydanie komendy setfacl nie powinno już zwrócić błędu.

Przy okazji, możemy zobaczyć jak wyglądają uprawnienia naszego katalogu:

nme@desktop ~ $ setfacl -R -m u:nobody:rwX test
nme@desktop ~ $ ls -lad test/
drwxrwxr-x+ 2 nme nme 4096 2009-12-30 14:29 test/
nme@desktop ~ $ getfacl test
# file: test
# owner: nme
# group: nme
user::rwx
user:nobody:rwx
group::r-x
mask::rwx
other::r-x

Warto zwrócić uwagę na uprawnienia zwracane komendą ls -l: drwxrwxr-x+ – na końcu listy uprawnień znajduje się znak + oznaczający rozszerzone informacje. Takie uprawnienia możliwe są do odczytu za pośrednictwem getfacl co też uczyniłem powyżej. Wynik komendy jest dość czytelny.

Wracając do wydanej komendy:

setfacl -R -m u:nobody:rwX test

Co po naszemu brzmi – rekursywnie zmodyfikuj uprawnienia dla użytkownika nobody dla katalogu test ustawiając uprawnienia rwx dla katalogów i rw dla plików.

Dziecinne proste. Rozbudujmy komendę:

setfacl -Rm u:nobody:rwX,d:u:nobody:rwX test

(pierwsza część jest tak naprawde zbędna, ponieważ uprawnienia dla użytkownika już ustawiliśmy, ale chciałem przedstawić sposób w jaki możemy łączyć uprawnienia w obrębie jednej komendy)

d:u:... można zapisać również jako default:u:... co oznacza, że dla nowo zakładanych plików/katalogów, takie atrybuty mają być domyślnie dodawane.

Ważna sprawa, na koniec

Aby używać list dostępu, aktywowaliśmy opcję acl poprzez przemontowanie systemu pliku. Niestety, po restarcie, system plików nie będzie już obsługiwał list dostępu.

Co zatem zrobić?

Jeśli chcemy, aby nasz system plików pamiętał o tym, że ma obsługiwać rozszerzone listy dostępu, w pliku /etc/fstab należy to zaznaczyć, acl jako opcję dla naszego systemu plików:

/dev/mapper/desktop-home /home           ext3    defaults,acl        0       2

Więcej informacji, wraz z przykładami znaleźć możecie na stronach manuala komend do obsługi acl które przedstawiłem w tym tekscie.

Ailurus: wygodny tuning Ubuntu

Niestrudzony Adrian Nowak, na blogu Ubucentrum zamieścił wpis Ailurus – ułatwi początki z Linuksem.

Czym jest Ailurus? To wygodny interfejs produkcji „Thrusted Digital Technology Lab.” z siedzibą w Chinach, do tuningu systemu i obsługi systemu :)

Faktycznie, narzędzie jest faktycznie bardzo ciekawe. Nie znajduje się jednak w standardowym repozytorium. Dlatego myślę, że warto wspomnieć, w jaki sposób najwygodniej je zainstalować.

Nie zalecałbym metody którą proponuje Adrian – czyli instalacji pojedynczej paczki z serwisu GetDeb.net.

Instalowanie pojedynczych paczek jest zaśmiecaniem systemu.

Instalacja

W Ubuntu 9.10 możemy w wygodny sposób dodawać repozytoria, które sprawią, że jeśli pojawi się nowa wersja pakietu, przy aktualizacji systemu, pakiet zostanie również uaktualniony.

# przechodzimy na roota
sudo -i

# dodajemy nowe repozytorium
add-apt-repository ppa:ailurus

# aktualizujemy wykaz aktualnych pakietów
aptitude update

# instalujemy pakiet
aptitude install ailurus

Aplikacja, po instalacji jest dostępna poprzez Programy / Narzędzia systemowe / Ailurus.

Co oferuje nam pakiet?

  • Tips and tricks – warto przeglądnąć – informacje jak za pomocą gconf-editora wykonać tuning naszego Gnome’a
  • Wygodny frontend do konfiguracji i sprawdzenia parametrów systemu (typ procesora, ilość pamięci, czy procesor jest 64-bitowy, rodzaj karty graficznej i sieciowej)
  • Skróty do instalacji różnych przydatnych aplikacji, których nazwy należałoby w innym wypadku pamiętać albo trzeba byłoby się bardziej narobić, żeby je zainstalować
  • Ustawienia systemowe – innymi słowy – edycja plików konfguracyjnych, modifykacja menu kontekstowego Nautilusa itp
  • i wiele innych…

Kiedy można sobie ułatwić życie, warto to robić :)

Infrastruktura PKI na podstawie SSH

openssh_logoInfrastruktura kluczy publicznych (ang. Public Key Infrastructure, w skrócie PKI) jest podstawą współczesnej kryptografii. Miałem już styczność z wieloma osobami z branży IT, które kompletnie nie czuły o co właściwie w tym chodzi.Myślę, że poniższy tekst napewno się komuś przyda oraz, że warto mu poświęcić 5 minut. Spróbuję się maksymalnie streścić ;)

Klucze symetryczne i niesymetryczne

Większość szyfrowanych kanałów transmisji wykorzystuje jednocześnie klucze niesymetryczne jak i symetryczne.

Zaletą kluczy symetrycznych (takich jak AES, Blowfish czy DES) jest szybkość szyfrowania/deszyfrowania przy stosunkowo niskim obciążeniu procesora.

Wadą kluczy symetrycznych jest etap nawiązania transmisji. Jeśli oba komputery nie posiadają tego samego klucza do szyfrowania/deszyfrowania wiadomości – klucz taki musiałby być wysłany z jednego z nich do drugiego drogą nieszyfrowaną. Taką wymianę klucza można byłoby łatwo podsłuchać. Następnie, korzystając z tak zdobytego klucza – można podsłuchać resztę transmisji (taki atak nosi nazwę Man In The Middle).

Dlatego właśnie pojawiły się klucze niesymetryczne (np. stosowany standardowo w protokole ssh – algorytm RSA). Klucz niesymetryczny składa się z dwóch części – publicznej i prywatnej. Posiadacz części publicznej klucza jest w stanie zaszyfrować wiadomość. Posiadacz klucza prywatnego – może taką wiadomość odszyfrować. Proste. Dodatkowo – na podstawie klucza publicznego jesteśmy w stanie zweryfikować odcisk klucza (fingerprint) – jeśli się zgadza, wiemy, że rozmawiamy z właściwym serwerem.

Klucze w praktyce

Serwery Linuxowe na których pracuje usługa ssh mają również wygenerowane swoje klucze. Autentykacja może być różnoraka, jednak do najpopularniejszych należą – para użytkownik-hasło oraz łączenie się z wykorzystaniem kluczy.

Wykorzystanie haseł jest proszeniem się o kłopoty. Warto przesiąść się na klucze. Jak to zrobić?

Wygenerujmy sobie klucz. W obecnych czasach warto zaznaczyć, że chcemy mieć klucz 4096-bitowy, będzie się generował dłużej, ale będzie bezpieczniejszy. Warto też ustawić hasło dla klucza.

nme@notebook ~ $ ssh-keygen -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/nme/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/nme/.ssh/id_rsa.
Your public key has been saved in /home/nme/.ssh/id_rsa.pub.
The key fingerprint is:
12:30:87:ca:06:81:d8:5a:32:41:81:4c:3a:74:33:a9 nme@notebook
The key's randomart image is:
+--[ RSA 4096]----+
|XO.++..          |
|X.+.++           |
|oB..  .          |
|.E+    .         |
| .    . S        |
|       .         |
|                 |
|                 |
|                 |
+-----------------+
nme@notebook ~ $

W katalogu .ssh pojawiły się dwa pliki id_rsa – będący naszym kluczem prywatnym oraz id_rsa.pub – czyli klucz publiczny.
Klucza publicznego nie trzeba specjalnie strzec. Ważne, aby nasz klucz prywatny nie dostał się w cudze ręce.

Po co ten obrazek w ASCII? Abyśmy nie musieli weryfikować znak po znaku naszych kluczy. Jeśli chcemy odczytać fingerprint klucza, wydajemy komendę:

ssh-keygen -l

Jeśli chcemy zobaczyć odcisk wraz z obrazkiem ASCII – wydajemy:

ssh-keygen -lv

Okej. Powiedzmy, że mamy klucze i serwer na który chcielibyśmy się łączyć za ich pomocą. Musimy umieścić zawartość naszego klucza publicznego w pliku .ssh/authorized_keys na serwerze docelowym. Możemy to zrobić komendą:

nme@notebook ~ $ ssh-copy-id serwer:
The authenticity of host 'serwer (x.x.x.x)' can't be established.
RSA key fingerprint is fe:2b:6b:71:6f:81:ef:07:74:89:72:e7:ef:ab:f8:62.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'serwer,x.x.x.x' (RSA) to the list of known hosts.
Password:
nme@notebook ~ $

teraz możemy już normalnie się zalogować:

nme@notebook ~ $ ssh serwer
nme@serwer ~ $

W pliku .ssh/authorized_keys możemy trzymać dowolną ilość kluczy.

Dobrą praktyką jest generowanie kluczy prywatnych na każdej stacji roboczej z której łączymy się na inne maszyny. W wypadku gdy np. ktoś ukradnie nam jedną z tych maszyn – wystarczy usunąć dane klucze z plików authorized_keys serwerów, do których mamy dostęp.

Skoro już opanowaliśmy klucze – warto wyłączyć autoryzację do naszych serwerów za pośrednictwem par użytkownik-hasło. Robimy to edytując plik /etc/ssh/sshd_config – weryfikujemy ustawienia:

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no

Restart sshd we współczesnych Ubuntu czy RedHatach wykonujemy komendą:

sudo service ssh restart

Kiedy wyłączymy już logowanie na pary użytkownik-hasło i pozostawimy jedynie logowanie na klucze:

nme@notebook ~ $ ssh serwer
Permission denied (publickey).
nme@notebook ~ $

Gdzie poza SSH stosowane są jeszcze klucze?

Infrastruktura kluczy publicznych (PKI) stosowana jest również przykładowo w HTTPS czy w sieciach bezprzewodowych – WPA2 (AES). Klucze niesymetryczne stosowane są do nawiązania transmisji między klientem i serwerem – celem wymiany klucza symetrycznego, a następnie transmisja jest już oparta o klucz symetryczny.

Znajomość ogólnych zasad działania PKI jest bardzo praktyczna również w przypadku, jeśli przymierzamy się do wykorzystania OpenPGP czy certyfikatów SSL, które możemy traktować jak wyższe stopnie zaawansowania ;)

Wyłączenie użytkownikowi MOTD na Ubuntu

Tematyka niniejszego wpisu jest, można powiedzieć wręcz banalna, ale myślę, że to trick warty poznania lub przypomnienia. Nie dotyczy tylko i wyłącznie dystrybucji Ubuntu, ale w zasadzie wszystkich Linuxów.

Jeśli logujesz się po ssh na inny komputer, wyświetlana jest zawartość Message Of The Day (/etc/motd). Jeśli nie chcesz tego widzieć, w swoim katalogu domowym wystarczy utworzyć plik o nazwie .hushlogin, wersja copy & paste:

cd
touch .hushlogin

(polecenie cd bez parametrów to kolejny trick – sprawia, że zostajemy przeniesieni do naszego katalogu domowego)

Efekt

Zilustrowałem poniżej:

nme@desktop ~ $ ssh laptop
Linux laptop 2.6.31-14-generic-pae #48-Ubuntu SMP Fri Oct 16 15:22:42 UTC 2009 i686

To access official Ubuntu documentation, please visit:

http://help.ubuntu.com/

  System information as of Fri Nov  6 20:56:41 CET 2009

  System load: 0.16              Memory usage: 18%   Processes:       155
  Usage of /:  7.1% of 35.51GB   Swap usage:   0%    Users logged in: 1

  Graph this data and manage this system at https://landscape.canonical.com/

Last login: Fri Nov  6 20:55:19 2009 from desktop.local
nme@laptop ~ $ touch .hushlogin
nme@laptop ~ $ logout
Connection to laptop closed.
nme@desktop ~ $ ssh laptop
nme@laptop ~ $ 

Proste, aczkolwiek przydatne :)

Wprowadzenie do systemu kontroli wersji Mercurial

mercurialPoniższy tekst jest jedynie wprowadzeniem do pracy z Mercurialem. Osoby które chcą pogłębić swoją wiedzę w zakresie tego tematu – zachęcam do przeczytania darmowej książki dostępnej w Internecie – Mercurial: The Definitive Guide.

Aby pracować na Mercurialu musimy go najpierw zainstalować. Dla systemu Windows Mercurial jest jedną wygodną do zainstalowania paczką. Informację jak zalecam to zrobić pod Ubuntu, zamieściłem tu: Instalacja Mercurial z GUI TortoiseHG pod Ubuntu 9.04.

Konfiguracja wstępna

Zanim rozpoczniemy pracę z Mercurialem, należy w swoim katalogu domowym utworzyć plik .hgrc w którym konfigurujemy swojego użytkownika. Plik ten powinien zawierać następującą treść:

[ui]
username = Imie Nazwisko < konto@domena.pl >

Pod Linuxem lub Unixem warto również ustawić zmienną środowiskową EDITOR wskazującą na nasz
ulubiony edytor. W moim wypadku, w pliku .bashrc w katalogu domowym
musiałem dodać na końcu linijkę:

export EDITOR="vim"

W tym momencie możemy już przystąpić do pracy.

Tworzenie repozytorium

Załóżmy, że jesteśmy w katalogu testy.

Utwórzmy w nim plik notatki.txt zawierający jedną linijkę tekstu:

To są moje notatki

Utwórzmy też katalog dokumenty, a w nim umieśćmy plik do-zrobienia.txt zawierający następującą treść:

[ ] Zrobić przelewy za październik
[ ] Podać do Energetyki stan licznika

Struktura plików i katalogów wygląda zatem następująco:

user@host testy $ ls
dokumenty  notatki.txt
user@host testy $ ls dokumenty/
do-zrobienia.txt

Możemy w tym momencie utworzyć sobie repozytorium Mercuriala. Przechodzimy zatem do katalogu testy i wydajemy komendę:

user@host testy $ hg init

W katalogu powinien pojawić się podkatalog .hg

Co teraz możemy zrobić? Dostępne komendy pojawią się po wydaniu komendy hg bez parametrów:

user@host testy $ hg
Mercurial Distributed SCM

basic commands:

 add        add the specified files on the next commit
 annotate   show changeset information by line for each file
 clone      make a copy of an existing repository
 commit     commit the specified files or all outstanding changes
 diff       diff repository (or selected files)
 export     dump the header and diffs for one or more changesets
 forget     forget the specified files on the next commit
 init       create a new repository in the given directory
 log        show revision history of entire repository or files
 merge      merge working directory with another revision
 parents    show the parents of the working directory or revision
 pull       pull changes from the specified source
 push       push changes to the specified destination
 remove     remove the specified files on the next commit
 serve      export the repository via HTTP
 status     show changed files in the working directory
 update     update working directory
 view       start interactive history viewer

use "hg help" for the full list of commands or "hg -v" for details

Jeśli chcemy uzyskać większą ilość komend, należy uruchomić polecenie
hg help.

Zobaczmy status naszego katalogu. Możemy napisać hg status, jednak można też zastosować skróconą wersję komendy:

user@host testy $ hg st
? dokumenty/do-zrobienia.txt
? notatki.txt

Widzimy, że system Mercurial widzi dwa pliki. Przed ich nazwami figuruje znak pytajnika, co oznacza, że Mercurial nie do końca wie, co to za pliki.

Dodawanie plików do repozytorium

Do dodawania plików do repozytorium służy komenda hg add [nazwa pliku], przy czym nazwa pliku jest parametrem opcjonalnym. Jeśli jej nie podamy – Mercurial doda wszystkie nieznane pliki w naszym katalogu i podkatalogach do repozytorium.
Dodajmy nasze pliki do repozytorium.

user@host testy $ hg add
adding dokumenty/do-zrobienia.txt
adding notatki.txt

podglądając status widzimy:

user@host testy $ hg st A dokumenty/do-zrobienia.txt A notatki.txt

Zatwierdzanie i weryfikowanie zmian

możemy w tym momencie zatwierdzić zmiany:

user@host testy $ hg commit

W tym momencie uruchomi się nam edytor w którym uzupełniamy pierwszą linię. Pozostałe zostały zasugerowane przez Mercuriala:

utworzone repozytorium

HG: Enter commit message.  Lines beginning with 'HG:' are removed.
HG: Leave message empty to abort commit.
HG: --
HG: user: Imie Nazwisko 
HG: branch 'default'
HG: added dokumenty/do-zrobienia.txt
HG: added notatki.txt

Jeśli chcemy którąś z tych linii pozostawić, powinniśmy usunąć HG: sprzed wpisu.

Po zapisaniu pliku, jeśli Mercurial znajdzie choć jedną linię opisu (czyli w naszym wypadku tekst „utworzone repozytorium”), zapisze to jako nową wersję (revision).

Możemy podejżeć zmiany:

user@host testy $ hg st
user@host testy $

Jak widać, nie ma żadnych. Zobaczmy zatem historię:

user@host testy $ hg log
changeset:   0:996ae301b615
tag:         tip
user:        Imie Nazwisko 
date:        Tue Oct 13 08:40:12 2009 +0200
summary:     utworzone repozytorium

user@host testy $

Dokonajmy jakiejś zmiany w pliku dokumenty/do-zrobienia.txt, powiedzmy, że teraz wygląda tak:

[x] Zrobić przelewy za październik
[ ] Podać do Energetyki stan licznika

Sprawdzając status widzimy:

user@host testy $ hg st
M dokumenty/do-zrobienia.txt
user@host testy $

Możemy też podejżeć co zostało zmienione:

user@host testy $ hg diff
diff -r 996ae301b615 dokumenty/do-zrobienia.txt
--- a/dokumenty/do-zrobienia.txt	Tue Oct 13 08:40:12 2009 +0200
+++ b/dokumenty/do-zrobienia.txt	Tue Oct 13 08:46:21 2009 +0200
@@ -1,2 +1,2 @@
-[ ] Zrobić przelewy za październik
+[x] Zrobić przelewy za październik
 [ ] Podać do Energetyki stan licznika
user@host testy $

Zatwierdzę teraz zmiany, sprawdzę status i historię:

user@host testy $ hg commit
user@host testy $ 

user@host testy $ hg st
user@host testy $ 

user@host testy $ hg log
changeset:   1:155c93da6b65
tag:         tip
user:        Imie Nazwisko 
date:        Tue Oct 13 08:48:01 2009 +0200
summary:     aktualizacja

changeset:   0:996ae301b615
user:        Imie Nazwisko 
date:        Tue Oct 13 08:40:12 2009 +0200
summary:     utworzone repozytorium

user@host testy $

Usuwanie plików z repozytorium

Teraz usunę plik notatki.txt:

user@host testy $ hg remove notatki.txt
user@host testy $ ls
dokumenty
user@host testy $

Zatwierdzę zmiany i zobaczę historię. Ograniczę sobie przy okazji historię do dwóch najaktualniejszych zmian:

user@host testy $ hg commit
user@host testy $ hg log -l 2
changeset:   2:ec95d15664fb
tag:         tip
user:        Imie Nazwisko 
date:        Tue Oct 13 08:51:36 2009 +0200
summary:     usunięte notatki

changeset:   1:155c93da6b65
user:        Imie Nazwisko 
date:        Tue Oct 13 08:48:01 2009 +0200
summary:     aktualizacja

user@host testy $

Zdecydowałem jednak, że przywrócę plik notatki. Cofnę zatem ostatniego commita komendą rollback, zobaczę jaki
jest status i przywrócę plik notatki.txt:

user@host testy $ hg rollback
rolling back last transaction
user@host testy $ hg log
changeset:   1:155c93da6b65
tag:         tip
user:        Imie Nazwisko 
date:        Tue Oct 13 08:48:01 2009 +0200
summary:     aktualizacja

changeset:   0:996ae301b615
user:        Imie Nazwisko 
date:        Tue Oct 13 08:40:12 2009 +0200
summary:     utworzone repozytorium

user@host testy $ hg st
R notatki.txt
user@host testy $ ls
dokumenty
user@host testy $ hg revert notatki.txt
user@host testy $ ls
dokumenty  notatki.txt
user@host testy $

Myślę, że jako wprowadzenie, taki opis wystarczy :)

Następnya strona »