openldap-serversパッケージの更新でエラーになる

AlmaLinux8 にopenldap-serversパッケージがインストールされた環境で、dnf upgradeしたらエラーが発生。

# dnf upgrade
エラー:
 問題: package openldap-servers-2.4.46-18.el8.x86_64 from @System requires openldap(x86-64) = 2.4.46-18.el8, but none of the providers can be installed
  - cannot install both openldap-2.4.46-19.el8_10.x86_64 from baseos and openldap-2.4.46-18.el8.x86_64 from @System
  - cannot install both openldap-2.4.46-19.el8_10.x86_64 from baseos and openldap-2.4.46-18.el8.x86_64 from baseos
  - パッケージの最良アップデート候補をインストールできません openldap-2.4.46-18.el8.x86_64
  - インストール済パッケージの問題 openldap-servers-2.4.46-18.el8.x86_64
(競合するパッケージを置き換えるには、コマンドラインに '--allowerasing' を追加してみてください または、'--skip-broken' を追加して、インストール不可のパッケージをスキップしてください または、'--nobest' を追加して、最適候補のパッケージのみを使用しないでください)


インストールされたバージョンを確認

# rpm -qa | grep openldap
openldap-clients-2.4.46-18.el8.x86_64
openldap-servers-2.4.46-18.el8.x86_64
openldap-2.4.46-18.el8.x86_64


状況からすると、

  • openldap-2.4.46-19(クライアント)をインストールできない
  • openldap-servers-2.4.46-18 の動作には、openldap(x86-64) = 2.4.46-18 が必要
  • クライアントをv19へ更新する際、openldap-serversパッケージでクライアントのv18が必要なので矛盾する

という事らしい。

openldap-serversも19へ一緒に更新できれば依存関係をクリアできるが、19が見つからない状況。

openldap-servers パッケージはpowertoolsリポジトリからインストールしていたので、以下のようにして解消。

# dnf --enablerepo=powertools upgrade

忘れてしまうので、
/etc/yum.repos.d/almalinux-powertools.repo
で以下のように変更。

[powertools]
- enabled=0
+ enabled=1

これで「--enablerepo=powertools」を付けなくても有効化される。


関連記事
shobon.hatenablog.com

CentOS 7のyumコマンドでCentOS-Vault.repoを参照する

CentOS 7のサポート期限が2024/6だったので、cronからエラーメールが届くようになった。

/etc/cron.hourly/0yum-hourly.cron:

Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 名前またはサービスが不明です"
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=extras&infra=stock error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 名前またはサービスが不明です"
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=updates&infra=stock error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 名前またはサービスが不明です"

よく利用させて頂くrikenのリポジトリへ行くと、readmeだけ。(大変お世話になりました)
https://ftp.riken.jp/Linux/centos/7/


解決策として、リポジトリhttps://vault.centos.org/ へ向けるよう変更する。

yumリポジトリディレクトリをバックアップ

# cp -r /etc/yum.repos.d /etc/yum.repos.d.2024-06-30

次に、2つの手順を行う。

(1)/etc/yum.repos.d/CentOS-Base.repo にて、ミラーリポジトリを無効にする。

[base][updates][extras] のディレクティブに、enabled=0 を追加する。
[centosplus] の初期値は 0 になっているが、1 で利用していた場合は 0 にする。

こんな感じで。

[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=0

(2)/etc/yum.repos.d/CentOS-Vault.repo を有効化する

もし、このファイルの末尾に、7.9.2009 の定義が無い場合は、それより前のバージョンの記述を参考に追記する。
7.9.2009 のbase/updates/extras の項目において、 enabled=1 とする。
centosplus は、enabled=0 or 1 どちらか用途に応じて設定。

こんな感じで。

# C7.9.2009
[C7.9.2009-base]
name=CentOS-7.9.2009 - Base
baseurl=http://vault.centos.org/7.9.2009/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

もし、利用しているCent7が 7.9 以外の場合は、そのバージョンのリポジトリを有効化する。


キャッシュを削除

# yum clean all

updateなどでリポジトリへのアクセスを確認

# yum  update
読み込んだプラグイン:fastestmirror
Determining fastest mirrors
C7.9.2009-base                                   | 3.6 kB     00:00
C7.9.2009-extras                                 | 2.9 kB     00:00
C7.9.2009-updates                                | 2.9 kB     00:00
(1/4): C7.9.2009-base/x86_64/group_gz              | 153 kB   00:00
(2/4): C7.9.2009-extras/x86_64/primary_db          | 253 kB   00:00
(3/4): C7.9.2009-base/x86_64/primary_db            | 6.1 MB   00:00
(4/4): C7.9.2009-updates/x86_64/primary_db         |  27 MB   00:00
No packages marked for update

サポート期限までに取り逃がしたupdateがあれば、適用できる。

ついでに、自動更新のパッケージ(yum-cron)をインストールしていた場合は、停止するか削除しておく。
(サポート期限より後では新しいパッチがリリースされず、自動更新する意味がないため)


CentOS 6の時にも同じような記事を書いてた
shobon.hatenablog.com

テンプレートエンジンにおけるループ回数(index)の初期値

テンプレートエンジンでループのインデックス(現在のループ回数)を得る方法が、0 または 1 から始まる違いがあったので調べた。

主要なテンプレートエンジンだけ抜粋。

Blade

Laravelのテンプレートエンジン。
indexは、0 から開始(1から開始するのは、@iteration)
https://readouble.com/laravel/8.x/ja/blade.html

PHPTAL

indexは、0 から開始(1から開始するのは、number)
https://phptal.org/manual/en/#tal-repeat

Twig

Symfonyのテンプレートエンジン。
indexは、1 から開始(0から開始するのは、index0)
https://twig.symfony.com/doc/2.x/tags/for.html#the-loop-variable

Volt

Phalconのテンプレートエンジン。
indexは、1 から開始(0から開始するのは、index0)
https://docs.phalcon.io/5.7/volt/#loop-context


indexが1から始まる場合、index0 という変数が用意されている。

シェルでコマンドの引数にハイフン2個(--)は何?

とあるサービスの起動スクリプトで、

if expr -- "${HOGE__ARGS[*]}" : '.*setuid.*' >/dev/null

といったものを見て、これ何だっけ?となったのでメモ。


これはgetoptの引数解析の仕様。

getoptのmanによると、以下のようにある。

"--" は特殊な引き数で、スキャンのモードによらず、 オプションのスキャンを強制的に終了させる。

ja.manpages.org

つまり、引数解析の終わりを示す。(これより先はオプションではない、と明示するもの)

ここでの「--」の役割は、 "${HOGE__ARGS[*]}" がハイフンから始まる場合に、exprコマンドの引数でない事を保証するためと思われる。

ただ、exprコマンドで - から始まる引数は、「--help, --version」ぐらいに思えるので、どれほど意味があるのかは謎のまま(´・ω・`)

mlmmj の追加設定

前回の続き、公式マニュアルの後半の手順。
6)Reply-To: などのカスタムヘッダを設定
7)フッターの指定
8)件名のプレフィックスを指定
9)モデレートの設定

カスタムヘッダ

リストの配下にある control 配下に、customheaders というファイルを作成する。(ml-admin:MLの名前のパス)

# cat /var/spool/mlmmj/ml-admin/control/customheaders
Reply-To: ml-admin@example.com

フッターの指定

フッターの指定は、~/control/footer というファイルを作成して内容を記載する。
デフォルトでは、何もなく空白。

件名のプレフィックスを指定

~/control/prefix というファイルを作成して内容を記載する。
# echo "[mlmmj-admin]" > control/prefix

mailman等のように、件名に連番を入れる機能は標準では無さそう。

モデレートの設定

~/control/moderated を作成する。
詳しくは未検証。

アーカイブ

/var/spool/mlmmj/リスト名/archive の配下に作成される。

listdir/control の配下に「noarchive」という名前のファイルを作成しておくと、アーカイブが生成されなくなる。
既存のアーカイブを削除するには、OS上でファイルを直接削除する。

メーリングリスト mlmmj を使ってみる

mlmmj とは?

mlmmj は、シンプルな機能を備えたメーリングリスト

mlmmj 公式Webサイト
http://mlmmj.org/

Mlmmjは、「Mailing List Management Made Joyful」の略らしい。


主な特徴は以下の通り。

  • デーモンを必要とせず、省リソースで動作する。
  • MITライセンス
  • シンプルでありながら、色々な機能を備えている

機能の例は以下の通り。

個人的には、件名に連番を付ける機能が欲しかった。(おそらく標準で実装されていない)

ソースコードの最新版は、1.3.0 で 2017/5/24 リリースとなっている。
epelから入手可能なパッケージも、バージョンは同じ。

mlmmj のインストールと設定

<環境>
AlmaLinux 8/9(どちらも同等の手順)

前提として、epel リポジトリを利用可能であること。
/etc/yum.repos.d/epel.repo にて enabled=1 と設定するか、dnfの --enablerepo オプションで有効化する。


パッケージの中身を確認

# dnf repoquery --list mlmmj
/usr/bin/mlmmj-bounce
/usr/bin/mlmmj-list
/usr/bin/mlmmj-maintd
/usr/bin/mlmmj-make-ml
/usr/bin/mlmmj-make-ml.sh
/usr/bin/mlmmj-process
/usr/bin/mlmmj-receive
/usr/bin/mlmmj-receive-strip
/usr/bin/mlmmj-recieve
/usr/bin/mlmmj-send
/usr/bin/mlmmj-sub
/usr/bin/mlmmj-unsub
・・・省略
/usr/share/doc/mlmmj/web
/usr/share/doc/mlmmj/web/perl-admin
・・・省略
/usr/share/doc/mlmmj/web/perl-user
/usr/share/doc/mlmmj/web/perl-user/config.pl
/usr/share/doc/mlmmj/web/perl-user/example.html
/usr/share/doc/mlmmj/web/perl-user/mlmmj.cgi
/usr/share/doc/mlmmj/web/php-admin
・・・省略
/usr/share/mlmmj
/usr/share/mlmmj/text.skel
・・・省略
/usr/share/mlmmj/text.skel/it/wait-sub
/usr/share/mlmmj/text.skel/pt
・・・省略

上記で確認した限り、
 /usr/share/doc/mlmmj/web/perl-admin
 /usr/share/doc/mlmmj/web/php-admin
が用意されているので、perlPHPのWebUIが用意されている模様。

また、/usr/share/mlmmj/text.skel 配下に ja が存在しないので、定型文は日本語で提供されていない。


公式ドキュメントの手順を参考にすると、手順は以下の通り。
http://mlmmj.org/docs/readme

 0)ソースのコンパイル、インストール
 1)拡張アドレスの設定(postfixの場合、recipient_delimiter を設定)
 2)MLを作成
 3)aliases に追加(newaliases を実行)
 4)mlmmj-maintd をタスクスケジュールに登録
   ※これは、長い間バウンスしたメールを掃除したり、
    配送できなかったメールの再送などメンテナンスを行うもの。
    Alma8のパッケージにはcron設定が同梱されていないので、自前で設定。
 5)リストへメンバを追加
 6)Reply-To: などのカスタムヘッダを設定
 7)フッターの指定
 8)件名のプレフィックスを指定
 9)モデレートの設定
 *)WebUIの設定
  →同梱されたREADMEは、以下のもの。
   /usr/share/doc/mlmmj/web/php-admin/README
   /usr/share/doc/mlmmj/web/php-moderation/README
   /usr/share/doc/mlmmj/web/php-user/README


インストールは dnf コマンドで簡単。

# dnf install mlmmj


Postfixにて、拡張メールアドレスを有効化するために recipient_delimiter を設定する。

拡張メールアドレスとは、
 address1@example.com が存在する際に、address1+ext@example.com
というアドレスを定義する機能。
ext の部分は何でも良い。区切り文字の + は任意に設定可能。


Alma8/9ではデフォルトで無効(空白)になっている。

# postconf |grep recipient_delimiter
recipient_delimiter =

/etc/postfix/main.cf にて、以下のように設定する。

#recipient_delimiter = +
 ↓
recipient_delimiter = +

Postfixを再起動

# systemctl restart postfix.service

リストの作成

「mlmmj-make-ml」コマンドを利用して、MLを作成する。
作成したMLは、/var/spool/mlmmj 配下にリスト毎に設定等が保存される。

上記のディレクトリのオーナーとパーミッションを修正する。
(デフォルトの状態 => /var/spool/mlmmj:root.root 755)

# chown postfix:mail /var/spool/mlmmj
# chmod 775 /var/spool/mlmmj


「ml-admin」というMLを作成してみる

# mlmmj-make-ml -c postfix:mail -L ml-admin
Creating Directorys below /var/spool/mlmmj. Use '-s spooldir' to change
The Domain for the List? [] : example.com    ←ドメインを入力
The emailaddress of the list owner? [postmaster] : postfix  ←postfixの実行ユーザを入力

For the list texts you can choose between the following languages or
give a absolute path to a directory containing the texts.

Available languages:
ast  cs  de  en  fi  fr  gr  it  pt  sk  zh-cn
The path to texts for the list? [en] :   ←日本語が無いのでデフォルトでEnter


Don't forget to add this to /etc/aliases:    ←aliasesへ追記するよう指示のメッセージ
ml-admin:  "|/usr/bin/mlmmj-receive -L /var/spool/mlmmj/ml-admin/"

chown -R postfix:mail /var/spool/mlmmj/ml-admin? [y/n]: y  ←オーナーを変更する確認メッセージ

If you're not starting mlmmj-maintd in daemon mode,
don't forget to add this to your crontab:
0 */2 * * * "/usr/bin/mlmmj-maintd -F -L /var/spool/mlmmj/ml-admin/"  ←cronへ追記するよう指示のメッセージ

 ** FINAL NOTES **
1) The mailinglist directory have to be owned by the user running the
mailserver (i.e. starting the binaries to work the list)
2) Run newaliases

mlmmj-make-ml のオプションには以下のようなものがある。

  • -L: The name of the mailing list
  • -s: Your spool directory (default /var/spool/mlmmj)
  • -a: Create the needed entries in your /etc/aliases file
  • -c: User to chown the spool directory to (default not to chown at all)
  • a オプションを付けると、/etc/aliases の末尾へ追記するか尋ねられ、承諾すると設定が追記される。

(-a オプションを指定しない場合は、手動で追記する)

手順的には、ここで「aliases に追加(newaliases を実行)」になるが、
そのまま追加するだけだと後述のエラーに遭遇するので、いったんスキップ。


次に、指示された設定を crontab に追記(実行タイミングは適宜調整)。
(もし、/etc/crontab に記載する場合は、ユーザ名の指定が必要)

0 */2 * * * "/usr/bin/mlmmj-maintd -F -L /var/spool/mlmmj/ml-admin/"


作成されたファイルを確認

# tree /var/spool/mlmmj/
/var/spool/mlmmj/
└── ml-admin
    ├── archive
    ├── bounce
    ├── control
    │   ├── listaddress
    │   └── owner
    ├── digesters.d
    ├── incoming
    ├── index
    ├── moderation
    ├── nomailsubs.d
    ├── queue
    │   └── discarded
    ├── requeue
    ├── subconf
    ├── subscribers.d
    ├── text
    │   ├── confirm
    │   ├── deny
    │   ├── deny-post
    │   ├── digest
    │   ├── faq
    │   ├── finish
    │   ├── finish-sub
    │   ├── gatekeep-sub
    │   ├── help
    │   ├── list
    │   ├── moderate-post
    │   ├── notify
    │   ├── probe
    │   ├── prologue
    │   ├── wait-post
    │   └── wait-sub
    └── unsubconf

メンバーの登録と削除

リストへメンバーを追加する

# /usr/bin/mlmmj-sub -L /var/spool/mlmmj/ml-admin/ -a user1@example.com
Changing to uid 89, owner of /var/spool/mlmmj/ml-admin/.


追加コマンドの主なオプションは以下の通り。

  • -a: Email address to subscribe
  • -c: Send welcome mail (unless requesting confirmation)
  • -C: Request mail confirmation (unless switching versions)
  • -d: Subscribe to digest version of the list
  • -f: Force subscription (do not moderate)
  • -L: Full path to list directory
  • -m: Moderation string
  • -n: Subscribe to nomail version of the list
  • -q: Be quiet (don't notify owner about the subscription)
  • -r: Behave as if request arrived via email (internal use)
  • -R: Behave as if confirmation arrived via email (internal use)
  • -s: Don't send a mail to the subscriber if already subscribed
  • -U: Don't switch to the user id of the listdir owner


追加されたメンバーは、
/var/spool/mlmmj/ml-admin/subscribers.d/
以下に先頭文字のファイルに追記される。
メンバーが0になると、そのファイルも消える。

メンバー一覧を見るには、catでテキストを確認する

# cat /var/spool/mlmmj/ml-admin/subscribers.d/u
user1@example.com

メンバーを削除する

# /usr/bin/mlmmj-unsub -L /var/spool/mlmmj/ml-admin/ -a user1@example.com
Changing to uid 89, owner of /var/spool/mlmmj/ml-admin/.

<削除コマンドの主なオプション>

  • -a: Email address to unsubscribe
  • -b: Behave as if unsubscription is due to bouncing (internal use)
  • -c: Send goodbye mail
  • -C: Request mail confirmation
  • -d: Unsubscribe from the digest version of the list
  • -L: Full path to list directory
  • -n: Unsubscribe from the nomail version of the list
  • -N: Unsubscribe from the normal version of the list
  • -q: Be quiet (don't notify owner about the unsubscribe)
  • -r: Behave as if request arrived via email (internal use)
  • -R: Behave as if confirmation arrived via email (internal use)
  • -s: Don't send a mail to the address if not subscribed
  • -U: Don't switch to the user id of the listdir owner


<MLの削除>
専用のコマンドは無いため、以下を行う。
 ・/var/spool/mlmmj 配下のディレクトリを丸ごと削除
 ・/etc/aliases の設定を削除
 ・cron の設定を削除


aliasへの設定

/etc/aliases へMLのaliasを追記して次の手順へ進もうとしたが、配送時にエラーが発生して失敗した。

<ml-admin@example.com>: Command died with status 1:
    "/usr/bin/mlmmj-receive -L /var/spool/mlmmj/ml-test/". Command output: Have
    to invoke either as root or as the user owning listdir


以下のマニュアルによると、
http://mlmmj.org/docs/readme-postfix/
デフォルトでは、Postfixがmlmmjをnobodyとして実行するためと思われる。

これを回避するには、上記URLにあるように、以下のいずれかを実施する。

  • リストの所有者をnobodyにする(安全はない)
  • Postfixの実行ユーザをmlmmjにする(安全でない、実用的でない)
  • mlmmjユーザが所有するaliasテーブルを追加(準最適)
  • Postfixのtransportを利用して、mlmmjユーザとしてmlmmjを実行(最適)


transportの設定は少し複雑なため、容易な準最適の方法を行った。

1)所有者がpostfixユーザのaliasファイルを新規に作成する。

# touch /var/spool/mlmmj/mlmmj-aliases
# chown postfix:mail /var/spool/mlmmj/mlmmj-aliases

2)main.cf に1番で作成したファイルを参照する設定を追加

alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
 ↓
alias_maps = hash:/etc/aliases, hash:/var/spool/mlmmj/mlmmj-aliases
alias_database = hash:/etc/aliases, hash:/var/spool/mlmmj/mlmmj-aliases

postfixを再起動

# systemctl restart postfix.service


/var/spool/mlmmj/mlmmj-aliases へMLのaliasを追記する。

# for mlmmj ML
ml-admin:  "|/usr/bin/mlmmj-receive -L /var/spool/mlmmj/ml-admin/"

aliasを反映させる

# newaliases

mlmmj-aliases.db が生成される

# ls -l /var/spool/mlmmj/mlmmj-aliases*
-rw-r--r--. 1 postfix mail   111  427 14:10 /var/spool/mlmmj/mlmmj-aliases
-rw-r--r--. 1 postfix mail 12288  427 14:28 /var/spool/mlmmj/mlmmj-aliases.db

※alias_maps と alias_database の違いは以下を参照。
[postfix-jp:01553] alias_maps と alias_database


ここまで完了したら、メールを送信してテストを行う。
投稿したメールがメンバーへ配送されるか、添付(日本語のファイル名も含む)が文字化けしないことを確認。


なお、新しくリストを作成するには、以上の手順をふまえて以下のようになる。
postfixの再起動は不要。

<ML作成時の手順のまとめ>
1)mlmmj-make-ml でリストを作成
 →# mlmmj-make-ml -c postfix:mail -L リスト名
2)cronに追記(1の作成時に表示される内容)
 →"/usr/bin/mlmmj-maintd -F -L /var/spool/mlmmj/リスト名/" を実行する日時
3)/var/spool/mlmmj/mlmmj-aliases に追記(1の作成時に表示される内容)
 →リスト名: "|/usr/bin/mlmmj-receive -L /var/spool/mlmmj/リスト名/"
4)newaliases で反映
5)メンバーを追加
 →# /usr/bin/mlmmj-sub -L /var/spool/mlmmj/リスト名/ -a 追加アドレス


基本的な設定は以上。
ちょっとした追加設定は次回へ続く。

AlmaLinux/RockyLinux8以降のメーリングリストを考える

メーリングリストとして長らくMailmanのお世話になっていたものの、CentOS 7のサポート終了が近く、OSを移行する事に。

ここで、AlmaLinux/RockyLinuxでMailmanを使おうとすると、以下の点に気が付く。

  • CenOS7まで使っていたMailmanは、python2で書かれたmailman2である
  • AlmaLinux/RockyLinux8では、python2は Retirement Date:Jun 2024 (末尾のLife Cycleを参照)
  • そもそも、python2はとっくにEOL(2020年)


AlmaLinux/RockyLinux8では、Mailman2をOSのサポート期限終了(2029年)まで安心して使えないため、使い慣れたMailman2を諦める事に・・・。

という訳で、Mailman2だった環境からMLを乗り換える時の選択肢を調べた。
(移行先はクラウドNG、オンプレ限定)

Mailman3(python3)

Mailman」と冠しているが、Mailman2と互換性は無い。
Fedora向けのepel9ではRPMパッケージがある。

mlmmj(本体はC、WebUIはperlまたはPHP

機能は少なくシンプル。
本体はCで書かれているため高速と思われる。
epel8/9でパッケージ提供あり。
公式のソースが2017年で開発が止まっている。EOLでは無さそう。
件名のprefixに連番を付ける機能が標準で無さそう(たぶん)
WebUIが微妙な感じ。

sympa(perl

mailmanのように高機能。
epel8/9でパッケージ提供あり。
件名のprefixに連番を付ける機能がある。(テキストのファイルを修正すれば、値を途中からにも変更可能)
GUIにはmod_proxyが必要。
(動作させて分かったが)メモリ消費が多く、sympaだけで1GB以上必要。
メモリが少ない環境では厳しい可能性あり。

fml(perl

ソースからインストールするしかない。
公式のソースが2018年で開発が止まっている。EOLでは無さそう?
WebUI環境を使えるようにするまでの敷居が高く見える。

majordomo(perl

ソースからインストールするしかない。
公式のソースが2000年で開発が止まっている。
こちらを選択する理由は無い。


なお、他にもezmlm(qmail環境下で利用)があるが、postfix環境のため除外。

インストールやアップデートのし易さから考えると、mlmmj または sympaが良さそう。

mlmmjはシンプル・省リソース、sympaは高機能・要メモリといった特徴になる。