質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Q&A

解決済

1回答

3059閲覧

web(php)でgpioの操作を教えてほしい

88_yuki_88

総合スコア13

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

0グッド

1クリップ

投稿2019/03/24 10:27

編集2019/03/24 10:58

前提・実現したいこと

ラズパイにnginx,phpを導入し、web上からgpioを操作したいです。
web→php→python→gpio→Lチカ

助けていただけるととても助かります。どうぞよろしくおねがいします。

発生している問題・エラーメッセージ

下記を確認したところ、webからgpioを制御しようとしてもLチカができない
(おそらくlinuxのgpioの権限の問題)

試したこと

php→pythonのtestファイルを作成し、web上からの動作確認済(ここの連携は問題なし)
web→php→pythonによる表示は問題なし。

プロンプト上でphpを起動し、pyファイルを呼び出し、Lチカすることを確認。
php→python→gpio→Lチカも問題なし

nginxのユーザ www-dataであることを確認し、gpioのグループに追加。
追加されたことを確認済。

###コード

php

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>LedTest</title> </head> <body> <?php if(isset($_POST["start"])) { echo "LED Light ON"; $path ='sudo python /var/www/html/ledStart.py'; exec($path); } else if(isset($_POST["stop"])) { echo "LED Light OFF"; $path ='sudo python /var/www/html/ledStop.py'; exec($path); } ?> <form method="POST" action=""> <input type="submit" value="start" name="start">  <input type="submit" value="stop" name="stop">  </form> </body> </html>

python(ledStart.py)

import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(25, GPIO.OUT) GPIO.output(25, True)

python(ledStop.py)

import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(25, GPIO.OUT) GPIO.output(25, False) GPIO.cleanup()

LEDはgpio25番に接続しています。

補足情報(FW/ツールのバージョンなど)

はじめて投稿させていただきます。
心優しい方、どうぞよろしくおねがいします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

WEBサーバーであるnginxを経由し、PHPスクリプト内でsudoコマンドを実行するときにはwww-dataユーザーで実行されるため、sudoコマンドの実行で失敗していると思います。その場合、/var/log/auth.logに恐らく以下のようなエラーログが出力されているはずです。

Mar 25 11:31:33 raspberrypi sudo: pam_unix(sudo:auth): conversation failed Mar 25 11:31:33 raspberrypi sudo: pam_unix(sudo:auth): auth could not identify password for [www-data]

もし上記があたっているとしたら、www-dataユーザーがsuコマンドを正しく実行でき、pythonスクリプトを実行できるようにする必要があります。具体的には、visudoコマンドで/etc/sudoersファイルを編集し、www-data ユーザーが sudo を使用して /usr/bin/python3を実行できるようにします。

以下は、質問者さんのような状況でwww-dataユーザーがsudoコマンドを実行できるようsudoersファイルを修正した例です。/etc/sudoers ファイルをcatコマンドで表示しています。

bash

1root@raspberrypi:/etc# cat /etc/sudoers 2# 3# This file MUST be edited with the 'visudo' command as root. 4# 5# Please consider adding local content in /etc/sudoers.d/ instead of 6# directly modifying this file. 7# 8# See the man page for details on how to write a sudoers file. 9# 10Defaults env_reset 11Defaults mail_badpass 12Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 13 14# Host alias specification 15 16# User alias specification 17 18# Cmnd alias specification 19 20# User privilege specification 21root ALL=(ALL:ALL) ALL 22 23# Allow members of group sudo to execute any command 24%sudo ALL=(ALL:ALL) ALL 25 26# See sudoers(5) for more information on "#include" directives: 27 28Cmnd_Alias LEDSTART_CMD = /usr/bin/python3 /var/www/html/ledStart.py 29Cmnd_Alias LEDSTOP_CMD = /usr/bin/python3 /var/www/html/ledStop.py 30 31#includedir /etc/sudoers.d 32pi ALL=(ALL) NOPASSWD: ALL 33www-data ALL=(ALL) NOPASSWD: LEDSTART_CMD, LEDSTOP_CMD 34root@raspberrypi:/etc#

下の方で www-data ALL=(ALL) NOPASSWD: LEDSTART_CMD, LEDSTOP_CMD と記述して、www-dataユーザーがパスワード無しで、/usr/bin/python3 /var/www/html/ledStart.py (と ledStop.py)を実行できるように指定しています。コマンドはフルPATHで指定する必要があるので pythonではなく、/usr/bin/python3とします。またLEDのON/OFFでpythonスクリプトファイルも違うので、Cmnd_Aliasでそれぞれ指定します。

WEBで検索するとwww-data ALL=(ALL) NOPASSWD: ALL のように簡単に修正する例が見つかりますが、上記のようにpythonコマンドだけでなく、なんでも実行できるようになってしまうので、セキュリティの観点からはお勧めできない指定だと思います。実験やテストではなく、実運用で使用する場合は危険ですので注意した方が良いかと思われます。(ラズパイであれば実験用だと思いますが)

visudo の使い方は検索すればいくらでも参考記事が見つかりますので割愛しますが、修正を間違えるとsuコマンドが使えなくなって致命的な状況になるのでご注意の上、使用してみてください。

この内容で当方のラズパイ1 modelBにてご提示のスクリプトとほぼ同等のものを使用し、GPIOでのLED 点灯/消灯ができました。質問者さんがご使用のラズパイ本体やraspbianは恐らくもっと新しいと思うので、異なるところもあるかもしれません。


**追記しました:2019-03-25 15:04 **

質問者さんのケースでは(恐らく)sudoerの問題だと思い、visudoコマンドでwww-dataユーザーをsudoさせるようにする回答をしましたが、別案のひとつとしてsudoコマンドを使用せず、/etc/sudoersの修正もせずにroot権限で実行する方法をご紹介します。

linuxにはSUID(Set User ID)と言う特殊なアクセス権があって、実行ファイルにこのアクセス権をセットすることでその実行ファイルのオーナー(所有者)の権限で実行することができます。

UNIX処方箋:- SUIDとは

これを利用して、/usr/bin/python3 /var/www/html/ledStart,pyを実行するC言語で作成したプログラムをPHPスクリプトから実行するようにすれば、sudoを使用しなくてもrootで/usr/bin/python3を実行し、GPIOを操作してLEDのON/OFFをすることができるようになります。

具体的には以下のようなsystem でプログラム内からpython3スクリプトを実行するC言語のプログラムを用意します。

C

1#include <stdlib.h> 2 3int main(int argc, char *argv[]) 4{ 5 system("/usr/bin/python3 /var/www/html/ledStart.py"); 6 7 return 0; 8}

これをコンパイル(ビルド)して実行ファイルを作り、その実行ファイルのオーナーをrootにしてchmod u+s 実行ファイル名としてSUIDをセットします。

bash

1 2pi@raspberrypi ~ $ gcc -Wall led_start.c -o led_start 3pi@raspberrypi ~ $ ls -l led_start 4-rwxr-xr-x 1 pi pi 5478 Mar 25 14:34 led_start 5 6pi@raspberrypi ~ $ sudo chown root:root led_start 7pi@raspberrypi ~ $ ls -l led_start 8-rwxr-xr-x 1 root root 5478 Mar 25 14:34 led_start 9 10pi@raspberrypi ~ $ sudo chmod u+s led_start; ls -l led_start 11-rwsr-xr-x 1 root root 5478 Mar 25 14:34 led_start 12pi@raspberrypi ~ $

この実行ファイルが/home/pi/led_startだとして、PHPスクリプトの中から以下のように実行するとLEDが点灯します。www-dataユーザーでPHPスクリプトが実行されますが、sudoを使用しなくてもGPIOを制御できます。

PHP

1# ...抜粋 2if(isset($_POST["start"])) { 3 echo "LED Light ON"; 4 #$path ='sudo python /var/www/html/ledStart.py'; 5 #$path ='sudo /usr/bin/python3 /var/www/html/ledStart.py'; 6 7 # SUID な/home/pi/led_startを実行する 8 $path ='/home/pi/led_start'; 9 exec($path); 10}

実験レベルではこんな使い方も有りかと思い、技術的な観点からご紹介させていただきました。

投稿2019/03/25 04:51

編集2019/03/25 06:05
dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

88_yuki_88

2019/03/25 13:11

とても丁寧なご回答、ありがとうございます! はじめてでありましたが、質問させていただけてよかったです。 ご指摘の通り、エラーログを発見いたしました。 セキュリティの観点からのご指摘もくださり、大変助かりました! 熟読、理解後、実装してみたいと思います! 本当にありがとうございます。
88_yuki_88

2019/04/07 02:08

先日www-dataに権限を付与したところ、機能しました! また、linuxの知識が不足していることにも気づかされました。 dodox86さんの丁寧な解説のおかげで、また1つの勉強できたこと、大変感謝しています。 ありがとうございます。
dodox86

2019/04/07 02:47 編集

経過のご報告ありがとうございます。お役に立てて良かったです。ラズパイだとlinuxでハードもつなげて色々試し易いので、色々いじってみると良いと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問