Robin Davies
Robin Davies

Reputation: 7834

How to shut down linux from a web service

Use case is web service intended to run as an appliance on a headless Raspberry Pi. OS: Raspbian (Debian).

The web service is running under a non-root service account, using a custom-rolled Boost Beast-based web server (avoid!).

What I want to do: provide a button in the web interface, running in a remote user's browser that allows the system to be shut down or rebooted.

What I've tried so far ... (C/C++)

   system("/usr/sbin/shutdown  -P now");  // (or -r for reboot)

Fails with the messages:

... [3460]: Failed to set wall message, ignoring: Interactive authentication required.
... [3460]: Failed to power off system via logind: Interactive authentication required.
... [3460]: Failed to open initctl fifo: Permission denied
... [3460]: Failed to talk to init daemon.

I also tried creating a wrapper executable that has been SUID-ed to root, that in turn calls system("/usr/sbin/shutdown ...") with identical results. So even with root credentials, shutdown fails. (Also tried /sbin/reboot, which also fails).

The service in question is written in c++, and services a web socket. The web client app sends a web socket request to shut down the system; and the shutdown is performed in the C++ server code. Everything works fine when the server is started in an interactive session; but it does not work when running in a systemd service.

The web server itself is running as a systemd service using a system account (so no login credentials, and I really do not want login credentials for the service account).

I'm perfectly willing to reconfigure the system, or create a service specifically for this purpose if necessary, and to do what I can to address security issues. But I have no clue as to what the path forward is. The issue is particularly pressing because there's no shutdown button on an out-of-the-box Raspberry Pi (although I do plan to address that for my own Pi). The fact that one CAN install a shutdown button on a Raspberry Pi means there must be some what to do it.

Ideally, I'd like to leave the R-Pi in a state that's usable for other purposes. So a no-password boot into a shell isn't an attractive option. I don't think. And rsh-based solutions are unattractive because they would require the appliance to have a preinstalled login account, with pre-installed credentials (and we all know how THAT goes).

Upvotes: 0

Views: 490

Answers (1)

Antonio Petricca
Antonio Petricca

Reputation: 11040

I solved the same issue by creating a C++ daemon, running as root, and listening ONLY on local host TCP port, in charge to shutdown the system when contacted by the web service.

Edit: Use https://man7.org/linux/man-pages/man2/reboot.2.html to shutdown the OS.

Upvotes: 1

Related Questions