Raspberry Pi3 に OpenCV 3.4.3を入れてみた

Python3からOpenCVが利用したくなってパッケージから入れようとしたけど失敗して今度はビルドして失敗してまたパッケージで頑張ったら動いた話

Windowsの場合はpipで入れるだけでOpenCV本体と共有ライブラリが同梱されていて簡単に動いたのですが、linuxの場合は別で用意してやらないといけないみたいです。
ubuntuなどの場合はaptから一発で入るようですが、Raspbianの場合はどうも簡単に行かないようです。(python2系ならいける?)
すでにいろいろ試されてる記事が多いですが、自分でコンパイルするか、不足しているパッケージをバカスカ入れていくか何方かのようです。

■環境

RaspberryPi3 model b+
RASPBIAN STRETCH LITE
Python3.5.3
OpenCV 4.0
OpenCV 3.4.3
numpy 1.15.4

■ビルドしてみた(失敗)

失敗した記録です

■ビルド環境の用意
ビルドする際に結構なメモリとディスク容量が必要です。

■空き容量
ビルド結果は5.8GBでしたのでそれ以上の空き容量が必要です。
8GBのSDカードを使用しているのですが、収まらなかったためUSBメモリ上でビルドしました。
USB上でビルドする場合はvfatでは収まらないファイルがいるため、ext4にフォーマットしてから使用する必要があります。

mkfs -t ext4 /dev/sda
mount /dev/sda /mnt

■メモリ
ModelB+のDRAM容量は1GBあり、スワップは初期設定では100MBありますが、それでも足りないのでスワップを大きくする必要があります。
SDカード上に大きなスワップを用意すると寿命が一気に減ってしまうので、USBメモリ上に作成しました。
最初気づかず、68%辺りでハングアップしました。
スワップの移動方法は参考サイト参照

mkfs -t ext4 /dev/sdb
mkdir /opt/swap
mount /dev/sdb /opt/swap

※USBは2個使用しています

■ソースコードの用意
以下のディレクトリ構成になるように取得&解凍します
せっかくなので最新の4.0.0を使ってみたいと思います。

/mnt/opencv-4.0.0
/mnt/opencv_contrib-4.0.0/

■ビルド
最低限のオプションでビルドしてみます。オプションが多すぎて適切なチョイスが難しそうです。
ビルドに数時間かかるので何か別のことをして待ったほうがいいです。

cmake -D OPENCV_EXTRA_MODULES_PATH=/mnt/opencv_contrib-4.0.0/modules ..
nohup make -j4 &

■インストール
make installすると各ライブラリの展開と、Pythonのsetup.pyが生成されるので、Pythonへのインストールまで行います。
※ここにバグがあるようです

make install
python3 /usr/local/python/setup.py build
python3 /usr/local/python/setup.py install

■BLASライブラリの差し替え
すんなり動作したら良かったのですが、numpyが参照しているライブラリに問題が発生しているようでした。

ImportError: /usr/local/lib/python3.5/dist-packages/numpy/core/multiarray.cpython-35m-arm-linux-gnueabihf.so: undefined symbol: cblas_sgemm

githubで言及されている症状と一致しており、BLASライブラリをAtlasからOpenBLASに変えてみたら上手く動きました。
https://github.com/Kitt-AI/snowboy/issues/38

numpyをOpenBLAS指定でビルドする方法は下の通りでいけました
numpy, scipyでOpenBLASを使う

■動作確認

# python3
>>> import cv2
ImportError: ERROR: recursion is detected during loading of "cv2" binary extensions. Check OpenCV installation.

OpenCV3.4.4から用意されている新しいPythonバインディング用のセットアップにバグがあるようでどうも動かないようです。
ここで断念しました。
https://github.com/opencv/opencv/issues/13202

■pipとaptで入れてみる

pipで入れたOpenCV環境では共有ライブラリが不足していて怒られるので、自分で持ってくる必要があります。
具体的にはlddコマンドで.soファイルを覗いてみて not found となっている共有ライブラリを探し、
ライブラリを含むパッケージをひたすらaptで入れていく作業です。

最初に必要なパッケージをpipでインストールします

# pip3 install opencv-python
# pip3 show opencv-python
Name: opencv-python
Version: 3.4.3.18
Summary: Wrapper package for OpenCV python bindings.
Home-page: https://github.com/skvark/opencv-python
Author: Olli-Pekka Heinisuo
Author-email: UNKNOWN
License: MIT
Location: /usr/local/lib/python3.5/dist-packages
Requires: numpy

# pip3 install opencv-contrib-python
# pip3 show opencv-contrib-python
Name: opencv-contrib-python
Version: 3.4.3.18
Summary: Wrapper package for OpenCV python bindings.
Home-page: https://github.com/skvark/opencv-python
Author: Olli-Pekka Heinisuo
Author-email: UNKNOWN
License: MIT
Location: /usr/local/lib/python3.5/dist-packages
Requires: numpy

# pip3 install numpy
# pip3 show numpy
Name: numpy
Version: 1.15.4
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: NumPy Developers
Author-email: numpy-discussion@python.org
License: BSD
Location: /usr/local/lib/python3.5/dist-packages/numpy-1.15.4-py3.5-linux-armv7l.egg
Requires:

/usr/local/lib/python3.5/dist-packages/cv2/cv2.cpython-35m-arm-linux-gnueabihf.so
にcv2のライブラリが保存されるのでlddで確認し、not found が全て無くなるまでaptでパッケージを入れていきます。

こんだけ入れたはずです

apt install liblapack-dev libcblas-dev libatlas-dev libatlas-base-dev libjasper-dev gstreamer1.0-plugins-base libqt4-test
root@raspberrypi:/# ldd /usr/local/lib/python3.5/dist-packages/cv2/cv2.cpython-35m-arm-linux-gnueabihf.so
        linux-vdso.so.1 (0x7ec0d000)
        /usr/lib/arm-linux-gnueabihf/libarmmem.so (0x75f57000)
        liblapack.so.3 => /usr/lib/liblapack.so.3 (0x75a31000)
        libcblas.so.3 => /usr/lib/arm-linux-gnueabihf/libcblas.so.3 (0x759d7000)
        libatlas.so.3 => /usr/lib/libatlas.so.3 (0x7575f000)
        libjpeg.so.62 => /usr/lib/arm-linux-gnueabihf/libjpeg.so.62 (0x75719000)
        libwebp.so.6 => /usr/lib/arm-linux-gnueabihf/libwebp.so.6 (0x756bb000)
        libpng16.so.16 => /usr/lib/arm-linux-gnueabihf/libpng16.so.16 (0x75681000)
        libtiff.so.5 => /usr/lib/arm-linux-gnueabihf/libtiff.so.5 (0x75607000)
        libjasper.so.1 => /usr/lib/arm-linux-gnueabihf/libjasper.so.1 (0x755ab000)
        libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0x75584000)
        libImath-2_2.so.12 => /usr/lib/arm-linux-gnueabihf/libImath-2_2.so.12 (0x75567000)
        libIlmImf-2_2.so.22 => /usr/lib/arm-linux-gnueabihf/libIlmImf-2_2.so.22 (0x752b4000)
        libIex-2_2.so.12 => /usr/lib/arm-linux-gnueabihf/libIex-2_2.so.12 (0x7528d000)
        libHalf.so.12 => /usr/lib/arm-linux-gnueabihf/libHalf.so.12 (0x7523a000)
        libIlmThread-2_2.so.12 => /usr/lib/arm-linux-gnueabihf/libIlmThread-2_2.so.12 (0x75224000)
        libgstbase-1.0.so.0 => /usr/lib/arm-linux-gnueabihf/libgstbase-1.0.so.0 (0x751b6000)
        libgstreamer-1.0.so.0 => /usr/lib/arm-linux-gnueabihf/libgstreamer-1.0.so.0 (0x75093000)
        libgobject-2.0.so.0 => /usr/lib/arm-linux-gnueabihf/libgobject-2.0.so.0 (0x75039000)
        libglib-2.0.so.0 => /lib/arm-linux-gnueabihf/libglib-2.0.so.0 (0x74f31000)
        libavcodec.so.57 => /usr/lib/arm-linux-gnueabihf/libavcodec.so.57 (0x73cf0000)
        libavformat.so.57 => /usr/lib/arm-linux-gnueabihf/libavformat.so.57 (0x73adc000)
        libavutil.so.55 => /usr/lib/arm-linux-gnueabihf/libavutil.so.55 (0x73a44000)
        libswscale.so.4 => /usr/lib/arm-linux-gnueabihf/libswscale.so.4 (0x739c6000)
        libQtGui.so.4 => /usr/lib/arm-linux-gnueabihf/libQtGui.so.4 (0x730e8000)
        libQtTest.so.4 => /usr/lib/arm-linux-gnueabihf/libQtTest.so.4 (0x730b9000)
        libQtCore.so.4 => /usr/lib/arm-linux-gnueabihf/libQtCore.so.4 (0x72e20000)
        libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x72e0d000)
        libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x72de4000)
        librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x72dcd000)
        libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x72c85000)
        libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x72c06000)
        libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x72bd9000)
        libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x72a9a000)
        /lib/ld-linux-armhf.so.3 (0x76fb6000)
        libblas.so.3 => /usr/lib/libblas.so.3 (0x72a5a000)
        libgfortran.so.3 => /usr/lib/arm-linux-gnueabihf/libgfortran.so.3 (0x729a5000)
        libf2c.so.2 => /usr/lib/arm-linux-gnueabihf/libf2c.so.2 (0x7297c000)
        liblzma.so.5 => /lib/arm-linux-gnueabihf/liblzma.so.5 (0x7294b000)
        libjbig.so.0 => /usr/lib/arm-linux-gnueabihf/libjbig.so.0 (0x7292e000)
        libgmodule-2.0.so.0 => /usr/lib/arm-linux-gnueabihf/libgmodule-2.0.so.0 (0x7291a000)
        libffi.so.6 => /usr/lib/arm-linux-gnueabihf/libffi.so.6 (0x72902000)
        libpcre.so.3 => /lib/arm-linux-gnueabihf/libpcre.so.3 (0x72889000)
        libswresample.so.2 => /usr/lib/arm-linux-gnueabihf/libswresample.so.2 (0x72863000)
        libva.so.1 => /usr/lib/arm-linux-gnueabihf/libva.so.1 (0x72836000)
        libmmal_core.so => /opt/vc/lib/libmmal_core.so (0x72818000)
        libmmal_util.so => /opt/vc/lib/libmmal_util.so (0x727f8000)
        libmmal_vc_client.so => /opt/vc/lib/libmmal_vc_client.so (0x727dd000)
        libbcm_host.so => /opt/vc/lib/libbcm_host.so (0x727b6000)
        libzvbi.so.0 => /usr/lib/arm-linux-gnueabihf/libzvbi.so.0 (0x72732000)
        libxvidcore.so.4 => /usr/lib/arm-linux-gnueabihf/libxvidcore.so.4 (0x7263b000)
        libx265.so.95 => /usr/lib/arm-linux-gnueabihf/libx265.so.95 (0x723e3000)
        libx264.so.148 => /usr/lib/arm-linux-gnueabihf/neon/vfp/libx264.so.148 (0x72274000)
        libwebpmux.so.2 => /usr/lib/arm-linux-gnueabihf/libwebpmux.so.2 (0x7225c000)
        libwavpack.so.1 => /usr/lib/arm-linux-gnueabihf/libwavpack.so.1 (0x72228000)
        libvpx.so.4 => /usr/lib/arm-linux-gnueabihf/libvpx.so.4 (0x7212b000)
        libvorbisenc.so.2 => /usr/lib/arm-linux-gnueabihf/libvorbisenc.so.2 (0x72099000)
        libvorbis.so.0 => /usr/lib/arm-linux-gnueabihf/libvorbis.so.0 (0x72062000)
        libtwolame.so.0 => /usr/lib/arm-linux-gnueabihf/libtwolame.so.0 (0x72032000)
        libtheoraenc.so.1 => /usr/lib/arm-linux-gnueabihf/libtheoraenc.so.1 (0x71fec000)
        libtheoradec.so.1 => /usr/lib/arm-linux-gnueabihf/libtheoradec.so.1 (0x71fc5000)
        libspeex.so.1 => /usr/lib/arm-linux-gnueabihf/libspeex.so.1 (0x71f9f000)
        libsnappy.so.1 => /usr/lib/arm-linux-gnueabihf/libsnappy.so.1 (0x71f88000)
        libshine.so.3 => /usr/lib/arm-linux-gnueabihf/libshine.so.3 (0x71f6d000)
        libopus.so.0 => /usr/lib/arm-linux-gnueabihf/libopus.so.0 (0x71f1a000)
        libopenjp2.so.7 => /usr/lib/arm-linux-gnueabihf/libopenjp2.so.7 (0x71ed4000)
        libmp3lame.so.0 => /usr/lib/arm-linux-gnueabihf/libmp3lame.so.0 (0x71e59000)
        libgsm.so.1 => /usr/lib/arm-linux-gnueabihf/libgsm.so.1 (0x71e47000)
        libssh-gcrypt.so.4 => /usr/lib/arm-linux-gnueabihf/libssh-gcrypt.so.4 (0x71dd8000)
        libopenmpt.so.0 => /usr/lib/arm-linux-gnueabihf/libopenmpt.so.0 (0x71c5d000)
        libgme.so.0 => /usr/lib/arm-linux-gnueabihf/libgme.so.0 (0x71c0e000)
        libbluray.so.1 => /usr/lib/arm-linux-gnueabihf/libbluray.so.1 (0x71bba000)
        libgnutls.so.30 => /usr/lib/arm-linux-gnueabihf/libgnutls.so.30 (0x71a2d000)
        libchromaprint.so.1 => /usr/lib/arm-linux-gnueabihf/libchromaprint.so.1 (0x71a0d000)
        libbz2.so.1.0 => /lib/arm-linux-gnueabihf/libbz2.so.1.0 (0x719ed000)
        libX11.so.6 => /usr/lib/arm-linux-gnueabihf/libX11.so.6 (0x718ca000)
        libvdpau.so.1 => /usr/lib/arm-linux-gnueabihf/libvdpau.so.1 (0x718b4000)
        libva-drm.so.1 => /usr/lib/arm-linux-gnueabihf/libva-drm.so.1 (0x718a1000)
        libva-x11.so.1 => /usr/lib/arm-linux-gnueabihf/libva-x11.so.1 (0x7188c000)
        libfontconfig.so.1 => /usr/lib/arm-linux-gnueabihf/libfontconfig.so.1 (0x71849000)
        libaudio.so.2 => /usr/lib/arm-linux-gnueabihf/libaudio.so.2 (0x71824000)
        libfreetype.so.6 => /usr/lib/arm-linux-gnueabihf/libfreetype.so.6 (0x71789000)
        libSM.so.6 => /usr/lib/arm-linux-gnueabihf/libSM.so.6 (0x71772000)
        libICE.so.6 => /usr/lib/arm-linux-gnueabihf/libICE.so.6 (0x7174c000)
        libXrender.so.1 => /usr/lib/arm-linux-gnueabihf/libXrender.so.1 (0x71733000)
        libXext.so.6 => /usr/lib/arm-linux-gnueabihf/libXext.so.6 (0x71714000)
        libsoxr.so.0 => /usr/lib/arm-linux-gnueabihf/libsoxr.so.0 (0x716b0000)
        libvcos.so => /opt/vc/lib/libvcos.so (0x71696000)
        libvchiq_arm.so => /opt/vc/lib/libvchiq_arm.so (0x71680000)
        libvcsm.so => /opt/vc/lib/libvcsm.so (0x7166b000)
        libogg.so.0 => /usr/lib/arm-linux-gnueabihf/libogg.so.0 (0x7165d000)
        libcairo.so.2 => /usr/lib/arm-linux-gnueabihf/libcairo.so.2 (0x7156c000)
        libgcrypt.so.20 => /lib/arm-linux-gnueabihf/libgcrypt.so.20 (0x7149b000)
        libgssapi_krb5.so.2 => /usr/lib/arm-linux-gnueabihf/libgssapi_krb5.so.2 (0x71452000)
        libmpg123.so.0 => /usr/lib/arm-linux-gnueabihf/libmpg123.so.0 (0x713f7000)
        libvorbisfile.so.3 => /usr/lib/arm-linux-gnueabihf/libvorbisfile.so.3 (0x713dd000)
        libxml2.so.2 => /usr/lib/arm-linux-gnueabihf/libxml2.so.2 (0x7124d000)
        libp11-kit.so.0 => /usr/lib/arm-linux-gnueabihf/libp11-kit.so.0 (0x711ef000)
        libidn.so.11 => /lib/arm-linux-gnueabihf/libidn.so.11 (0x711ae000)
        libtasn1.so.6 => /usr/lib/arm-linux-gnueabihf/libtasn1.so.6 (0x7118e000)
        libnettle.so.6 => /usr/lib/arm-linux-gnueabihf/libnettle.so.6 (0x71147000)
        libhogweed.so.4 => /usr/lib/arm-linux-gnueabihf/libhogweed.so.4 (0x7110a000)
        libgmp.so.10 => /usr/lib/arm-linux-gnueabihf/libgmp.so.10 (0x71097000)
        libxcb.so.1 => /usr/lib/arm-linux-gnueabihf/libxcb.so.1 (0x71068000)
        libdrm.so.2 => /usr/lib/arm-linux-gnueabihf/libdrm.so.2 (0x7104b000)
        libXfixes.so.3 => /usr/lib/arm-linux-gnueabihf/libXfixes.so.3 (0x71034000)
        libexpat.so.1 => /lib/arm-linux-gnueabihf/libexpat.so.1 (0x71002000)
        libXt.so.6 => /usr/lib/arm-linux-gnueabihf/libXt.so.6 (0x70fa2000)
        libXau.so.6 => /usr/lib/arm-linux-gnueabihf/libXau.so.6 (0x70f97000)
        libuuid.so.1 => /lib/arm-linux-gnueabihf/libuuid.so.1 (0x70f83000)
        libbsd.so.0 => /lib/arm-linux-gnueabihf/libbsd.so.0 (0x70f5a000)
        libgomp.so.1 => /usr/lib/arm-linux-gnueabihf/libgomp.so.1 (0x70f22000)
        libpixman-1.so.0 => /usr/lib/arm-linux-gnueabihf/libpixman-1.so.0 (0x70e80000)
        libxcb-shm.so.0 => /usr/lib/arm-linux-gnueabihf/libxcb-shm.so.0 (0x70e6d000)
        libxcb-render.so.0 => /usr/lib/arm-linux-gnueabihf/libxcb-render.so.0 (0x70e52000)
        libgpg-error.so.0 => /lib/arm-linux-gnueabihf/libgpg-error.so.0 (0x70e30000)
        libkrb5.so.3 => /usr/lib/arm-linux-gnueabihf/libkrb5.so.3 (0x70d79000)
        libk5crypto.so.3 => /usr/lib/arm-linux-gnueabihf/libk5crypto.so.3 (0x70d3a000)
        libcom_err.so.2 => /lib/arm-linux-gnueabihf/libcom_err.so.2 (0x70d27000)
        libkrb5support.so.0 => /usr/lib/arm-linux-gnueabihf/libkrb5support.so.0 (0x70d0e000)
        libkeyutils.so.1 => /lib/arm-linux-gnueabihf/libkeyutils.so.1 (0x70cfb000)
        libresolv.so.2 => /lib/arm-linux-gnueabihf/libresolv.so.2 (0x70cd6000)
        libicui18n.so.57 => /usr/lib/arm-linux-gnueabihf/libicui18n.so.57 (0x70ac6000)
        libicuuc.so.57 => /usr/lib/arm-linux-gnueabihf/libicuuc.so.57 (0x7095c000)
        libicudata.so.57 => /usr/lib/arm-linux-gnueabihf/libicudata.so.57 (0x6f0cf000)
        libXdmcp.so.6 => /usr/lib/arm-linux-gnueabihf/libXdmcp.so.6 (0x6f0b8000)

■動作確認
なんとか動きました

# python3
>>> import cv2
>>> cv2.__version__
'3.4.3'

■参考サイト

Install guide: Raspberry Pi 3 + Raspbian Jessie + OpenCV 3
今更ながらPythonでOpenCVを使うための覚書
RaspberryPi (3 Model B+) へのOpenCV(3.4.2)のインストール
ラズパイにOpenCVをインストールする方法
OpenCV 3.4.4 Python binding #13202
compiling opencv from github
undefined symbol: cblas_sgemm #38
numpy, scipyでOpenBLASを使う
error build openCV
OpenCV 3.0 Makefile生成用スクリプトファイル(Ubuntu15.04)
ラズパイ(Raspbian Jessie)とスワップメモリ容量の変更(環境設定の続き)
UbuntuにOpenCVをパッケージからapt-getを使ってインストールする。

php5から7.0にアップデートしたらwordpressが早くなった

php5時点でのApacheBench

$ ab -n 100 -c 20 https://helloidea.org/XXXX
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking helloidea.org (be patient).....done


Server Software:        Apache/2.4.25
Server Hostname:        helloidea.org
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128

Document Path:          /XXXX
Document Length:        78540 bytes

Concurrency Level:      20
Time taken for tests:   1.997 seconds
Complete requests:      100
Failed requests:        10
   (Connect: 0, Receive: 0, Length: 10, Exceptions: 0)
Total transferred:      7870988 bytes
HTML transferred:       7853988 bytes
Requests per second:    50.07 [#/sec] (mean)
Time per request:       399.423 [ms] (mean)
Time per request:       19.971 [ms] (mean, across all concurrent requests)
Transfer rate:          3848.81 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       80  301  79.0    305     444
Processing:    34   70  24.6     62     136
Waiting:        7   23  14.3     18      71
Total:        129  370  83.9    374     546

Percentage of the requests served within a certain time (ms)
  50%    374
  66%    414
  75%    422
  80%    436
  90%    458
  95%    490
  98%    542
  99%    546
 100%    546 (longest request)

php7.0変更後のApacheBench

$ ab -n 100 -c 20 https://helloidea.org/XXXX
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking helloidea.org (be patient).....done


Server Software:        Apache/2.4.25
Server Hostname:        helloidea.org
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128

Document Path:          /XXXX
Document Length:        84958 bytes

Concurrency Level:      20
Time taken for tests:   0.967 seconds
Complete requests:      100
Failed requests:        89
   (Connect: 0, Receive: 0, Length: 89, Exceptions: 0)
Total transferred:      8510241 bytes
HTML transferred:       8493241 bytes
Requests per second:    103.38 [#/sec] (mean)
Time per request:       193.454 [ms] (mean)
Time per request:       9.673 [ms] (mean, across all concurrent requests)
Transfer rate:          8592.00 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       58  131  49.8    120     313
Processing:    15   46  31.7     37     164
Waiting:        4   17  10.6     13      40
Total:        105  177  51.1    165     343

Percentage of the requests served within a certain time (ms)
  50%    165
  66%    191
  75%    200
  80%    205
  90%    262
  95%    297
  98%    321
  99%    343
 100%    343 (longest request)

約2倍ほど早くなりました。
キャッシュ系のプラグインを使用していましたが、もう不要かもしれないです。
もっと早く気づきたかった…

パッケージのインストール

apt install php7.0
apt install php5-mysql
apt install libapache2-mod-php7.0
apt install php7.0-gd
apt install php7.0-xml
apt install php7.0-xmlrpc
apt install php7.0-mbstring

php5からphp7.0への切り替え

a2dismod php5
a2enmod php7.0
/etc/init.d/apache2 restart

※php.iniは元々手を加えていた差分だけマージすれば良さそうです

WordPressのコメント欄からメールアドレス、ウェブサイトを消す

調べるとphpファイルを編集する方法と、cssを変更する方法が見つかりますが、
「外観 -> CSS編集」から追加CSSを使って上書きする形が良いと思います。

こんな感じに非表示になるよう上書きします。クラス名はChromeの開発コンソールから追っていくとすぐ見つかりました。

/* メールアドレスが公開されることはありません。 */
.comment-notes {display:none;}
/* コメント欄 */
/* .comment-form-comment {display:none;} */
/* 名前 */
/* .comment-form-author {display:none;} */
/* メールアドレス */
.comment-form-email {display:none;}
/* サイト */
.comment-form-url {display:none;}
/* 新しいコメントをメールで通知 */
.comment-subscription-form {display:none;}
/* 新しい投稿をメールで受け取る */
.comment-subscription-form {display:none;}

上の例で、コメント欄 と 名前 以外は非表示になります。

変更前
変更後

サイトをhttps化してみる

結構前からGoogleが本気でhttps化を促していて、気にはしていたものの結局放置していたのですが、気が向いたのでhttps化してみようと思います。

■環境
Apache2 – 2.4.25-3+deb9u5
DebianパッケージのApache2になります

■構築
1. Apache2のsslモジュールを有効化する

以下のコマンドを実行して、sslモジュールとsslのデフォルト設定を有効化します

# sslモジュール有効化
$ a2enmod ssl
# sslサイトデフォルト設定有効化
$ a2ensite default-ssl
# apache2再起動
$ systemctl restart apache2

コマンドを実行することによって、
mods-availableへのシンボリックリンクがmods-enabledに置かれ
sites-availableへのシンボリックリンクがsites-enabledに置かれることになります
手作業で普通にシンボリックリンクを作成しても良いと思います。
再起動も普通に /etc/init.d/apache2 restart としても良いです。

etc
+apache2
|+conf-available
|+conf-enabled
|+mods-available
||+ssl.conf
||+ssl.load
|+mods-enabled
||+ssl.conf
||+ssl.load
|+sites-available
||+000-default.conf
||\default-ssl.conf
|+sites-enabled
||+000-default.conf
||\default-ssl.conf
|+apache2.conf
|+apache2.conf.dpkg-dist
|+envvars
|+magic
|\ports.conf

これだけでApache2は443ポートで待ち受けするようになりました。

$ ss -ltn | grep 443
LISTEN     0      128         :::443                     :::*

※443ポートアクセスは80ポートとは別のVirtualHostとなるためDocumentRootの設定など揃える必要があります。

2. 証明書の設定
apache2のインストール時に最初から自己証明書が生成されており、
デフォルトのssl設定(default-ssl.conf)からも参照されているので、特に何もしなくても動きはします。
SSLCertificateFileとSSLCertificateKeyFileから参照してます

ssl用の公開鍵と秘密鍵は以下のディレクトリに既に存在しているはずです。

etc
+ssl
|+certs
||+ssl-cert-snakeoil.pem
|+private
||\ssl-cert-snakeoil.key
|\openssl.cnf

この段階ですでにhttpsアクセス出来ますが、認証されていないオレオレ証明書なので
CAサービスから認証済みの証明書を入手し、差し替える必要があります。

今回は無料のCAで有名そうな?letsencryptを使ってみます。
普通は結構高額な金額が掛かるらしいですが無料で使えるそうです。助かる。
https://letsencrypt.jp/

ユーザー登録など不要で、Certbotというソフトを入れるだけでいけます。
debianのbackportsパッケージにcertbotが入っていますので、aptからインストールします。
※backportsは標準ではsources.listに入っていないので追加が必要です。

# パッケージ管理システムからインストールします
$ sudo apt install certbot python-certbot-apache
# 証明書の入手とapacheへの適応を行います
$ certbot --apache

–apacheオプションを付けたことにより、sites-availableディレクトリに “000-default-le-ssl.conf” シンボリックファイルが自動生成されていることが分ります。
そして、”000-default-le-ssl.conf” から/etc/letsencrypt/live/helloidea.org/(略) への証明書の参照があることも分ります。
また、/etc/cron.d/certbot に1日2回の証明書更新クローンが置かれるため、証明書のメンテナンスも不要の様です。

これで、https化完了です。
最後に既存のhttpリンクをhttpsにリダイレクトさせます
.htaccessの変更とプラグインで対応できます

# httpからhttpsへ強制リダイレクト
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

プラグイン: Really Simple SSL

Web-based SSHクライアントについて調べてみた

手元にSSHクライアントが無い状況でもブラウザさえあればSSH可能になるやつです
セキュリティが気になるのでWEBサービス系の使用は避けたいところです
商用版のあるタイプの物を自鯖に入れたほうが良さげ

shellinabox
https://code.google.com/archive/p/shellinabox/
2016年が最終リリースです。開発はほぼ終わっていてメンテナンスのみの印象です。

tools.bartlweb
https://tools.bartlweb.net/webssh/
shellinaboxを個人で運用公開してるサービスのようです

KeyBox
https://www.sshkeybox.com/
開発が活発な印象です。商用版あり

serFISH
https://www.serfish.com/console/
WEBサービス型のSSHクライアント

Anyterm
https://anyterm.org/
2005年から2017年まで開発が続けられています
13872回という桁違いの恐るべきコミット数です。しかも個人で。恐らくまた開発再開されるでしょう

Ajaxterm
https://github.com/antonylesuisse/qweb/tree/master/ajaxterm
Anytermからインスパイアされて開発
12年前から開発停止中

■ GateOne
http://liftoffsoftware.com/Products/GateOne
開発は現在止まっており、2017年までコミットはありますが、最終リリースは2012年です。商用版あり