min117の日記

初期desireもち。趣味Mac,メインFedora,仕事xp。

fedora Apache(httpd)で cgi-bin が動かない場合の対処(permissionエラー)

Apache から直接 pythonスクリプトを実行したいが、どうしてもエラーになる。

You don't have permission to access /test.py on this server.

f:id:min117:20170702120200p:plain

環境は以下。

fedora 20

Apache/2.4.10(Fedora

ーーー

解決手順

① まずログをみる

$ sudo -s

# ls -sharlt /var/log/httpd/ | grep error | tail -n 5

f:id:min117:20170702115627p:plain

# vim virtual.host-error_log

f:id:min117:20170702115837p:plain

エラーがわかった。

because search permissions are missing on a component of the path

cgi-bin がどこにあるかを conf ファイルで確認する

$ sudo -s

# cd /etc/http/conf/

# vim httpd.conf

f:id:min117:20170702120600p:plain

cgi-bin という文字列で検索をかける。

f:id:min117:20170702120714p:plain

↑ このconfの行数でいうと

・756行目にScriptAlias

 ブラウザから http://test.com/cgi-bin/ と表記したときに、/var/www/cgi-bin にアクセスできるようにする(ショートカットを作る)機能。

・770行目のDirectory

 cgi実行権限を決める場所。Options +ExecCGI Require all granted が無いと pythonスクリプトが動かない。

なお、Apache は Ver2.4から「Require all granted」という表記になったらしい。Ver2.2だと表記方法が違う。

komeiy.hatenablog.com

cgi-bin フォルダの権限が「drwxr-xr-x」になっているか確認

f:id:min117:20170702123047p:plain

④ 実行するスクリプトファイル権限が「-rwxr-xr-x」になっているか確認

f:id:min117:20170702123226p:plain

cgi-bin フォルダ所有者httpd を実行しているユーザーになっているか確認

# ps aux | grep httpd

f:id:min117:20170702124348p:plain

実行ユーザーは「www-data」であることがわかった。③と④から、cgi-binフォルダも、test.pyスクリプトも、どちらも所有者が www-data なので、問題なし。

python スクリプトにヘッダ行があるか確認する

python スクリプト「 Content-type: text/html¥n 」の記述があるか確認する。これがないと(①の手順でログを見たときに)malformed header from script」というエラーが出てしまう。

http://www.futomi.com/lecture/apache/cgier

# vim test.py

f:id:min117:20170702122602p:plain

Apache を再起動する

ここまで設定したら、Apache を再起動する。

$ sudo -s

# systemctl restart httpd.service

f:id:min117:20170702122354p:plain

ーーー

ここまでの設定で cgi-bin は動くと思うが、VirtualHost を立てている(複数のWEBアドレスを使って運用している)ときはさらに /etc/httpd/conf.d/vhost.conf も見る。

$ sudo -s

# vim /etc/httpd/conf.d/vhost.conf

f:id:min117:20170702121623p:plain

f:id:min117:20170702121840p:plain

↑ このconfの Directory の設定を、上記の 756行目と770行目と同じにしないといけない。

設定を変えたので、もう一度 Apache を再起動する。

$ sudo -s

# systemctl restart httpd.service

f:id:min117:20170702122354p:plain

ブラウザ からアクセスして、動くか試してみる。

f:id:min117:20170702122739p:plain

 無事動いた。

ーーー

2017/7/16 追記

python3 から ヘッダーをprintしないとうまくいかないことがあることもわかった。

fedora の場合、エラーは /etc/httpd/logs/ の中にある。ログファイル名は環境によって違うので読み替える。

$ sudo -s

# vim /etc/httpd/logs/virtual.host-hoge-error_log

f:id:min117:20170716224039p:plain

実際に出たエラーごとに見てみる。

ーーー

エラー① python3 スクリプト内に日本語文字列が含まれている

# vim /etc/httpd/logs/virtual.host-hoge-error_log

f:id:min117:20170716224422p:plain

python3 の print文に、日本語文字列を含んでいたためにエラーになった。「u753b…」のような部分で、日本語がうまく処理できていないとわかる。pythonスクリプトを見てみる。

# vim twAllDL.py

f:id:min117:20170716224706p:plain

確かに日本語を出力しているが、処理するための記述(ヘッダでのutf8宣言)には問題なさそう。 ちゃんと # -*- coding:utf-8 -*- と書いているし。

f:id:min117:20170716224751p:plain

原因調査は面倒なので、日本語のところを英語にして対応しちゃう。

f:id:min117:20170716224849p:plain

これで エラー①は消えた。

ーーー

エラー② ヘッダ出力する print文を書いてない

# vim /etc/httpd/logs/virtual.host-hoge-error_log

f:id:min117:20170716225036p:plain

Bad header というエラーになるようだ。python3ソースを見てみる。

# vim twAllDL.py

f:id:min117:20170716225458p:plain

うむ。確かにヘッダのprint文が無い。print("Content-type: text/html¥n") を書き足してみる。 ← python3 なのでprint文にはカッコがつくので注意。

f:id:min117:20170716225649p:plain

ーーー

2017/7/17 追記

・ヘッダに注意

 #!/usr/bin/python3 ← python2か3か

・日本語をutf-8でラップする

 import io

 sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

print文の前行に必ず Content-type ヘッダ出力が必要

 http://ura22.sakura.ne.jp/pycgi/practice.html

f:id:min117:20170717065440p:plain

 ↑ 改行コードは ¥n だけでいけた。

f:id:min117:20170717073656p:plain

コマンドまとめ

(www-data は httpd の実行ユーザ)

$ sudo -s

# cd /var/www/

# sudo chmod www-data:www-data cgi-bin

# sudo chmod 755 cgi-bin

# cd cgi-bin

# sudo chmod www-data:www-data twAllDL.py

# sudo chmod 755 twAllDL.py

# vim twAllDL.py

print("Content-type: text/html¥n")

# systemctl restart httpd.service

# vim /etc/httpd/logs/virtual.host-hoge-error_log

ーーー

注意点まとめ

PythonスクリプトPython2か、3か(3なら、print文にカッコがついているはず)

Pythonスクリプト字下げは半角スペースかタブかどちらかで統一されているか

Pythonスクリプトにヘッダーを書いているか

 print("Content-type: text/html¥n")

 または

 print('Content-type: text/html; charset=UTF-8\r\n')

ーーー

参考(Python3 スクリプト

Python3で作る簡素なCGI

yxshipg.appspot.com

ーーー

参考(cgi-bin配下のhtml)

/cgi-bin/ディレクトリ配下の画像やHTMLが表示できない

f:id:min117:20170717075919p:plain