スマートフォン・タブレットからインターネットサーバーオペレーション

APPW.jp
 
ConoHa VPS移設記/2GB・3コア → 4GB・4コア/Ubuntu 26.04 LTS

③ Apache2

旧サーバーの設定をそのまま持ち込むのではなく、まず読み解いて何が今も必要で何が2021年以前の名残なのかを仕分けた。 モジュール構成の見直し、5サイト共存のためのVirtualHost設計、そして最後に浮上した権限まわりの整理までを記録する。

作業端末: iPad mini(Termius)

MIGRATION ROADMAP — 全17工程
  1. ① SSH、ユーザー追加
  2. ② IPv4/IPv6追加、netplan、ufw
  3. ③ Apache2
  4. ④ Let's Encrypt
  5. ⑤ PHP
  6. ⑥ MariaDB
  7. ⑦ WordPress
  8. ⑧ Dovecot、Postfix
  9. ⑨ Vsftpd
  10. ⑩ Python
  11. ⑪ llama.cpp、ChromaDB
  12. ⑫ Anaconda、Keras、TensorFlow
  13. ⑬ Node.js
  14. ⑭ MongoDB
  15. ⑮ Mosquitto
  16. ⑯ RabbitMQ
  17. ⑰ Supervisor

01旧サイト設定の棚卸し

5サイト分の設定を一括で書き直す前に、実際に使っているsasagawa.tokyoの設定ファイルを読み解いて、 今も必要なものと、そうでないものを仕分けた。

  • mod_wsgiの実利用箇所:sasagawa.tokyo自体ではなく、iseeit.jpのMNISTデモ・word2vecツールが専用venv(python-home=/home/login-user/env3.12)経由で使用。それぞれMosquitto・RabbitMQ経由でモデルへ接続する構成(この部分の詳細は⑮⑯で改めて記事化予定)
  • KeepAlive / KeepAliveTimeout:VirtualHost内に書かれていたが、この2つはApacheの仕様上server configコンテキストのみ有効で、VirtualHost内に置いても構文エラーにはならないものの「同じIP:ポートの最初のVirtualHostの値が全体に適用される」という紛らわしい挙動になる。5サイト共存を機にapache2.conf側へ移設
  • 死んでいたコメントアウト行:WebSocketプロキシがws://からwss://へ切り替わった際の旧設定の残骸。削除
  • SSLProxy系の証明書検証無効化設定:127.0.0.1へのループバック接続専用なのでそのまま維持

02VirtualHostのIPバインド設計

②で確保できた追加IPv4は1個のみだったため、5サイトはこの1個をSNI(Server Name Indication)による名前ベース仮想ホストで共有する。 一方IPv6は17個使えるため、サイトごとに専用の1個を割り当てた。

サイトIPv6(下4桁)
iseeit.jp...xx1
gwaw.jp...xx2
appw.jp...xx3
ibe.tokyo...xx4
sasagawa.tokyo...xx5

443側のVirtualHostは共有IPv4とサイト専用IPv6の両方を明示バインドする。*:443のままでも動作はするが、 標準IPv4(メール・管理用)側にWebコンテンツが一切乗らない、という設計意図が設定上はっきり見える形にした。

/etc/apache2/sites-available/ssl-sasagawa_tokyo.conf
<VirtualHost 160.251.145.xx:443 [2400:8500:2002:3164:a160:251:175:xx5]:443> ServerName sasagawa.tokyo ServerAlias www.sasagawa.tokyo ...

80側は平文HTTPなのでSNIは関係なく、Hostヘッダーで振り分けられる。*:80のまま、 ServerNameDocumentRoot・ログパスだけをサイトごとに調整すればよい。 5サイト×2ポート(80/443)=10ファイルという構成自体は変更せず維持した。

保留事項 80側に.well-known/acme-challenge/用の設定を入れるかどうかは、Let's EncryptをHTTP-01(webroot)で取るかDNS-01にするかの判断待ち。この点は④で扱う。

03Apache2本体とモジュールのインストール

login-user@新サーバー
$ sudo apt update $ sudo apt install apache2 $ sudo a2enmod http2 proxy proxy_wstunnel rewrite setenvif ssl $ sudo ufw allow 'Apache Full'
mod_wsgiは今回見送り mod_wsgi.soは特定のPythonバージョンに対して静的にリンクされるため、apt標準のlibapache2-mod-wsgi-py3を入れるとシステムのデフォルトPython(Ubuntu 26.04では3.14)にリンクされる。 一方、MNIST・word2vecはTensorFlowの都合上Python 3.12系のvenvで動かす必要があり、このままではバージョン不一致で動かない。 対応にはmod_wsgiを3.12venv内からpip installして個別にビルドする必要があるため、⑩Pythonの回でvenv構築と合わせて対応することにした。

045サイト分のVirtualHostを反映

棚卸しの内容を反映し、10ファイル(5サイト×80/443)を修正した。

login-user@新サーバー
$ sudo cp /etc/apache2/mods-available/*.conf.orig 2>/dev/null; true # 443側10ファイルはVirtualHost行を明示バインドへ、死んだコメント行を削除 $ sudo vi /etc/apache2/sites-available/ssl-iseeit_jp.conf $ sudo vi /etc/apache2/sites-available/ssl-gwaw_jp.conf $ sudo vi /etc/apache2/sites-available/ssl-appw_jp.conf $ sudo vi /etc/apache2/sites-available/ssl-ibe_tokyo.conf $ sudo vi /etc/apache2/sites-available/ssl-sasagawa_tokyo.conf # KeepAlive / KeepAliveTimeout はapache2.conf側へ $ sudo vi /etc/apache2/apache2.conf # .htpasswd はDocumentRoot外のファイルなので個別にコピー $ sudo cp /path/to/backup/.htpasswd /etc/apache2/.htpasswd
login-user@新サーバー
$ sudo apache2ctl configtest Syntax OK $ sudo systemctl enable apache2 $ sudo systemctl restart apache2

05Apache(www-data)とPHP(login-user)の権限を分ける

ドキュメントルートは/home/login-user/www/...で所有者はlogin-user。旧サーバーではXML-RPC経由の画像アップロードがパーミッションで失敗し、 /etc/apache2/envvarsAPACHE_RUN_USER/APACHE_RUN_GROUPlogin-userに変更するなどして解決した記憶があったが、 これはApache全体(=5サイト共通のプロセス)がlogin-user権限で動くことを意味し、1サイトの脆弱性が他サイトへ波及する範囲を広げてしまう。

今回は役割を分けることにした。

役割実行ユーザー権限
Apache本体(静的配信・プロキシ)www-data(デフォルトのまま)読み取りのみ
PHP(WordPress本体)login-user(PHP-FPMのpool設定で指定、⑤で対応)書き込み可

envvarsは変更せずwww-dataのまま維持し、書き込み(アップロード含む)はPHP-FPM側のpool設定に任せる。 Apache自体はサイトの中身に対して書き込み権限を持たない。

ただし/home/login-userはデフォルトのパーミッションだと所有者以外アクセス不可のことが多く、www-dataがそもそも中に入れない可能性がある。 「その他」に開放するのではなく、www-dataをlogin-userグループに入れる形で対応した。

login-user@新サーバー
$ ls -ld /home/login-user $ sudo usermod -aG login-user www-data $ sudo chmod 750 /home/login-user $ sudo systemctl restart apache2
確認完了 envvarsはwww-dataのまま、www-dataをlogin-userグループへ追加、configtest OK、systemctl登録、ufwまで完了。書き込み権限の解決は⑤PHPのpool設定へ持ち越し。

06ここまでの状態

  • Apache2本体・標準モジュール(http2, proxy, proxy_wstunnel, rewrite, setenvif, ssl)導入済み。mod_wsgiは⑩へ先送り
  • 5サイト×2ポート=10ファイルのVirtualHostを、共有IPv4+サイト別IPv6の明示バインドへ更新
  • KeepAlive設定はapache2.confへ集約、死んだコメント行を削除、.htpasswdを移行
  • Apache(www-data・読み取り専用)とPHP(login-user・書き込み可)の権限分離方針を決定
← 前回: ② IPv4/IPv6追加、netplan、ufw 次回: ④ Let's Encrypt →

『ConoHa VPS移設記 ③ Apache2』を公開しました。