はじめに
SakuraVPS(CentOS6)にて構築している『AIPO7』があるのですが、CentOS6のサポートが終了していまして、yum コマンドも使えなくなっている状況です。(裏技はあるみたいですが信用しきれない)。yumが使えないのでサーバーがおかしくなったときに復旧できなくなる恐れがありますのでなんとかしておきたいところです。
そこでサポート継続しているCentOS9へ『AIPO7』を移行しておきたいという奇抜なことをお考えの方々向けに、次のことを検証してみました。本当は自分のための記録なのですが、一応カッコつけてみました(笑)。
- Aipo7 を CentOS9で動かせるか?
- AIPO7(Tomcat)をリバースプロキシで動かすときの問題点
なかなか面白い体験だったなと思いましたので、公開(記録)してみました。
想定する読者
- AIPO7を使い続けたい!といういう方々(組織)
- 未来の自分自身
Aipo7を使い続けたいと思っている方々へ向けて、お役にたつヒントを届けることができたら嬉しいなと思います。
記事の概要
- AIPO7をインストールした結果(CentOS9)
- AIPO8をインストールした結果(CentOS9)
- AIPO8をAIPO7にすり替えた結果
- Apache2のリバースプロキシでAIPO7を動かした結果
- NginxのリバースプロキシでAIPO7を動かした結果
本記事の前提事項
SakuraVPS(1G)
・OS: CentOS Stream 9
・Kernel: Linux 5.14.0-474.el9.x86_64
・管理ユーザ: centos
・Sakuraのパケットフィルター: TCP 80, 443 22 のみを通す
・Firewall: 有効にしていない
使用するAIPOのバージョン
・ AIPO7 (7.0.2)
・ AIPO8 (8.1.1)
メモリスワップ領域拡張
契約したSakuraVPSサーバーはメモリ1G であり、メモリサイズに不安があるのでメモリスワップできるようにしています。
$ sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
$ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
事前作業
必要パッケージをインストール
$ sudo dnf update -y
$ sudo dnf install net-tools wget tar zip unzip -y
$ sudo dnf libnsl -y
$ sudo dnf gcc readline-devel zlib-devel nmap lsof -y
libnsl はCentOS9には標準で入っていないようで、AIPO7を実行するときに必要ですので入れておきます。
gcc,readline-devel,zlib-devel,nmap,lsof は AIPO7,AIPO8のインストールにて必要になりますので入れておきます。※ zip unzip は、本記事内の操作では使用していませんでしたね。すいません。
$ dnf list --installed | grep -e libnsl -e gcc -e zlib -e nmap -e lsof
gcc.x86_64 11.5.0-2.el9 @appstream
libgcc.x86_64 11.5.0-2.el9 @baseos
libnsl.x86_64 2.34-133.el9 @baseos
lsof.x86_64 4.94.0-3.el9 @baseos
nmap.x86_64 3:7.92-3.el9 @appstream
nmap-ncat.x86_64 3:7.92-3.el9 @appstream
zlib.x86_64 1.2.11-41.el9 @anaconda
zlib-devel.x86_64 1.2.11-41.el9 @appstream
AIPO7のインストール(CentOS9)
AIPO7の入手
インストーラーセットを紛失しているときは、『mirrors.dotsrc.org』より入手しましょう。
作業ディレクトリは、ユーザー「centos」のホームディレクトリとしています。
$ pwd
/home/centos
$ mkdir aipo7
$ cd aipo7
$ wget https://mirrors.dotsrc.org/osdn/aipo/60038/aipo7020aja_linux64.tar.gz
インストーラーの展開
$ pwd
/home/centos/aipo7
$ tar xvzf aipo7020aja_linux64.tar.gz
インストール手順
展開した結果を確認します。
$ pwd
/home/centos/aipo7/aipo7020aja_linux
$ ls
aipo7020.tar.gz readme.txt
AIPOインストール先は /usr/local/aipo
/usr/local 直下に aipoディレクトリが作成されます。
$ cd /usr/local
$ ls
bin etc games include lib lib64 libexec sbin share src
$ sudo cp ~/aipo7/aipo7020aja_linux/aipo7020.tar.gz ./
$ sudo tar xvzf aipo7020.tar.gz
$ sudo rm aipo7020.tar.gz
$ ls
aipo bin etc games include lib lib64 libexec sbin share src
インストールスクリプトの実行権限
bin/installer.sh に実行権限がついていないのでつけてあげます
$ cd /usr/local/aipo
$ ls
backup bin license logs src
$ ls -l bin/installer.sh
-rw-r--r-- 1 root root 506 Nov 7 2012 installer.sh
$ sudo chmod 755 bin/installer.sh
-rwxr-xr-x 1 root root 506 Nov 7 2012 installer.sh
ネットワークインタフェース記述の修正
1番目のネットワークインタフェースを確認しておきます(今回はens3)
inetとbroadcast の xxx.xxx.xxx.xxx のところは実際には存在するIPですが、ここではマスクしてます(etherのところもマスクしてます)。
$ ifconfig
ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet xxx.xxx.xxx.xxx netmask 255.255.254.0 broadcast xxx.xxx.xxx.xxx
ether xx:xx:xx:xx:xx:xx txqueuelen 1000 (Ethernet)
RX packets 2099080 bytes 690661057 (658.6 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 336622 bytes 82290808 (78.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
以下省略
bin/install.conf の記述を修正します。(今回は、eth0 ⇒ ens3 )
$ sudo vi bin/install.conf
=== 修正前 ===
netitf=eth0
dest_str=linux
check_pass=false
enc_str=utf8
def_addr=127.0.0.1
=== 修正後 ===
netitf=ens3
dest_str=linux
check_pass=false
enc_str=utf8
def_addr=127.0.0.1
AIPO7のインストーラー実行
$ pwd
/usr/local/aipo
$ sudo bin/installer.sh
tomcat/postgresのコンパイル(gcc/make)が行われます。
実行前にユーザ(aipo_postgres)が存在しているのであれば、事前に削除しておいてください。
$ sudo userdel -r aipo_postgres
インストールした結果
手順どおりにインストーラーを実行すると 次の結果になります。
以下は実行時のログの抜粋です。
(途中省略)
createdb: could not connect to database postgres: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
cp: cannot stat '/usr/local/aipo/postgres/data/pg_hba.conf': No such file or directory
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
(以降省略)
PostgresDBのDataが入る/usr/local/aipo/postgres/data の中が空のままで、postgresをスタートできません。
インストーラースクリプトに不良があるようですが、原因を特定する余裕がないのであきらめることにします。
gcc によるコンパイルに不良がでているような気もかなりしているのですけどソース入手をしてまで解析する暇はありません。(gcc が新しすぎてコンパイルできないのかもと直感)
結論(2024/11/1時点)
CentOS9 へ AIPO7をダイレクトにインストールできない。
postgresコンパイルの過程で問題が起きている気がする。
古いgccセットを用意すればなんとかなるかもしれないが、そこまで制限をつけたくないし。
AIPO8のインストール(CentOS9)
AIPO7を消す
$ sudo userdel -r aipo_postgres
$ cd /usr/local
$ sudo rm -rf aipo
AIPO8の入手
作業ディレクトリは、ユーザー「centos」のホームディレクトリとしています。
$ pwd
/home/centos
$ mkdir aipo8
$ cd aipo8
$ wget https://mirrors.dotsrc.org/osdn/aipo/64847/aipo-8.1.1-linux-x64.tar.gz
インストーラーの展開
$ pwd
/home/centos/aipo8
$ tar xvzf aipo-8.1.1-linux-x64.tar.gz
$ ls
aipo-8.1.1-linux-x64 aipo-8.1.1-linux-x64.tar.gz
インストール手順
展開した結果を確認します。
$ pwd
/home/centos/aipo8/aipo-8.1.1-linux-x64
$ ls
bin dist installer.sh readme.txt
スクリプト修正(bin/varidate.sh)
lsof の存在チェックのところを修正します( /usr/sbin ⇒ /usr/bin )
$ vi bin/validate.sh
====修正前====
if [ -x /usr/sbin/lsof ]; then
echo "lsof OK."
else
tmp_packages=$tmp_packages"lsof "
fi
====修正後====
if [ -x /usr/bin/lsof ]; then
echo "lsof OK."
else
tmp_packages=$tmp_packages"lsof "
fi
AIPO8のインストーラー実行
$ cd `/aipo8/bin
$ pwd
/home/centos/aipo8/bin
$ sudo ./installer.sh
tomcat/postgresのコンパイル(gcc/make)が行われます。
実行前にユーザ(aipo_postgres)が存在しているのであれば、事前に削除しておいてください。
$ sudo userdel -r aipo_postgres
インストールした結果
こんなのが表示されたらインストール成功です。
Aipo のインストールが完了しました。
バージョン : 8.1.1.0
インストール先 : /usr/local/aipo
PostgreSQLユーザー : aipo_postgres
PostgreSQLパスワード: d28V8EdGWBZB
アクセス先:
http://xxx.xxx.xxx.xxx
ID/PASSWORD:
admin/admin
起動方法:
/usr/local/aipo/bin/startup.sh
停止方法:
/usr/local/aipo/bin/shutdown.sh
アクセス先の xxx.xxx.xxx.xxx は実際には存在するIPですが、ここでは x でマスクしています。
PostgreSQLパスワードはランダムに変わるので気にしないでください。PostgreSQLユーザーがaipo_postgres0になったときは、aipo_posgres ユーザの削除忘れですので、2つのaipo_postgresユーザを消し、/usr/local/aipo を削除してから、やり直してください。
AIPO8 起動
$ cd /usr/local/aipo
$ sudo bin/startup.sh
この段階で、ブラウザ(AIPO)表示が可能です。
http://(HostIP)/
AIPO8 停止
$ sudo bin/shutdown.sh
AIPO用の postgresプロセス、tomcatプロセスが停止します。
AIPO8をAIPO7で入れ替える
Tomcat(webapps)
$ cd /usr/local/aipo/tomcat/webapps
$ sudo rm -rf container
$ sudo cp -r ~/aipo7/aipo7020aja_linux/aipo/src/webapps/aipo ./
Tomcat設定修正(JRE_HOME追記)
JRE_HOMEの設定を追記します。(Tomcatの起動スクリプト、停止スクリプト)
$ cd /usr/local/aipo
$ sudo vi tomcat/bin/startup.sh
==== JRE_HOME設定を追加
#!/bin/sh
# 最初の方に追加するとよい
export JRE_HOME=/usr/local/aipo/jre
# 以下略
====
$ sudo vi tomcat/bin/shutdown.sh
==== JRE_HOME設定を追加
#!/bin/sh
# 最初の方に追加するとよい
export JRE_HOME=/usr/local/aipo/jre
# 以下略
====
dbcp-org001.properties
$ sudo vi tomcat/webapps/aipo/WEB-INF/datasource/dbcp-org001.properties
==== 修正前 =====
cayenne.dbcp.driverClassName=org.postgresql.Driver
cayenne.dbcp.url=jdbc:postgresql://localhost:5432/org001
cayenne.dbcp.username=postgres
cayenne.dbcp.password=aipo
cayenne.dbcp.maxActive=100
cayenne.dbcp.minIdle=3
cayenne.dbcp.maxIdle=20
cayenne.dbcp.maxWait=10000
==== 修正後 =====
cayenne.dbcp.driverClassName=org.postgresql.Driver
cayenne.dbcp.url=jdbc:postgresql://localhost:5432/org001
cayenne.dbcp.username=aipo_postgres
cayenne.dbcp.password=d28V8EdGWBZB
cayenne.dbcp.maxActive=100
cayenne.dbcp.minIdle=3
cayenne.dbcp.maxIdle=20
cayenne.dbcp.maxWait=10000
cayenne.dbcp.username は aipo_postgres とする。
cayenne.dbcp.passwordは、aipo8インストール時のものを使うこと。
DBの中身をAIPO7に入れ替え
移行元のAIPO7のDBダンプ
移行元AIPO7のサーバーにログインしてダンプしましょう。
$ cd /usr/local/aipo
$ sudo -u aipo_posgres postgres/bin/pg_dump org001 > backup/org001.sql
ダンプできたら移行先サーバーへアップしておきましょう。
移行先でDB入れ替え
AIPOは停止状態であること(Postgresプロセスが停止していること)
$ cd /usr/local/aipo/postgres
$ sudo -rf data
$ sudo mkdir data
$ sudo chown -R aipo_postgres. data
$ sudo chmod -R 700 data
$ cd /usr/local/aipo
$ sudo -u aipo_postgres postgres/bin/initdb --encoding=UTF8 --no-locale --pgdata=/usr/local/aipo/postgres/data
$ cd /usr/local/aipo
$ sudo -u aipo_postgres postgres/bin/postgres -D /usr/local/aipo/postgres/data &
$ cd /usr/local/aipo
$ sudo -u aipo_postgres postgres/bin/createdb org001 -O aipo_postgres
~ パス/〇〇 に おいてあるとする
$ sudo postgres/bin/psql -U aipo_postgres -d org001 -f /〇〇/org001.sql
$ cd /usr/local/aipo
$ sudo -u aipo_postgres postgres/bin/pg_ctl -D /usr/local/aipo/postgres/data stop
Tomcat コネクター変更(80 ⇒ 8080)
この後に Apacheをいれるので 80ポートがぶつからないように ポートを変更します。
$ cd /usr/local/aipo
$ sudo vi tomcat/conf/server.xml
===== 修正前:80コネクターの場所
<Connector port="80" maxThreads="1000" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
=====
===== 修正後:80 ⇒ 8080
<Connector port="8080" maxThreads="1000" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
=====
$ cd /usr/local/aipo
$ sudo tomcat/bin/shutdown.sh
$ sudo tomcat/bin/startup.sh
Apacheを入れる
$ sudo dnf install httpd -y
$ sudo vi /etc/httpd/conf.d/aipo.conf
tomcat と ajp通信(8009)でリバーシプロキシをさせます。
ServerNameのところは適時読み替えてください。
=====新規====
<VirtualHost *:80>
DocumentRoot /var/www/html
ServerName www.xxxxxxxx.xxx
RewriteEngine On
ProxyRequests Off
ProxyPreserveHost On
AddDefaultCharset off
ProxyPass /aipo/ ajp://localhost:8009/aipo/
ProxyPassReverse /aipo/ ajp://localhost:8009/aipo/
ProxyPass /gadgets/ ajp://localhost:8009/gadgets/
ProxyPassReverse /gadgets/ ajp://localhost:8009/gadgets/
ErrorLog logs/aipo_error_log
TransferLog logs/aipo_access_log
</VirtualHost>
=============
$ sudo systemctl start httpd
AIPO起動(AIPO7)
$ cd /usr/local/aipo
$ sudo bin/startup.sh
http://(HostIP)/aipo/
ログインしてみる
移行元AIPOのユーザでログイン可能です。
ログインすると、ユーザのアバターが「表示不可」になっています。
エラーログを見る
$ sudo vi /var/log/httpd/aipo_error_log
(抜粋)
AH02429: Response header name 'Expires ' contains invalid characters, aborting request ~~
AH02429エラーが多発しています。これは次のとおりの意味です。
レスポンスヘッダーの Expires の後に余計な半角スペースがある。
Apacheはリバーシプロキシを通さない。
エラーの解説
画像を返すとき Expires :~~ となっているようです( コロンの前に余分な半角スペース)
これに対処するには余分な半角スペースを除去する必要があります。
AIPO7のアプリケーション側を修正して Expires: とする必要がありますが、修正をするJavaソースを入手しても「提供元と同じ開発環境を作る」自信がないのでこの対応は事実上無理そうです。できたとしてもテストに半端ない労力を要しそうです。
また、Apache側で細工をして 'Expires 'の画像データを通すようにする方法は見つかっていません(そんなことはできなそう)。
apache-cve-2016-8743
余計な半角スペースを許さない問題はApacheアップデートに起因しています(DSA 3796-1)
関連記事を載せておきますので興味があるかたは見てくださいね。
https://blog.tigertech.net/posts/apache-cve-2016-8743/
https://lists.debian.org/debian-security-announce/2017/msg00049.html
https://httpd.apache.org/security/vulnerabilities_22.html
これらの記事によると、CVE-2016-8743 は Responseヘッダーに不適切文字列を紛れ込ませることでセキュリティ上の問題を生じてしまうバグの件です。このバグは 2016/12/10 に対応修正版が公開されており、2.2.15 にも取り込まれている様子です。そういえば移行元AIPO7で使うApacheは2.2.15であり、このAIPOでも同じ現象が起きていました( イケてない+言えない方法でごまかしましたけど)
昔 Aipo7 (apache2+tomcat)を構築したときの Apacheバージョンは Apache 2.2.15 ( Build 2017/10/19 )
Aipo7 は 2015年にはリリースされているみたいですので、その時点では、Response Headerに誤り有りでもApacheが許していたのでしょうね。年月が経つのは早いものです。
Apacheを使う上での結論
Apacheでのリバースプロキシで AIPO7は使えない!
NginxでAIPO7を使ってみる(ProxyPass)
Apacheを停止(または削除)して、Nginxを起動して試してみましょう。
Apache停止
$ sudo systemctl stop httpd
Nginx インストール
$ sudo dnf install nginx -y
$ sudo vi /etc/nginx/conf.d/aipo.conf
===新規( server_nameは適時読み替えてください)
server {
listen 80;
# Host URL or Host IP
server_name xxxxxxxxx;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /aipo/ {
root /usr/share/nginx/html;
proxy_pass http://127.0.0.1:8080/aipo/ ;
# Proxy headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /gadgets/ {
root /usr/share/nginx/aipo7;
proxy_pass http://127.0.0.1:8080/gadgets/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
===
Nginx 起動
sudo systemctl start nginx
ちゃんと画像を表示しました。
最終結論
AIPO8 ⇒ AIPO7 の置き換えを行い、WebサーバーにはNginxを使うのであれば、CentOS9でも 比較的簡単に『AIPO7』を使うことができそうです。
Nginx はApacheと比べてセキュリティ要件が緩いのでしょうか。
今後、Nginxのセキュリティチェックが厳しくなり、Response Header の不当文字(空白混入など)を許さなくなる可能性は将来的にあるかもしれませんが、当面はNginxで大丈夫そうですね。( 2024/11/1 現在 )
AIPO8でAIPO7を使う(Nginxで) の組み合わせはよさげです!ということをこの記事での結論としてみたいと思います。
なお、やっぱり動かないじゃねーか!実害が生じた!というクレームは一切受け付けませんので 自己責任でご利用くださいませ。将来的に ApacheやNginxがどのようにアップグレードされていくのかは私にはわかりませんので。