Webプログラム」カテゴリーアーカイブ

CentOS7でPHP7.2からPHP7.4にバージョンアップ。ただ簡単すぎた。

ただいま仕事がないのでサーバ系やフリーソフトのバージョンアップをしながらメンテナンスをしている状況です。で、今回はPHPのバージョンアップ。今までPHP7.2系を使っていましたがセキュリティメンテナンスの期限も過ぎてしまったのでさすがにまずいということでPHP7.4系にバージョンアップすることにしました。この手のバージョンアップは状態によっては手順がかなり面倒だったりするのですが…。

 

Remi経由でPHP7.2をインストール済みの環境から

今回の前提条件がこれ。CentOS8のように元からPHP7.2が入っている環境ではなくRemi経由でPHPのバージョンが7.2系にバージョンアップ+設定がちゃんとなされている状態から始まっています。これのおかげでこの後の作業がとんでもなく楽な作業になってしまいました。

 

Remi経由でPHP7.2が入っているならリポジトリを微妙に変更してアップデートを行うだけであっさり終わり

そう。単にアップデートを行うだけで終わりだったわけです。PHP7.2系のリポジトリはremi-php72なので、remi-php74を指定するとPHP7.4系のリポジトリに切り替わります。そのため、とりあえず最新の状態まで更新が完了すれば一発

$ sudo yum update --disablerepo=base,updates --enablerepo=remi,remi-php74

これだけで終わりです。簡単でしょ?まあ、アップデートするときに一時的にPHPに関するサーバを止めてしまったもよかったのかもしれませんが…。あとは更新対象になったものをすべて更新すれば完了です。設定もそこまで違うことはないので使い回しできそうですし、更新の途中でPHP Warningが大量に出てきますがこれもそれほど気にする必要はないと思います。

 

後は運用しながら様子見

とりあえずblogも問題なく動いているようですし、あとは不具合が見つかれば設定などを見直していく、という感じになるかと思います。WordPressのプラグインもそうですが、この手の更新についてもちゃんと確認していかないとセキュリティメンテナンスがされていないものを使っているとどこからアタックが仕掛けられるかわからないですからね。ちゃんとやっていきましょう。

久しぶりにBlog(WordPress)の広告系設定を見直してみた

いろいろと忙しかったのでその手の設定を放置していたのですよ…。ちょうどGoogleの広告に関する状態を見に行ったときにいろいろと警告も出ていたのでいくつか修正してみることにしました。

 

AMPを導入

この場合のAMPはAccelerated Mobile Pagesの方です。モバイル系でアクセスされたときに速度を向上させるための技術ですね。出た当初はWordPressへ導入するのがかなり大変だったことと、とりあえずWPTouchでモバイルページ側をどうにかしていたので放置しておいたのですが、今回プラグインの導入とともにWPTouchを破棄することにしてみました。メニューとかがなくなって見づらくなっていると思いますが、モバイル版の方は後でテーマを変更して調整する予定です。プラグインは一応2種類あるようですが、公式に近いと思われる方を導入しています。もう片方の方は有料モードがあるのでちょっと怪しいということで今回は使いません。

 

Google広告のプラグインも変更

AMPを導入することで問題になるのが広告ユニットの問題。AMPではJavaScriptが使えない影響でそのままでは広告ユニットが表示できない、という問題があります。…まあ、なんとなくですがここ数年はWPTouch側でも広告を出す処理を設定にしていないような気がしているのでそれはそれでいいのかもしれませんが…。とりあえずAMP対応かつ有料にならないものを探す、ということで今回はAd Inserterを導入してみました。解説ページなどから設定をしてとりあえず動く状態には持って行っています。ヘッダ部への設定およびAMPのページでのみ動作する広告と通常ページで動作する広告を混ぜるのがちょっと大変でした。また特に設定箇所を表示する機能が地味に使えるのがうれしいところで、挿入箇所が予定していたポイントでなかったときにデバッグ的に使うことができました。なお、設定を少し代えてトップページの広告だけ第一記事と第二記事に表示するように設定しています。

 

そのほか詳しいことは別のサイトに譲ります

今回は説明サイトに従って設定してみたただの記録なのでこれで終わりです。WordPressでAMPを導入してかつGoogleなどの広告を表示させるのであればWordPressのプラグインであるAMPとAd Inserterの組み合わせがそれなりにいいのでは?という個人的感想を書いて終わりにします。

 

CMSサイトの構築とSELinux

というわけで今回はこういう話題です。ほとんどの解説サイトがSELinuxを前提にしていない書き方をしているためにこの系の権限変更がちゃんと行われず、サイトの初期設定すらまともに行えない、という現象にはまることが多いような気がするのでそれについて書いてみます。

 

SELinuxが持っているhttp系の初期権限

これを知らないと大変なことになります。SELinuxでは、http系で操作される各種ファイルについて以下のようなラベルを割り当てて管理しています。大まかに必要な分だけですが…。

権限名 意味 権限
httpd_sys_content_t 通常コンテンツ 読み込み専用
httpd_sys_rw_content_t 通常コンテンツ(読み書きあり) 読み書き
httpd_sys_script_exec_t 実行可能コンテンツ(CGIなど) 読み込みおよび実行
httpd_var_lib_t /var以下に存在するhttpの動作に関わる補助ファイル(phpのキャッシュなど) 読み書き
httpd_var_run_t /var以下に存在するhttp上で実行されるコンテンツの補助ファイル(phpのセッションなど) 読み書き

下二つはあまり関係しませんが、php-fpmなどの設定時に関わってくることがあります。で、問題は上の3つ。

 

SELinuxがhttp系ファイルにつける初期ラベルはhttpd_sys_content_tになる

これが要注意ポイント。つまり読み込み専用になるわけです。この状態は通常のコンテンツをアップロードしたときには正しいのですが、CMSサイトのようにディレクトリ内にキャッシュを持ったり、自分自身でファイルのアップデートを行うコンテンツにおいては非常に相性が悪い(というかこの状態だとうまく使えないこと)になってしまいます。

 

CMSサイトのディレクトリにはhttp_sys_rw_content_tをつけないとインストールできないことも

この件について調べるのにかなり時間がかかってしまいました…。特に内部的にキャッシュディレクトリを持つ場合はそのキャッシュディレクトリにhttp_sys_rw_content_tを設定しておかないとキャッシュが動かず実行できません。これは大変です。また、CMSの場合たまにあるのが、アップデート時に何らかのスクリプトをCGI権限で動かすパターンがあるのですが、その場合は個別にhttpd_sys_script_exec_tを設定しないとたとえchmodによる実行権があってもSELinuxにより実行が拒否されますので対応する必要があります。

 

CMSサイトのディレクトリには必要な部分にhttp_sys_rw_content_tを設定しよう

という結論になります。もちろん、全域に設定するとセキュリティが弱くなるので必要な部分だけ、というのはあるのでコンテンツに関するディレクトリだけです。例えば/var/www/cms以下にコンテンツをインストールして、/var/www/cms/webroot以下を書き換え可能にするとするなら

# semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/cms/webroot(/.*)?"
# restorecon -R -v /var/www/cms/webroot

のような処理が必要になります。この処理はターミナル上からしかできないのでSELinuxを設定している時は要注意になります。また、実行権が必要になるファイルにもhttpd_sys_script_exec_tの設定処理が必要になりますので、これを参考にやっておきましょう。

 

SELinuxがセキュリティに貢献していることがよくわかる…

chmodによる権限変更だけでは受け入れない堅さが自慢です、というところですか。面倒ですが、少しずつ覚えていって使いこなせるようにならないとまずいような気はしますね。

 

Fedora32のPHPは初期設定でphp-fpmになるのか…

そして今回の出来事の中で気がついてしまったこと。昔はApacheの場合はphpがhttpd上で動く組み込みパターンになるのでphpの実行者はhttpdの実行者と同じになっていたのですが、Fedora32の場合は初期設定がphp-fpmによる外部動作なので、phpの実行者がphp-fpmで設定されている実行者になる、という「suexecを考えるよりはわかりやすいのか?」という状態になっているようです。このあたりも気をつける必要がある人は気をつけましょう。

WordPressのCaptchaを変更してみる(Advanced noCaptcha & invisible Captcha)

というわけで、Captchaが大分バグっている、というかとある事情で不具合が起こっていたようなので更新しました。その更新について少し書いておきたいと思います。一応コメントの書き込みテストはしているのでキャッシュ処理に関する問題はないはずですが…。

 

大量のスパムコメントがあった理由は…

4月までの数年間WordPressの更新は「緊急性の高いものを除きとりあえずセキュリティアップデートだけ」という状態だったので、一部の事態に鈍感になっていたことが大きかったです。で、本題の大量のスパムコメントですが、とりあえずコメントのフィルタシステムでスパム扱いされていたので半分無視していたのですが、妙に気になったのでCaptchaに関して調べてみると・・・。

SI Captcha Anti-SpamCaptchaは問題あり

という内容の記事があり、調べてみると開発者が変わって更新が止まっているとかバックドアが仕込まれているとかいろいろと情報がありました。ちなみに私が二年前の段階で導入していたのがSI Captcha Anti-Spamの方で、どうもこれがスパムコメントの原因だったようです。

 

別の種類のCaptchaを導入してみることに

さすがにCaptchaが一つもない、というのは微妙ということで調べてみていくつか導入候補を考えたのですが、それが

  • Google Captcha (reCAPTCHA)
  • Login No Captcha reCAPTCHA
  • Advanced noCaptcha & invisible Captcha

になりました。ところがどっこい。基本的にこれらはすべてGoogleのCaptchaシステムを借りて行うものなので変に所有者が変わらない限りはCaptchaとしての動きはほぼ変わりません。後は信頼度と設定がどこまでできるか?に依存するため、今回はAdvanced noCaptcha & invisible Captchaを使ってみることにしました。

 

導入の手順はおそらくこの3つともほとんど変わらない(と思う)

というのも、結局はGoogleのreCAPTCHAを借りることになるため、

  1. WordPressの管理画面からプラグインを検索してインストールする
  2. GoogleのreCAPTCHAの管理画面にGoogleアカウントでログインしてAPIキーとSecretキーを取得する
  3. 設定画面でAPIキーとSecretキーを登録して、ほか必要な設定を行う

となります。GoogleからAPIキーを取得するためのアドレスは大抵プラグインの設定画面にリンクが張られていると思うのでそれを参照すればよいと思います。ちょっと注意が必要なのが、reCAPTCHAのキーを取得するときに認証のバージョンなどを設定することができますが、そのバージョンにプラグイン側の設定も合わせる必要がある、ということです。v2(noCaptchaもしくはinvisible Captcha)で設定する場合とv3で設定する場合でそれぞれ方法が異なりますので注意しましょう。

あとはどの場所にCaptchaを設置するかどうかです。Advanced noCaptcha & invisible Captchaではいくつかの場所にチェックボックスだけで設定できるので、コメント投稿およびログイン画面に設定することにしました。これで安全性がかなり高まるかと思います。ちなみにAdvanced noCaptcha & invisible Captchaの場合はbbPressやBuddyPress、WooCommerceとも連動させてCaptchaをかけることができるので、これらのプラグインでサイトを作っている人には簡単に設定できるようになる分おすすめかもしれません。

 

Captchaのプラグインを変えるだけでスパムコメントが一切なくなった…

というわけで、Captchaのプラグインを変えて数日間たったわけですが、スパムコメントが一切なくなりました。まあ、このサイトこの2年間くらい記事更新がほとんどなかったこともありコメントらしいコメントもないので正しいコメントが受け付けられているかどうかはテストしたこと以上のことは不明なのですが、それでも管理の手間が大分減っているのでちょっと感動です。スパムコメントのフィルタリングに関してはIPフィルタ以上の効果ですね。

PHPの「Fatal error: Can’t use function return value in write context」に要注意 (WordPressで管理画面に入れないことも)

ということで先ほどプラグインを更新したときにいきなり発生した事態について書いてみます。「いったい何事?」と考えてしまいましたが理由がわかればプログラムの修正でなんとかなるのですが、知識がない人にもわかるようにいろいろと書いてみます。

 

PHPのとある処理に起因する問題

エラーメッセージで検索すれば詳しく出てくるので詳しくは書きませんが、もしPHPやHTTPサービスのログを直接見られる場合はこんなログが書いてあることがあります。

PHP Fatal error:  Can't use function return value in write context

このエラーですが、調べてみると関数に見えるPHPの演算子(に近いのかな?)に対して関数の戻り値を直接渡した場合エラーとなる、というものです。よくあるのがisset()やempty()に関数の戻り値を直接渡す場合、例としては

function hoge()
{
	return array(...);
}

if(empty(hoge())){

}
else{

}

というものです。この場合、エラーを避けるためには一時的に変数に関数の戻り値を受け取ってからempty()やisset()に判定させる必要がある、つまり

function hoge()
{
	return array(...);
}

$ret = hoge()
if(empty($ret)){

}
else{

}

としなければならない、ということだそうです。で、もう一つ重要なポイントとしてはPHP5.5以降であればempty()については関数の戻り値を直接渡してもエラーとならない、ということになったようです。今回引っかかったのがこれです。

 

EWWW Image Optimizerを3.2.0に更新したら管理画面に入れなくなった…

つまり見事に上の現象に引っかかってしまったわけです。私の場合はエラーログを直接確認できる立場だったので何が起こったのか即座に判定してなんとかしたわけですが知らない人だと検索しても出てこないのでたぶん大変ですね…。まあ、レンタルサーバーなんかだとPHP5.5系以上のはずなので問題ないはずですが…。

 

PHPのバージョンを上げるか回避処理を追加しよう

通常はバージョンを5.5以上にあげる処理を行えばOKです。もしそれができないのであれば一時的に変数に受け取ってempty関数に渡すようにスクリプトを変更することで回避しましょう、とだけ書いておきます。どんなスクリプトになるのか知りたい方はコメント欄にでも要望を書いておいてください。あとで追記するかもしれません。

 

12:00 追記

EWWW Image Optimizerですが、3.2.1で修正されていることを確認しました。なので手動修正としては3.2.1のコードを手元にダウンロードしてbulk.phpをFTP経由などで書き換えることで対応することが可能です。この手の問題って確認漏れなのでいろいろな環境で試さないとだめなのとバグ報告の早さおよび対応の早さが評価の鍵となってしまいますかね。