野良APTリポジトリを作る

※先日同様の記事を書きましたが、挙動がおかしいような感じだったので一旦削除しました
0ベースで作りなおし、問題なさそうでしたので再度やったことをまとめてみます

# 発端

普段Ubuntuを利用しており、日々 `apt upgrade` を実行している
aptラインが存在していればsources.list.d以下にファイルを作り、 `apt upgrade` で管理が可能になるが、世の中にはGitHubで.debファイルを公開しているようなケースがある

このようなソフトウェアについてはそれぞれ個別に.debファイルをダウンロードするスクリプトを作っている

最近ふと自前のAPTリポジトリを作れば別なマシンにインストールすることになっても楽なのでは？と思い、色々と調べてみた結果セットアップできたのでやったことをまとめてみます

## 前提

- 普段使っているPCがUbuntu
- 別途ホスト名を指定してアクセスできるサーバーがある
- 調査してる際にURIがsshでも使えることが判明したのでsshでアクセスするリポジトリを作る

# APTリポジトリを作るサーバー側

## GPGの鍵を用意する

```
gpg --gen-key --batch <(echo Key-Type: RSA; echo Key-Length: 3072; echo Passphrase: pass; echo Name-Real: user; echo Name-Email: user@example.com)
```

gpgコマンドを何度か打っていたら上手く動作しなくなることが起きた
pinentryというプロセスが生きていると正しく終了しないような雰囲気で、pinentryのプロセスをKILLしてから再度実行したら上手く動作した

## debファイルを置くディレクトリを生成する

```
mkdir -p /home/user/packages
```

## GPGの公開鍵を置いておく

まずIDを調べる

```bash
gpg --list-keys
```

上記で表示されたIDを指定して公開鍵を生成する

```bash
gpg --export ID > /home/user/packages/public.key
```

## debファイルダウンロードスクリプトを作る

(例)

```bash:zoom-download.sh
#!/usr/bin/bash

wget -q -O zoom.deb "https://zoom.us/client/latest/zoom_amd64.deb"

apt-ftparchive packages . > Packages
apt-ftparchive contents . | gzip -9 > Contents-$(dpkg --print-architecture).gz
apt-ftparchive release . > Release
test -e InRelease && rm InRelease
echo -n "pass" | gpg --batch --passphrase-fd 0 --pinentry-mode loopback --clearsign -o InRelease Release
test -e Release.gpg && rm Release.gpg
echo -n "pass" | gpg --batch --passphrase-fd 0 --pinentry-mode loopback -abs -o Release.gpg Release
```

ビデオ通話のzoomクライアントをダウンロードして、ディレクトリに配置された.debファイルについてのメタ情報のようなものを生成する

# apt installするクライアント側

## aptでsshのURIでアクセスできるようにする

```conf:/etc/apt/apt.conf/d/30-ssh-transport
Dir::Bin::Methods::ssh "ssh";
```

## sources.listの設定

新しい形式の設定ファイルを作ってみる

```conf:/etc/apt/sources.list.d/myapt.sources
Types: deb
URIs: ssh://apt.example.com/home/user/packages
Suites: ./
Trusted: yes
Signed-By: /usr/share/keyrings/myapt.gpg
```

## rootユーザーで鍵を準備する

aptがroot権限で動くのでrootで用意する

```bash
ssh-keygen -t ed25519 -f .ssh/apt
```

sshのconfigを設定しておく

```conf:/root/.ssh/config
Host apt.example.com
    HostName apt.example.com
    User user
    IdentitiesOnly yes
    IdentityFile ~/.ssh/apt
```

sshの公開鍵をAPTリポジトリに設定し、 `ssh apt.example.com` でuserユーザーとしてログインできるようにしておく

## GPGのインポートを行う

### GPGの公開鍵を取得する

```bash
ssh apt.example.com "cat packages/public.key" > public.key
```

### /usr/share/keyrings/にGPGのインポートを行う

```bash
gpg --no-default-keyring --keyring=apt.example.com.gpg --import public.key
gpg --no-default-keyring --keyring=apt.example.com.gpg --export --output myapt.gpg
sudo mv myapt.gpg /usr/share/keyrings/
```

# 完了

これで `sudo apt update; sudo apt install -y zoom` などとするとzoomクライアントをインストールできるようになりました
あとはAPTリポジトリにあるzoom.debが更新されれば `sudo apt upgrade` で更新されます
(2022/12/28現在:実際に更新されるところまで確認できてない)
(2022/12/30現在:無事に野良APTリポジトリからパッケージが更新されるところまで確認できた)

# 雑感

- sshを使えるということで挑戦してみたが、正直rootで鍵を作ったりする必要があるのでAPTリポジトリサーバーで一手間増えるがhttp(s)の環境を作る方が楽なのではと感じた

- APTリポジトリを作ること自体はとても簡単だった

- .debファイルのダウンロードは可能ならダウンロード済みの.debのバージョンを確認し、配布先のサイトでバージョンが公開されているなら事前にバージョンの比較を行い、新規.debファイルが存在する場合にダウンロードするようにしたい

- .debファイルが公開されていなくても自前でソースからビルドし、.debファイルを作るようにすれば今回作ったリポジトリに追加することで導入が楽になりそう

# 参考文献

https://pyopyopyo.hatenablog.com/entry/20160114/p1

https://mag.osdn.jp/14/01/17/090000/3

http://www.katsuster.net/index.php?arg_act=cmd_show_diary&arg_date=20190811

https://gihyo.jp/admin/serial/01/ubuntu-recipe/0677

https://askubuntu.com/questions/348878/how-to-configure-apt-to-access-a-deb-repository-over-ssh

http://www.usamimi.info/~pochi/linux/apt-ftparchive.html

---

それでは良いaptライフを