【问题标题】:How to make a Linux Service that Accepts Commands via Web Server?如何制作通过 Web 服务器接受命令的 Linux 服务?
【发布时间】:2009-06-12 02:34:40
【问题描述】:

我需要一个应用程序在我的 Web 服务器的后台运行,但我需要能够以 root 权限启动/停止该应用程序。

为了做到这一点,我想要运行一个具有 root 权限的服务,以便它可以终止应用程序,并在需要时重新启动它。

最后,我需要能够通过 Apache/PHP 向服务发送启动和终止命令,以便可以通过 web 间接控制它。

如何创建 Linux 服务?
如何以这种方式与 Linux 服务通信?

提前致谢!

【问题讨论】:

    标签: php linux service background-process background-service


    【解决方案1】:

    在 PHP 脚本中使用 exec 命令来调用 shell 文件。可以使用“setuser”位设置 shell 文件,因此它将以其所有者身份运行(而不是使用 Web 服务器的权限运行)。

    当然,您需要非常小心——大量的测试、监控等。

    最后,考虑以专用用户而非 root 用户身份运行的服务。例如,像 apache 和大多数其他做得好的服务一样。

    添加:回复:在 Linux 中运行服务。取决于你的 Linux 风格。如果您想确保您的应用服务在失败时会自动重新启动,加上日志记录,请查看 Runit:

    https://web.archive.org/web/1/http://blogs.techrepublic%2ecom%2ecom/opensource/?p=202

    http://smarden.org/runit

    补充:我认为弗兰克的建议(在评论中)使用 sudo 系统而不是 setuid 位更好。

    【讨论】:

    • 除了setuser位,你可以添加一个规则来允许脚本执行到/etc/sudoers,例如:apache ALL=(root) NOPASSWD: /bin/my.restart.script。 sh -- 那你就 exec('sudo /bin/my.restart.script.sh');
    • +1 我同意弗兰克的观点。我认为为您的特定 cmds 设置 sudoers 比设置 setuser 位更好。此外,sudo 可以记录普通用户(php 服务器)以 root 身份调用 sudo 命令的次数。
    • 感谢您到目前为止的回复!你知道我将如何与服务通信吗?
    • 不同的 linux 服务框架具有从服务启动/停止/获取状态的命令。例如“服务 foo 开始|停止|状态”。 Runit 使用它的“sv”命令:sv start|stop|kill|status foo。您的 php 程序将执行“sudo sv status foo”并将状态报告给网络用户。
    • 作为补充说明,在 Fedora(可能还有其他一些发行版)中,您还需要在 sudoers 文件中注释掉“Default requiretty”行。
    【解决方案2】:

    所以,你这里有三个部分:

    • 您没有 root 权限的 Web 服务器
    • 一个应用程序
    • 监控应用程序的守护进程

    您的问题不是启动守护程序,而是编写它,并从 Web 服务器与其通信,而不需要 root 权限。

    守护进程可以像在后台启动的非交互式应用程序一样简单:

    # my_dameon &
    

    我不是php开发者,但是搜索消息队列和php,发现beanstalkd
    查看第一页上的示例,您似乎可以使用它来执行以下操作:

    • apache/php 向 beanstalkd 发送一些消息
    • 您的守护程序从 beanstalkd 读取消息。根据命令启动或终止或重新加载后台应用程序。

    你可以用php写你的守护进程,因为有client in many languages
    也可以查看this question

    【讨论】:

      【解决方案3】:

      您可以创建一个接受以下命令的守护程序:

      • daemon_name start
      • daemon_name stop
      • daemon_name restart
      • deamon_name reload

      启动守护进程应该不难。只需从 PHP 脚本执行 daemon_name start 即可运行它。启动后,您可以将进程的 PID 写入锁定文件(用于稍后停止、重新启动或重新加载)。守护进程应该处理信号。

      然后,您可以在 PHP 脚本中调用 daemon_name stop。这应该会启动一个新的守护进程,它将检查锁定文件并获取正在运行的守护进程的 PID,并发送一个将由正在运行的守护进程处理的信号。锁定文件应该被移除/清除,然后stop 启动守护进程/进程可以退出。

      【讨论】:

      • 简直太棒了,我认为它会更复杂!
      【解决方案4】:

      我认为您应该查看inetd,它可以配置为运行各种服务,并且以root 身份运行。然后,您可以编写一个相对简单的程序,该程序本身没有 root 特权,但当由 root 运行时,它可以完成您需要完成的任务。

      【讨论】:

        【解决方案5】:

        就与服务通信而言,您没有说明它是什么类型的服务,但是假设您自己编写它,最常用的方法是通过 UNIX 套接字或 MMAP 进行通信。真的取决于你的需求。

        哦,是的,应该指出已经有用于 linux 系统的 web 管理的应用程序。 Webmin 是一个非常好的工具,可以根据需要进行配置以允许尽可能多或尽可能少的控制。

        【讨论】:

          【解决方案6】:

          正如@shodanex 所建议的那样,使用 Beanstalkd 将是断开 Web 前端与以 root 身份运行的命令行工作者的绝妙方法。它可以简单地设置为只运行所需的内容。

          要运行 worker,Pear's System_Daemon 可以生成并运行守护进程运行脚本,包括启动/停止/重启。

          【讨论】:

            【解决方案7】:

            这样做时要非常小心。切勿在 exec 命令中使用任何用户从 Web 提交的数据。这可能允许某人在您的机器上任意执行命令。

            另外,我第二次 Frank 使用 sudo 规则,这样您就可以使用所需的权限运行该特定命令,但仅此而已。这样会更安全。

            【讨论】:

            • 是的,我知道,这就是我说“间接”的原因。我只需要启动和终止命令,所以我不会传递任何文本命令或任何复杂的东西。身份验证将由 PHP 前端处理。
            【解决方案8】:

            当然有

            sudo apt-get install openbsd-inetd
            

            你可以创建你想要的服务

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-05-19
              • 1970-01-01
              • 2011-10-12
              • 1970-01-01
              • 2018-04-29
              相关资源
              最近更新 更多