Chienomi

Pacman v7でのSSHFSによるキャッシュの共有における問題の対応

Live With Linux::manjaro

2024-10にPacmanがv7にバージョンアップしたが、これにより従来有効だったSSHFSを用いたキャッシュの共有ができなくなった。

従来「比較的簡単かつ安全な方法」として、/var/cache/pacman/pkgroot:wheel 775にしておき、wheelに属するユーザーを使ってSSHFSでマウントするという方法があった。

この方法の良いところは、rootでのSSHアクセスを許容しなくて良いこと、/var/cache/pacman/pkgのパーミッションを777にしなくて良いことが挙げられ、セキュリティリスクを(ほとんど)冒すことなく、Pacmanキャッシュを共有して時間と帯域を節約することができた。

だが、v7でこの方法を使うと

警告: 複数のファイルの取得に失敗しました
エラー: 処理を完了できませんでした (予期しないエラー)
エラーが発生したため、パッケージは更新されませんでした。

となってしまう。

結論としてはローカルroot:リモートrootでマウントすれば良いのだが、そうなるとSSH側も工夫が必要になるので、その話をする。

前提として、rootで自由にログインできるようにする、というのはナシとする。

基本的なsshd_configによる制約

Matchブロックにより設定の効力に条件をつけることができる。 Matchブロックを終了する方法は次のMatchブロックを開始するしかないため、全体に適用したい設定はMatchブロックよりも前に記述する。

Archlinuxの設定だと/etc/ssh/sshd_config.d以下を読むようになっているので、そこに分けて書くと管理しやすい。

LANセクションが192.168.1.0/24だと仮定すると、次のようにしてLAN内のみパスフレーズ認証を許容する。

AuthenticationMethods publickey

Match 192.168.1.0/24
  AuthenticationMethods publickey password

外部ネットワークからのログインを一切許容せず、LAN内はroot以外のログインを許容するようにするならば次のようになる。

DenyUsers *
AuthenticationMethods publickey

Match 192.168.1.0/24
  DenyUsers root
  AuthenticationMethods publickey password

Zeroconf (Avahi, Bonjour)を使う場合、IPv6で解決されてしまいうまくコントロールできない可能性がある。 IPv6をちゃんと設定するという選択肢もあるが、正直Matchの書きやすさを考えるとIPv4に限定するのが良いと私は思っている。 私の場合特にそれで困ることもない。

また、デフォルトだとCipherはchacha20-poly1305@openssh.comが使われるが、普通に使うハードウェアはAES-NIを使っている関係上AESを使ったほうがだいぶ軽いので、そちらも設定したい。

というわけで、基本となる設定は次のとおり。

AddressFamily inet
Ciphers aes256-gcm@openssh.com,aes256-ctr,aes192-ctr
DenyUsers *
AuthenticationMethods publickey

Match Address 192.168.1.0/24
  DenyUsers root
  AuthenticationMethods publickey password

Pacmanキャッシュをrootでマウントさせる

しかしこの設定ではrootでのSSHログインができないため、リモートユーザーrootでのSSHFSマウントは効かない。

ここではrootでのSSHアクセスがPacmanキャッシュにおいてのみ必要である、という前提で進める。

Matchブロックは条件に一致したものはすべて適用されるが、同一のキーワード(例えばDenyUsers)が出現した場合は最初のもののみが適用される。

条件は複数書くことが可能である。

これを踏まえて、rootにPacmanキャッシュへのアクセスのみを許すのが以下の設定だ。

AddressFamily inet
Ciphers aes256-gcm@openssh.com,aes256-ctr,aes192-ctr
DenyUsers *
AuthenticationMethods publickey

Match Address 192.168.1.0/24 User root
  DenyUsers !root
  AuthenticationMethods publickey
  ForceCommand internal-sftp
  ChrootDirectory /var/cache/pacman

Match Address 192.168.1.0/24 User !root
  DenyUsers root
  AuthenticationMethods publickey password

先のMatchに後のMatchで定義しているDenyUsersAuthenticationMethodsが出てくるため、User !rootは必要なさそうに思えるが、なぜかUser !rootを省略すると後に出てきたDenyUsers rootが適用されてしまってアクセスできなくなるため、このように書いておく必要がある。 また、User !rootDenyUsers rootするのは単にDenyUsersを上書きするためのものでしかないため、いっそnobodyあたりをDenyUsersに入れるでもいい。

あとは

# sshfs -v -o allow_other,default_permissions mainpc.local:pkg /var/cache/pacman/pkg

という感じでマウントすればPacman v7でもPacmanキャッシュをSSHFSを用いて共有できる。

個人的には……

sshd_configに書く形だと構成が変わったときに面倒になるので、rootでマウントする必要があるというのはだいぶ好ましくない。

というか、そもそもなんでrootでのマウントが必要になっているのかがわからない。 リモートユーザーの権限でキャッシュには書けるのだが、書き込んだキャッシュがユーザー所有になっているのを弾いてしまうのだろうか。