有馬総一郎のブログ

(彼氏の事情)

2022年01月28日 10:11:55 JST - 4 minute read - Comments - subsonic

AirsonicをTomcat9コンテナで起動したら、ユーザー、グループ権限がtomcatなのにファイル作成の許可がありませんエラー

結局、 Airsonic-Advancedスタンドアロンアプリケーションで起動させることになって、外部Tomcat1は使わないことになったのだけど、Tomcat8からTomcat9にアップグレードするときに色々、罠があったので、メモしておく。

インストールはsudo apt install tomcat9で行なった。 server.xml ファイルだけ少し修正。

/var/lib/tomcat9/conf/server.xml

-  <Server port="-1" shutdown="SHUTDOWN">
+  <Server port="8005" shutdown="SHUTDOWN">
-      <!--
-      <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
+      <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-      -->

で、tomcat8は

/etc/default/tomcat8

# Run Tomcat as this user ID. Not setting this or leaving it blank will use the
# default of tomcat8.
TOMCAT8_USER=tomcat8

# Run Tomcat as this group ID. Not setting this or leaving it blank will use
# the default of tomcat8.
TOMCAT8_GROUP=tomcat8

と定義してるとおり、tomcat8というユーザー、グループで実行していた。それがtomcat9インストールとともにtomcatというユーザー、グループが追加された。

$ cat /etc/passwd | grep tomcat
tomcat8:x:111:118::/var/lib/tomcat8:/bin/false
tomcat:x:997:997:Apache Tomcat:/:/sbin/nologin
$ cat /etc/group |  grep tomcat
tomcat8:x:118:
tomcat:x:997:

/etc/default/tomcat9 にはTOMCAT8_USERTOMCAT8_GROUPといった設定箇所はなくなっている。

ubuntu - Tomcat9 keep running under user tomcat9 even after change in /etc/default/tomcat9 file - Stack Overflow などみると、ユーザー、グループを変えたい時は、tomcat設定ファイルの編集をするのではなく、OSのサービスの設定に従って変更しろってことのようだ。

sudo systemctl enable tomcat9.serviceしたときにリンク貼られる。/etc/systemd/system/multi-user.target.wants/tomcat9.serviceのリンク元ファイル/lib/systemd/system/tomcat9.serviceを覗くと、なるほど

# Security
User=tomcat
Group=tomcat

とある。実際は/etc/systemd/system/tomcat9.service.d/override.confまたは/etc/systemd/system/tomcat9.serviceを作って編集する2ということなのかな?

ともあれ、ユーザー、グループの変更はせずtomcatairsonicを実行するので、それまでtomcat8権限だったディレクトリ、ファイルの権限を変更する。

sudo chown -R tomcat:tomcat /var/airsonic
sudo chown -R tomcat:tomcat /var/lib/tomcat9/webapps/airsonic.war

しかし、これで実行したら

Caused by: java.io.FileNotFoundException: /var/airsonic/airsonic.properties (許可がありません)
Caused by: org.hsqldb.HsqlException: Database lock acquisition failure: lockFile: org.hsqldb.persist.LockFile@22d6d632[file =/var/airsonic/db/airsonic.lck, exists=false, locked=false, valid=false, ] method: openRAF reason: java.io.FileNotFoundException: /var/airsonic/db/airsonic.lck (読み込み専用ファイルシステムです)

などエラーが出てしまった。元からあるファイル、ディレクトリのせいかと思い、 var/airsonic 配下を新規に作り直しても駄目。いっそ、sudo chmod -R 777 /var/airsonicとしてしまうも、やはり駄目。

Airsonic not playing nice with Tomcat9 · Issue #1055 · airsonic/airsonic · GitHubに回答があった。

/etc/systemd/system/tomcat9.service.d/airsonic.conf

[Service]
ReadWritePaths=/var/airsonic/

上記のようにファイルを作成することで解決した。確かに Tomcat WAR installation - Airsonicをみると、手順として書かれていた。見落としていた…

サービス設定ファイルの# Securityをよくよく見ると

/lib/systemd/system/tomcat9.service

ProtectSystem=strict
ReadWritePaths=/etc/tomcat9/Catalina/
ReadWritePaths=/var/lib/tomcat9/webapps/

とあって systemd.execを見ると

ProtectSystem=

Takes a boolean argument or the special values “full” or “strict”. If true, mounts the /usr/ and the boot loader directories (/boot and /efi) read-only for processes invoked by this unit. If set to “full”, the /etc/ directory is mounted read-only, too. If set to “strict” the entire file system hierarchy is mounted read-only, except for the API file system subtrees /dev/, /proc/ and /sys/ (protect these directories using PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=). This setting ensures that any modification of the vendor-supplied operating system (and optionally its configuration, and local mounts) is prohibited for the service. It is recommended to enable this setting for all long-running services, unless they are involved with system updates or need to modify the operating system in other ways. If this option is used, ReadWritePaths= may be used to exclude specific directories from being made read-only. This setting is implied if DynamicUser= is set. This setting cannot ensure protection in all cases. In general it has the same limitations as ReadOnlyPaths=, see below. Defaults to off.

とある。適当に抜粋、翻訳すると

strictに設定すると、API ファイルシステムのサブツリー /dev/、/proc/、/sys/ (PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups= でこれらのディレクトリを保護) を除くファイルシステム階層全体がリードオンリーでマウントされます。 このオプションを使用する場合、ReadWritePaths= を使用して、特定のディレクトリを読み取り専用にすることを除外することができます。 一般的には、ReadOnlyPaths=と同じ制限があります。

となっている。ふうん。いやぁ、もうchmodchownでえいや!とやってれば、自由に読み書きできる時代じゃないってことなんだね。それだけ、今のネットは修羅の国ということか。


  1. 埋め込みTomcatは使う。 ↩︎

  2. どっちなんだろるか?またサービスの設定変更は、直に設定ファイルを編集しても良いがsudo systemctl edit tomcat9.serviceといったコマンドがあるんだなぁ。それ経由だと/etc/systemd/system/tomcat9.service.d/override.confを作成・編集するようだ。 ↩︎