_____ _   _ _    _    ___      _
 / ____| \ | | |  | |  / / |    (_)
| |  __|  \| | |  | | / /| |     _ _ __  _   ___  __
| | |_ | . ` | |  | |/ / | |    | | '_ \| | | \ \/ /
| |__| | |\  | |__| / /  | |____| | | | | |_| |>  <
 \_____|_| \_|\____/_/   |______|_|_| |_|\__,_/_/\_\

Własne repozytorium dla pakietów Debiana

We wcześniejszym artykule zajmowaliśmy się tworzeniem własnych pakietów dla dystrybucji GNU/Linux Debian. Na końcu tego materiału znajduje się opis testowej metody instalacji utworzonych przez nas paczek .deb. Nie było tam ani słowa o tym jak pakiet znalazł się na komputerze docelowym, w ogóle nie było również zaznaczone, że autor zmienił komputer. Oczywiste jest, że mając takie narzędzie jak APT, możemy pakiety przenosić lub dystrybuować w najbardziej wygodny dla nas sposób. Jednakże pakiety tworzyliśmy w konkretnym celu, aby mieć jak najlepszy sposób instalacji oraz kontroli nad wytwarzanym przez nas oprogramowaniem na innych systemach niż system jego twórcy. No właśnie, kontroli. Program APT zapewnia nam najlepszy sposób kontroli nad oprogramowaniem w całym systemie, za pomocą prostych poleceń możemy instalować, usuwać oprogramowanie czy aktualizować (o ile pojawiły się nowe wersje) już obecne pakiety w systemie. Czy na etapie korzystania programu APT musimy martwić się o dostarczenie pakietów do systemu? Jeśli komputer ma dostęp do sieci internet to nie. Systemy dystrybucji oprogramowania wykorzystywane przez dystrybucje Linuksa posiadają taki element jak repozytorium - jest to struktura katalogów dostępna gdzieś na serwerach w internecie przechowywująca pakiety z oprogramowaniem w taki sposób, aby było dostępne przy użyciu takich programów jak APT. Zatem obecnie wykorzystujemy pakiety .deb, do wygodnej i niezawodnej instalacji naszego opgrogramowanie na różnych maszynach, to teraz dowiemy się w jaki sposób skonfigurować repozytorium, aby także w najlepszy sposób dostarczać swoje oprogramowanie w postaci pakietów do owych systemów.

Używanie repozytorium ma jeszcze jedną bardzo ważną cechę, otóż aktualizacje. Jakby wyglądała by aktualizacja, kiedy musimy sami dostarczać pakiety do systemu? W przypadku repozytorium wystarczy, że dostawca oprogramowania doda najnowszą wersję programu w postaci pakietu i w naszym systemie przeprowadzimy aktualizacje, jakie wykonywaliśmy do tej pory. To jeśli dokonaliśmy instalacji z repozytorium to rzeczona aktualizacja również zostanie zainstalowana.

Do wykonania repozytorium dla własnego oprogramowania instalowanego za pomocą paczek .deb, potrzebujemy trzech składników:

  1. Klucza tajnego GPG do podpisywania list pakietów oraz bazującego na nim certyfikatu osiągalnego z poziomu internetu, żeby jego ręczna instalacja nie była jakąś skomplikowaną czynnością.
  2. Oprogramowania Debiana, odpowiedzialnego za to, żeby struktura katalogowa oraz kilka plików były uważane za repozytorium pakietów - pakietu reprepro.
  3. Serwera WWW, który udostępni tą strukturę w sieci. W tym materiale skupię się na serwerze Apache2, oczywiśnie można do tego wykorzystać nginx - po opis konfiguracji zapraszam do link źródłowego nr. 1.

Konfigurację rozpoczniemy od kryptografii. Na początku należy sprawdzić czy w naszym systemie dostępne jest polecenie gpg, jeśli nie to musimy je zainstalować.

xf0r3m@debian:~$ sudo apt install gpg

Po założeniu, że pakiet gpg jest obecny w systemie możemy przejść do generowania klucz. Parę kluczy generujemy za pomocą polecenia

xf0r3m@debian:~$ gpg --gen-key

Program zapyta nas o imię, nazwisko oraz adres email. Podajemy dane (nie muszą być prawdziwe, z technicznego punktu widzenia) zatwierdzamy i wybieramy opcję (D)alej. Program utworzy parę kluczy i wyświetli podsumowanie. W tym momencie warto zrobić jedną, rzecz - przedłużyć ważność klucza, tak aby on nie wygasał.

Aby przedłużyć ważność klucza musimy uruchomić program gpg w trybie edycji klucza za pomocą poniższego polecenia. Polecenie będzie wymagać podania user-id w tym przypadku jest adres poczty elektronicznej podany podczas generowania klucza.

xf0r3m@debian:~$ gpg --edit-key jnowak@example.pl
...
gpg>expire
Zmiana daty ważności głównego klucza.
Okres ważności klucza.
         0 = klucz nie ma określonego terminu ważności
      <n>  = termin ważności klucza upływa za n dni
      <n>w = termin ważności klucza upływa za n tygodni
      <n>m = termin ważności klucza upływa za n miesięcy
      <n>y = termin ważności klucza upływa za n lat
Okres ważności klucza? (0) 
Klucz nie wygaśnie w ogóle
Czy wszystko się zgadza (t/N)? t

W ten sposób przedłużyliśmy klucz prywatny (tajny), a co z kluczem publicznym? W trybie edycji zawsze domyślnie wybierany jest pierwszy klucz prywatny. Musimy zmienić klucz i ponownie wydać polecenie expire. Dokonamy tego poprzez wydanie polecenia key i podając jako argument numer klucza. Warto pamiętać o tym, że GPG numeruje swoje klucze od 0 - dlatego drugi klucz to 1.

gpg>key 1
sec  ed25519/ABB37426FDFBD4BD
     utworzono: 2026-01-31  wygasa: nigdy       użycie: SC  
     zaufanie: absolutne     poprawność: absolutne
ssb* cv25519/8CB8FE91345B125F
     utworzono: 2026-01-31  wygasa: 2029-01-30  użycie: E   
[   absolutne   ] (1). Jan Nowak <jnowak@example.pl>

gpg>expire
Zmiana daty ważności głównego klucza.
Okres ważności klucza.
         0 = klucz nie ma określonego terminu ważności
      <n>  = termin ważności klucza upływa za n dni
      <n>w = termin ważności klucza upływa za n tygodni
      <n>m = termin ważności klucza upływa za n miesięcy
      <n>y = termin ważności klucza upływa za n lat
Okres ważności klucza? (0) 
Klucz nie wygaśnie w ogóle
Czy wszystko się zgadza (t/N)? t

Po przedłużeniu klucza, dodamy do bazy klucz - ten właściwy klucz do podpisywania list pakietów. Wykonamy tę czynność za pomocą polecenia addkey. Nowy klucz musi być kluczem RSA z funkcją wyłącznie do podpisywania. Debian wymaga, aby listy pakietów były podpisane kluczami o niekrótszymi niż 4096 bitów. Dla własnej wygody ustawiamy, aby klucz nigdy nie wygasał.

gpg>addkey
Proszę wybrać rodzaj klucza:
   (3) DSA (tylko do podpisywania)
   (4) RSA (tylko do podpisywania)
   (5) Elgamala (tylko do szyfrowania)
   (6) RSA (tylko do szyfrowania)
  (10) ECC (tylko do podpisywania)
  (12) ECC (tylko do szyfrowania)
  (14) Istniejący klucz z karty
Twój wybór? 4
Klucze RSA będą miały od 1024 do 4096 bitów długości.
Jakiej długości klucz wygenerować? (3072) 4096
Żądana długość klucza to 4096 bitów.
Okres ważności klucza.
         0 = klucz nie ma określonego terminu ważności
        = termin ważności klucza upływa za n dni
      w = termin ważności klucza upływa za n tygodni
      m = termin ważności klucza upływa za n miesięcy
      y = termin ważności klucza upływa za n lat
Okres ważności klucza? (0) 
Klucz nie wygaśnie w ogóle
Czy wszystko się zgadza (t/N)? t
Czy na pewno utworzyć? (t/N) t
...
sec  ed25519/ABB37426FDFBD4BD
     utworzono: 2026-01-31  wygasa: nigdy       użycie: SC  
     zaufanie: absolutne     poprawność: absolutne
ssb* cv25519/8CB8FE91345B125F
     utworzono: 2026-01-31  wygasa: nigdy       użycie: E   
ssb  rsa4096/BAEF7E64274DBF27
     utworzono: 2026-01-31  wygasa: nigdy       użycie: S   
[   absolutne   ] (1). Jan Nowak <jnowak@example.pl>

Tak utworzony klucz będzie trzeci na liście, przy kluczach znajdują się takie dziwne wartości bitowe, to są identyfikatory kluczy i trzeba identyfikator klucza podpisu będzie zapamiętać. W moim przypadku jest to BAEF7E64274DBF27 Następnie możemy opuścić powłokę polecenia gpg poleceniem save.

gpg>save

Kiedy mamy już utworzony odpowiedni klucz możemy opublikować na jednym z ogólnodostępnych serwerów kluczy dzięki czemu, będziemy wstanie pobrać certyfikat dla systemów korzystających z naszego repozytorium, ale także osoby z zewnątrz, które będą z niego korzystać będą mogły zweryfikować wiarygodność źródła. Dlatego ważne jest aby umieścić jak najbardziej wiarygodne dane przy generowaniu klucz lub takie które jesteśmy w stanie potwierdzić. Publikacji klucza dokonujemy za pomocą poniższego polecenia.

xf0r3m@debian:~$ gpg --keyserver keyserver.ubuntu.com --send-key BAEF7E64274DBF27
gpg: wysyłanie klucza ABB37426FDFBD4BD na hkp://keyserver.ubuntu.com

Zwróć my uwagę na to, że program zwrócił nam identyfikator klucza prywatnego (tajnego). Tym identyfikatorem będziemy odszukiwać certyfikat na serwerze kluczy. Aby to zrobić uruchamiamy przeglądarkę i przechodzimy pod adres https://keyserver.ubuntu.com w polu wyszukiwania podajemy identyfikator klucz prywatnego poprzedzony znakami 0x. Jeśli serwer, odpowiada Not Found, oznacza, że jeszcze przetwarza klucz i należy spróbwać za jakie 10 - 15 min. Po przedtworzeniu powinna nam się pokazać strona jak na zrzucie poniżej.

Jeśli kliknięmy w link w linii oznaczonej jako pub lub w dowolny inny link przedstawiający identyfikator klucz powinno rozpocząć się pobieranie certyfikatu. Certyfikat jest zakodowany:

xf0r3m@debian:~/Pobrane$ file 6c54db860b2106a2119720d3abb37426fdfbd4bd.asc
6c54db860b2106a2119720d3abb37426fdfbd4bd.asc: PGP public key block Secret-Key

Możemy go odkodować za pomocą polecenia gpg wraz z opcją --dearmor.

xf0r3m@debian:~/Pobrane$ cat 6c54db860b2106a2119720d3abb37426fdfbd4bd.asc | gpg --dearmor --output repo-test.asc
xf0r3m@debian:~/Pobrane$ file repo-test.asc 
repo-test.asc: OpenPGP Public Key Version 4, Created Sat Jan 31 15:17:00 2026, EdDSA; User ID; Signature; OpenPGP Certificate

Gotowy certyfikat możemy umieścić gdzieś, skąd łatwo będzie go można pobrać. Każdy klient naszego repozytorium będzie musiał mieć zainstalowany certyfikat w systemie (wystarczy umieścić w plik w odpowiednim folderze). Uzyskując certyfikat, zakończyliśmy pierwszy etap naszej konfiguracji, teraz przejdziemy do utworzenia samego repozytorium.

Za utworzenie oraz zarządzanie repozytorium w tym dodawniu do niego pakietów odpowiada jeden program o bardzo ciekawej nazwie reprepro. Pakiet ten jest dostępny w repozytorium.

xf0r3m@debian:~$ sudo apt install -y reprepro

Sama koncepcja repozytorium opiera na plikach i katalogach podobnie jak jest pakietami. W tym przypadku również potrzebujemy katalogów dwóch katalogów oraz dwóch plików. Również na tym etapie musimy określić, miejsce w którym będzie nasze repozytorium. W moim przypadku będzie to jeden z katalogów, w klasycznym folderze dla hostingu www.

xf0r3m@debian:~$ sudo mkdir -p /var/www/html/debian
xf0r3m@debian:~$ sudo chown -R xf0r3m:xf0r3m /var/www
xf0r3m@debian:~$ mkdir /var/www/html/debian/conf

Utworzyłem również podkatalog conf, który będzie przechowywać pliki konfiguracyjne repozytorium. Mając utworzone katalogi możemy przejść do tworzenia plików. Pliki potrzebne są dwa, pierwszy z nich options zawiera opcje konfiguracyjne dla programu reprepro. Drugi - distributions, w nim znajdują się definicje repozytoriów dla poszczególnych wersji dystrybucji Debiana. Dla każdej wersji w pliku musi znajdować odrębna definicja repozytorium. Zaczniemy od pliku options.

basedir /var/www/html/debian
ask-passphrase
verbose

Najzwyklejsza konfiguracja tego pliku zamyka się w trzech linijkach. Pierwsza opcja wskazuje na katalog bazowy repozytorium, druga opcja nakazuje programowi, aby uruchmiał GPG wraz opcją pytania o hasło do klucza podczas podpisywania list pakietów. Trzecia natomiast nakazuje wyswietlanie komunikatów diagnostycznych - mimo tej opcji nie ma ich zbyt wiele.

Drugi plik distributions będzie opiewać w nieco więcej szczegółów, poniżej znajduje się plik z mojego repozytorium i na jego analizie się skupimy.

Origin: deb.morketsmerke.org
Label: debian
Suite: stable
Codename: trixie
Version: stable
Architectures: i386 amd64 arm64 armhf source
Components: main
UDebComponents: main
Description: Morketsmerke Linux toolbox repository
SignWith: BAEF7E64274DBF27 

Ten plik na pierwszy rzut oka może okazać się dość skomplikowany, dla osób niezaznajomionych z tematem. Panuje tutaj jednak dość duża swoboda przy wypełnianiu tych pól. Ważne jest aby dobrze ustawić architektury dla których to repozytorium będzie przechowywać pakiety oraz komponenty, określające prawa autorskie oprogramowania przechowywanego w danym repozytorium. Komponent main, przechowuje wyłącznie oprogramowanie otwartoźródłowe. Oznaczenia są takie same jak byśmy konfigurowali repozytoria w naszych systemach klienckich. Więc tak: w polu Origin: podałem nazwę hosta, którą będzie udostępniać repozytorium, Label: podałem katalog, pod którym dostępne będzie repozytorium z poziomu URL hosta. Pola Suite: oraz Version: są równoważne i oznaczają ogólną wersję Debiana (poza nazwą kodową). Codename: zawiera nazwę kodową wersji dla której przygotowaną tą definicję repozytorium (całe repozytorium). Pole UDebComponents jest równoważne z polem Components. W polu Description znajduje się opis repozytorium. W ostatnim polu SignWith znajduje się identyfikator klucz, którego program ma użyć do podpisu listy pakietów.

Teraz to repozytorium jest gotowe na przyjęcie pakietów od ich opiekunów. Aby dodać pakiet do repozytorium będziemy posługiwać się poleceniem reprepro zgodnie z poniższą składnią.

xf0r3m@debian:~$ reprepro --confdir /var/www/html/debian/conf includedeb trixie ./helloworld_0.0.1.deb 
./helloworld_0.0.1.deb: component guessed as 'main'
Exporting indices...

Po wydaniu powyższego polecenia, zostaniemy poproszeni o hasło klucza prywatnego i po wpisaniu, pakiet zostanie dodany do repozytorium. Aby sprawdzić zawartość repozytorium wykorzystujemy poniższe polecenie.

xf0r3m@debian:~$ reprepro --confdir /var/www/html/debian/conf list trixie 
trixie|main|i386: helloworld 0.0.1
trixie|main|amd64: helloworld 0.0.1
trixie|main|arm64: helloworld 0.0.1
trixie|main|armhf: helloworld 0.0.1

Ze względu na to, że repozytorium skonfigurowane jest dla czterech różnych architektur, pakiet na liście pokazany jest dla każdej z nich. Teraz nasz testowy pakiet jest gotowy do pobrania i instalacji, tylko na początek trzeba go jeszcze w dobry sposób udostępnić.

Do udostępnienia repozytorium posłuży nam serwer WWW, w tym przypadku Apache2 z odpowiednią konfiguracją. Naszą konfiguracją rozpoczynamy od zainstalowania serwera WWW

xf0r3m@debian:~$ sudo apt install -y apache2

Teraz musimy dokonać konfiguracji dostępu do poszczególnych podkatalogów repozytorium, aby nie udostępniać czegoś czego nie musimy. W pliku /etc/apache2/sites-available/000-default.conf zapisujemy poniższą konfigurację uwzględniając swoje ścieżki.

<Directory /var/www/html/debian/>
  Options Indexes FollowSymlinks MultiViews
  AllowOverride None
  Order allow,deny
  allow from all
</Directory>

<Directory /var/www/html/debian/db/>
  Require all denied
</Directory>

<Directory /var/www/html/debian/conf/>
  Require all denied
</Directory>

Po udostępnieniu repozytorium, pozostało nam to tylko przetestować, dobrym pomyśłem będzie użycie np. dystrybucji działającej w trybie LiveCD.

Po uruchomieniu systemu, na początek pobieramy certyfikat i umieszczamy go w systemowej bazie klucz /usr/share/keyrings

xf0r3m@vm-b322bd2:~$ wget deb.morketsmerke.org/repo-test.asc
...
xf0r3m@vm-b322bd2:~$ sudo cp repo-test.asc /usr/share/keyrings/

Następnie dodajemy listę z naszym repozytorium do konfiguracji programu APT. W poniższym przykładzie muszę złamać linię z poleceniem, ma to na celu jedynie zachowanie estetyki strony. W prawdziwej konfiguracji, żadno złamanie nie występuje w tym przypadku.

xf0r3m@vm-b322bd2:~$ echo "deb [signed-by=/usr/share/keyrings/repo-test.asc]
http://deb.morketsmerke.org/debian trixie main" | sudo tee /etc/apt/sources.list.d/repo-test.list

deb [signed-by=/usr/share/keyrings/repo-test.asc] http://deb.morketsmerke.org/debian trixie main

Teraz możemy odświeżyć listy pakietów w systemie i pobrać tą z naszego repozytorium.

xf0r3m@vm-b322bd2:~$ sudo apt update
Pobr:1 http://deb.morketsmerke.org/debian trixie InRelease [6 895 B]
Pobr:2 http://deb.morketsmerke.org/debian trixie/main amd64 Packages [560 B]                     
Było:3 http://security.debian.org/debian-security stable-security InRelease         
Było:4 http://deb.debian.org/debian stable InRelease      
Było:5 http://deb.debian.org/debian stable-updates InRelease
Pobrano 7 455 B w 0s (42,5 kB/s)
...

Jeśli w tym miejscu APT, nie zwróci żadnego błędu z repozytorium, oznacza to, że całość jest poprawnie skonfigurowana i gotowa do pracy. Dlatego też na koniec zainstalujemy nasz pakiet testowy i go uruchomimy.

xf0r3m@vm-b322bd2:~$ sudo apt install helloworld 
Instalowane:                         
  helloworld

Podsumowanie:
  Aktualizowanych: 0, Instalowanych: 1, Usuwanych: 0, Nieaktualizowanych: 126
  Do pobrania: 1 728 B
  Wymagane miejsce: 0 B / 729 MB dostępnych

Pobr:1 http://deb.morketsmerke.org/debian trixie/main amd64 helloworld all 0.0.1 [1 728 B]
Pobrano 1 728 B w 0s (0 B/s)               
Wybieranie wcześniej niewybranego pakietu helloworld.
(Odczytywanie bazy danych ... 134951 plików i katalogów obecnie zainstalowanych.)
Przygotowywanie do rozpakowania pakietu .../helloworld_0.0.1_all.deb ...
Rozpakowywanie pakietu helloworld (0.0.1) ...
Konfigurowanie pakietu helloworld (0.0.1) ...
Przetwarzanie wyzwalaczy pakietu man-db (2.13.1-1)...

xf0r3m@vm-b322bd2:~$ helloworld 
Hello, World!

W ten oto sposób, jaki został pokazany w powyższym artykule zapeniliśmy naszym pakietom najlepszy możliwy sposób zarządzania nimi przez właśnie repozytorium APT. Teraz za pomocą tego jednego narzędzia będzie my mogli instalować nowe pakiet, usuwać wadliwe, oraz je aktualizować. Wiele repozytoriów obecnie wykorzystuje zarówno protokół HTTP jak HTTPS do przysłania pakietów, jeśli chcielibyśmy w swoim systemie skorzystać repozytorium przez protokoł HTTPS to potrzebujemy pakietu apt-transport-https, zainstalowane przed pobraniem list pakietów. Teraz możemy również dodać kolejne repozytoria dla dalej wspierych wersji Debian, przy obecnej konfiguracji wymagać to będzie jedynie zmian wersji, Suite oraz nazwy kodowej - reszta może pozostać bez zmian.

Źródła:

  1. Creating a Private Package repository for Debian
  2. Tworzenie repozytorium przy pomocy reprepro
  3. How To: apt-key is deprecated, here's how to fix it
  4. Wyjaśnienie architektur w definicji repozytorium

~xf0r3m