繁体   English   中英

在 lighttpd 上使用 sudo 运行 python cgi 脚本

[英]Running python cgi script with sudo on lighttpd

谢谢阅读!

我将一个 adafruit neopixel 连接到我的 Raspberry Pi Zero(第 1 代),并让它们使用测试 python 代码。

作为下一步,我想生成一个带有控制neopixel的按钮的网页。 我主要遵循本教程https://www.hackster.io/mjrobot/iot-controlling-a-raspberry-pi-robot-over-internet-6988d4#toc-step-5--installing-the-lighttpd-webserver- 8

起初我运行了一个简单的 bash cgi 脚本,它创建了当前时间并将其写入文件。 切换到 python cgi 脚本相当容易,无需更改任何配置文件,这让我感到疑惑。 但是从 html 运行测试 python 代码根本不起作用。 与以前的问题一样,我开始阅读和修改,但似乎我尝试过的任何解决方案都对我不起作用。

我无法叙述(工作和阅读过去几天)我所做的一切,但我将 www-data 添加到 sudoer 组,我在 /etc/sudoers.d 目录中创建了一个名为 010_www-data-nopasswd 的文件,其中包含www-data ALL=(ALL) NOPASSWD: ALL作为内容。

我将 www-data 添加到 gpio、i2c 和 spi 组中。 我运行了sudo visudo并添加了www-data ALL=(ALL:ALL) ALLwww-data ALL = NOPASSWD: /var/www/lighttpd/cgi-bin/neopixelTest.py ,但它仍然无法正常工作。

我尝试了 bash cgi 脚本来使用sudo调用测试 python 脚本,它可以工作。 所以我认为归结为这一点。

我读过,在配置文件中有一行像".py" => "/usr/bin/python"告诉 lighty 调用 /usr/bin/python 以获取以 .py 结尾的 cgi 脚本,所以我来了提出将sudo放入这一行的想法,这样基本上每个 python 脚本都会作为 sudo 运行。 确实不是一件好事,但我认为整个项目比以 root 身份运行 lighty 更快、更脏、更好。 但是我找不到这条线。

这是我的 /etc/lighttpd/lighttpd.conf 文件。

 1 server.modules = (
 2     "mod_indexfile",
 3     "mod_access",
 4     "mod_alias",
 5     "mod_redirect",
 6 )
 7
 8 server.document-root        = "/var/www/lighttpd"
 9 server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
10 server.errorlog             = "/var/log/lighttpd/error.log"
11 server.pid-file             = "/var/run/lighttpd.pid"
12 server.username             = "www-data"
13 server.groupname            = "www-data"
14 server.port                 = 80
15
16 # strict parsing and normalization of URL for consistency and security
17 # https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_http-parseoptsDetails
18 # (might need to explicitly set "url-path-2f-decode" = "disable"
19 #  if a specific application is encoding URLs inside url-path)
20 server.http-parseopts = (
21   "header-strict"           => "enable",# default
22   "host-strict"             => "enable",# default
23   "host-normalize"          => "enable",# default
24   "url-normalize-unreserved"=> "enable",# recommended highly
25   "url-normalize-required"  => "enable",# recommended
26   "url-ctrls-reject"        => "enable",# recommended
27   "url-path-2f-decode"      => "enable",# recommended highly (unless breaks app)
28  #"url-path-2f-reject"      => "enable",
29   "url-path-dotseg-remove"  => "enable",# recommended highly (unless breaks app)
30  #"url-path-dotseg-reject"  => "enable",
31  #"url-query-20-plus"       => "enable",# consistency in query string
32 )
33
34 index-file.names            = ( "index.php", "index.html" )
35 url.access-deny             = ( "~", ".inc" )
36 static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
37
38 compress.cache-dir          = "/var/cache/lighttpd/compress/"
39 compress.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain" )
40
41 # default listening port for IPv6 falls back to the IPv4 port
42 include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
43 include_shell "/usr/share/lighttpd/create-mime.conf.pl"
44 include "/etc/lighttpd/conf-enabled/*.conf"
45
46 #server.compat-module-load   = "disable"
47 server.modules += (
48     "mod_compress",
49     "mod_dirlisting",
50     "mod_staticfile",
51 )

这是我的 /etc/lighttpd/conf-enabled/10-cgi.conf 文件。


 1 # /usr/share/doc/lighttpd/cgi.txt
 2
 3 server.modules += ( "mod_cgi" )
 4
 5 $HTTP["url"] =~ "^/cgi-bin/" {
 6     cgi.assign = ( "" => "" )
 7     alias.url += ( "/cgi-bin/" => "/var/www/lighttpd/cgi-bin/" )
 8 }
 9
10 ## Warning this represents a security risk, as it allow to execute any file
11 ## with a .pl/.py even outside of /usr/lib/cgi-bin.
12 #
13 #cgi.assign      = (
14 #   ".pl"  => "/usr/bin/perl",
15 #   ".py"  => "/usr/bin/python",
16 #)
17

我知道,有".py" => "/usr/bin/python"行,但它被注释掉了。

这是我的 /etc/lighttpd/conf-enabled/10-fastcgi.conf 文件。

 1 # /usr/share/doc/lighttpd/fastcgi.txt.gz
 2 # http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ConfigurationOptions#mod_fastcgi-fastcgi
 3
 4 server.modules += ( "mod_fastcgi" )
 5

我认为这整件事甚至没有使用fastcgi。

最后但同样重要的是,这是我的 html 文件。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4
 5         <!-- answer to favicon.ico request, see https://stackoverflow.com/a/38917888/15081525  -->
 6         <link rel="icon" href="data:,">
 7
 8         <meta charset="utf-8">
 9         <!-- description for google -->
10         <meta name="description" content="This is a website to control the RPi zero">
11         <title>RPi Zero index</title>
12     </head>
13
14     <style>
15         body {background-color: lightyellow}
16         h1 {color:blue}
17         button {
18             color: black;
19             background: lightgrey;
20             border: 1px solid #000;
21             border-radius: 8px;
22             position: center;
23         }
24     </style>
25
26     <body>
27         <div style="text-align:center">
28             <h1>Hello world!</h1>
29             <br>
30             <p>please press test button</p>
31             <br>
32             <button onclick="alerttest('hello world!')">Alert!</button>
33             </p>
34             <button onclick="alert('wazzup!')">wazzup!</button>
35             </p>
36             <!-- button to call .cgi-script - it works  -->
37             <button style="height: 50px; width: 125px; font-size: 25px" onclick="test_func()">test</button>
38             </p>
39             <!-- button to call .cgi-script which calls python scripts - it works  -->
40             <button style="height: 50px; width: 125px; font-size: 25px" onclick="test_func2()">test2</button>
41             </p>
42             <!-- button to call python script directly - it works  -->
43             <button style="height: 50px; width: 125px; font-size:25px" onclick="test_py()">python</button>
44             </p>
45             <!-- button to call neopixelTest.py  -->
46             <button style="height: 50px; width: 125px; font-size:25px" onclick="test_neopixel()">neopixel</button>
47
48             <!--
49             <img src="/hello.png">
50             -->
51
52         </div>
53
54         <script>
55             var xmlhttp;
56             xmlhttp=new XMLHttpRequest();
57
58             function test_func() {
59                 xmlhttp.open("GET","cgi-bin/test.cgi",true);
60                 // prevent XML syntax error (in Firefox console, does not prevent execution or something, so only cosmetic co$
61                 xmlhttp.overrideMimeType('application/javascript');
62                 xmlhttp.send();
63             }
64
64
65             function alerttest(parameter) {
66                 alert(parameter);
67             }
68
69             function test_func2() {
70                 xmlhttp.open("GET","cgi-bin/python.cgi",true);
71                 // prevent XML syntax error (in Firefox console, does not prevent execution or something, so only cosmetic co$
72                 xmlhttp.overrideMimeType('application/javascript');
73                 xmlhttp.send();
74             }
75
76             function test_py() {
77                 xmlhttp.open("GET","cgi-bin/pythontest.py",true);
78                 // prevent XML syntax error (in Firefox console, does not prevent execution or something, so only cosmetic co$
79                 xmlhttp.overrideMimeType('application/javascript');
80                 xmlhttp.send();
81             }
82
83             function test_neopixel() {
84                 xmlhttp.open("GET","cgi-bin/neopixelTest.py",true);
85                 // prevent XML syntax error (in Firefox console, does not prevent execution or something, so only cosmetic co$
86                 xmlhttp.overrideMimeType('application/javascript');
87                 xmlhttp.send();
88             }
89         </script>
90     </body>
91 </html>
92

neopixelTest.py 文件基本上就是这个文件https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel/blob/master/examples/neopixel_rpi_simpletest.py 我刚刚添加了#! /usr/bin/python #! /usr/bin/python到代码的顶部。

我知道,我是一个绝对的初学者,但我仍然会感谢每一个帮助或想法! 提前致谢!

cgi.assign = ( "" => "" )告诉 lighttpd 直接执行 cgi 脚本(因此它们必须被标记为可执行( chmod +x ))并且应该有#!/usr/bin/python3或类似的第一行.

对于需要以 root 身份运行的特定 CGI 脚本,您可以在 cgi-bin 中创建一个名为my-script-name的包装脚本,其中 exec 的sudo <renamed-original-script>

另一种选择是将所有特权脚本放入子目录中,并创建一个 lighttpd 条件

$HTTP["url"] =~ "^/cgi-bin/priv/" {
    cgi.assign = ( "" => "/path/to/my-sudo-wrapper-script" )
}

并且my-sudo-wrapper-script必须从环境中获取 CGI 目标$SCRIPT_NAME以执行。

第三种选择是将 python 代码作为守护进程运行,以 root 身份运行,并让 lighttpd 通过 FastCGI 连接到它。 这将允许您的代码以 root 身份运行,但 lighttpd 继续以www-data身份运行

我遇到的第四个选项是简单地将sudo添加到 shebang 中,如下所示:

#!/usr/bin/sudo python

这对我有用。 我猜执行用户(在我的情况下为 www-data)必须有权在不输入密码的情况下使用sudo

但同样,这是一个安全问题(尽管我不打算向网络开放我的 RPi),所以我想在学习如何通过 FastCGI 将 lighttpd 与 python 守护进程连接后,我会尝试第三个选项。 谢谢!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM