【ソフトウェア】

DeleGate+robots.txtで大ハマリ

DeleGate+robots.txt で大ハマリしたので、メモ。

会社の公開サーバは、複数のサーバをひとつの固定IPアドレスで公開しているため、内向きの、いわゆるリーバース・プロキシを通すことで、インターネットから入ってくる接続を各サーバに振り分けている。
使用しているプロキシ・サーバは DeleGate

DeleGateは、/robots.txt にアクセスがあった場合、自動的にプロキシ経由のURLを検索エンジンにヒットさせないように、robots.txt の内容を自動的に書き換えて返す。

たとえば、以下のような内容で /robots.txt が置かれていた場合…・

User-agent: *
Disallow: /

DeleGateは、以下の様に自動的に出力を追加する。

User-agent: *
Disallow: /
Disallow: /-_-
Disallow: /=@=

この動作は、/robots.txt が存在しているか否かに関わらず自動的に出力され、/robots.txt が存在しなくても、常に以下の様に出力される。

User-agent: *
Disallow: /-_-
Disallow: /=@=

昨今は、WEBサイトがどんどんSSL化されつつあるが、httpsでアクセスした場合、/robots.txt にどのように記載してあったとしても、すべて捨てられてしまっている事に気付いた。
常に /robots.txt が存在しないものとして、DeleGateの自動出力だけが出力されている。
すなわち、/robots.txt を置いても置かなくても、/robots.txt にどのように記述してあっても、常にこのように出力される。

User-agent: *
Disallow: /-_-
Disallow: /=@=

マヂすか。(涙)
まぁ、DeleGateと言えども、SSLで通信されている内容を傍受/復元して「内容を改ざんする」事はできないだろうから、SSLで通信をしている場合は、出力のすべてを置き換えるしか方法がないのだろうな。
もし、傍受/復元が可能だとすると、SSLでて暗号化している意味がない。
確かに、そりゃそうだと思う。

DeleGateが開発された当時は、まだSSLは一般的ではなく、特殊な環境であったと思うので、この動作でも大きな問題ではなかったのだろうけれど、ほとんどのWEBサイトがSSL化されている現在の状況では、この動作はちょっと厳しい。

困ったぞ。
サーバ上のコンテンツはインターネットから見える様にはしているが、検索エンジンにはヒットさせたくない。
そして逆に、このブログを含め、検索エンジンにヒットさせたいコンテンツもある。

DeleGateのマニュアルと読むと、MOUNT のオプションに「robots={no|ok}」という設定は存在しているが、どう設定しても出力は変化しない。
過去に仕事で X-Window のソースと格闘し、死ぬほど苦労した ずんべ としては、正直、こういったソフトウェアのソースコードは覗きたくない。はっきり言うと、ソースコードが「すごく汚い」のだ。たいていの場合、読めたもんじゃない。
さりとて、robots.txt が制御できないのも困る。

仕方がない、ソースコードを開いてみることにする。
がい、しかし、やっぱり、読むには辛いソースコードだ。
同じ構造体を、異なるソースファイルだと、異なる型で定義されていたり...、
関数の情報はヘッダファイルなどにまとめられておらず、各ソースファイルで必要に応じてという形で記述されていたり...。
マクロだらけで、結局、どういうソースに展開されるのか、ぜんぜんわからない...。
各ソースは、それが「クラス」であるかの如く振る舞うような作りになっているように思えるけれど、一貫性がない。

それでも頑張って、追ってみる、追ってみる、追ってみる。
「robots={no|ok}」を参照しているコードはあった。
しかし、その設定が、robots.txt の出力のコードの部分で使われているようには見えない。
やはりこの設定、ぜんぜん機能してないんじゃないか?

さて、どうするか。
設定では対処できそうにないので、ぶっちゃけ、やりたくないけど、プログラムを修正し、この問題を何とかしてみることにする。

修正の方向性はふたつ考えられる。

【方向性1】
robots.txt に出力する機能をオフにできるようにする。
すなわち、この制御をオフにした場合は、他のファイルの出力と同様、/robots.txt も、そのまま出力する。
運用としては、/robots.txt は通常通りコンテンツとして置き、これまで DeleGate が自動出力していた記述を手動で書き込む事にする。
もちろん、この場合、/robots.txt が存在しなければ、他のファイルと同様、404 Not Found になる。
【方向性2】
robots.txt への出力内容を指定/設定できるようにする。
MOUNTのオプションに、公開する/しないの設定を追加し、公開するか否かで「Disallow: /」の出力を決める。

【方向性1】の方が汎用性があるような気がするのだけれど、ざっとソースコードを追う限り、ちょっと面倒な修正になりそうだし、すべてのコンテンツの /robots.txt を書き換え、かつ、過去のコンテンツを復活させる場合も、新しいコンテンツを作る場合も、もれなく /robots.txt を置いていくのはちょっと面倒だ。
と、いう事で、汎用性は狭められてしまうけれど、【方向性2】で行くことにする。

以下の様に修正を行う事にする。

MOUNTのオプションに「sitepub={no|ok}」を追加する。
記述はこんな感じ。

MOUNT="/* https://X.X.X.X/* nvserv=-thru,host=-blog2.zunbe.com,sitepub=ok"

「ok」の場合は「Disallow: /」を出力しない。
「no」の場合は「Disallow: /」を出力する。
設定が無い場合、上記以外の場合は「Disallow: /」を出力する。つまり、デフォルトは非公開。

一応、パッチも公開しておく。

delegate 9.9.13用パッチ

patch httpd.c < httpd.c.patch
patch mount.c < mount.c.patch

ただし、「自分が使えればいいや」レベルでの修正なので、いろいろきちんと作っていない。
使用は自己責任で。

DBD::mysqlで大ハマリ

DBD::mysqlで大ハマリしたので、メモ。

問題が発生した環境。

① CentOS 7.6
② Apache 2.4.37(自力でビルド)
③ MySQL 5.6.44(自力でビルド)
④ perl 5.16.3
⑤ DBD::mysql 4.050(自力でビルド)

各ソフトウェアは、ひとつのOS上で複数のバージョンを稼働させる必要から、yum や rpm を使わず、基本的に自力でコンパイルして動作環境を構築している。

この環境で、Apache経由でアクセスし、perl から MySQLに 接続したところ、500エラーが発生した。
エラーログを見てみると、以下の様に記録されていた。

/usr/bin/perl: relocation error: /***/local/lib/perl5/auto/DBD/mysql/mysql.so: symbol mysql_options4, version libmysqlclient_18 not defined in file libmysqlclient.so.18 with link time reference

このような組み合わせの環境構築は、これまでに何度も行っているが、はじめて見るエラーだ。
自力でビルドした DBD::mysql の共有ライブラリ(mysql.so)から、自力でビルドした MySQL の共有ライブラリ(libmysqlclient.so.18)にアクセスして、なぜかエラーになっている。どういうことだ?

とりあえず、実行環境を模擬した上で、読み込まれるライブラリを確認してみる。
問題なく読み込まれている。

$ cd /***/local/lib/perl5/auto/DBD/mysql
$ LD_LIBRARY_PATH=/***/local/mysql-5.6.44/lib ldd mysql.so
linux-gate.so.1 => (0xb77a4000)
libmysqlclient.so.18 => /***/local/mysql-5.6.44/lib/libmysqlclient.so.18 (0xb73d6000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb73b4000)
(以下略)

LD_LIBRARY_PATH を指定しなければ、当然「共有ライブラリが見つからない」エラーになるはずだよな、と、念のため LD_LIBRARY_PATH を外して確認してみる。

$ cd /***/local/lib/perl5/auto/DBD/mysql
$ ldd mysql.so
linux-gate.so.1 => (0xb779a000)
libmysqlclient.so.18 => /usr/lib/mysql/libmysqlclient.so.18 (0xb748a000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb746f000)
(以下略)

が... あれ? エラーにならない。
「/usr/lib/mysql/libmysqlclient.so.18」を読み込んでる。何これ?

確認してみると、このファイルは確かに存在している。
このディレクトリに、MySQLのライブラリをインストールした覚えはないのだが...。
これは、CentOSが標準でインストールするものだろうか。

$ cd /usr/lib/mysql
$ ls -l libmysqlclient.so.*
lrwxrwxrwx. 1 root root 24 7月 8 03:21 libmysqlclient.so.18 -> libmysqlclient.so.18.0.0
-rwxr-xr-x. 1 root root 3052044 8月 17 2018 libmysqlclient.so.18.0.0

自力でビルドしたMySQLのライブラリを確認してみる。

$ cd /***/local/mysql-5.6.44/lib
$ ls -l libmysqlclient.so.*
lrwxrwxrwx. 1 root root 24 9月 17 2019 libmysqlclient.so.18 -> libmysqlclient.so.18.1.0
-rwxr-xr-x. 1 root root 7753856 9月 17 2019 libmysqlclient.so.18.1.0

DBD::mysql は「libmysqlclient.so.18」をロードしようとするのだが、コンパイル時に指定した、自力でビルドした MySQL の「libmysqlclient.so.18」に接続できず、標準の「libmysqlclient.so.18」に接続しようとして、エラーになっているようだ。

しかし、「/lib」とか「/usr/lib」とか「/usr/local/lib」とかなら、自動で読み込まれるのはわかるが、「/usr/lib/mysql」が自動で読み込まれるというのは、どういうことなのだろう?
もしかして、/etc/ld.so.conf か?

$ cd /etc/ld.so.conf.d
$ ls
mariadb-i386.conf
$ cat mariadb-i386.conf
/usr/lib/mysql

ビンゴ!
このサーバには mariadb も入れてはいるが、インストールの時に、このファイルを入れた覚えはない。CentOS が勝手に入れているのだろうか。余計な事をしてくれる。

少し古い CentOS の場合、どうなっているのだろう?

$ cd /etc/ld.so.conf.d
$ ls
mysql-i386.conf
$ cat mysql-i386.conf
/usr/lib/mysql

mariadb ではなく、mysql として、同じ設定が入っていた。
では、この「/usr/lib/mysql」には何が入っているのだろうか。

$ cd /usr/lib/mysql
$ ls -l libmysqlclient.so.*
lrwxrwxrwx. 1 root root 24 1月 22 03:45 2014 libmysqlclient.so.16 -> libmysqlclient.so.16.0.0
-rwxr-xr-x. 1 root root 1525312 11月 23 08:19 2013 libmysqlclient.so.16.0.0

「libmysqlclient.so.16」が入っている。
なるほどね、これまでは、バージョンが違っているから、たまたま競合しなかったのかと言う事なのか。

これは困ったぞ、どうするか...。
Apache は、DBD::mysql が共有ライブラリを読み込もうとするとき、/etc/ld.so.conf の設定に従ってしまうので、狙っていない共有ライブラリを読んでしまう。
それならば、Apacheを起動するときに、自力でビルドした MySQL のライブラリを読みに行かせるようにするしかないか。
と、言う事で、Apache の起動時の環境設定を変更する事にする。

# cd /***/local/httpd-2.4.37/bin
# vi envvars

以下の1行を追加。

LD_LIBRARY_PATH="/***/local/mysql-5.6.44/lib:$LD_LIBRARY_PATH"

Apacheを再起動。

# systemctl restart httpd-2.4.37

無事、MySQL に接続できた。
ふぅ...。

システムクロックで大ハマリ

このエピソードの続き。

CPUを換装してみた
CPUをオーバークロックしてみた

このPCに CentOS7 をインストールして動かしているのだけれど、どうにもシステムクロックが思うように動いてくれない。

システムクロックで大ハマリ

システムクロックの進みが異常に遅く、1分で30秒も遅れてしまう。
あっという間に時刻が大きくズレていく。

この動画は、時刻がズレていく様子。上が正常な時刻、下がこのPCの時刻。
動画の開始から終了までで、上は30秒進んでいるが、下は15秒しか進んでいない。

これくらいの大きなズレがあると、chrony でも、ntp でも、まったく同期が行われない。
また、nfsマウントしてコピーなどを行うと、コピー途中でOSがクラッシュしてしまう。

仕方なしに、かなり強引だけれども、cronで次のような設定をして1分間隔で強制的に時刻調整を行うようにしてみた。

# EDITOR=cat crontab -e | grep ntpdate
* * * * * /sbin/ntpdate (ntpサーバ) > /dev/null 2>&1
#

この状態であれば、ある程度は正しい時刻を保ってくれるが、時刻を再設定するまでの1分の間に30秒も遅れてしまうので、シビアに時刻管理をしていると思われるnfsマウントは正常に動作せず、やはりコピー途中でOSがクラッシュしてしまう。
また、この方法では、さまざま負荷が大きい。

もう少し負荷を軽くするならば、ハードウェアクロックの値を拾ってシステムクロックを調整するという事も考えられる。
しかし、この方法では、1分の間に30秒遅れてしまう事に変わりはないし、ハードウェアクロックを基準に時刻を調整するなんて、本末転倒なおかしな話である。
この方法では、根本的に何も解決されない。

何か時刻の進み具合をコントロールする方法はないものだろうか。
WEBを漁ってみると、VMWare や VirtualBox などの仮想環境上に構築したゲストOSで時刻が遅れる場合があり、その対処として、OS起動時のカーネルのパラメータに「clock=pit」を設定すると回避できるという記述がけっこう見られる。
試しに、OS起動時にこのパラメータを手動でセットして起動してみる。
起動時に「e」を押して編集モードに入ってパラメータ「clock=pit」を追加し、「Ctrl+x」で起動させる。

clock=pit clock=pit

しかし、この方法では問題は解消されなかった。
相変わらずシステムクロックは遅れていく。

更に探す。
時刻を刻むための基準となる何かがあるはずだ。
マザーボードの水晶振動子か、CPUの動作周波数か、CPUのFSB絡みか、メモリとの同期周波数などか...
このPCは、CPUを換装し、更にオーバークロックもしているので、このあたりが原因としてあり得そうだが...
このあたりに関連するキーワードを含めながら、更に探してみる。
探す...探す...探す...
あった!

カーネルにおけるタイマー事情 ~第4回 タイマーハードウェアの抽象化~

Linux上で時刻を刻むための情報に「clocksource」という情報があるらしい。
むむむ、「clocksource」とは、そのままのズバリの名称ではないか。(^^;

確認してみる。

# cd /sys/devices/system/clocksource/clocksource0
# cat available_clocksource
tsc acpi_pm
#

このPCで利用可能な設定は「tsc」「acpi_pm」の2種類という事らしい。

現在の設定はどうか。

# cat current_clocksource
tsc
#

「tsc」が設定されている。

試しに、設定を「acpi_pm」に変更してみる。

# echo "acpi_pm" > current_clocksource
# cat current_clocksource
acpi_pm
#

この状態で時刻をウォッチしてみると...
おぉ! 時刻が遅れなくなった!
上が正常な時刻、下がこのPCの時刻。

しかし、この設定は、サーバを再起動すると元の「tsc」戻ってしまうようなので、「acpi_pm」を常態設定にする必要がある。
お手軽に設定するなら、/etc/rc.local などで、以下のような設定をしてもいいとは思うのだけれど…

# cat /etc/rc.local | grep acpi_pm
echo "acpi_pm" > /sys/devices/system/clocksource/clocksource0/current_clocksource
#

ここは、起動時のカーネルオプションの設定を変更する事にする。

# cd /etc/default
# vi grub
GRUB_CMDLINE_LINUX="(既存の設定) clocksource=acpi_pm"
# cd /boot/grub2
# grub2-mkconfig -o grub.cfg

PCを再起動し、狙い通りに設定されているか確認する。
起動オプションに「clocksource=acpi_pm」が設定されている。
OKだ。

起動設定

念のため、CentOS起動後の設定を確認する。
「acpi_pm」が設定されている。
OKだ。

$ cd /sys/devices/system/clocksource/clocksource0
$ cat current_clocksource
acpi_pm
$

chrony の同期状況を確認する。
ntpサーバの頭に「*」が付いており、同期されている。
OKだ。

$ chronyc sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* (ntpサーバ)                   3   8   377   150    -41us[  -46us] +/-   70ms
$

更に、nfsマウントを設定し、大量/大容量のファイルをnfs経由でコピーしてみる。
システムクロックがおかしい状態では、数GBをコピーするとOSがクラッシュしてしまったが、システムクロック調整後は、何十GBコピーしても問題なくコピーが続く。
OKだ。

やっと予定通りの運用ができるようになった。
まだまだ知らない事がたくさんあるな。
まだまだ勉強が必要だ。

 

一連記事:

mSATAノートPCのディスク・ベンチマーク

このエピソードの続き。

mSATAアダプタ・アダプタ

SSD化した事で、どの程度ディスクアクセスが変わったのかを計測してみた。

使用したツールは CrystalDiskMark。
計測した環境は以下の通り。

・OSは Windows 7 SP1 (x86)。
・Windows Update を最新まで適用。
・Security Essentialsをインストール

CrystalDiskMark は、デフォルトの設定のまま、ハードディスクの場合とSSDの場合で3回ずつ実行して平均を取った。
結果は以下の通り。

シーケンシャル・アクセスでは、大差ない。
ランダム・アクセスでは、約20倍の速度だった。

ATA-100 のインターフェースが足枷になってたいして速度が出ないという結果を恐れていたのだけれど、まぁ、速くなったと考えていいのかな。

 

一連記事:

delegate + TLS 1.2

このエピソードの続き。

CentOS 5.9 + TLS 1.2

今回は、delegate でリバース・プロキシを組んでいる環境で TLS 1.2 での接続を行う。

現在の環境では、FireFoxで警告が出てしまう。

SSL警告

リバース・プロキシの環境では、ブラウザの接続先はプロキシ・サーバとなるため、プロキシ・サーバが TLS に対応していなければ、この警告が出る。
従って、プロキシ・サーバがロードしている openssl ライブラリを更新して対処する事にする。

現在のプロキシ・サーバがロードしている openssl は 0.9.8x。古い。(^^;

Loaded: OpenSSL 0.9.8x 10 May 2012
Loaded: Zlib 1.2.3

これを、新しい openssl を読み込ませるように更新する。

それでは、トライしてみる。

(1).openssl を手動でインストールする。

$ cd openssl-1.0.2s
$ ./config shared enable-ssl2 enable-ssl3 --prefix=/*****/openssl-1.0.2s
$ make
$ su -
# make install

(2).opensslライブラリを差し替える。

この環境では、単純に delegate のディレクトリに openssl ライブラリを置く事で、そのライブラリを読むようにしている。

# cd /*****/delegate/sbin
# ls -l
合計 4084
-rwxr-xr-x. 1 root root 4180673 2月 19 23:43 2014 delegated
lrwxrwxrwx. 1 root root 51 7月 18 09:58 2019 libcrypto.so -> /*****/openssl-0.9.8x/lib/libcrypto.so.0.9.8
lrwxrwxrwx. 1 root root 48 7月 18 09:59 2019 libssl.so -> /*****/openssl-0.9.8x/lib/libssl.so.0.9.8

このシンボリックリンクを置き換える。
既存の openssl ライブラリ(0.9.8x)をバックアップする。

# mv libcrypto.so 20190718.libcrypto.so
# mv libssl.so 20190718.libssl.so

新しい openssl ライブラリ(1.0.2s)のシンボリックリンクを作成する。

# ln -s /*****/openssl-1.0.2s/lib/libcrypto.so.1.0.0 libcrypto.so
# ln -s /*****/openssl-1.0.2s/lib/libssl.so.1.0.0 libssl.so

確認する。

# ls -l
合計 4084
lrwxrwxrwx. 1 root root 51 2月 20 15:14 2014 20190718.libcrypto.so -> /*****/openssl-0.9.8x/lib/libcrypto.so.0.9.8
lrwxrwxrwx. 1 root root 48 2月 20 15:14 2014 20190718.libssl.so -> /*****/openssl-0.9.8x/lib/libssl.so.0.9.8
-rwxr-xr-x. 1 root root 4180673 2月 19 23:43 2014 delegated
lrwxrwxrwx. 1 root root 51 7月 18 09:52 2019 libcrypto.so -> /*****/openssl-1.0.2s/lib/libcrypto.so.1.0.0
lrwxrwxrwx. 1 root root 48 7月 18 09:52 2019 libssl.so -> /*****/openssl-1.0.2s/lib/libssl.so.1.0.0

delegate を再起動し、ロードされた openssl ライブラリを確認する。

Loaded: OpenSSL 1.0.2s 28 May 2019
Loaded: Zlib 1.2.3

上記(1)でインストールした openssl 1.0.2s がロードされた。

(3).正常な鍵マークが復活!

正常な鍵マークが復活!

無事、TLS 1.2 で通信された。

TLS 1.2 で接続された

これでよし!

楽天アフィリエイト WordPressプラグイン

WordPress用の楽天アフィリエイト プラグインを作った。

これまで、Amazonのアソシエイトを中心に商品リンクを貼っていたのだが、Amazonアソシエイトは規約が変更され、ある程度の売上実績がないとAPIが利用できなくなってしまった。

[重要] Product Advertising API 利用ポリシーの変更について

そこで、楽天アフィリエイトにもAPIがあるので、主軸を楽天アフィリエイトに移そうと思う。

API一覧 - 楽天ウェブサービス

Amazonでは、商品のコードは「ASIN」と呼ばれる商品コードに統一されており、どのような種類の商品でも、同じAPIで「ASIN」を商品コードとする事で商品リンクが作成できた。
しかし楽天では、商品の種類によって、呼び出すAPIや商品コードの指定方法が異なるので、ここが少々めんどくさい。
とりあえず今回は、楽天市場用、楽天ブックス(書籍)用、楽天ブックス(DVD/Blu-ray)用の3種類のプラグインを作成する事にする。

また、以前に、Aliexpress用プラグインを作成しているが、この実装に合わせて、以下の様な書式で商品リンクの挿入ができるようにし、キャッシュ機能も実装する。

(1).楽天市場

楽天市場の商品では、商品コードを拾うのが少々めんどくさい。
ページのソースを開き、ソース中の以下の様な記述を探す。

itemid:['honest-online:10000015'],

商品コードは「:」で区切られていて、前半が店舗コード、後半が商品コードと思われるが、「:」も含めて全体が商品コードであるので、これを商品コードとして記述する。
小さいサイズの商品リンクも表示できる。

[rakuten size="large"]honest-online:10000015[/rakuten]
[rakuten size="small"]honest-online:10000015[/rakuten]

実際の表示は以下のようになる。

(2).楽天ブックス(書籍)

楽天ブックス(書籍)の商品では、ページ中に表示されている「ISBNコード」を商品コードとして記述する。

[rbooks size="large"]9784062764131[/rbooks]
[rbooks size="small"]9784062764131[/rbooks]

実際の表示は以下のようになる。

(3).楽天ブックス(DVD/Blu-ray)

楽天ブックス(DVD/Blu-ray)では、ページ中に表示されている「JANコード」を商品コードとして記述する。

[rdvd size="large"]4988135805799[/rdvd]
[rdvd size="small"]4988135805799[/rdvd]

実際の表示は以下のようになる。

Aliexpress用プラグインとフォーマットを合わせてあるので、これらを混在させて並べてもOK。

大きいサイズ。

小さいサイズ。

これでヨシ。
とりあえず、バージョン1.0。

CentOS 5.9 + TLS 1.2

あるWEBサイトで、最新の FireFox でSSLの警告が出るようになった。

SSL警告

SSLは Let's Encryptで、何か更新処理を誤ったのだろうかと思ったのだけれど、他のブラウザ(Internet Explorer 11、Edge、Google Crome)では警告は出ておらず、FireFoxのみで警告が出ている。スマホでも同様にFireFoxでは警告が表示される。
この警告が出るのは、企業のサイトでは、ちょっとマズい感じ。

この警告がどうして出るのかいろいろ調べてみると、証明書そのものも問題ではなく、プロトコルの問題のようだ。
どうやら、各ブラウザが2020年に TLS 1.0、TLS 1.1 での接続ができなくなるように動作が変更されるようなので、FireFoxは、その事前警告を出しているようだ。

TLS 1.0 で接続されている

このWEBサイトはレンタルサーバで、OSは CentOS 5.9。
root権限が貰えているサーバであるけれど、テスト環境があるわけではないので、様々アップデートをかけるのは少々リスクが大きい。なんとかWEBサーバのみに影響範囲を抑える形で対処したい。

いろいろ悩んで、以下の方法で対処する事にした。

① 最新のopensslをユーザ領域に手動でインストールする。
② Apacheの起動スクリプトを修正し、上記(1)でインストールしたopensslをロードさせるようにする。

それでは、トライしてみる。

(1).opensslを手動でインストールする。

$ cd openssl-1.0.2s
$ ./config shared enable-ssl2 enable-ssl3 --prefix=/*****/local
$ make
$ make install

稼働しているApacheは、古いバージョンのライブラリをロードする様になっている。
Apacheを再コンパイルするなどすると影響が大きいので、インストールしたライブラリのバージョンを偽装する事にする。

# cd /*****/local/lib
# ln -s libssl.so.1.0.0 libssl.so.6
# ln -s libcrypto.so.1.0.0 libcrypto.so.6

(2).Apacheが上記(1)でインストールしたライブラリを正しくロードするか、依存関係を確認してみる。

まず、通常の起動。
/usr/lib 配下のライブラリがロードされる。

# ldd /usr/sbin/httpd | grep libssl
libssl.so.6 => /lib/libssl.so.6 (0xb7b04000)

次に、上記(1)でインストールしたライブラリをロードさせての起動。
上記(1)でインストールしたライブラリがロードされた。

# LD_LIBRARY_PATH=/*****/local/lib ldd /usr/sbin/httpd | grep libssl
libssl.so.6 => /*****/local/lib/libssl.so.6 (0xb7a8d000)

よし、いけそうだ。

(3).Apacheの起動スクリプトを修正する。

# cd /etc/init.d
# vi httpd

Apacheの起動部分に、LD_LIBRARY_PATHでopensslのパスを挿入する。
これにより、上記(1)でインストールしたライブラリは、Apacheに限定して使用される。

LANG=$HTTPD_LANG LD_LIBRARY_PATH=/*****/local/lib daemon --pidfile=${pidfile} $httpd $OPTIONS

(4).Apacheを再起動する。

# /etc/init.d/httpd restart

が、残念ながら、phpのモジュールのロードでエラーが発生してしまった。

# /etc/init.d/httpd restart
httpd を停止中: [ OK ]
httpd を停止中: [失敗]
httpd を起動中: httpd: Syntax error on line 210 of /etc/httpd/conf/httpd.conf: Syntax error on line 6 of /etc/httpd/conf.d/php.conf: Cannot load /etc/httpd/modules/libphp5.so into server: /etc/httpd/modules/libphp5.so: undefined symbol: EVP_md2
[失敗]
#

がんばってphpの再インストールもトライしようかと思ったけれど、このWEBサイトではphpは使用していないので、phpのサービスを停止する事で対処する事にした。

(5).サーバのコントロール・パネルでphpのサービスを停止する。

phpを停止

(6).再びApacheを再起動する。

# /etc/init.d/httpd restart
httpd を停止中: [ OK ]
httpd を起動中: [ OK ]
#

成功した!

(7).正常な鍵マークが復活!

正常な鍵マークが復活!

無事、TLS 1.2 で通信された。

TLS 1.2 で接続された

これでよし!

Apache 仮想ドメイン設定の読み込み

会社の開発サーバにおいて、Apache に設定する仮想ドメイン <VirtualHost></VirtualHost> は頻繁に設定を追加/削除する。
新しいプロジェクトが立ち上がれば仮想ドメインを追加、プロジェクトが終了すれば削除、プロジェクトが再開すれば設定を復元。

これまでは、以下の様に設定して運用していた。

Apache の「httpd.conf」では、以下の様に仮想ドメインのまとめ設定ファイル「vhosts.conf」をインクルードしておく。

Include ~/conf/vhosts.conf

読み込む「vhosts.conf」では、以下のように必要な仮想ドメインの設定ファイルをインクルードする。
不要な仮想ドメインは「#」でコメントアウトされている。

Include ~/conf/blog.zunbe.com.conf
Include ~/conf/blog2.zunbe.com.conf
Include ~/conf/www.patentic.co.jp.conf
#Include ~/conf/www.archive.com.conf
#Include ~/conf/www.archive.net.conf

その上で、ディレクトリ内に置かれている仮想ドメインの設定ファイルを置いておくのだが、ただ置いただけでは、どの仮想ドメインが現状で有効であるのかわかりにくいため、archives ディレクトリを作成して、無効なドメインは移動して隔離していた。

~/conf/blog.zunbe.com.conf
~/conf/blog2.zunbe.com.conf
~/conf/www.patentic.co.jp.conf
~/conf/archives/www.archive.com.conf
~/conf/archives/www.archive.net.conf

仮想ドメインを追加/削除/復元するには、vhosts.conf の記述を変更した上で、仮想ドメインの設定ファイルを archives ディレクトリから移動し、Apacheを再起動していた。

十分簡単だとは思うのだけれど、もう少し簡単にならないだろう。
ん~と考えて、はっと気が付いた。
Include ディレクティブって、ワイルドカード(*)が使えるじゃないか。

と、言う事で、以下の様な設定での運用に変更。

Apache の「httpd.conf」では、以下の様に仮想ドメインのまとめ設定ファイルをインクルードしておく。
「+」が付いているのがミソ。

Include ~/conf/+*.conf

その上で、以下の様に仮想ドメインの設定ファイルを配置する。
先頭が「+」である設定ファイルのみが読み込まれる。

~/conf/+blog.zunbe.com.conf
~/conf/+blog2.zunbe.com.conf
~/conf/+www.patentic.co.jp.conf
~/conf/-www.archive.com.conf
~/conf/-www.archive.net.conf

仮想ドメインを追加する場合は、先頭が「+」の設定ファイルを作成して置く。
仮想ドメインを削除する場合は、先頭の「+」を「-」にリネームする。
仮想ドメインを復元する場合は、先頭の「-」を「+」にリネームする。
その上で、Apache を再起動する。

仮想ドメインが有効か無効かは、ファイル名を見るだけでわかる。

なんてことない技だけど、これでずいぶん運用が楽になった。(^^)

SELinuxで小ハマリ

SELinux で小ハマリしたのでメモ。

CentOS 上で稼働している Apache にSSL証明書を取り込もうとしている。

オレオレSSL証明書を作る。
コマンド的には、ざっと、こんな感じ。

# openssl req -new -key server.key -sha256 -out server.csr
# openssl x509 -req -days 365 -sha256 -in server.csr -signkey server.key -out server.crt
# openssl rsa -in server.key -out server-nopw.key

とりあえず、/root/ssl に置いて試してみる。

# mkdir /root/ssl
# cp server.csr server-nopw.key /root/ssl

Apache の設定ファイル(/etc/httpd/conf.d/ssl.conf)に作成したSSL証明書を設定する。

SSLCertificateFile /root/ssl/server.crt
SSLCertificateKeyFile /root/ssl/server-nopw.key

Apache を再起動すると…あれ? 起動しない!

# service httpd restart
Redirecting to /bin/systemctl restart  httpd.service
Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.

メッセージの通り、コマンドを打ち直してステータスを確認してみる。

# systemctl status httpd.service -l
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since 火 2017-08-01 20:26:01 JST; 1min 34s ago
Docs: man:httpd(8)
man:apachectl(8)
Process: 24056 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
Process: 22160 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)
Process: 24055 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
Main PID: 24055 (code=exited, status=1/FAILURE)8月 01 20:26:01 laravel systemd[1]: Starting The Apache HTTP Server...
8月 01 20:26:01 laravel httpd[24055]: AH00526: Syntax error on line 105 of /etc/httpd/conf.d/ssl.conf:
8月 01 20:26:01 laravel httpd[24055]: SSLCertificateFile: file '/root/ssl/server.crt' does not exist or is empty
8月 01 20:26:01 laravel systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
8月 01 20:26:01 laravel kill[24056]: kill: cannot find process ""
8月 01 20:26:01 laravel systemd[1]: httpd.service: control process exited, code=exited status=1
8月 01 20:26:01 laravel systemd[1]: Failed to start The Apache HTTP Server.
8月 01 20:26:01 laravel systemd[1]: Unit httpd.service entered failed state.
8月 01 20:26:01 laravel systemd[1]: httpd.service failed.

「SSLCertificateFile: file '/root/ssl/server.crt' does not exist or is empty」と表示されている。
「ファイルが存在しない、または、空」って、どういう事?

ファイルを確認する。
存在するる。

# ls -l /root/ssl/server.crt
-r--------. 1 root root 1277  8月  1 20:25 /root/ssl/server.crt

ファイルの内容を確認する。
内容は問題ないように見える。

# cat /root/ssl/server.crt
-----BEGIN CERTIFICATE-----
MIIDgjCCAmoCCQD6g88R6RKqXjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMC
SlAxDjAMBgNVBAgMBUFpY2hpMQ8wDQYDVQQHDAZOYWdveWExCzAJBgNVBAoMAlBz

(略)

S6+Q5EMXtIyCSUHFEOp525JFVAEJ/hTYv6ivBu8Cv7hi4057Cfg=
-----END CERTIFICATE-----

SSL証明書を作成する時に何か間違えたか?
SSL証明書を作り直してみる。
同じエラーが発生する。

ファイルのパーミッションか?
rootのみが見えるように変更してみる。
同じエラーが発生する。

# chmod 700 /root/ssl
# chmod 600 /root/ssl/*

ん~? なんだこれ?

あれやこれやと悩んで、はっと気が付いた。もしかして、SELinux か!
SELinux の状態を確認してみる。オンだ。

# getenforce
Enforcing

SELinux を無効化し、Apacheを起動してみる。
起動した!

# setenforce 0
# getenforce
Permissive
# service httpd start
Redirecting to /bin/systemctl start httpd.service

原因はSELinuxだ!
Apache は、SELinux に阻まれて、SSL証明書が読めないのだ。

Apache の設定ファイルのディレクトリを確認してみる。
なるほど、「httpd_config_t」が必要なのか。

# ls -dZ /etc/httpd/conf
drwxr-xr-x. root root system_u:object_r:httpd_config_t:s0 /etc/httpd/conf

SSL証明書が置かれているディレクトリの設定を確認する。

# ls -dZ /root/ssl
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 /root/ssl

SELinux の設定を変更する。

# chcon -R -t httpd_config_t .
# ls -dZ /root/ssl
drwxr-xr-x. root root unconfined_u:object_r:httpd_config_t:s0 /root/ssl

SELinux を有効化し、Apacheを起動してみる。
起動した!

# setenforce 1
# getenforce
Enforcing
# service httpd start
Redirecting to /bin/systemctl start  httpd.service

わかってしまえば何てことないのだが、4時間も悩んでしまった。(^^;

ESXi上のゲストOSのパーティション操作

ESXi上で稼働させている仮想マシンのディスクが足りなくなってしまった。

ディスクが足りなくなってしまった

最初に仮想マシンを作成した時に、ディスク容量をケチったら、Cドライブがいっぱいになってしまい、残り389MB。Windows Updateにも失敗するようになってしまった。
昔なら、ディスクのパーティション分割をやり直して、OSを再インストールという状況なのだけれど、最近はパーティションの構成を編集できる便利なツールがあるので、これを利用してなんとかしてみる。

「コンピュータの管理」で見ると、現在のパーティションの構成は、こんな感じ。

パーティションの構成

仮想マシンのディスク容量は、ESXiの管理パネルである VMWare vSphere Client を操作して増やすことができる。
40GB→60GBと、20GBを追加した。

20GBを追加 20GBを追加

再び「コンピュータの管理」で見ると、現在のパーティションは、こんな感じになる。

パーティションの構成

追加した20GBは末尾にある。
増やしたいドライブはCドライブなのだが、パーティションが連続していないと結合(拡張)できないので、この状態では、追加20GBをCドライブに追加する事ができない。
Dドライブを末尾に移動して、すなわち、以下の様な状態にする必要がある。

パーティションを移動する

このパーティションの移動は、以下のツールで行う事にする。

EASEUS Partition Master

しかし、ひとつ問題がある。
このツールはインストールが必要なのだけれど、現在稼働中のこの仮想マシンにインストールしたくない(余計なソフトウェアをインストールしたくない)。
かといって、ディスクは仮想なので、物理ディスクのように、他のハードにディスクを接続するというわけにはいかない。
どうするか。

考える。
考える。
考える。
ちーん。

物理ディスクと同じ様に、仮想ディスクを他の仮想ハードに接続すればいんじゃないのか。
そして、他の仮想ハードにツールをインストールして、接続した仮想ディスクのパーティションを操作すればいいのではないか。
やってみよう。
問題の仮想マシンをパワーオフした上で、VMWare vSphere Client で、問題の仮想マシンに接続されている仮想ディスクを、他の仮想ハードに接続する。

仮想ディスクを他の仮想ハードに接続する

仮想ディスクを他の仮想ハードに接続する 仮想ディスクを他の仮想ハードに接続する 仮想ディスクを他の仮想ハードに接続する 仮想ディスクを他の仮想ハードに接続する 仮想ディスクを他の仮想ハードに接続する

仮想ディスクを他の仮想ハードに接続する

他の仮想ハードを起動し、「コンピュータの管理」で見ると、こんな感じになる。

パーティションを移動する

Partition Master Free を起動し、Gドライブを末尾に移動する。

Gドライブを末尾に移動する Gドライブを末尾に移動する

続いて、Fドライブと未割り当て領域をを結合(Fドライブを拡張)する。

Fドライブを拡張する Fドライブを拡張する

変更を反映する。

変更を反映する

「コンピュータの管理」で確認する。
バッチリだ。

パーティションの構成

他の仮想マシンから、仮想ディスクを切り離す。

仮想ディスクを切り離す 仮想ディスクを切り離す

問題の仮想マシンを起動し、エクスプローラで確認する。

エクスプローラで確認する

無事、Cドライブが拡張され、Cドライブのディスク領域に余裕ができた。
Windows Update も成功。
よしよし。

広告

まとめページ

取得した資格
登った山

広告

サイト内検索

WordPress

最近のコメント

広告

RSS

RSS 記事
RSS コメント
Server offered by
有限会社パテンティックソフトウェア
Profile for zunbe