スポンサーリンク

Dockerを利用してTLSv1.0 → 1.2のアップグレードの検証を行ったときの話

  • テストサーバーが存在しない
  • サーバー運営会社の管理コンソールで環境の複製(コピー、クローン)はできない
  • ぶっつけで本番環境でやるのはNG
  • 対象のサーバーのOSがCentOS5なのでEC2が使えない(公式のAMIがない)

さてどうしよう??ということでDockerを使って既存の環境と似た環境を構築→検証という対応を行ったのでメモ。
Dockerのコマンド操作がちょっとだけわかった。
でも、Dockerを使うってこういうことじゃない気がする。

構築する環境について

まず最初にアップデート対象のサーバーに似た環境の構築をDocker上で行います。
似た環境というのはyumでインストールされてるものは同じようにyumでインストールを行い、ソースからビルドしているものがあれば同じようにソースからビルドするということ。
まったく同じ環境を作ることは不可能なので主要なLAMP部分について同じような構成となる手順を構築しました。

その後、Docker内に構築した環境に対して本来の目的だったTLSv1.0→TLSv1.2とそれに付随するアップデートのもろもろを行いました。
httpdはなんでアップグレードしたのか忘れたけど何かしらの理由で2.2系はダメだったとかそういうのがあったから2.4系になってるんだと思います(^q^

アップデート前アップデート後
OSCentOS 5.11CentOS 5.11
php5.2.45.2.4
httpd2.2.32.4.41
mysql5.0.51a5.0.51a
OpenSSL0.9.8e1.1.1

ソースからビルドされているものについてはconfigureを行う際にどのようなオプションを指定したかを知る必要があります。
PHPはphpinfoから知ることができました。
MySQLは以下の情報が参考になりました。
参考:MySQLのconfigureオプションを知りたいとき – かみぽわーる

# VISUAL='grep "Configure command" 1>&2' /usr/local/mysql/bin/mysqlbug > /dev/null

Dockerのコンテナ作成

CentOS5のコンテナはCentOS公式のDockerイメージに存在しなかったり?、デフォルトのままだとyumで参照するリポジトリのリンクが切れてしまっている。。
そのため、vault.centos.orgというアーカイブを参照するようURLが修正されている「astj/centos5-vault」というリポジトリをチェックアウトして使わせていただきました。

作成するコンテナにはcentos5と命名。
httpdの動作確認を行うので8080ポートで80番ポートに、8443ポートで443ポートに繋がるよう設定。
また、環境構築にはSSHクライアントソフト(RLogin)を使いたいので22番ポートも開けました。

> docker search centos5
NAME                                                DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
fatherlinux/centos5-base                            Centos5, same method as RHEL5 image.            8
astj/centos5-vault                                  A drop-in replacement of centos:5.11 with mo…   7                                       [OK]
themattrix/centos5-vault-i386                       A drop-in replacement for alanfranz/fwd-cent…   2                                       [OK]
sergeykrivohatskiy/centos5_for_nuke_plugins_build   Centos 5 with gcc, g++ and make installed fo…   1
alanfranz/centos5-i386                              Unofficial Centos5 i386 image for Docker.       1                                       [OK]
~~~省略~~~

> docker pull astj/centos5-vault
> docker run --name centos5 -it -p 8080:80 -p 8443:443 -p 22:22 astj/centos5-vault /bin/bash

アップグレード前の環境構築1 ssh設定

使い慣れたSSHクライアントソフト(RLogin)でコンソール2個開いて左側Docker、右側本番環境みたいな状態で作業したかったのでDockerのコンテナ内にopenssh-serverをインストールしました。
SFTPでファイル転送とかもできるので外部のサーバーにSSH接続してる感覚で使える。
ちなみに、Dockerコンテナ内へのファイル転送について普通はdocker cpコマンドで行うそうです。

# yum install openssh-server
# mkdir /root/.ssh
# chmod 700 /root/.ssh
# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
5b:b9:d9:87:7a:52:de:d3:52:90:37:da:b5:ab:17:1c root@ed88dd240da5

# mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
# chmod 600 /root/.ssh/authorized_keys
# cat /root/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA2aL9Ku7VMx8KMNlaj5Up+eof/PorEcqu7aGLxKuXYQJYart2
y2ZSTLywRXHg8Me3czAPqsUDzq1w79EnzsfC0Z8BpugyUvyl9Hd+qAC1xJsaEoo8
tTTLl00IQBUqIa7GPHVhw4dE2mkt5rqJ+9ZNlb4D1c1ou8Fo6lFkmniy5589TCDb
+o+KUb9JqbF4OE2DuOcMH0UGlnalh4qkRazZUYTwVYYgQXzwchj8uN6cmFvLVbW5
Aw6TtGnxHTz6h/pEyY2kttsf5CxiwyzAY8vF4yvOwX+QLRKzynM8jI5rmbuce9iD
9EdvfXiQ4VSeBZmxJRsKB9EG/Zk50XsmgLPGZQIBIwKCAQEA02sh0e9Sw/JEafe3
DyMwF1h22H399Aa4jxH1fTj5dC4qAUhkxZaZF1g2NNUGZj5ab+WLj/KV+/jxXf5h
L0W18DQQO7z9r7OZ5irwEOq/NARieGkHxfjFxi2S/GxU0ENhfI9JBxWwmagAtEAu
RRlSrriWAuTMJBr4NBSNnV9OtRyNsR5bZ2/uCGReo9MOlXW+Jm/39+4fASMLm8zz
pvMOE83QmXFsM4ejjuhjRuKelAKBSAYZJM/j5npQvdrpx1AkUHjZBlHoDSusUoWa
OyuJda0pbvIspKRM/84ihxjC04ieLUyvgfKb6UzrHLjkINQXj0/OhAZ2BMG1qF2Y
Ic60CwKBgQD3ieX67dZgTGEm2YseVxlgHih0R+ekdOM4qQNkGr9WQivEWWXCq7kE
lRW6wLmutwbbHyqFgbwD4VuPw8eGCJzz7Xp232UkDB1pUCZDfIudPkxjNTAuLSCt
64nFnZU6OsvKcc/GsPoAwVIvoSmmtdo4XUM0Xl2ptPDZswiUIrvENQKBgQDhE25z
5gItdTMMrwlSZXcrJ+HrZzONgkmzviU2Sly4VVCZA9FBBl3wq8i9p6UOZxYf1dA3
vU9hdNvC8F9lubf+TQAwUPR96J5Ah3z0uWYqM0PA5WUk/Bu2m1kIGJvwWAFNU99y
AUwol0gj7eUbiE6NtFD5ivQ+JaS7tOUMWUjfcQKBgD+nHeFwW7JcyIZVMmbjMmks
U4uddhRYkjMkJXGDOIPlITJ9Y09QuowmVgtzYvJplAx1unoaC8Z7xxZW6inHs1Sq
x7gq0N1iM3LaGHfA8LNnyn/pGwSPQurky6fYEG4PHnXiwGZKw/GQy/2eeGyya1BS
fv7Wb9suhxNojS1oBGWnAoGAGbkT7/0HkCqmv575wEYcP3JFtIDSsRY0Tw5qpx5w
/x+xcJK41Ds9756amVT867QCh0uixIqp/IJiQioZh/f3xUqg75Q5MvYDdRbMc71q
wv6LZoCd2FdTn9c9YALP/jXxhS4oKklKiEvNuvad10LHJiM8dEplDmqzva5GEAo0
NssCgYEAncfo7mtefL91lF9mzn0VPOpny7o7hwcwnscM/4r1vIzh2tAW8iSTZLeE
gEvhvhL4obLiB87vlRR0I7B6BNbIfd+ar9gxBrlxJzZlc5nR7vqTy8qdg4MzuWdP
hAE78n9xHjsXAhKP/QMcbKReWFj+T36C3xH6jvEsPcXAk1Zj/K8=
-----END RSA PRIVATE KEY-----
# sed -i.bak 's/#PermitRootLogin yes/PermitRootLogin yes/g' /etc/ssh/sshd_config
# /etc/init.d/sshd start

sshサーバーのインストール、rootログインの許可、ssh秘密鍵と公開鍵のキーペア作成を行っています。
catで出力したid_rsaを適当な名前でローカルにcentos5_id_rsaという名前で適当なディレクトリに保管。RLoginの「SSH Identity Key」に設定して接続できることを確認しました。

Dockerのイメージ作成1

本格的にいろいろ作業する前に何かあった時にsshサーバーのインストールが完了した状態へ戻せるように復元用のイメージを作成します。
一応bashとsshクライアントでの接続は抜け、コンテナも停止した状態で作成するようにしています。

> docker stop centos5
> docker ps -a
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                                                             NAMES
2788accc95e6        astj/centos5-vault   "/bin/bash"         6 minutes ago       Up 6 minutes        0.0.0.0:22->22/tcp, 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp   centos5

> docker commit --message="installed openssh-server" 2788accc95e6 tikuwa_centos5:v1
sha256:8eaa3f4ad16cec5a9ca702d4d997a511d7da047a35cf440611cc1eb63a17de8f

> docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
tikuwa_centos5       v1                  8eaa3f4ad16c        5 seconds ago       396MB
astj/centos5-vault   latest              e79faab040e1        2 years ago         284MB

復元したいときは以下のように既存のコンテナを削除してからイメージ名とタグ名を元に再生成しています。

> docker rm 2788accc95e6
> docker run --name centos5 -it -p 8080:80 -p 8443:443 -p 22:22 tikuwa_centos5:v1 /bin/bash

アップグレード前の環境構築2 LAMP構築

まっさらなCentOS5環境にいろいろインストールや設定を行います。


まずはhttpdと日本語設定
httpdはyumでインストールされてたものが使用されてたのでざっくりインストール。

# yum install httpd httpd-devel mod_ssl openssl-devel
# yum install wget curl curl-devel make gcc gcc-c++

# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# echo 'LANG="ja_JP.UTF-8"' > /etc/sysconfig/i18n
# . /etc/sysconfig/i18n

次にMySQLのインストールと設定
wgetやcurlでプログラムのソースを取得する際wgetやcurlが使用する証明書?が古いことが原因でダウンロードできないことがあります。今回はMySQLのソースを取得する際にエラーが出てダウンロードできませんでした。
こういった時はブラウザで普通にダウンロードしたものをRLoginのSFTP転送機能で直接/usr/local/srcに配置しました。
yumでインストールしているmysqlはクライアントソフトです。インストールすると/etc/my.cnfが出来上がります。mysqlを起動する前に文字エンコーディングとソケットについて設定を変更しています。

# cd /usr/local/src
# wget https://downloads.mysql.com/archives/get/file/mysql-5.0.51a.tar.gz
OpenSSL: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
SSL による接続が確立できません。
# yum install mysql
# yum install ncurses ncurses-devel
# tar zxvf mysql-5.0.51a.tar.gz
# cd mysql-5.0.51a
# ./configure --with-extra-charsets=all --with-mysqld-user=mysql --prefix=/usr/local/mysql
# make
# make install
# vi /etc/my.cnf

# groupadd -r mysql
# useradd -r -g mysql mysql
# /usr/local/mysql/bin/mysql_install_db --basedir=/usr/local/mysql --datadir=/var/lib/mysql --user=mysql
# chown -R mysql:mysql /usr/local/mysql
# cp /usr/local/mysql/share/mysql/mysql.server /etc/init.d/mysql
# /etc/init.d/mysql start
# chkconfig mysql on
[mysqld]
datadir=/var/lib/mysql
-socket=/var/lib/mysql/mysql.sock
+socket=/tmp/mysql.sock
user=mysql
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1

# Disabling symbolic-links is recommended to prevent assorted security risks;
# to do so, uncomment this line:
# symbolic-links=0
+character-set-server=utf8

+[client]
+socket=/tmp/mysql.sock
+default-character-set=utf8

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

最後にPHPのインストール
実際はGDの設定でたくさんオプションがあったような気がしますがその辺は覚えてないので省略。

# cd /usr/local/src 
# wget http://museum.php.net/php5/php-5.2.4.tar.gz
# yum install libxml2 libxml2-devel libmcrypt libmcrypt-devel
# tar zxvf php-5.2.4.tar.gz
# cd php-5.2.4
# ./configure --with-config-file-path=/etc --with-apxs2=/usr/sbin/apxs --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --enable-mbstring --enable-zend-multibyte --sysconfdir=/etc --datadir=/usr/share --with-pear=/usr/share/PEAR --with-curl --with-mcrypt
# make
# make install
# cp php.ini-dist /etc/php.ini

動作確認1

httpdを起動してブラウザアクセスによる動作確認を行いました。
Dockerコンテナ作成時の設定より80ポートへはhttp://localhost:8080/、443ポートへのアクセスはhttps://localhost:8443/でアクセス。

# /etc/init.d/httpd start

IEのプロパティからTLSのバージョンが1.0となっていることを確認。

FireFoxの場合はページ内右クリック>ページの情報を表示>セキュリティタブ>技術情報で確認できました。FireFoxの方ではTLS 1.0の表記の隣に「脆弱な暗号化」とも表示されていました。


また、インストールされたプログラムのバージョン等について以下の確認を行いました。

# httpd -v
Server version: Apache/2.2.3
Server built:   Jul 18 2016 10:45:28

# php -v
PHP 5.2.4 (cli) (built: Dec 12 2019 22:58:55) 
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies

# php -i | head -20
phpinfo()
PHP Version => 5.2.4

System => Linux a85ebbef67a5 4.9.184-linuxkit #1 SMP Tue Jul 2 22:58:16 UTC 2019 x86_64
Build Date => Dec 12 2019 22:58:17
Configure Command =>  './configure' '--with-config-file-path=/etc' '--with-apxs2=/usr/sbin/apxs' '--with-mysql=/usr/local/mysql' '--with-pdo-mysql=/usr/local/mysql' '--with-mysql-sock=/tmp/mysql.sock' '--enable-mbstring' '--enable-zend-multibyte' '--sysconfdir=/etc' '--datadir=/usr/share' '--with-pear=/usr/share/PEAR' '--with-curl' '--with-mcrypt'
Server API => Command Line Interface
Virtual Directory Support => disabled
Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini
PHP API => 20041225
PHP Extension => 20060613
Zend Extension => 220060519
Debug Build => no
Thread Safety => disabled
Zend Memory Manager => enabled
IPv6 Support => enabled
Registered PHP Streams => php, file, data, http, ftp  
Registered Stream Socket Transports => tcp, udp, unix, udg
Registered Stream Filters => string.rot13, string.toupper, string.tolower, string.strip_tags, convert.*, consumed, convert.iconv.*

# mysql --version
mysql  Ver 14.12 Distrib 5.0.95, for redhat-linux-gnu (x86_64) using readline 5.1

# mysql
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.0.51a   | 
+-----------+

Dockerのイメージ作成2

アップデート前のLAMP環境が構築ができたのでいったんこの状態をバックアップします。
タグをv2としてみました。

> docker stop centos5
> docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
a85ebbef67a5        tikuwa_centos5:v1   "/bin/bash"         26 minutes ago      Exited (137) 2 minutes ago                       centos5
> docker commit --message="installed httpd:2.2.3, mysql:5.0.51a, php:5.2.4" a85ebbef67a5 tikuwa_centos5:v2
sha256:63365622e263b2ba7528d7b87c46fa6525d8dbc1ab0b4e5b96359b43466d4248

> docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
tikuwa_centos5       v2                  63365622e263        16 seconds ago      1.35GB
tikuwa_centos5       v1                  8eaa3f4ad16c        26 hours ago        396MB
astj/centos5-vault   latest              e79faab040e1        2 years ago         284MB

アップグレード作業実施

以下のような作業手順となりました。

  1. perl 5.10.1をビルド
    1. OpenSSL 1.1.1をビルドするのに5.10.1以上のperlが必要なため
  2. OpenSSL 1.1.1をビルド
  3. httpd 2.4.41をビルド
    1. 何が原因だったか忘れた(^q^
      2.2がなんかダメだったので2.4系になった?
      OpenSSL 1.1.1との相性がよくなかった?
      Dockerイメージをバックアップとして取得してるので後で調べるかも
  4. php 5.2.4を再ビルド
    1. 再ビルドはhttpd 2.2→2.4とした過程でhttpd2.2のときのlibphp.soが読み込めなくなってしまうため
    2. ソースを一部httpd2.4用に書き換える必要があった

アップグレード作業実施1 perl 5.10.1をビルド

この辺からビルドするものは/opt以下に入れるようにしました。
perlは5.8.8がインストールされていますがOpenSSL1.1.1をビルドする際perl5.10.1以上を求められるため先にビルドしました。
5.10.1のビルド後、今回は既存の5.8.8は削除せずにパスを上書きすることにしました。

# perl -v
This is perl, v5.8.8 built for x86_64-linux-thread-multi

# cd /usr/local/src/
# wget http://www.cpan.org/src/5.0/perl-5.10.1.tar.gz
# tar xvzf perl-5.10.1.tar.gz
# cd perl-5.10.1
# ./configure.gnu --prefix=/opt/perl-5.10.1
# make
# make install
# /opt/perl-5.10.1/bin/perl -v
This is perl, v5.10.1 (*) built for x86_64-linux

# echo 'export PATH="/opt/perl-5.10.1/bin:$PATH"' >> ~/.bashrc
# source ~/.bashrc
# perl -v
This is perl, v5.10.1 (*) built for x86_64-linux

アップグレード作業実施2 OpenSSL 1.1.1をビルド

# yum install zlib-devel bzip2
# cd /usr/local/src/
# wget https://www.openssl.org/source/openssl-1.1.1.tar.gz
# tar xvzf openssl-1.1.1.tar.gz
# cd openssl-1.1.1/
# ./config --prefix=/opt/openssl-1.1.1 shared
# make
# make install

インストール後バージョンを確認しようとしたところlibssl.so.1.1という共有ライブラリが見つからないというエラーが出てしまいました。
以下のページを参考にfindで対象のファイルを探して共有ライブラリのパスの設定を行いました。
参考:CentOS 7 OpenSSL 1.1.0gのソースファイルからのインストール – Qiita

# /opt/openssl-1.1.1/bin/openssl version
/opt/openssl-1.1.1/bin/openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory

# find /opt -name "libssl.so.1.1"
/opt/openssl-1.1.1/lib/libssl.so.1.1

# echo "/opt/openssl-1.1.1/lib/" >> /etc/ld.so.conf.d/lib64.conf
# ldconfig
# /opt/openssl-1.1.1/bin/openssl version
OpenSSL 1.1.1  11 Sep 2018

# mv /usr/bin/openssl /usr/bin/openssl.bak
# chmod -x /usr/bin/openssl.bak
# ln -s /opt/openssl-1.1.1/bin/openssl /usr/bin/openssl
# openssl version
OpenSSL 1.1.1  11 Sep 2018

アップグレード作業実施3 httpd 2.4.41をビルド

CentOS5環境下でhttpd2.4系をソースからビルドする場合、apr、apr-util、pcreの辺りのバージョンが古いことが原因でビルドに失敗してしまうため先に関連するプログラムをソースからビルドしました。
httpdをビルドする際、事前にビルドしておいたopenssl、apr、apr-util、pcreのパスをオプション(with-ssl、with-apr、with-apr-util、with-pcre)で指定しました。
httpdのビルド後、httpd2.2の起動ファイル等をよけて/opt以下にインストールしたhttpd2.4の起動ファイルを/etc/init.d以下にコピーしました。

# yum list installed | grep apr
apr.x86_64                             1.2.7-11.el5_6.5                installed
apr-devel.x86_64                       1.2.7-11.el5_6.5                installed
apr-util.x86_64                        1.2.7-11.el5_5.2                installed
apr-util-devel.x86_64                  1.2.7-11.el5_5.2                installed

# yum list installed | grep pcre
pcre.x86_64                            6.6-9.el5                       installed

# cd /usr/local/src
# wget http://ftp.kddilabs.jp/infosystems/apache//apr/apr-1.6.5.tar.gz
# tar zxvf apr-1.6.5.tar.gz
# cd apr-1.6.5
# ./configure --prefix=/opt/apr-1.6.5
# make
# make install

# cd /usr/local/src
# wget http://ftp.kddilabs.jp/infosystems/apache//apr/apr-util-1.6.1.tar.gz
# tar zxvf apr-util-1.6.1.tar.gz
# cd apr-util-1.6.1
# ./configure --prefix=/opt/apr-util-1.6.1 --with-apr=/opt/apr-1.6.5
# make
# make install

# cd /usr/local/src
# wget http://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz
# tar zxvf pcre-8.43.tar.gz
# cd pcre-8.43
# ./configure --prefix=/opt/pcre-8.43
# make
# make install

# cd /usr/local/src
# wget http://archive.apache.org/dist/httpd/httpd-2.4.41.tar.gz
# tar xvfz httpd-2.4.41.tar.gz
# cd httpd-2.4.41
# ./configure --prefix=/opt/httpd-2.4.41 --enable-rewrite=shared --enable-ssl=shared --enable-mem-cache=shared --enable-so --enable-modules=all --enable-mods-shared=all --with-ssl=/opt/openssl-1.1.1 --with-apr=/opt/apr-1.6.5 --with-apr-util=/opt/apr-util-1.6.1 --with-pcre=/opt/pcre-8.43
# make
# make install

# /etc/init.d/httpd stop
# mv /etc/init.d/httpd /etc/init.d/httpd.bak
# chmod -x /etc/init.d/httpd.bak
# ln -s /opt/httpd-2.4.41/bin/apachectl /etc/init.d/httpd
# mv /usr/sbin/httpd /usr/sbin/httpd.bak
# chmod -x /usr/sbin/httpd.bak
# ln -s /opt/httpd-2.4.41/bin/httpd /usr/sbin/httpd

アップグレード作業実施4 php 5.2.4を再ビルド

httpd2.2→httpd2.4のバージョン変更が原因でビルドはうまく行くけどhttpd開始時にエラーが出て起動できないという問題が発生しました。
以下の情報を参考にcのソースの一部を書き換えてからビルドを実施しました(php_functions.cタブ参照)。
参考:php5.2.14とapache2.4.3 – rougeref’s diary

apxsはhttpd2.4のものを参照するようパスを修正しました。

# mv /usr/sbin/apxs /usr/sbin/apxs.bak
# ln -s /opt/httpd-2.4.41/bin/apxs /usr/sbin/apxs

# cd /usr/local/src/php-5.2.4
# vi ./sapi/apache2handler/php_functions.c
# make distclean
# ./configure --with-config-file-path=/etc --with-apxs2=/usr/sbin/apxs --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --enable-mbstring --enable-zend-multibyte --sysconfdir=/etc --datadir=/usr/share --with-pear=/usr/share/PEAR --with-curl --with-mcrypt
configure: error: Cannot find libmysqlclient_r under /usr/local/mysql.
Note that the MySQL client library is not bundled anymore!

# cd /usr/local/mysql/lib/mysql
# ln -s libmysqlclient.so.15.0.0 libmysqlclient_r.so
# chown -h mysql:mysql libmysqlclient_r.so

# cd /usr/local/src/php-5.2.4
# ./configure --with-config-file-path=/etc --with-apxs2=/usr/sbin/apxs --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --enable-mbstring --enable-zend-multibyte --sysconfdir=/etc --datadir=/usr/share --with-pear=/usr/share/PEAR --with-curl --with-mcrypt 
# make
# make install
PHP_MINFO_FUNCTION(apache)
{
        char *apv = php_apache_get_version();
        smart_str tmp1 = {0};
        char tmp[1024];
        int n, max_requests;
        char *p;
        server_rec *serv = ((php_struct *) SG(server_context))->r->server;
#if !defined(WIN32) && !defined(WINNT) && !defined(NETWARE)
-        AP_DECLARE_DATA extern unixd_config_rec unixd_config;
+        AP_DECLARE_DATA extern unixd_config_rec ap_unixd_config;
#endif

        for (n = 0; ap_loaded_modules[n]; ++n) {
                char *s = (char *) ap_loaded_modules[n]->name;
                if ((p = strchr(s, '.'))) {
                        smart_str_appendl(&tmp1, s, (p - s));
                } else {
                        smart_str_appends(&tmp1, s);
                }
                smart_str_appendc(&tmp1, ' ');
        }
        if ((tmp1.len - 1) >= 0) {
                tmp1.c[tmp1.len - 1] = '\0';
        }

        php_info_print_table_start();
        if (apv && *apv) {
                php_info_print_table_row(2, "Apache Version", apv);
        }
        snprintf(tmp, sizeof(tmp), "%d", MODULE_MAGIC_NUMBER);
        php_info_print_table_row(2, "Apache API Version", tmp);

        if (serv->server_admin && *(serv->server_admin)) {
                php_info_print_table_row(2, "Server Administrator", serv->server_admin);
        }

        snprintf(tmp, sizeof(tmp), "%s:%u", serv->server_hostname, serv->port);
        php_info_print_table_row(2, "Hostname:Port", tmp);

#if !defined(WIN32) && !defined(WINNT) && !defined(NETWARE)
-        snprintf(tmp, sizeof(tmp), "%s(%d)/%d", unixd_config.user_name, unixd_config.user_id, unixd_config.group_id);
+        snprintf(tmp, sizeof(tmp), "%s(%d)/%d", ap_unixd_config.user_name, ap_unixd_config.user_id, ap_unixd_config.group_id);
        php_info_print_table_row(2, "User/Group", tmp);
#endif

phpの再ビルドの際にlibmysqlclient_rが見つからないという旨のエラーが出てしまいました。
解決方法を調べると最新のMySQLコネクターCをインストールするという手順を紹介しているブログが見つかったりしました。その通りに対応したところビルドは正常に通るようになりましたが動作確認の際、PEARのMDB2というデータベースへの接続を行うライブラリの読み込みの辺りでセグメンテーション違反が発生してしまいどうにもならなくなってしまうという事態に陥りました。。
※そのときインストールしたやつ→(mysql-connector-c-6.1.11-src.tar.gz)
ダウンロード先:MySQL :: Download MySQL Connector/C (Archived Versions)
上記MySQLコネクターのビルド後、インストール先のディレクトリを確認するとlibmysqlclient_r.soが出来上がっていることを確認しました。実態はlibmysqlclient.soのシンボリックリンクでした。

Dockerイメージからコンテナを復元し、libmysqlclient_rについて最新のMySQLコネクターのインストールは行わずにlibmysqlclient.soのシンボリックリンクを貼るという対応を取ってみました(上の手順の11~13行目)。
今のところこれで問題なく動いてますがもしかしたらどっかしら壊れてたりするかも。。

httpd2.4の設定

/opt以下にインストールしたhttpd2.4について、httpd.conf、httpd-ssl.confを開きSSL関連の設定を実施しました。
SSLProtocolでAllからSSLv2、SSLv3、TLSv1を引いてTLSv1.2以上の通信とする設定を行っています。
SSL証明書について自己証明書の作成は行わず、httpd2.2に設定されていたものを流用しました。
/etc/pki/tls/certs以下の証明書はたぶんmod_sslインストール時に一緒に入るやつ。

# vi /opt/httpd-2.4.41/conf/httpd.conf
//////////
88行目
-#LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
+LoadModule socache_shmcb_module modules/mod_socache_shmcb.so

144行目
-#LoadModule ssl_module modules/mod_ssl.so
+LoadModule ssl_module modules/mod_ssl.so
511行目
-#Include conf/extra/httpd-ssl.conf
+Include conf/extra/httpd-ssl.conf
//////////

# vi /opt/httpd-2.4.41/conf/extra/httpd-ssl.conf
//////////
79,80行目
-SSLProtocol all -SSLv3
-SSLProxyProtocol all -SSLv3
+SSLProtocol All -SSLv2 -SSLv3 -TLSv1
+SSLProxyProtocol All -SSLv2 -SSLv3 -TLSv1

144行目
-SSLCertificateFile "/opt/httpd-2.4.41/conf/server.crt"
+SSLCertificateFile /etc/pki/tls/certs/localhost.crt

154行目
-SSLCertificateKeyFile "/opt/httpd-2.4.41/conf/server.key"
+SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
//////////

動作確認2

httpdを再起動してブラウザアクセスによる動作確認を行いました。

IEのプロパティからTLSのバージョンが1.2となっていることが確認できました。

FireFoxで確認したところTLSのバージョンは1.3となっていました。
TLSv1.0の頃「脆弱な暗号化」と表示されてた箇所も「接続が暗号化されています」という安心できるメッセージに変わっていることを確認しました。

また、レスポンスヘッダーの情報よりhttpd2.4.41、OpenSSL1.1.1、PHP5.2.4で稼働していることを確認しました(画像右下)。

念のためサーバー側でも以下の確認を行いました。

# httpd -v
Server version: Apache/2.4.41 (Unix)
Server built:   Dec 14 2019 12:33:16

# php -v
PHP 5.2.4 (cli) (built: Dec 14 2019 12:43:12) 
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies

# php -i | head -20
phpinfo()
PHP Version => 5.2.4

System => Linux 1d152e7fb87c 4.9.184-linuxkit #1 SMP Tue Jul 2 22:58:16 UTC 2019 x86_64
Build Date => Dec 14 2019 12:42:33
Configure Command =>  './configure'  '--with-config-file-path=/etc' '--with-apxs2=/usr/sbin/apxs' '--with-mysql=/usr/local/mysql' '--with-pdo-mysql=/usr/local/mysql' '--with-mysql-sock=/tmp/mysql.sock' '--enable-mbstring' '--enable-zend-multibyte' '--sysconfdir=/etc' '--datadir=/usr/share' '--with-pear=/usr/share/PEAR' '--with-curl' '--with-mcrypt'
Server API => Command Line Interface
Virtual Directory Support => enabled
Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini
PHP API => 20041225
PHP Extension => 20060613
Zend Extension => 220060519
Debug Build => no
Thread Safety => enabled
Zend Memory Manager => enabled
IPv6 Support => enabled
Registered PHP Streams => php, file, data, http, ftp  
Registered Stream Socket Transports => tcp, udp, unix, udg
Registered Stream Filters => string.rot13, string.toupper, string.tolower, string.strip_tags, convert.*, consumed, convert.iconv.*

Dockerのイメージ作成3

目的とした環境構築と動作確認が行えたので最後にイメージ作成によるバックアップを作成しました。
タグをv3としてみました。

> docker stop centos5
> docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
1d152e7fb87c        tikuwa_centos5:v2   "/bin/bash"         31 minutes ago      Exited (0) 20 seconds ago                       centos5
> docker commit --message="installed openssl:1.1.1 httpd:2.4.41 etc." 1d152e7fb87c tikuwa_centos5:v3
sha256:be5348ee75eed2896effa650384f1420868137bff1115650c7c565369e72be25

> docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
tikuwa_centos5       v3                  be5348ee75ee        17 seconds ago      1.99GB
tikuwa_centos5       v2                  63365622e263        38 hours ago        1.35GB
tikuwa_centos5       v1                  8eaa3f4ad16c        2 days ago          396MB
astj/centos5-vault   latest              e79faab040e1        2 years ago         284MB

Dockerコマンド操作の備忘録

# コンテナ起動
>docker start centos5

# コンテナのbashに入る
>docker exec -it centos5 /bin/bash

# コンテナ終了
>docker stop centos5

# 稼働中のコンテナの一覧表示
>docker ps

# コンテナの一覧表示
>docker ps -a
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS                     PORTS               NAMES
ed88dd240da5        astj/centos5-vault   "/bin/bash"         17 minutes ago      Exited (0) 9 minutes ago                       centos5

# コンテナの削除
>docker rm ed88dd240da5

# イメージの作成
>docker commit --message="hogehoge" [CONTAINER ID] tikuwa_centos5:v1

# イメージの一覧
>docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
tikuwa_centos5             latest              b35c280bc42a        12 seconds ago      565MB
astj/centos5-vault         latest              e79faab040e1        2 years ago         284MB
fatherlinux/centos5-base   latest              9fe2350adfc8        5 years ago         1.14GB

# イメージの削除
>docker rmi b35c280bc42a
Untagged: tikuwa_centos5:latest
Deleted: sha256:b35c280bc42a81c21f357999f95212abb1269d01fef9252adcb38e383b1312a8
Deleted: sha256:a7ffad73831c7168e976928fc0ac56831d6dbbca669caa642173fbecc2125e7e

タグの使い方あってないような気がする。
タグは指定しないとlatestというタグを参照するようになっているようでした。

まとめ

途中phpのソース書き換えたりするときはまじかーと思ったりもしましたが最終的にはなんとか目的としたOpenSSLのバージョンアップ、TLSv1.2での通信が確認できました。
httpd2.4.41、php5.2.4のビルドはトライ&エラーで実際は数回イメージからの復元を行っています。
実際の業務の中ではMySQLデータベースのCRUDの動作確認やhttpdのドキュメントルートを変更してのWebシステムの動作確認なんかを行いました。

Dockerを使った環境構築については、「なんかコマンド操作間違ったか?」「この操作いらなかったのでは??」といったときに作成中のコンテナを破棄して保存したイメージを元に復元するといった作業を1分そこらでできるのがすごく便利。

Dockerfileの作り方についてはいつか勉強する。

その他

MySQLサーバーの古いソースコードのダウンロードリンクを見つけるのに10分くらい掛かったのでメモ(´;ω;`)
https://downloads.mysql.com/archives/community/

タイトルとURLをコピーしました