ubuntuusers.de

Eigene Paketquelle anlegen

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:


Du möchtest den Artikel für eine weitere Ubuntu-Version testen? Mitarbeit im Wiki ist immer willkommen! Dazu sind die Hinweise zum Testen von Artikeln zu beachten.

Wiki/Icons/package.png Neben der Nutzung der offiziellen Paketquellen oder von anderen Quellen wie z.B. ein PPA und weiteren Fremdquellen gibt es auch die Möglichkeit, eine eigene Paketquelle lokal anzulegen. Dies kann zum Beispiel dann sinnvoll sein, wenn man regelmäßig Pakete bzw. Paketzusammenstellungen braucht, die in dieser Form in keiner anderen Quelle vorhanden sind oder die man selbst erstellt hat.

Weitere Programme mit ähnlichen Funktionen sind im Artikel Lokale Paketquellen zu finden.

Installation der Abhängigkeiten

Das Erstellen der lokalen Paketquelle setzt die Installation [1] des folgenden Paketes voraus:

  • dpkg-dev (main)

Befehl zum Installieren der Pakete:

sudo apt-get install dpkg-dev 

Oder mit apturl installieren, Link: apt://dpkg-dev

Paketquelle anlegen

Um die Paketquelle zu erstellen, legt man zunächst beispielsweise im Homeverzeichnis einen neuen Ordner Software und darin den Unterordner ~/Software/apt-repo an, in den man die gewünschten Pakete schiebt. Im Laufe der Erstellung der Paketquelle wird folgende Ordnerstruktur geschaffen:

/home/user/software/apt-repo/
├── dists
│   └── stable
│       ├── InRelease
│       ├── main
│       │   └── binary-amd64
│       │       ├── Packages
│       │       └── Packages.gz
│       ├── Release
│       ├── release.conf
│       └── Release.gpg
├── KEY.gpg
└── pool
    └── main
        └── todotxt-cli_2.11.0-2_all.deb

6 directories, 8 files

Debian-Paket

Als Vorraussetzung für die Erstellung der Paketquelle wird ein Debian-Paket benötigt, das in folgendem Format vorliegen sollte:

<programmname>_<version>-<release-nummer>_<architektur>.deb

Dieses kann neu erstellt werden, alternativ lässt sich mittels dpkg-repack eine vorhandenes Paket neu packen. In diesem Artikel wird als Beispiel hello-world_0.0.1-1_amd64.deb verwendet. Als Architektur wird hierbei amd64 (64-Bit) benutzt. Wenn das Programm unabhängig von einer Architektur ist, kann all genutzt werden.

Die Validität des Paketes sollte vor dem Einsatz in der Paketquelle überprüft werden:

dpkg-deb --info hello-world_0.0.1-1_amd64.deb 

new Debian package, version 2.0.
size 2832 bytes: control archive=336 bytes.
    182 bytes,     7 lines      control
Package: hello-world
Version: 0.0.1
Maintainer: karzer <karzer@packaging.com>
Depends: libc6
Architecture: amd64
Homepage: http://example.com
Description: A program that prints hello

Dateien

Im Folgenden wird die Bedeutung der einzelnen zu erstellenden Dateien erklärt.

  • hello-world_0.0.1-1_amd64.deb: Das DEB-Paket, dass von der Paketquelle später ausgeliefert werden soll

  • Packages und Packages.gz (komprimierte Version): Liste aller in der Paketquelle vorhandenen Pakete

  • Release und Release.gpg (signiert mit dem Paketquellenschlüssel): enthält Metadaten der Paketquelle und eine Liste aller Packages-Dateien

  • InRelease: Enthält den Inhalt der Release-Datei und seine Signatur

  • release.conf Enthält Metadaten des Repositoriums zur Generierung der Release-Datei

  • repo-key.public: öffentlicher Paketquellen-Schlüssel, zum Verifizieren der Signaturen der Paketquellen-Dateien durch den Nutzer

Ordnerstruktur einrichten

Debian-Paket

Zuerst wird ein Ordner erstellt, der das Debian-Paket enthalten soll. Hier wird vorausgesetzt, dass das Paket in der Paketquellen-Komponente main abgelegt werden soll. Dorthin wird das Beispielpaket kopiert:

mkdir -p ~/Software/apt-repo/pool/main/ 
cp hello-world_0.0.1-1_amd64.deb ~/Software/apt-repo/pool/main/ 

Packages

Die Packages-Datei enthält eine Liste aller in dem Repositorium enthaltenen Pakete und muss bei der Bereitstellung eines neuen Paketes oder einer neuen Version erneut generiert werden. Zuerst wird der Ordner erstellt, der die Paketinformationen enthalten soll:

mkdir -p ~/Software/apt-repo/dists/stable/main/binary-amd64 

Experten-Info:

Wenn Pakete für mehre Architekturen bereitgestellt werden sollen, müssen entsprechende Ordner nach dem Format binary-architektur erstellt werden. Beispiel, für 32-Bit:

mkdir -p ~/Software/apt-repo/dists/stable/main/binary-i386 

Anschließend muss in den Wurzelordner der Paketquelle, ~/Software/apt-repo/ gewechselt werden. Dieser Schritt ist wichtig, da andernfalls die Pfade zu den Paketen in der Packages-Datei falsch zeigen. Daraufhin wird der Befehl dpkg-scanpackages zur Generierung der Datei genutzt:

cd ~/Software/apt-repo
dpkg-scanpackages --arch amd64 pool/ > dists/stable/main/binary-amd64/Packages
cat dists/stable/main/binary-amd64/Packages | gzip -9 > dists/stable/main/binary-amd64/Packages.gz 

Der letzte Schritt dient zur Komprimierung [7] der Datei. Dies ist angeraten (bzw. erforderlich), da Apt bevorzugt die komprimierten Versionen herunterlädt.

Experten-Info:

Besonders bei mit checkinstall selber erzeugten Paketen wird eine leere Depends-Zeile in die Paketbeschreibung eingefügt, was zu Problemen mit APT führt. Abhilfe schafft, die leere Depends-Zeile zu entfernen. Das funktioniert am besten mit

dpkg-scanpackages --arch amd64 pool/ | sed '/^Depends:[[:space:]]*$/d' > dists/stable/main/binary-amd64/Packages 

Release

Die Release-Datei enthält Metadaten des Repositoriums und eine Liste aller Packages-Dateien.

Zuerst wird die Datei release.conf mit folgendem Inhalt im Ordner ~/Software/ erstellt:

APT::FTPArchive::Release::Origin "Karzer Packaging";
APT::FTPArchive::Release::Label "stable";
APT::FTPArchive::Release::Suite "stable";
APT::FTPArchive::Release::Version "1.0";
APT::FTPArchive::Release::Architectures "amd64";
APT::FTPArchive::Release::Components "main";

Dies legt die Metadaten für das Repositorium in der Apt-Konfigurationssyntax fest.

Experten-Info:

Falls die Paketquelle für verschiedene Ubuntu-Versionen Pakete bereitstellen soll, werden unter ~/Software/apt-repo/dists/ und ~/Software/apt-repo/pool/ Unterordner mit den entsprechenden Codenames der Versionen erstellt. Etwa werden am Beispiel von Ubuntu 22.04 Verzeichnisse mit dem Namen jammy/ erstellt.

In der obigen Konfigurationsdatei wird sodann unter der Einstellung APT::FTPArchive::Release::Suite jammy eingetragen und der Punkt Label ebenso angepasst. Auch die Option APT::FTPArchive::Release::Codename lässt sich mit diesem Wert bestücken. Ansonsten gilt die gleiche Ordnerstruktur wie oben beschrieben.

Anschließend wird mittels apt-ftparchive unter Angabe der Konfigurationsdatei die Datei generiert und komprimiert:

cd ~/Software/apt-repo/dists/stable/
apt-ftparchive release -c release.conf . > Release
cat Release | gzip -9 > Release.gz 

InRelease

In den im Folgenden beschrieben Schritten wird die Release-Datei mit einem neu erstellten GnuPG-Schlüssel [6] signiert, wodurch eine neue Datei namens Release.gpg erstellt wird. Anschließend wird ihr Inhalt samt der Signatur in eine Datei namens InRelease im selben Verzeichnis eingefügt. Dies ist notwendig, da Apt nur signierte Quellen verarbeitet und ansonsten folgende Fehlermeldung aufkommt:

W: The repository 'http://example.com/apt-repo stable Release' is not signed.
N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.
N: See apt-secure(8) manpage for repository creation and user configuration details.

Hinweis:

Apt bietet die Option --allow-insecure-repositories für den update-Befehl, um unsignierte Paketquellen zu verwenden. Diese Option ist allerdings nicht dokumentiert und von ihrer Verwendung wird aus Sicherheitsgründen abgeraten.

Alternativ lässt sich eine unsignierte Paketquelle mit dem folgenden Eintrag in die unten beschriebene Softwarequellenliste verwenden:

deb [arch=amd64 trusted=yes] file:/home/BENUTZER/Software/apt-repo stable main

Aus Sicherheitsgründen wird für den folgenden Schritt mittels mktemp ein temporäres Verzeichnis für den Schlüsselbund erstellt. Dies geschieht durch Setzen der Umgebungsvariable GNUPGHOME:

export GNUPGHOME="$(mktemp -d ~/Software/pgpkeys-XXXXXX)" 

Nun wird ein neues GnuPG-Schlüsselpaar erzeugt. Dabei müssen die Daten des Paketquellenbetreuers angegeben werden. Anschließend sollte der Schlüsselbund ungefähr so aussehen:

gpg --list-keys 

/home/user/Software/pgpkeys-pyml86/pubring.kbx
-------------------------------
pub   rsa4096 2021-05-18 [SCEA]
      B4D5C8B003C50A38A7E85B5989376CAC59892E72
uid           [ultimate] karzer <karzer@packaging.com>

Anschließend werden Sicherungskopien des Schlüsselpaares gemacht. Diese müssen gut aufbewahrt werden, und es ist wichtig, dass der private Schlüssel außerhalb der Paketquelle gelagert wird, um einer Kompromittierung vorzubeugen:

gpg --armor --export-secret-keys karzer@packaging.com > ~/Software/repo-key.private 
gpg --armor --export karzer@packaging.com > ~/Software/repo-key.public 

Jetzt kann die Release-Datei mit dem neu erstellten privaten Schlüssel signiert werden:

cat ~/Software/apt-repo/dists/stable/Release | gpg --default-key karzer@packaging.com -abs > ~/Software/apt-repo/dists/stable/Release.gpg 

Um die Schnelligkeit der Prüfung des Apt-Repositoriums durch das System zu erhöhen, sollte anschließend noch eine InRelease-Datei erstellt werden, die die den Inhalt der Release-Datei und ihre Signatur vereint:

cat ~/Software/apt-repo/dists/stable/Release | gpg --default-key karzer@packaging.com -abs --clearsign > ~/Software/apt-repo/dists/stable/InRelease 

Einbindung in das System

Um die selbst zusammengestellte Paketquelle in das System einzubinden, wird in dem Verzeichnis /etc/apt/sources.list.d eine neue Softwarequellen-Liste mit Namen private-software.list erstellt:

echo "deb [arch=amd64 signed-by=$HOME/Software/repo-key.public] file:/home/BENUTZER/Software/apt-repo stable main" | sudo tee /etc/apt/sources.list.d/private-software.list 

Alternativ lässt sich nach dem neueren, leichter lesbaren DEB822-Quellenformat ein Datei /etc/apt/sources.list.d/private-software.sources erstellen:

Types: deb
URIs: file:/home/user/Software/apt-repo/
Suites: stable
Components: main
Signed-By: /home/user/Software/pgp-key.public
Architectures: amd64

Bitte die Schreibweise der Quelle genau beachten - nur ein einfacher Slash nach dem file:, alles andere schlägt fehl (s.a. das Debian-Anwenderhandbuch 🇩🇪).

Hinweis!

Zusätzliche Fremdquellen können das System gefährden.


Anmerkung: Da es sich auch bei einer lokalen Paketquelle nicht um eine offizielle Ubuntu-Quelle handelt, muss sie wie alle anderen Fremdquellen behandelt werden. Die Risiken für das System und die Paketverwaltung bestehen weiterhin, auch wenn man möglicherweise einzelne Aspekte ausschließen kann.

Natürlich ist es auch möglich, eine Paketquelle in einem durch einen Webserver (z.B. Apache) freigegebenen Verzeichnis zu erstellen, um die selbst erstellten bzw. zusammengesuchten Pakete im Netzwerk/Internet verfügbar zu machen. Dafür wird der Ordner ~/Software/apt-repo/ auf den Server übertragen. Die Paketquelle wird dann unter Angabe der Server-IP-Adresse oder -Domain im Feld URIs eingebunden.

Vor der Bereitstellung der Paketquelle muss der öffentliche Paketquellenschlüssel in den Wurzelordner, also ~/Software/apt-repo/ kopiert werden, um die Kontrolle der Paketquelle seitens der Benutzer zu ermöglichen.

Achtung!

Der Ordner ~/Software/, beziehungsweise der darin befindliche private Schlüssel, darf nicht auf den Server kopiert werden, da er ansonsten kompromittiert werden kann.

Nach dem Hinzufügen müssen die gesamten Paketquellen grundsätzlich neu eingelesen werden, etwa über das Terminal [2]:

sudo apt update 

Die Paketverwaltung liest die Quelle nur ein, wenn sie auch richtig angegeben wurde. Andernfalls kann es passieren, dass das System bei Leseversuchen auf eine falsch angegebene Quelle einfriert und nur noch sporadisch reagiert. Falls die Quellenangabe in Synaptic vorgenommen wurde, wird sie im Falle, dass sie falsch war, automatisch gelöscht und das System läuft ohne Probleme weiter. Demzufolge ist die Angabe einer lokalen Paketquellen in Synaptic einer manuellen Bearbeitung der sources.list vorzuziehen.

Selbstverständlich ist es auch möglich, die Paketquelle auf CD/DVD zu brennen und dann in das System einzubinden. Dazu muss im einfachsten Fall der Inhalt des Software-Ordners direkt in der obersten Verzeichnisebene der CD liegen - ohne Unterverzeichnisse!

Vereinfachung

Um nicht bei jedem neu hinzugefügten Paket oder der neuen Erstellung einer Paketquelle die obige Befehlsfolge von Hand eingeben zu müssen, kann man diesen Vorgang durch ein Skript vereinfachen. Dazu erstellt man mit einem Texteditor [4] und Root-Rechten [8] eine Datei /usr/local/bin/refresh_repo mit dem folgenden Inhalt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash

# Ordner, in dem die Quelle liegt
basedir="$HOME/Software"

# Erstellen der Ordnerstruktur, falls nicht existent
mkdir -p $basedir/apt-repo/ && cd $basedir/apt-repo/
mkdir -p dists/stable/main/binary-amd64/ pool/main/

dpkg-scanpackages --arch amd64 pool/ > dists/stable/main/binary-amd64/Packages
cat dists/stable/main/binary-amd64/Packages | gzip -9 > dists/stable/main/binary-amd64/Packages.gz
cd $basedir/apt-repo/dists/stable/
apt-ftparchive release -c $basedir/release.conf . > Release
cat Release | gzip -9 > Release.gz
# Erstellung der Signaturen
export GNUPGHOME="$(mktemp -d $basedir/pgpkeys-XXXXXX)"
read -p "Soll ein neuer GnuPG-Schlüssel erstellt [n], oder der existierende verwendet werden [y]? " erstellen

if [ -z "$erstellen" ]; then
	gpg --import $basedir/pgp-key.private
else
	gpg --full-generate-key
fi

gpg --armor --export-secret-keys > $basedir/repo-key.private
gpg --armor --export > $basedir/repo-key.public

cat $basedir/apt-repo/dists/stable/Release | gpg -abs > $basedir/apt-repo/dists/stable/Release.gpg
cat $basedir/apt-repo/dists/stable/Release | gpg -abs --clearsign > $basedir/apt-repo/dists/stable/InRelease

Nun muss diese Datei noch als für ihren Besitzer ausführbar markiert werden [5].

Diese Revision wurde am 8. August 2023 16:07 von karzer erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Paketverwaltung, System