「広告」

httpd CGI SuEXECで、[Internal Server Error] (CentOS7)

「広告」
記事内に広告が含まれています。
「広告」

httpd 2.4、CentOS7系で、SuEXECで、Internal Server Errorに少しはまった件です。
httpdは、yumでインストールをしています。

「広告」

「パーミッション」「権限」の重要性

デザイン系のWEB制作者でも、「パーミッション」とか「権限」とか聞いた事があると思います。

WEBアプリ(CGI)を動かすときに、避けて通れないものです。
デザイナーは、「755にしないと!実行権限をつけないと!改行に気をつけないと!」
と「気をつけないと!」と思っているかと思います。

「パーミッション」「権限」は、それほど、WEBアプリ(CGI)には、頻繁に出てくるキーワードです。

「広告」

SuEXECを試す

今回、あるプログラムから、サーバー内の「実行ユーザ」を「特定のもの」にする必要がありました。
実際には、「Postfix3.3 迷惑メール対策 SpamAssassin(スパムアサシン)[ユーザ毎の設定]」の記事の「SpamAssassin」の設定ファイルをCGIで、読み込ませるためです。
「Postfix、マルチドメイン」のディレクトリは、「特定のユーザ」のみが閲覧できます。

httpd 2.4など初期設定では、「apache」などのユーザでプログラムが動きます。
つまり、「apache」というユーザが、「SpamAssassin」の特定のファイルが読めるようになっていないといけません。
かし、実際には、「apache」ではなく、「違う特定のユーザ」で、「Postfixのマルチドメイン環境」が構成されています。

そこで、apache 1.3 の時代から、「SuEXEC」という「指定されたユーザで実行する」という設定が、apache(httpd)で可能です。

今回、httpd2.4 の中のVirtualHostの中で、SuEXECを活用して、「Postfixの設定ファイル(SpamAssassinの設定ファイル)」が読めるようにしました。

具体的には、

<VirtualHost *:80>
  ServerName (独自ドメインFQDN)
  ServerAdmin (管理者メールアドレス)
  SuexecUserGroup (動かしたいユーザ) (動かしたいグループ)
  DocumentRoot /home/(dir)/www
  CustomLog /home/(dir)/logs/access_log combined
  ErrorLog /home/(dir)/logs/error_log
</VirtualHost>

が書かれたファイルを

/etc/httpd/conf.d/
の下に、置きました。

(ファイル名は、任意のファイル名で大丈夫です)

「広告」

SuEXECが有効か?

perlで書かれたWEBアプリ(CGI)を、ブラウザ上から起動すると、
「InternalServerError」がでます。

最初は、「SuEXEC」が有効になっているのか?
を疑いました。

有効かどうかは、「apachectl -V」というコマンドで調べます。

# apachectl -V
Server version: Apache/2.4.34 ()
Server built:   XXX XX 2019 XX:XX:XX
Server's Module Magic Number: XXXXXX:XX
Server loaded:  APR 1.6.3, APR-UTIL 1.6.1
Compiled using: APR 1.6.3, APR-UTIL 1.6.1
Architecture:   64-bit
Server MPM:     prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="/run/httpd/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

上記の「 -D SUEXEC_BIN=”/usr/sbin/suexec”」と指定があります

かつ

# ls -al /usr/sbin/suexec
-r-x--x--- 1 root apache 15280 XXX  XX  2019 /usr/sbin/suexec

とファイルもあります。
有効になっています。

再度試行錯誤します。

「広告」

journalctlで、SuEXECのエラーを確認する。

次に「journalctl」コマンドで、チェックします。

ソースコードで、httpdを入れる場合、SuEXECのエラーファイルの指定することができます。
また、/var/log/httpd/suexec.log というファイルに書かれる場合もありますが、CentOS7系のyumで入れると、そのようなファイルは作成されません。

# journalctl -f
suexec[4799]: cannot run as forbidden gid (100/check.cgi)

↑というエラーメッセージがでてきました。
check.cgiというファイル名を実行しようとしています。
上記は、「実行グループが、許可されていなよ」というエラーです。

suexecの仕様をチェックしてみます。

# suexec -V
 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=1000
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_SYSLOG
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=1000
 -D AP_USERDIR_SUFFIX="public_html"

↑この中で、

 -D AP_GID_MIN=1000

と指定されています。

「グループのIDが、最低でも1000だよ。」ということです。
今回、「100」のグループIDで実行しようとしました。

調整をします。

再び、check.cgiを実行しようとしたところ、InternalServerErrorがでました。

# journalctl -f
suexec[4988]: command not in docroot (/home/(dir)/check.cgi)

というエラーが出てきました。

プログラムを動かす場所が「ダメ」というものです。

再度、SuEXECの仕様を見てみます。

# suexec -V
 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=1000
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_SYSLOG
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=1000
 -D AP_USERDIR_SUFFIX="public_html"

↑この中で、

 -D AP_DOC_ROOT="/var/www"

とあります。
つまり、「/var/www」以下にコンテンツがないといけません。

そこで、コンテンツを

/home/以下
から
/var/www/html
に持ってきます。

これでやっと、CGIが動きました。

「広告」

SuEXECの、DOC_ROOTを変える

この「/var/www」を変更するには、基本、「httpdのソースインストール」しかないようです。
裏技的には、「/usr/sbin/suexec」のバイナリの中身を変更する。という方法もあるようですが・・・
「そこまでして・・・。ならば、ソースインストールしますわ。」という気持ちになります。

SuEXECを活用したい場合、VirtualHostで、
「このドメインは、このユーザ権限で」
「あのドメインは、あのユーザ権限で」
という発想があるからだと思います。
一つのドメインならば、httpd.confで、指定している大元のユーザ名を希望のものにすればいいはずです。

おそらく、VirtualHostの指定を

/var/www/html01
/var/www/html02

などと、すればいいのかと思います。

/home/(dir01)/www/
/home/(dir02)/www/

というのは、ちょっと、異質的な発想なのかもしれません・・・

「広告」

SuEXEC、その他のエラー

そのほか、指定したユーザ/グループ以外が書き込める状態だとエラーになる。
など、「権限」に厳しいです。
「journalctl -f」コマンドで確認しましょう。

「広告」

SuEXEC、まとめ

エラーは、

journalctl -f
suexec -V
で、チェック

当然ながら、CGI自体のエラーがあるかもしれません。

気分でエラーを出している分けではないので、「なにか原因があります」
根気よく探しましょう!

タイトルとURLをコピーしました