NEET
NEET

Reputation: 61

systemd for NodeJS permission issue

My NodeJS's app app.js is a socket.io server, the code shown as below.
If it get event shutdown, and I want the computer shutting down.

var path = require('path')
var express = require('express')
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function (req, res) {
    app.use(express.static(path.resolve('..', 'pages')));
    res.sendFile(path.resolve('..', 'pages/index.html'));
});

io.on('connection', function (socket) {
    console.log('a user connected');

    socket.on('disconnect', function () {
        console.log('user disconnected');
    });

    socket.on('shutdown', function () {
        require('child_process').exec('/sbin/shutdown -h now', console.log);
    });
});

http.listen(3000, function () {
    console.log('listening on http://localhost:3000');
});

I've let my user get the permission by visudo

ubuntu ALL=NOPASSWD:/sbin/shutdown

It works as expected that I run it manually.

But it doesn't work that run by systemd, it will occur permission denied error.

Here is my systemd service file:

[Unit]
Description=app.js
After=network.target

[Service]
Type=idle
User=ubuntu
ExecStart=/home/ubuntu/.nvm/versions/node/v12.18.3/bin/node /home/ubuntu/myapp/app.js
Restart=on-failure
WorkingDirectory=/home/ubuntu/myapp

[Install]
WantedBy=multi-user.target

What's the different between systemd and run on terminal by myself?

It works with User=root, but I think it does not a good idea.

Upvotes: 0

Views: 674

Answers (1)

Jürgen Hötzel
Jürgen Hötzel

Reputation: 19747

From the path I can deduce that you use ubuntu. This distribution seems to change the default config of sudo:

https://serverfault.com/questions/111064/sudoers-how-to-disable-requiretty-per-user

Since your unit system does not configure

StandardInput and Standardoutput to a terminal.

sudo will fail.

You must use the sudo Configuration !requiretty for the service to work (man sudoers):

 requiretty        If set, sudo will only run when the user is logged in to a real tty.  When this flag is set, sudo can only be run from a login session and not via other means such as cron(8) or cgi-bin scripts.  This flag is
                   off by default.

Upvotes: 1

Related Questions