[[Vorlage(Getestet, jammy)]] {{{#!vorlage Wissen [:Pakete_installieren: Installation von Paketen] [:Terminal: Ein Terminal öffnen] [:Paketquellen freischalten: Bearbeiten von Paketquellen] [:Editor: Einen Editor öffnen] [:Rechte: Rechte für Dateien und Ordner ändern] [:GnuPG: Verschlüsselung mit GnuPG] [:gzip:Komprimierung mit GNU Zip] [:mit Root-Rechten arbeiten:] }}} [[Inhaltsverzeichnis()]] [[Bild(Wiki/Icons/package.png, 48, left)]] Neben der Nutzung der offiziellen [:Paketquellen:] oder von anderen Quellen wie z.B. ein [:Launchpad/PPA: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: {{{#!vorlage Paketinstallation dpkg-dev, main }}} = 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: {{{ _-_.deb }}} Dieses kann [:Grundlagen_der_Paketerstellung:neu erstellt] werden, alternativ lässt sich mittels [man: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: {{{#!vorlage Befehl 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 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/#main:Paketquellen-Komponente ''main''] abgelegt werden soll. Dorthin wird das Beispielpaket kopiert: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl mkdir -p ~/Software/apt-repo/dists/stable/main/binary-amd64 }}} {{{#!vorlage Experten 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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. {{{#!vorlage Experten 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 {{{#!vorlage Befehl 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. {{{#!vorlage Experten 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 [:22.04: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 [#Paketquelle-anlegen oben beschrieben]. }}} Anschließend wird mittels [man:apt-ftparchive:] unter Angabe der Konfigurationsdatei die Datei generiert und komprimiert: {{{#!vorlage Befehl 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. }}} {{{#!vorlage 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 [#Einbindung-in-das-System 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 [man:mktemp:] ein temporäres Verzeichnis für den Schlüsselbund erstellt. Dies geschieht durch Setzen der Umgebungsvariable `GNUPGHOME`: {{{#!vorlage Befehl export GNUPGHOME="$(mktemp -d ~/Software/pgpkeys-XXXXXX)" }}} Nun wird ein neues GnuPG-Schlüsselpaar [:GnuPG/#Schluesselpaar-erzeugen:erzeugt]. Dabei müssen die Daten des Paketquellenbetreuers angegeben werden. Anschließend sollte der Schlüsselbund ungefähr so aussehen: {{{#!vorlage Befehl gpg --list-keys }}} {{{ /home/user/Software/pgpkeys-pyml86/pubring.kbx ------------------------------- pub rsa4096 2021-05-18 [SCEA] B4D5C8B003C50A38A7E85B5989376CAC59892E72 uid [ultimate] karzer }}} 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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: {{{#!vorlage Befehl 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 [:sources.list/#etc-apt-sources-list-d:'''/etc/apt/sources.list.d'''] eine neue Softwarequellen-Liste mit Namen '''private-software.list''' erstellt: {{{#!vorlage Befehl 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 [https://repolib.readthedocs.io/en/latest/deb822-format.html 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 [http://debiananwenderhandbuch.de/dpkg-scanpackages.html Debian-Anwenderhandbuch] {de}). [[Vorlage(Fremd, Quelle, "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. {{{#!vorlage Warnung 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]: {{{#!vorlage Befehl 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: {{{#!code Bash #!/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]. = Links = * [:Lokale_Paketquellen:] {Übersicht} Übersichtsartikel * [:reprepro:] - Werkzeug für eigene Paketquellen * [https://debian-handbook.info/browse/de-DE/stable/sect.setup-apt-package-repository.html Anleitung im Debian-Anwenderhandbuch] {de} * Apt-Repositorium erstellen: * [http://www.pro-linux.de/artikel/2/1459/apt-repositorium-erstellen-variante-1-apt-ftparchive.html Variante 1 - apt-ftparchive] {de} * [http://www.pro-linux.de/artikel/2/1475/apt-repositorium-erstellen-variante-2-reprepro.html Variante 2 - reprepro] {de} * [https://repolib.readthedocs.io/en/latest/deb822-format.html Erläuterung des DEB822-Formates zum Hinzufügen von Paketquellen] {en} #tag: System, Paketverwaltung