Xserverのサーバー移行でDjangoがおかしくなった3

Xserverのサーバー移行でDjangoがおかしくなった2のつづき

メールが送れない

Djangoの機能を利用したメール送信ができない。
これが一番大変だった。

どこかのページの中の処理でDjangoを使ってメールを送ろうとすると、500サーバーエラーになってしまう。

とりあえずサーバーの管理画面からエラーログをチェックしつつ、サポートに連絡。

エラーログを見るとimport sslで失敗している。
libssl.so.6が見つからないと注意されている。

[Fri Oct 12 18:37:54.395689 2018] [cgi:error] [pid 123548] [client
14.10.0.0:37946] AH01215:   File
"/home/xxx/local/lib/python2.7/site-packages/django/core/mail/backends/smtp.py",
line 3, in <module>, referer: https://xxx/
[Fri Oct 12 18:37:54.395697 2018] [cgi:error] [pid 123548] [client
14.0.0.0:37946] AH01215:     import ssl, referer:
https://xxx/
[Fri Oct 12 18:37:54.395732 2018] [cgi:error] [pid 123548] [client
14.0.0.0:37946] AH01215:   File
"/home/xxx/local/lib/python2.7/ssl.py", line 97, in <module>,
referer: https://xxx/
[Fri Oct 12 18:37:54.395769 2018] [cgi:error] [pid 123548] [client
14.0.0.0:37946] AH01215:     import _ssl             # if we can't
import it, let the error propagate, referer:
https://xxx/
[Fri Oct 12 18:37:54.395811 2018] [cgi:error] [pid 123548] [client
14.0.0.0:37946] AH01215: ImportError: libssl.so.6: cannot open
shared object file: No such file or directory, referer:
https://xxx/


そういえばpythonのリビルドの際に以下のようなエラーが出ていた。

Python build finished, but the necessary bits to build these modules were not found:
_curses            _curses_panel      _tkinter       _ssl
bsddb185           bz2                dl
imageop            readline           sunaudiodev
To find the necessary bits, look in setup.py in detect_modules() for the module's name.

make時に_sslが見つからないのがポイント。
サーバ移転に伴うOpenSSLのバージョンアップが問題らしい。

sslが使えないのでpipなんかもこんな感じのエラーをはいて失敗する。

Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)'),)': /simple/pip/
Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)'),)': /simple/pip/
Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)'),)': /simple/pip/
Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)'),)': /simple/pip/
Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)'),)': /simple/pip/

libssl.so.6のシンボリックリンクを作成してみる

検索してみるとXserverでlibssl.so.6が見つからないエラーを解決した人がいた。

qiita.com

この通りにするとSSHでpipが使えるようになった!

これで解決!と思ったらDjangoからは相変わらずlibssl.so.6が見つからないと注意されてしまう。
なにかちょっとした設定で直りそうな気もしたので、いろいろ調べてみたけど結局わからなかった。

サポートから返信

このころサポートから返信。
「メールソフトの設定を見直してください」とのこと。
状況説明が足りなかったようだ。

OpenSSLをユーザーディレクトリにインストールしてみる

仕方がないので別の解決法を探ることにした。

openssl-develをインストールするのが通常の方法

openssl-develをyumあたりでインストールするのが、通常の解決方法らしい。

でもレンタルサーバーなので、当然yumとか使えない。
ソースからコンパイルできないかと探してみたが、yum用のパッケージしか見つからなかった。

OpenSSLをユーザーディレクトリにインストール

libssl.so.6はOpenSSLのファイルなので、OpenSSL自体をユーザーディレクトリにインストールしてみることにした。

まずはサーバーにインストールされているOpenSSLのバージョンを調べる。
SSHで接続して、

$ openssl version

念のためそれに揃えたバージョンのOpenSSLをダウンロードしてインストールする。

$ cd ~/local/src
$ wget http://www.openssl.org/source/openssl-1.0.2k.tar.gz
$ tar xzvf openssl-1.0.2k.tar.gz
$ cd openssl-1.0.2k
$ ./config --prefix=$HOME/local/ssl --openssldir=$HOME/local/ssl
$ make
$ make install

そしてPythonをリビルドする。
ソースは以前のものを再利用した。

$ cd ~/local/src/Python-2.7.10
$ make distclean

この段階でPython-2.7.10内のファイルSetup.distを編集する。 218~221行目

#SSL=/usr/local/ssl
#_ssl _ssl.c \
#  -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
#  -L$(SSL)/lib -lssl -lcrypto

をアンコメントして

SSL=/home/xxx/local/ssl
_ssl _ssl.c \
    -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
    -L$(SSL)/lib -lssl -lcrypto

SSL=の後ろを先ほどOpenSSLをインストールしたフォルダに書き換える。xxxはユーザーによって違う。
そのあと

$ ./configure --prefix=$HOME/local
$ make
$ make install

ただし自分の環境では何か設定を変えてしまったのか、Setup.distの編集が反映されなかった。
それでmakeに失敗してこんなエラーが

gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes  -I. -IInclude -I./Include   -DPy_BUILD_CORE  -DUSE_SSL -I/home/xxx/local/include -I/home/xxx/local/include/openssl -c ./Modules/_ssl.c -o Modules/_ssl.o
./Modules/_ssl.c:56:25: 致命的エラー: openssl/rsa.h: そのようなファイルやディレ クトリはありません
 #include "openssl/rsa.h"
                         ^
コンパイルを停止しました。
make: *** [Modules/_ssl.o] エラー 1

その場合は仕方がないので同フォルダのMakefileファイル内の

SSL=/usr/local/ssl

をOpenSSLインストール場所に書き換えてmakeする。

どうにか完了

これでどうにかすべてのエラー処理が完了した。

ただ本当にこれでいいのだろうか、とても不安になった。
XServer側で何か更新されたときとか、やばいんじゃなかろうか。

サポートに連絡してみると、返信が来た。

お客様にて設置されたプログラムの精査はかないませんが、 記載いただいた方法で解決したのであれば、問題ないかと存じます。

このまま様子を見ていただければと存じます。

様子を見ることにする。

もしダメだったらlinuxbrewとpipenvで仮想環境にしよう。