Podpisywanie pakietów w Arch Linuksie, cz. 1: makepkg i repo-add

09 listopad 2011

Wpis jest swobodnym i raczej kiepskim tłumaczeniem Pacman Package Signing – 1: Makepkg and Repo-add autorstwa Allana McRae, zajmującego się rozwijaniem pacmana i toolchainem w Arch Linuksie.

W związku z rozwojem pacmana, powoli zbliżającym się do wydania 4.0.0, pomyślałem, że dobrze będzie napisać o lubianym przez wszystkich (i nie do końca kontrowersyjnym) temacie… podpisywaniu pakietów. Nie wszystko, co będzie opisane na ten temat będzie aktualne w chwili wydania nowego pacmana. Wpisy będą raczej przybliżać techniczne szczegóły implementacji podpisywania pakietów w pacmanie i jego narzędziach, nie zastosowania nowych funkcji w Arch Linuksie i potencjalne problemy.

Pierwszą rzeczą potrzebną do podpisywania pakietów i bazy danych repozytorium jest klucz PGP. Szczegóły dotyczące jego tworzenia można znaleźć wszędzie. Pod uwagę należy wziąć rodzaj klucza. Obecnie 2048 bitowy klucz RSA wydaje się standardem, 4096 bitowy jest prawdopodobnie zbyt duży i może spowolnić proces weryfikacji (co będzie odczuwalne na starszych procesorach).

Kiedy już posiada się klucz, można zacząć podpisywać pakiety używając makepkg. Implementacja jest całkiem prosta: jeżeli potrzebne jest podpisanie pakietu, makepkg wywołuje gpg --detach-sign na stworzonym pakiecie. Jeżeli w tle uruchomiony jest agent GPG, paczkujący nie będzie pytany o hasło. Oczywiście podpisywanie pakietów jest opcjonalne: odpowiada za nie opcja "sign" w BUILDENV w makepkg.conf, która może być nadpisana parametrami --sign oraz --nosign. Domyślnie, pakiety są podpisywane głównym kluczem GPG, co można zmienić za pomocą zmiennej GPGKEY (w makepkg.conf bądź powłoce) albo przekazując parametr --key do makepkg.

Zmiany w repo-add są równie proste. Gdy dodaje się pakiet do bazy repozytorium, repo-add sprawdza, czy istnieje podpis i jeżeli istnieje, dodaje go do wpisu pakietu w bazie, gotowego do wykorzystania przez libalpm. Oczywiście, samo podpisywanie pakietów to mało; potrzebna jest też możliwość podpisania samej bazy. Jest to możliwe dzięki opcjom analogicznym do tych z makepkg: -s lub --sign służącemu do podpisania bazy i --key do wskazania innego klucza. Dodatkowo, repo-add posiada także parametr, który służy do weryfikacji bazy przed jej aktualizacją. Jest to istotne z tego względu, że repo-add aktualizuje istniejącą bazę, zamiast tworzyć nową od zera.

Na marginesie, kilka innych poprawek bezpieczeństwa zostało wprowadzonych do repo-add i makepkg. Została dodana możliwość weryfikowania podpisów plików źródłowych (podziękowania dla Wielanda Hoffmanna). Podpisy sprawdzane są tylko wtedy, gdy w tablicy source zostaną wykryte pliki z rozszerzeniem .asc lub .sig. Można to sobie ułatwić dzięki uzupełnianiu basha

sources=($pkgname-$pkgver.tar.gz{,.sig})

dzięki czemu łatwo odczytać, które pliki są podpisane. Sprawdzanie może zostań pominięte za pomocą parametru --skippgpcheck lub --skipinteg (który pomija również sprawdzanie sum kontrolnych). Od teraz repo-add wspiera również dodatkowo sumy SHA256 (jako uzupełnienie MD5), ale póki co libalpm (a więc pacman także) w żaden sposób z tego nie korzysta.

Na sam koniec krótki komentarz z jakimi wyzwaniami mogą się spotkać dystrybucje korzystające z wyżej wymienionych narzędzi. Udogodnienia, które umożliwiają makepkg i repo-add sprawdzają się świetnie w przypadku repozytoriów, do których pakiety są budowane lokalnie, dodawane do bazy danych i dopiero wtedy wysyłane na serwer (tak jak w przypadku mojego repozytorium), ale nie przy repo rozwijanym przez wiele osób. Na przykład, jeżeli opiekun pakietu buduje pakiet na zdalnej maszynie, nie powinien przechowywać na niej swojego prywatnego klucza. Na chwilę obecną nie da się tego w łatwy sposób rozwiązać, więc budowanie i podpisywanie pakietów muszą być odseparowane: najpierw buduje się pakiet na serwerze, potem pobiera się go na własną maszynę i dopiero wtedy podpisuje (może się to zmienić w przyszłych wydaniach GnuPG, widziałem łatki stanowiące proof-of-concept zdalnego podpisywania). Podobnym problemem jest podpisywanie bazy; wymaga to umożliwienie każdemu opiekunowi dostępu do klucza, a więc albo braku hasła, albo udostępnieniu go. Skonfigurowane z należną uwagą, nie obniża to bardzo poziomu bezpieczeństwa - w ten sposób rozwiązało to kilka dystrybucji, ale nie jest to doskonałe rozwiązanie. Przez co ponownie wracamy do zdalnego podpisywania.