おことわり
この記事は、あんまよくわかってないことにチャレンジしてみた結果の備忘録です。
あまりよくないやり方とか、間違ってる内容が含まれる可能性がありますので、参考にされる際はご注意ください。
※むしろ、ここはこうしたほうがいいよとかそういう指摘ございましたら是非
また、作業をある程度自動化できるように、シェルコマンドの羅列には行の最後に && \ を追記しています。
シェルスクリプトにまとめるか、Dockerfileにしちゃえばって話な気もするけど、それはまた別途。
モチベーション
- 新しい技術に触れてみたい
- 普段yumでしかやらないので、configureとかmakeとかよくわかってない
- 台風
環境
- OS:CentOS7(CentOS Linux release 7.3.1611 (Core))の上にたてたCentOS7(CentOS Linux release 7.4.1708 (Core))
# docker images | grep "centos"
centos latest 196e0ce0c9fb 6 weeks ago 197MB
以下のシェルスクリプトを実行すると、上のcentosイメージを使ってランダムな名前を付けた使い捨てのCentOSコンテナを建てて、そこにシェルログインする。このコンテナ上でインストールや動作確認などを実施。
#!/bin/bash
CONTAINER_NAME=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n1)
docker run --privileged --name ${CONTAINER_NAME} -d centos /sbin/init
docker exec -ti ${CONTAINER_NAME} bash
最終的に手動でインストールしたもの、バージョン
インストールする順番に上から並べる。
名前 | バージョン | prefix | DLページ | 備考 |
---|---|---|---|---|
OpenSSL | 1.0.2l | /opt/openssl | https://www.openssl.org/source/ | 言わずもがな、オープンソースのSSL通信用ライブラリ |
nghttp2 | 1.27.0 | /opt/nghttp2 | https://github.com/nghttp2/nghttp2/releases/tag/v1.27.0 | http2のライブラリ。apacheでhttp/2で通信するために利用する。 |
curl | 7.56.1 | /opt/curl7-56 | https://curl.haxx.se/download.html | http/2での通信の動作確認に使う。CentOSにデフォルトでインストールされているバージョン(7.29.0)だとhttp/2のエクステンションが使えないので、最新をインストールしなおす。 |
apr | 1.6.3 | /opt/apr | https://apr.apache.org/download.cgi | apacheをインストールするのに使う。ApachePortableRuntime |
apr-util | 1.6.1 | /opt/apr-util | https://apr.apache.org/download.cgi | 上同 |
apache | 2.4.29 | /opt/httpd24 | https://httpd.apache.org/download.cgi#apache24 | apacheの最新。http/2で通信する(mod_http2を有効にする)には、2.4.14以降が必要 |
mysql | 8.0.3-0.1.rc | /var/lib/mysql | https://dev.mysql.com/downloads/mysql/8.0.html | mysqlの最新。どうもRHEL向けにはrpmしか配ってないようなので、rpmを使う。 |
php | 7.2.0RC4 | /opt/php7 | https://downloads.php.net/~pollita/ | phpの最新。10/26時点でRC5が最新。11/30にGA予定。 |
上記以外でインストールに必要なものは、yumでがつっとやる。
手順
dockerイメージを建ててシェルログイン後から。
なお、インストール以外に必要な作業は今回は省く(時刻設定やfirewallなど)。
また、すべての作業はrootで行われる。
yumupdate && 必要なものをyumインストール
yum -y update && \
yum -y upgrade && \
yum -y install epel-release gcc gcc-c++ make cmake autoconf git telnet wget pcre which lsof libaio net-tools numactl && \
yum -y install zlib-devel bzip2-devel libcurl-devel libxml2-devel expat-devel pcre-devel ncurses-devel
※最終的に不必要なものとか、動作確認に使うものとかも含まれてる
/opt配下にprefixとして利用するディレクトリを作成する
cd /opt && \
mkdir httpd24 apr apr-util openssl php7 curl7-56
※mysqlはrpmインストールでデフォルトに設定されている/var/lib/配下にインストールされる
ソースを持ってきて展開する
cd /usr/local/src && \
wget http://ftp.riken.jp/net/apache//httpd/httpd-2.4.29.tar.gz && \
wget http://ftp.riken.jp/net/apache//apr/apr-1.6.3.tar.gz && \
wget http://ftp.riken.jp/net/apache//apr/apr-util-1.6.1.tar.gz && \
wget https://github.com/nghttp2/nghttp2/releases/download/v1.27.0/nghttp2-1.27.0.tar.gz && \
wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2l.tar.gz && \
wget https://curl.haxx.se/download/curl-7.56.1.tar.gz && \
wget https://downloads.php.net/~remi/php-7.2.0RC4.tar.gz && \
for TARGET in $(ls) ; do tar zxvf $TARGET ; done && \
chown -R root:root /usr/local/src/*
OpenSSLをインストールし、パスを通す。
cd openssl-1.0.2l && \
./config \
--prefix=/opt/openssl \
shared zlib && \
make && \
make install && \
echo /opt/openssl/lib > /etc/ld.so.conf.d/openssl102l.conf && \
ldconfig && \
ln -s /opt/openssl/bin/* /usr/local/bin/ && \
cd ..
確認
# openssl version
OpenSSL 1.0.2l 25 May 2017
# ldconfig -p | grep "openssl"
libssl.so.1.0.0 (libc6,x86-64) => /opt/openssl/lib/libssl.so.1.0.0
libssl.so (libc6,x86-64) => /opt/openssl/lib/libssl.so
libcrypto.so.1.0.0 (libc6,x86-64) => /opt/openssl/lib/libcrypto.so.1.0.0
libcrypto.so (libc6,x86-64) => /opt/openssl/lib/libcrypto.so
nghttp2をインストールし、パスを通す
env OPENSSL_CFLAGS="-I/opt/openssl/include" OPENSSL_LIBS="-L/opt/openssl/lib -lssl -lcrypto" && \
./configure \
--prefix=/opt/nghttp2 && \
make && \
make install && \
echo /opt/nghttp2/lib > /etc/ld.so.conf.d/nghttp2.conf && \
ldconfig
cd ..
確認
# ldconfig -p | grep "nghttp"
libnghttp2.so.14 (libc6,x86-64) => /opt/nghttp2/lib/libnghttp2.so.14
libnghttp2.so (libc6,x86-64) => /opt/nghttp2/lib/libnghttp2.so
curl-7.56.1をhttp2エクステンションを追加してインストールし、curl7-56コマンドで実行できるようにする。
cd curl7-56 && \
./configure \
--prefix=/opt/curl7-56 \
--with-ssl=/opt/openssl \
--with-nghttp2=/opt/nghttp2 && \
make && \
make install && \
ln -s /opt/curl7-56/bin/curl /usr/local/bin/curl7-56 && \
ln -s /opt/curl7-56/bin/curl-config /usr/local/bin/curl-config-7-56 && \
cd ..
確認
# curl --version
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.28.4 zlib/1.2.7 libidn/1.28 libssh2/1.4.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz unix-sockets
# curl7-56 --version
curl 7.56.1 (x86_64-pc-linux-gnu) libcurl/7.56.1 OpenSSL/1.0.2l zlib/1.2.7 nghttp2/1.27.0
Release-Date: 2017-10-23
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy
curl7-56のほうはnghttp2がリンクされており、HTTP2が使えることが確認できる。またOpenSSLも自分でインストールしたものがリンクされている。
apacheをインストールするためのaprとapr-utilをインストールする。
cd apr-1.6.3 && \
./configure --prefix=/opt/apr && \
make && \
make install && \
cd ..
cd apr-util-1.6.1 && \
./configure \
--prefix=/opt/apr-util \
--with-apr=/opt/apr && \
make && \
make install && \
cd ..
apacheをインストールし、http/2で通信できることを確認する。
※configureのオプションについては、お好みで追加など
インストール
cd httpd-2.4.29 && \
./configure \
--prefix=/opt/httpd24 \
--enable-http2 \
--with-nghttp2=/opt/nghttp2 \
--enable-ssl \
--with-ssl=/opt/openssl \
--with-apr=/opt/apr \
--with-apr-util=/opt/apr-util \
--enable-so \
--with-pcre=builtin \
--with-expat=builtin \
--enable-mpms-shared=all && \
make && \
make install && \
ln -s /opt/httpd24/bin/* /usr/local/bin/ && \
cd ..
SSL通信をするために自己証明書を作成
http/2はSSL通信が必須。Let'sEncryptとかを試してもいいけど、今回は自己証明書で。
※curlは自己証明書を使ってるSSL通信に対して警告を吐く。無視する場合は -k オプションを使う。
cd /opt/httpd24
mkdir cert && cd cert
openssl genrsa 2048 > server.key
openssl req -new -key server.key > server.csr #commonnameは適当に、それ以外は空でおk
openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt
chmod 400 server.*
※openssl req は対話的にやる必要があります、注意
config修正
以下の部分を修正する。
httpd.conf
cd /opt/httpd24/conf && \
mkdir .backup && \
cp -pri httpd.conf .backup/httpd.conf.org && \
vi httpd.conf
===
#LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
#LoadModule http2_module modules/mod_http2.so
#LoadModule ssl_module modules/mod_ssl.so
↓
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule http2_module modules/mod_http2.so
LoadModule ssl_module modules/mod_ssl.so
===
===
#ServerName www.example.com:80
↓
ServerName www.example.com:80
===
#localhostでよかったかも、自己証明書のcommon nameと合わせておいたほうが、何かとよいかもしれない?
===
#Include conf/extra/httpd-ssl.conf
↓
Include conf/extra/httpd-ssl.conf
===
httpd-ssl.conf
cd extra && \
mkdir .backup && \
cp -pri httpd-ssl.conf .backup/httpd-ssl.conf.org && \
vi httpd-ssl.conf
===
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
↓
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
===
===
SSLProtocol all -SSLv3
↓
SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2
===
デフォルトで書いてある、
<VirtualHost _default_:443>
~
</VirtualHost>
をすべてコメントアウト
以下を追記。
<VirtualHost *:443>
<IfModule http2_module>
ProtocolsHonorOrder On
Protocols h2 http/1.1
</IfModule>
ServerName www.example.com:443
DocumentRoot "/opt/httpd24/ssl_htdocs/"
SSLEngine on
SSLCertificateFile "/opt/httpd24/cert/server.crt"
SSLCertificateKeyFile "/opt/httpd24/cert/server.key"
<Directory "/opt/httpd24/ssl_htdocs/">
Options +Indexes +Includes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
SetEnvIf Request_URI "\.(gif|jpg|png|css|js)$" nolog
ErrorLog /var/log/error_log
CustomLog /var/log/access_log combined env=!nolog
Header add Strict-Transport-Security "max-age=15552000"
CustomLog "/opt/httpd24/logs/ssl_request_log" \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
ドキュメントルートを作成
mkdir /opt/httpd24/ssl_htdocs
起動
# apachectl -t
Syntax OK
# apachectl #apache起動。停止する場合は、 apachectl stop
# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 13919 root 3u IPv4 248445154 0t0 TCP *:http (LISTEN)
httpd 13920 daemon 3u IPv4 248445154 0t0 TCP *:http (LISTEN)
httpd 13921 daemon 3u IPv4 248445154 0t0 TCP *:http (LISTEN)
httpd 13922 daemon 3u IPv4 248445154 0t0 TCP *:http (LISTEN)
# lsof -i:443
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 13919 root 4u IPv4 248445160 0t0 TCP *:https (LISTEN)
httpd 13920 daemon 4u IPv4 248445160 0t0 TCP *:https (LISTEN)
httpd 13921 daemon 4u IPv4 248445160 0t0 TCP *:https (LISTEN)
httpd 13922 daemon 4u IPv4 248445160 0t0 TCP *:https (LISTEN)
止めるときは、apachectl stop
※systemctlに登録するとかは、別で。いったん動けばおk
動作確認
# 動作確認用のファイルを作成
echo "test.html 80" > /opt/httpd24/htdocs/test.html
echo "test.html 443" > /opt/httpd24/ssl_htdocs/test.html
curl http://localhost/test.html
=> test.html 80 を出力
curl https://localhost/test.html -k
=> test.html 443 を出力
curl7-56 https://localhost/test.html -k
=> test.html 443 を出力
# ログ確認
tail /opt/httpd24/logs/ssl_request_log
[29/Oct/2017:12:42:31 +0000] 127.0.0.1 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 "GET /test.html HTTP/1.1" 14
[29/Oct/2017:12:43:19 +0000] 127.0.0.1 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 "GET /test.html HTTP/2.0" 14
上記ログで、http/1.1 http/2 それぞれで通信できたことを確認できた。
※時刻が気になる場合はちゃんと設定しておきましょう。
PHP7.2をインストール
※configureのオプションはお好みで足してください
インストール
cd /usr/local/src/php-7.2.0RC4 && \
./configure \
--prefix=/opt/php7 \
--with-apxs2=/opt/httpd24/bin/apxs \
--enable-mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-curl=/opt/curl7-56 \
--with-openssl=/opt/openssl
make && \
make install && \
cd ..
確認
# 確認用ファイル作成
echo "<?php phpinfo(); ?>" >/opt/httpd24/ssl_htdocs/phpinfo.php
# curlで接続
curl7-56 https://localhost/phpinfo.php -k
=> phpinfoがどばどばーっとでてくる。ちゃんと生成されてるっぽいのでまぁいっかと思ったけど、念のため内容をファイルにリダイレクトしローカルに持ってきてブラウザから確認。php7.2(RC)がインストールされて動いてることが確認できた。
# log
tail /opt/httpd24/logs/ssl_request_log -n 1
[29/Oct/2017:12:47:57 +0000] 127.0.0.1 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 "GET /phpinfo.php HTTP/2.0" 80510
MySQLインストール
MySQLだけ、rpmで配布されているものを利用。
※mysqlのソースインストールでググると、ソースからcmakeでインストールしてる記事が大量に出てくるんだけど今回はrpm利用。
公式DLページから自分の環境にあったものを選ぶ。
今回は「Red Hat Enterprise Linux 7 / Oracle Linux 7 (x86, 64-bit), RPM Bundle」をもってきて、必要なものをrpmで入れる。
mkdir /usr/local/src/mysql8 && \
wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.3-0.1.rc.el7.x86_64.rpm-bundle.tar && \
tar xvf mysql-8.0.3-0.1.rc.el7.x86_64.rpm-bundle.tar && \
rpm -Uvh mysql-community-server-8.0.3-0.1.rc.el7.x86_64.rpm mysql-community-client-8.0.3-0.1.rc.el7.x86_64.rpm mysql-community-common-8.0.3-0.1.rc.el7.x86_64.rpm mysql-community-libs-8.0.3-0.1.rc.el7.x86_64.rpm
で、とりあえず最低限必要なものはOK.
起動、動作確認
systemctl start mysqld.service
=> A temporary password is generatedのメッセージがでるので、初期パスワードを確認する。mysqld.logに書いてある。
mysql -uroot -p
Enter password: => ログに出力された初期パスワードを入力。
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '[パスワード]';
=> rootのパスワードを変更。以後自由。
以上で、CentOS7上に最新のapache+php+mysqlの構成、および動作確認までができました。
補足
何回も試行錯誤してコンテナぽこじゃが建ててるとどんどんゴミコンテナがたまってくので、以下のシェルスクリプトで一斉お掃除。
#!/bin/bash
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)