Mediawikiのメジャーアップグレードの作業メモ

旧LTSバージョンの1.27系列から、1.31.0にアップグレードしたので手順を載せておきます。

【2020/09/27追記】
1.31.10から1.35.0への以降を検証した時のメモを追加し、全体を見直しています。

【2022/12/21追記】
1.35.8から1.39.0へアップグレード可能か検証した際のメモを追加し、全体を見直しています。

【2023/06/27追記】
1.35.9から1.39.3へアップグレードした時のメモを追加しています。

【2025/04/10追記】
1.39.11から1.43.0へアップグレードした時のメモを追加しています。

# 環境 & 注意事項

稼動している環境は、以下のとおりです。

## OS

* 1.27.x to 1.31.0 
  * Ubuntu 16.04.5 LTS amd64版
* 1.31.10 to 1.35.0
  * Ubuntu 20.04.1 LTS amd64版
* 1.35.8 to 1.39.0
  * Ubuntu 20.04.5 LTS amd64版 (作業完了後に22.04.1 LTSに更新予定)
* 1.35.9 to 1.39.3
  * Ubuntu 22.04.2 LTS amd64版
* 1.39.11 to 1.43.0
  * Ubuntu 24.04.2 LTS amd64版

Ubuntu 22.04 では、パッケージで導入できるデフォルトのPHPのバージョンは8.1に更新されています。
PHP8のサポートは、1.38.4以降, 1.39.0以降が対象となっているため、1.39.0へのアップグレードは、Ubuntuのバージョンアップ前に実施しました。

1.39.0での検証ではLDAPAuthentication2がPluggableAuth 6.xに未対応だったため本番環境への適用は見送りました。LDAPAuthentication2がPluggableAuth 7.xに対応したため、1.39.3を本番環境へ適用しましたが、その際にはAnsibleのRoleを利用して本番環境を構築しています。

1.43.0へ移行する際には事前にOSをUbuntu 24.04.2にアップグレードしています。Ubuntu 24.04.2でも1.39.11は問題なく動作しました。

::note
Ubuntu 24.04.2へのアップグレード時には、Apache2のモジュールとしてphp8.1が有効になったままでした。

実際にはphp8.3がインストールされていたため、そのままではApache2はlibphp8.1がロードできないために起動しませんでした。

手動で``sudo a2dismod php8.1 && a2enmod php8.3``を実行してから、``sudo systemctl restart apache2.service``を実行しています。
:::

## Mediawiki Extensions

現在は使用していませんが、1.31.xまでの環境で利用していた拡張機能は以下のとおりです。

* LdapAuthentication
* GraphViz
* MultiUpload

使用しているExtensionや設定ファイルの内容は環境依存ですので、適宜読み替えてください。
既存環境からアップグレードした実例としてみていただければと思います。

1.35以降ではこれらのExtensionsはテストされていないか、更新頻度が低下しているなどの理由から、推奨されなくなりました。
作業の中では、LDAPAuthenticaion2の利用も平行して進めています。

1.39以降では、利用している拡張機能は1.35と同様に提供されていますが、PluggableAuthがバージョン6になったことで大きく変更されており、LDAPAuthentication2が2022年12月時点では対応していない状況です。対応する意向は示されているので、しばらく待つか、OpenID Connectに移行するか検討しているところです。

検証結果からOIDCへの移行ではUXが大きく変化してしまうことを懸念し、2023年6月にPluggableAuth 7.0からLDAPAuthentication2が対応したことを受けて、1.35.xと同様のExtensionsを続けて利用しています。

1.39.3で利用しているExtensionsは次のとおりです。

* LDAPAuthentication2-REL1_39-125b09a.tar.gz
* LDAPAuthorization-REL1_39-7caf22c.tar.gz
* LDAPProvider-REL1_39-12bd838.tar.gz
* LDAPUserInfo-REL1_39-01a4b9e.tar.gz
* PluggableAuth-REL1_39-8a48b65.tar.gz

1.43.0をテストした際にはExtensionsをREL1_43対応版に変更するだけで問題なく動作しています。

この他に本番環境で使用はしていませんが、1.39, 1.43で問題なくテストできたものにOpenIDConnect (OpenIDConnect-REL1_39-f193bef.tar.gz) があります。

# Mediawiki LTSと最新バージョンについて

Mediawikiは長期サポートバージョンをLTSとしてリリースしており、このLTS版のみを利用してきています。

1.39系列は2022/11/30から2025/11までサポートされる予定のLTSバージョンです。

PluggableAuth周りの変更が大きかったため、関連するExtensionsが整備された2023年6月に1.35.9からのアップグレードを実施しました。

1.40系列は2024/12/21から2027/12までサポートされる予定のLTSバージョンです。
1.39.0のような大幅な変更がなかったため、2024年4月に1.39.11から1.43.0にアップグレードしました。

* [Mediawikiバージョンライフサイクル](https://www.mediawiki.org/wiki/Version_lifecycle/ja)

LTS版は変更自体はありませんが、セキュリティ上の問題が頻繁に発見されています。

同一LTSバージョン内の更新作業は比較的定型的な作業です。

メーリングリストに入るなどして、頻繁に更新することをお勧めします。

# アップグレードのテストについて

Mediawikiのアップグレード方法については、VMWare上でテストしています。

このテストには実機上でautomysqlbackupによって、定期的に保存されているMySQLのDBバックアップファイルを使用して稼動を確認しています。

テスト手順をまとめて、ansible roleとして[Github上で公開](https://github.com/YasuhiroABE/ansible-mediawiki-restoredb)しています。

ansibleはパッケージでも導入することができますが、kubesprayのようにバージョンに厳しい場合があるので、個別にvenv環境を準備するのがお勧めです。

```bash:ansibleを利用する前の準備作業(もし導入していない場合)
$ python3 -m venv venv/ansible
$ . venv/ansible/bin/activate
(ansible) $ pip3 install ansible
```

プロンプトが変化するとvenv/ansible/bin/以下のコマンドを優先的に利用します。

ロールはAnsible Galaxyにも登録しているため、次のようにダウンロードして利用することができます。

```bash:ansibleのロールを取得する手順
(ansible) $ ansible-galaxy install yasuhiroabe.mediawiki_restoredb
```

このansible roleを利用するとして、テストは概ね次のような手順になります。

1. ansibleを導入し、```(ansible) $ ansible -m ping``` コマンドが正常に実行できるよう、ansible.cfg と hostsファイルを準備する
2. ansibleや手動で、検証環境にPHPとMySQLサーバーを導入する
3. 本番機からMySQLのバックアップファイルをコピーしてくる (files/dump.sql.gz, etc.)
4. MediaWikiの拡張機能(extensions)の1.39対応版をfiles/にコピーする
5. MySQLの管理ID、パスワード情報等をplaybookに記述する
6. ansibleを実行
7. 稼動確認

1.43.0をテストするタイミングで、ansibleはpython3-pymysqlパッケージに依存するように変更されていたので、``yasuhiroabe.mediawiki_restoredb`` ansible-roleを更新しました。

## 【テスト環境構築】1. ansible環境の設定

利用しているansible.cfgの設定は次のようになっています。

ここでは**remote_user**に指定したユーザーは、対象のホストでパスワードなしにsudoコマンドが実効できるようにしています。

パスワードを要求するままにしたい場合は、ansible vaultの設定を行ってください。

```text:ansible.cfg
[defaults]
inventory = hosts

remote_user = user01

host_key_checking = True
private_key_file = /home/user01/.ssh/id_ed25519
roles_path = ./roles
log_path = ansible.log

[privilege_escalation]
become = True
```

hostsファイルには仮想マシンなどのIPアドレスを指定しておきます。

```text:hostsファイルの内容
[mediawiki]
192.168.1.10
```

正しく設定が終ると次のような手順で、検証環境から反応があります。

```bash:ansibleコマンドのテスト
(ansible) $ ansible -m ping
```

## 【テスト環境構築】2. 検証環境にPHPとMySQLサーバーを導入する

Ubuntu 24.04の検証環境では、次の手順でパッケージを導入しています。

```bash
$ sudo apt install mysql-server
```

## 【テスト環境構築】3. 本番環境からファイルをコピーし、files/に配置する

次のようなファイルを本番環境からコピーしてきます。

* MySQLのバックアップファイル
* LocalSettings.php
* ロゴなどのimagesファイル

本番環境のバックアップファイルを入手して、ansible.cfgを配置したディレクトリにfilesディレクトリを作成し、中に保存します。

MySQLについては、本番環境でautomysqlbackupコマンドを利用しているので、/var/lib/automysqlbackup/daily/my_wiki/my_wiki_2020-09-27_06h25m.Sunday.sql.gz にあるファイルを転送し、ファイル名を"dump.sql.gz"に変更して利用しています。

LocalSettings.phpやimageファイルは、files/にコピーし、後でplaybook.yamlに記述します。

## 【テスト環境構築】4. MediaWikiの拡張機能(extensions)の1.43対応版を入手する

Mediawikiの拡張機能は次のURLから検索して、1.43に対応するバージョンを入手します。

* https://www.mediawiki.org/wiki/Special:ExtensionDistributor

ダウンロードしたファイルは、dump.sql.gzと同様に、files/ディレクトリに配置します。

:::note
別途記載しているとおり、1.31から1.35への更新では、これまで利用していた3つのextensionsは1.35.xでは十分にテストされていなかったり、別のextensionが推奨されていたりする状況でした。アップグレードする場合には利用しているextensionの情報に注意してください。
:::

## 【テスト環境構築】5.MySQLの管理ID、パスワード情報等をplaybook.yamlファイルを準備する

ansible-playbookコマンドの引数に指定するYAML景気のファイル(この例ではplaybook.yamlファイル）を準備します。

files/ディレクトリに配置したdump.sql.gzやextensionsファイルの情報を追記します。

```bash:files/ディレクトリの様子
$ $ ls -l files/
total 55968
-rw-r--r-- 1 yasu yasu  1058123 Dec 21 15:04 dump.sql.gz
-rw-rw-r-- 1 yasu yasu    93637 Dec  5 21:12 LDAPAuthentication2-REL1_39-2f16a35.tar.gz
-rw-rw-r-- 1 yasu yasu    98428 Dec  7 17:16 LDAPAuthorization-REL1_39-68d10f0.tar.gz
-rw-rw-r-- 1 yasu yasu      960 Mar 10  2021 ldapprovider.json
-rw-rw-r-- 1 yasu yasu   132369 Dec  4 19:12 LDAPProvider-REL1_39-63dc241.tar.gz
-rw-rw-r-- 1 yasu yasu    91501 Dec  4 19:13 LDAPUserInfo-REL1_39-492578d.tar.gz
-rw-rw-r-- 1 yasu yasu     5298 Dec 21 15:22 LocalSettings.php.j2
-rw-rw-r-- 1 yasu yasu 55728839 Dec  1 05:38 mediawiki-1.39.0.tar.gz
-rw-rw-r-- 1 yasu yasu     2935 Jan 22  2015 mylogo.png
-rw-rw-r-- 1 yasu yasu    74044 Dec  7 02:18 PluggableAuth-REL1_39-3a8142d.tar.gz
```

LocalSettings.php.j2はPythonのJinja2テンプレートエンジンに対応したスケルトンファイルで、memi_mysql_passなどを変数として展開できます。今回は単純に本番環境のLocalSettings.phpのファイル名を変更しています。

mylogo.pngはMediawikiの左上に表示されるロゴのイメージファイルで、本番環境からコピーしてきたものです。

これらの情報を反映したplaybook.yamlファイルの内容は次のようになりました。

```yaml:playbook.yaml
---
- hosts: all
  vars:
    memi_mediawiki_filepath: "files/mediawiki-1.43.0.tar.gz"
    memi_restoredb_filepath: "files/dump.sql.gz"
    memi_restore_dbname: "my_wiki"
    memi_mysql_user: "wiki"
    memi_mysql_pass: "test"
    memi_mediawiki_extensions_filepath:
      - "files/LDAPAuthentication2-REL1_43-a98cfcc.tar.gz"
      - "files/LDAPAuthorization-REL1_43-7533dd2.tar.gz"
      - "files/LDAPProvider-REL1_43-7febfb9.tar.gz"
      - "files/LDAPUserInfo-REL1_43-8c3735f.tar.gz"
      - "files/LastUserLogin-REL1_43-9ea9eba.tar.gz"
      - "files/OpenIDConnect-REL1_43-953d604.tar.gz"
      - "files/PluggableAuth-REL1_43-b9a8782.tar.gz"
    memi_mediawiki_additional_files:
      - { src: "files/mylogo.png", dest: "{{ memi_mediawiki_destdir }}/images" }
      - { src: "files/ldapprovider.json", dest: "{{ memi_mediawiki_destdir }}" }
  roles:
    - yasuhiroabe.mediawiki_restoredb
```

:::note
2020/09/27に確認したところ、ansible galaxyに登録していた yasuhiroabe.mediawiki_restoredb は、roles/yasuhiroabe.mediawiki_restoredb/files/... を探しにいくようになっていたので、ansible.cfg等のファイルを配置しているディレクトリを起点として、./files/... を探しにいくように変更しました。

2024/04/10に確認したところ、Ubuntu 24.04.2で新規にmysqldを動作させたタイミングでは正常に動作しなかったため、DBセットアップのための内部taskの動作順を変更しています。
:::

## 【テスト環境構築】6. ansibleを実行

```bash:準備したplaybook.yamlの実行
(ansible) $ ansible-playbook playbook.yaml
```

MySQLに対しては、playbook.yamlに設定した memi_mysql_user, memi_mysql_pass が設定されます。
これと同じ内容がLocalSettings.phpに記述する必要があります。

php update.phpを実行するタイミングで、これらの設定が正しくないと、MySQLに接続しようとしたままansibleタスクがハングアップします。

この他、古いバージョンの記述が残っている場合にはエラーが表示されるので、適宜解決して、繰り返し ansible-playbookコマンドを実行してください。

## 【テスト環境構築】8. DBスキーマの更新

リモートサーバー(ここではhostsに設定した192.168.1.10)にログインし、次のようにデータベースの内容を更新します。

```bash:
$ cd /var/www/html/mediawiki/
$ sudo php maintenance/update.php
```

## 【テスト環境構築】7. 稼動の確認

ansible-playbookが正常に終了すると、既にapache2, mysqldは稼動しているので、Webブラウザからアクセスできること、各拡張機能が正常に稼動していることを確認します。

# アップグレード手順 (本番機)

ansible-playbookを利用することもできますが、DBの初期化など不要な作業が多いので、ここではコマンドレベルで作業の流れを記述します。

## 作業概要

まずapache2プロセスを停止します。

本番環境ではMySQLは停止せずにバックアップファイルが保全されていることを確認します。

次にmediawiki-1.43.0のtargzballを展開し、LocalSettings.phpファイルを配置した上で、maintenanceディレクトリで"$ sudo php update.php"を実行します。

最後にパーミッションを適切に変更し、apache2プロセスのリスタートします。

### ファイルの準備
~/mediawiki-1.43.0/ の下に次のようにファイルを準備します。

```shell
-rw-rw-r--  1 user01 user01 35210387 Sep 20 15:28 mediawiki-1.43.0.tar.gz
-rw-rw-r-- 1 user01 user01  96259 Apr 10 12:02 LastUserLogin-REL1_43-9ea9eba.tar.gz
-rw-rw-r-- 1 user01 user01 102686 Apr 10 12:29 LDAPAuthentication2-REL1_43-a98cfcc.tar.gz
-rw-rw-r-- 1 user01 user01 108465 Apr 10 12:30 LDAPAuthorization-REL1_43-7533dd2.tar.gz
-rw-rw-r-- 1 user01 user01 144903 Apr 10 12:32 LDAPProvider-REL1_43-7febfb9.tar.gz
-rw-rw-r-- 1 user01 user01 101186 Apr 10 12:31 LDAPUserInfo-REL1_43-8c3735f.tar.gz
-rw-rw-r-- 1 user01 user01 132314 Apr 10 12:32 PluggableAuth-REL1_43-b9a8782.tar.gz
```

### apache2プロセスの停止

プロセスを停止します。

```bash:apache2の停止
$ /etc/init.d/apache2 stop
```

#### ファイルの展開

```bash
$ cd /var/www/html
$ ls -l    ## mediawiki-1.43.0 ディレクトリが存在しない事を確認する
$ tar xvzf ~/mediawiki1.43.0/mediawiki-1.43.0.tar.gz
```

### LocalSettings.phpファイルの準備

"cp -i"の部分では、カレントディレクトリにLocalSettings.phpが存在するとエラーとなります。

```bash
$ cd /var/www/html/mediawiki-1.43.0
$ sudo cp -i ../mediawiki/LocalSettings.php .
```

### extensionsディレクトリへのモジュールの展開

```bash
$ cd /var/www/html/mediawiki-1.43.0/extensions
$ sudo tar xvzf ~/mediawiki1.43.0/LastUserLogin-REL1_43-9ea9eba.tar.gz
$ sudo tar xvzf ~/mediawiki1.43.0/LDAPAuthentication2-REL1_43-a98cfcc.tar.gz
$ sudo tar xvzf ~/mediawiki1.43.0/...
```

### imagesディレクトリのコピー

```bash
$ cd /var/www/html/mediawiki-1.43.0/images
$ sudo rsync -av ../../mediawiki/images/. .
```

### 本番ディレクトリへのプロモーション

```bash
$ cd /var/www/html
$ sudo mv mediawiki mediawiki-1.39.11
$ sudo mv mediawiki-1.43.0 mediawiki
```

### php update.phpの実行

DBの構造を1.31系列に対応させるためにupdate.phpを実行します。

```bash
$ cd /var/www/html/mediawiki/maintenance
$ sudo php update.php
```

### パーミッションの変更
自分以外はサーバーにログインできないため、apache2プロセスから最低限のファイルだけ書き換えられるように変更しています。

```bash
$ cd /var/www/html/mediawiki/
$ sudo chown -R root:www-data .
$ sudo chmod -R a+rX,g-w,o-w .
$ sudo chown -R www-data:www-data LocalSettings.php images cache
$ sudo chmod 0600 LocalSettings.php
```

cache/ディレクトリは一度cdbファイルの更新が終れば戻しても大丈夫ですが、権限がないと更新直後にlocalization関連のファイルを更新する時に次のようなエラーメッセージが表示されます。

```text:cache/ディレクトリに権限が不足している時のエラーメッセージ
[Wed Jul 03 12:39:33.086187 2024] [php:warn] [pid 16996] [client 192.168.1.20:15014] PHP Warning:  fopen(/var/www/html/mediawiki/cache/l10n_cache-en.cdb.tmp.707784744): Failed to open stream: Permission denied in /var/www/html/mediawiki/vendor/wikimedia/cdb/src/Writer/PHP.php on line 44
```

### apache2の起動

```bash
$ sudo /etc/init.d/apache2 start
```

## マイナー更新作業手順の全体

メジャーアップグレードと違いマイナーアップグレードは頻繁に発生する作業です。
そのため実際に使用している手順を掲載しておきます。

Ubuntu 24.04.2で1.43.0を稼動していた環境で、最新の1.43.1に更新した際には次のような資料を作成してから作業を実施しました。

```bash:実際の作業手順書から抜粋
 $ sudo /etc/init.d/apache2 stop
 $ cd /var/www/html/
 ## バックアップの作成
 $ sudo mv mediawiki ../mediawiki-1.43.0
 $ ls -l   ## mediawikiディレクトリがない事を確認する
 ## 新しいmediawiki tarballの展開
 $ sudo tar xvzf ~/mediawiki-1.43.1/mediawiki-1.43.1.tar.gz
 $ sudo mv mediawiki-1.43.1 mediawiki
 $ cd mediawiki
 ## 必要なファイルのコピー
 $ sudo rsync -av ../../mediawiki-1.43.0/images/. images/.
 ## 手間を削減するため安定してきてパッケージが更新されなくなったら 1.43.0/extentions/ からファイルをコピーする手順を記述する 
 ## 今回は省略  →  (e.g. $ echo sudo rsync -av ../../mediawiki-1.43.x/extensions/PluggableAuth extensions/.)
 ## その他の設定ファイルをコピーする
 $ sudo cp -ip ../../mediawiki-1.43.0/LocalSettings.php .
 $ sudo cp -ip ../../mediawiki-1.43.0/ldapprovider.json .
 ## cacheファイルを更新する
 $ sudo cp -ip ../../mediawiki-1.43.0/cache/* cache/.
 ## 更新されたextensionsを更新する
 $ sudo tar xvzf ~/mediawiki-1.43.1/PluggableAuth-REL1_43-*.tar.gz -C extensions/.
 $ sudo tar xvzf ~/mediawiki-1.43.1/LastUserLogin-REL1_43-*.tar.gz -C extensions/.
 $ sudo tar xvzf ~/mediawiki-1.43.1/LDAPUserInfo-REL1_43-*.tar.gz -C extensions/.
 $ sudo tar xvzf ~/mediawiki-1.43.1/LDAPProvider-REL1_43-*.tar.gz -C extensions/.
 $ sudo tar xvzf ~/mediawiki-1.43.1/LDAPAuthorization-REL1_43-*.tar.gz -C extensions/.
 $ sudo tar xvzf ~/mediawiki-1.43.1/LDAPAuthentication2-REL1_43-*.tar.gz -C extensions/.
 ## ファイル&ディレクトリパーミッションの変更
 $ sudo chown -R root:www-data .
 $ sudo chmod -R a+rX,g-w,o-w ./
 $ sudo chown -R www-data:root LocalSettings.php images cache
 $ sudo chown root:root cache/.htaccess
 $ sudo chmod 0600 LocalSettings.php
 ## 作業完了後に、サービスを起動する
 $ sudo /etc/init.d/apache2 start
```

:::note warn
テスト環境で利用したansible playbookではupdate.phpを必ず実行するようにしているため、本番環境を構築するためにも利用可能ですが、DBの内容がバックアップで上書きされてしまうので慎重に検討してください。
:::

# LocalSettings.phpの変更点

## 1.35.0への移行時

1.31.10から.1.35.0へのバージョンアップ時に内容を見直しましたが、LdapAuthentication用の設定で、1.27より古い記述が残っていたので最新のフォーマットに変更しました。

## 1.39.3への移行時

1.35.9から1.39.3へのアップグレードでは、LocalSettings.phpには大きな変更はありませんでした。
update.phpを必ず実施しなければいけない点に注意すれば移行自体はそれほど大変ではないと思います。

PluggableAuthの内部機構が大きく変更されたことを受けて関連するExtensionの設定の変更が必要でした。

* [Manual:Upgrading](https://www.mediawiki.org/wiki/Manual:Upgrading)
* [Extension:PluggableAuth](https://www.mediawiki.org/wiki/Extension:PluggableAuth/ja)
* [Extension:LDAPAuthentication2 - Migration from PluggableAuth 5](https://www.mediawiki.org/wiki/Extension:LDAPAuthentication2#Configuration)

主な変更点は以下のとおりです。

なお$wgPluggableAuth_Configで指定している'domain' => 'LDAP_ID' の **LDAP_ID** はldapprovider.jsonに記述している変数名です。

```diff:
diff --git a/files/LocalSettings.php.j2 b/files/LocalSettings.php.j2
index e7b3565..5520a75 100644
--- a/files/LocalSettings.php.j2
+++ b/files/LocalSettings.php.j2
@@ -127,10 +127,10 @@ $wgDefaultSkin = "vector";
 
 # Enabled skins.
 # The following skins were automatically enabled:
-wfLoadSkin( 'MonoBook' );
-wfLoadSkin( 'Timeless' );
-wfLoadSkin( 'Vector' );
-
+wfLoadSkin('MinervaNeue');
+wfLoadSkin('MonoBook');
+wfLoadSkin('Timeless');
+wfLoadSkin('Vector');
 
 # End of automatically generated settings.
 # Add more configuration options below.
@@ -154,7 +154,12 @@ $LDAPProviderDefaultDomain = "LDAP_ID";
 
 ## -- Setting of PluggableAuth --
 $wgPluggableAuth_EnableAutoLogin = true; ## default: false
-$wgPluggableAuth_ButtonLabelMessage = "Login with your LDAP-ID";
+$wgPluggableAuth_Config['Log In (LDAP ID)'] = [
+    'plugin' => 'LDAPAuthentication2',
+    'data' => [
+        'domain' => 'LDAP_ID'
+    ]
+];
 
 ## -- Setting of LDAPAuthentication2 --
 $LDAPAuthentication2UsernameNormalizer = "strtolower";
```

1.39.3への移行は、ldapprovider.jsonなどの変更は必要なく、各Extensionの説明に記載されているとおりの軽微な変更で完了しました。

# 1.39.0へのアップグレードを検討した際の不具合について

## LDAP - The supplied credentials could not be authenticated.

このメッセージは、機能拡張ではなく、mediawiki自体が表示するメッセージです。

"languages/i18n/en.json"を確認すると、"authmanager-authn-no-primary" がキーとなっていて、このメッセージは、./includes/auth/AuthManager.php が表示していると分かります。

この情報を元に検索すると、次のドキュメントが発見できて、LDAPAuthentication2を使っている以上は、ちょっと回避できなさそうな雰囲気を感じています。

* [https://www.mediawiki.org/wiki/Extension_talk:PluggableAuth](https://www.mediawiki.org/wiki/Extension_talk:PluggableAuth)

```text:引用
I'm having the same issue and I'm fiddling aroung with that for days within a Docker container. 
What I found out is that the PluggableAuth in version >6 seems to have breaking changes and doesn't support LDAPAuthentication2 anymore.

This is quite unfortunate since I already ran the database update. 
:-D I guess I will have to switch to SAML authentication to make it work again. 
Or does anyone know more about upcoming support of LDAPAuthentication2 on this?
```

ここで言及されているように、PluggableAuthのCompatibility Matrixを確認すると、バージョン6では、サポートする機能拡張の種類は大きく削減されています。

* [https://www.mediawiki.org/wiki/Extension:PluggableAuth#Installation](https://www.mediawiki.org/wiki/Extension:PluggableAuth#Installation)

:::note info
PluggableAuthのバージョン7ではサポートされる機能拡張は増えています。
この段階で1.39.3への移行を行いました。
:::

OpenID Connectはサポートされているので、基盤としてLDAPをバックエンドとするDexを運用しているため移行はできるのですが、なかなか大きな変更が必要になります。

LDAPAuthentication2の方ではどうなっているか確認すると、次の記事が出てきます。

* [https://www.mediawiki.org/wiki/Topic:X8rqc0kuh13u14nz](https://www.mediawiki.org/wiki/Topic:X8rqc0kuh13u14nz)

ここでは2023年以降に対応するかな、といった反応になっていて、すぐには解決しそうにありません。

認証基盤を変更することのデメリットは、ユーザー情報が引き継がれず、新規ユーザーとなる可能性があることです。

しばらくOpenID Connectへの移行も検討しながら、様子をみようと思います。

## Ubuntu 20.04 における、OpenID Connectへの対応

Ubuntu 20.04は、PHP7.4が標準のパッケートとして準備されていますが、Ubuntu 22.04では、PHP8.1になります。

現時点では1.35.xでのPHP8.1サポートも限定的ではありますが提供されていて、バックポートも検討されているようです。

とはいえ、1.39.0リリース時点での現実的な対応は、Ubuntu 20.04側で1.39.0にアップグレードしてから、Ubuntu 22.04.xで問題がないことを確認した後にOSをアップグレードすることになります。

これらを含めて、OpenID Connect(OIDC)を試した際の留意点は次のようになります。

* Ubuntu 20.04のまま、Mediawikiを1.39.0に更新することで問題が発生しないか
* 付属パッケージのcomposerが古いため、手動で /usr/local/bin/ に composerをインストールする
* $wgLanguageCode = "ja";を指定すると、OIDCのRedirectURIが"/Special:PluggableAuth"から"/特別:PluggableAuth"になり、RedirectURIの内部検証でエラーとなる
    * wgLanguageCodeの変更("ja"から"en")は、メインページへのリダイレクトが正常に行われないなどの影響がある
    * メインページの変更は/mediawiki/index.php/MediaWiki:Mainpageの設定を変更することで対応可能
    * [https://www.mediawiki.org/wiki/Manual:Language/ja](https://www.mediawiki.org/wiki/Manual:Language/ja)では、$wgLanguageCodeの設定値は、稼動期間内で不変であるべきという記述に留意すること

試したところそれぞれ対応可能ですが、一番問題なのは、ローカライズされた特別ページのURLを利用すると正常に動作しない点です。

これはDex側の問題とみられたため、利用している[dexidp/dexにissuesとして報告](https://github.com/dexidp/dex/issues/2766)しています。

手元のDexにはパッチを当てて運用しているのでOpenID Connectでユーザー情報が引き継がれない問題は残るものの移行自体は可能だという事が分かりました。

### 検証に使用したOIDC用の設定

LocalSettings.phpには次のようなコードを追加しています。

この時のPluggableAuthはバージョン6です。

```php:OIDC認証用のLocalSettings.phpの追加部分(Mediawiki1.39.0)
wfLoadExtensions( [
  'PluggableAuth',
  'OpenIDConnect'
] );

## -- Setting of PluggableAuth --
$wgPluggableAuth_EnableAutoLogin = true; ## default: false
$wgPluggableAuth_ButtonLabelMessage = "Login with your LDAP-ID";

## Setting for OpenID Connect
$wgPluggableAuth_Config[] = [
    'plugin' => 'OpenIDConnect',
    'data' => [
        'providerURL' => 'https://dex.example.org/dex',
        'clientID' => 'mediawiki',
        'clientsecret' => '5f6f6e5fe62156d88783885143526621'
    ]
];
$wgOpenIDConnect_UseEmailNameAsUserName = true;
```

使用するExtensionsの数は減っていますし、かなり便利ですが、これまでLDAPで利用していたユーザーとのID統合は難しそうです。

# 1.39.3をデプロイする際に使用したAnsible-Playbookとハードウェア環境の移行

1.35.9からの更新のタイミングで、ハードウェアをそれまでのPC Engines社製APUから、Protectli社製VP2420に変更しました。

ハードウェアのコストが2倍になって、性能はPassmark値で6倍ほどになっていますが、SSDのIO性能にはほぼ変更がないため体感できる性能差は大きくありません。

同時にUbuntu 20.04だったOSは、22.04を新規にインストールしていて、OSレベルで多くの差異が発生しています。

今後の事も考えて今回の作業内容はUbuntuのAutoInstallやAnsibleを利用してreplayableにしています。

間違ってplaybookが動作するとMediawikiの内容をバックアップDBの内容まで戻ってしまうため、automysqlbackupパッケージを動作させて万が一の事故に備えています。

これらの変更を行うためのYAMLファイルは次のとおりです。

```yaml:setup.yaml
---
- name: mediawiki setup script
  hosts: all
  vars:
    mfts_sshd_listen_ipaddr: 192.168.1.20
    mfts_hostname: "mediawiki"
    mfts_sysctl_rules:
      - { name: net.ipv4.ip_forward, value: 0 }
    mfts_additional_packages:
      - apache2
      - automysqlbackup
      - iptables-persistent
      - make
      - mysql-server
      - openntpd
      - php
      - php-db
      - php-intl
      - php-ldap
      - ufw
     mfts_lineinfile_after_packages:
      - { path: "/etc/default/ufw", regexp: "^IPV6=", line: "IPV6=no", state: "present", insertbefore: "" }
    mfts_setup_directory:
      - { path: "/etc/netplan/00-installer-config.yaml", state: "absent" }
      - { path: "/usr/share/ca-certificates/local", state: "directory", mode: "0755", owner: "root", group: "root" }
    mfts_copy_files:
      ## netplan
      - { src: "{{ inventory_dir }}/files/netplan/01-br0.yaml", dest: "/etc/netplan/01-br0.yaml", owner: "root", group: "root", mode: "0444" }
      ## check scripts
      - { src: "{{ inventory_dir }}/files/scripts/check-sshd", dest: "/usr/local/sbin", owner: "root", group: "root", mode: "0744" }
    mfts_copy_files_after_packages:
      ## openntpd
      - { src: "{{ inventory_dir }}/files/openntpd/ntpd.conf", dest: "/etc/openntpd/ntpd.conf", owner: "root", group: "root", mode: "0644" }
      - { src: "{{ inventory_dir }}/files/openntpd/default", dest: "/etc/default/openntpd", owner: "root", group: "root", mode: "0644" }
      ## apache2
      - { src: "{{ inventory_dir }}/files/apache2/nii-odca4g7rsa.cer", dest: "/usr/share/ca-certificates/local", owner: "root", group: "root", mode: "0644" }
      - { src: "{{ inventory_dir }}/files/apache2/mediawiki.example.com.cer", dest: "/usr/share/ca-certificates/local", owner: "root", group: "root", mode: "0644" }
      - { src: "{{ inventory_dir }}/files/apache2/mediawiki.example.com.nopass.key", dest: "/etc/ssl/private/", owner: "root", group: "root", mode: "0400" }
      - { src: "{{ inventory_dir }}/files/apache2/mediawiki.conf", dest: "/etc/apache2/sites-available/", owner: "root", group: "root", mode: "0644" }
      - { src: "{{ inventory_dir }}/files/apache2/mediawiki-ssl.conf", dest: "/etc/apache2/sites-available/", owner: "root", group: "root", mode: "0644" }
    mfts_command_after_copyfiles: []  ## - { command: "netplan apply", become: "yes" }
    mfts_command_after_packages:
      - { command: "/usr/sbin/a2dissite -q 000-default", become: "yes" }
      - { command: "/usr/sbin/a2enmod -q ssl", become: "yes" }
      - { command: "/usr/sbin/a2enmod -q rewrite", become: "yes" }
      - { command: "/usr/sbin/a2enmod -q ldap", become: "yes" }
      - { command: "/usr/sbin/a2ensite -q mediawiki", become: "yes" }
      - { command: "/usr/sbin/a2ensite -q mediawiki-ssl", become: "yes" }
    mfts_systemd_rules:
      - { name: "apache2.service", state: "started", enabled: "yes", daemon_reload: "yes" }
    ## ufw (firewall)
    mfts_ufw_enable: True
    mfts_ufw_enable_logging: True
    mfts_ufw_service_rules:
      - { type: "allow", port: "22", from_ip: "192.168.139.0/24", to_ip: "192.168.1.20/32" }
      - { type: "allow", port: "80", from_ip: "192.168.0.0/16", to_ip: "192.168.1.20/32" }
      - { type: "allow", port: "443", from_ip: "192.168.0.0/16", to_ip: "192.168.1.20/32" }
    mfts_cronjob_rules:
      - { name: "reboot", minute: "30", hour: "3", day: "1,15", job: "/sbin/shutdown -r now" }
      - { name: "check-sshd", minute: "5", job: "/usr/local/sbin/check-sshd" }
    mfts_command_atlast:
      - { command: "/usr/sbin/iptables-save | tee /etc/iptables/rules.v4", become: "yes" }
  roles:
    - YasuhiroABE.myfavorite-setting
```

1.35.9のバックアップDBから、1.39.3をセットアップした時のansible-playbook YAMLファイルは次のようになっています。

```yaml:
---
- hosts: all
  vars:
    memi_mediawiki_filepath: "files/mediawiki/mediawiki-1.39.3.tar.gz"
    memi_restoredb_filepath: "files/automysqlbackup/my_wiki_2023-06-25_06h25m.Sunday.sql.gz"
    memi_restore_dbname: "my_wiki"
    memi_mysql_user: "wikiuser"
    memi_mysql_pass: "0dfa29fa26"
    memi_mediawiki_extensions_filepath:
      - "files/mediawiki/LDAPAuthentication2-REL1_39-125b09a.tar.gz"
      - "files/mediawiki/LDAPAuthorization-REL1_39-7caf22c.tar.gz"
      - "files/mediawiki/LDAPProvider-REL1_39-12bd838.tar.gz"
      - "files/mediawiki/LDAPUserInfo-REL1_39-01a4b9e.tar.gz"
      - "files/mediawiki/PluggableAuth-REL1_39-8a48b65.tar.gz"
    memi_mediawiki_additional_files:
      - { src: "files/mediawiki/header.png", dest: "{{ memi_mediawiki_destdir }}/images" }
      - { src: "files/mediawiki/ldapprovider.json", dest: "{{ memi_mediawiki_destdir }}" }
  roles:
    - yasuhiroabe.mediawiki_restoredb
```

ただ mediawiki/images/ ディレクトリの内容は複雑なので、別途手動で展開しています。

なお利用したAnsibleのRoleのコードは[github.com/YasuhiroABE/ansible-mediawiki-restoredb](https://github.com/YasuhiroABE/ansible-mediawiki-restoredb)に置いています。

テストでVM上に既存の環境をコピーする時に使っています。

# 1.39.11から1.43.0への移行時の問題

Extensionsを1.43に対応したバージョンに置き換えないとmediawikiが動作しないということはテスト環境ではありましたが、私の利用範囲では問題はまったくありませんでした。

以前のバージョンアップと比べると、今回の作業はテスト環境の構築と検証などはありましたが、難易度はパッチレベルのアップデート作業と同程度でした。

以上