0

I'm working on a technically breakthrough for a web interface (php) to process audio files with a separation module (spleeter https://github.com/deezer/spleeter).

My demo app didn't work. See below. After useful feedback(thx @cas @marcus-müller), I know that I won't achieve my goal with it.

What I actually want to achieve is to execute the `spleeter` command in php

On the terminal as root it works

root@myServer:/var/www/html# spleeter separate -p spleeter:2stems -o output audio_example.mp3
INFO:spleeter:File output/audio_example/vocals.wav written succesfully
INFO:spleeter:File output/audio_example/accompaniment.wav written succesfully

In php no result

exec("spleeter separate -p spleeter:2stems -o output audio_example.mp3");

If I execute this command to test as www-data user I got following errors:

root@j344977:/var/www/html# sudo -u www-data spleeter separate -p spleeter:2stems -o output audio_example.mp3
Traceback (most recent call last):
  File "/usr/local/bin/spleeter", line 8, in <module>
    sys.exit(entrypoint())
  File "/usr/local/lib/python3.6/dist-packages/spleeter/__main__.py", line 256, in entrypoint
    spleeter()
  File "/usr/local/lib/python3.6/dist-packages/typer/main.py", line 214, in __call__
    return get_command(self)(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.6/dist-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/typer/main.py", line 497, in wrapper
    return callback(**use_params)  # type: ignore
  File "/usr/local/lib/python3.6/dist-packages/spleeter/__main__.py", line 114, in separate
    from .separator import Separator
  File "/usr/local/lib/python3.6/dist-packages/spleeter/separator.py", line 27, in <module>
    from librosa.core import istft, stft
  File "/usr/local/lib/python3.6/dist-packages/librosa/__init__.py", line 211, in <module>
    from . import core
  File "/usr/local/lib/python3.6/dist-packages/librosa/core/__init__.py", line 5, in <module>
    from .convert import *  # pylint: disable=wildcard-import
  File "/usr/local/lib/python3.6/dist-packages/librosa/core/convert.py", line 7, in <module>
    from . import notation
  File "/usr/local/lib/python3.6/dist-packages/librosa/core/notation.py", line 8, in <module>
    from ..util.exceptions import ParameterError
  File "/usr/local/lib/python3.6/dist-packages/librosa/util/__init__.py", line 83, in <module>
    from .utils import *  # pylint: disable=wildcard-import
  File "/usr/local/lib/python3.6/dist-packages/librosa/util/utils.py", line 1848, in <module>
    def __shear_dense(X, factor=+1, axis=-1):
  File "/usr/local/lib/python3.6/dist-packages/numba/core/decorators.py", line 214, in wrapper
    disp.enable_caching()
  File "/usr/local/lib/python3.6/dist-packages/numba/core/dispatcher.py", line 812, in enable_caching
    self._cache = FunctionCache(self.py_func)
  File "/usr/local/lib/python3.6/dist-packages/numba/core/caching.py", line 610, in __init__
    self._impl = self._impl_class(py_func)
  File "/usr/local/lib/python3.6/dist-packages/numba/core/caching.py", line 348, in __init__
    "for file %r" % (qualname, source_path))
RuntimeError: cannot cache function '__shear_dense': no locator available for file '/usr/local/lib/python3.6/dist-packages/librosa/util/utils.py'

Is there a simple solution for this problem?

Configuration for my demo app

As root I can execute the command:

root@myServer:/var/www/html# ./spleetercommand.sh

As www-data no luck:

root@myServer:/var/www/html# sudo -u www-data ./spleetercommand.sh

Here is my setup:

/var/www/html/spleetercommand.sh

#!/bin/bash

echo "--- Start spleeter ---"

/usr/local/bin/spleeter separate -p spleeter:2stems -o /var/www/html/output /var/www/html/audio_example.mp3

echo "--- End spleeter ---"

?>

/var/www/html/command.php

<?php

echo "get_current_user(): " . get_current_user();
echo "whoami: " . (exec("whoami"));
echo (exec("/var/www/html/spleetercommand.sh"));

?>

Browser output command.php

get_current_user(): root
whoami: www-data
--- End spleeter ---

/etc/sudoers


#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

/etc/sudoers.d/spleeter

www-data All=NOPASSWD: /var/www/html/spleetercommand.sh

sudoers parse test

root@myServer:/etc/sudoers.d# sudo visudo -c  
/etc/sudoers: parsed OK
/etc/sudoers.d/spleeter: parsed OK

(Ubuntu 18, Apache, PHP7)

HaKa
  • 11
  • 1
  • Anything speaking against the SETUID bit for your script? Also what are permissions and ownership of the script? Also your php-exec has no sudo in it. Why would you want to execute as root in the first place? – FelixJN Jul 14 '21 at 19:14
  • 2
    @FelixJN `setuid` [does not work on scripts](https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts) – Panki Jul 14 '21 at 20:03
  • @Archemar Yes, it was a typo (copy/paste-error) – HaKa Jul 14 '21 at 20:21
  • *I'm working on a technically breakthrough* um, by using someone else's technical knowledge, years of ML research and experience, and knowledge to run infrastructure at scale, with a PHP website? I like your ambition, but I think you might be overselling a bit :) – Marcus Müller Jul 14 '21 at 23:39
  • 3
    why not just make `/var/www/html/output` writable by user `www-data`? something like this should not need to run as root. – cas Jul 15 '21 at 02:44
  • @MarcusMüller I wasn't my intention. Maybe "Technischer Durchstich" is a better wording :) – HaKa Jul 15 '21 at 08:40
  • @cas I tried. But unfortunately no success... – HaKa Jul 15 '21 at 08:43
  • That (can't write to /var/www/html/output) is the problem you need to solve, not compromise security with unnecessary use of sudo. So, yes, as you suspected in a comment, you *do* have an [XY problem](http://xyproblem.info/). sudo is not the answer, sudo is a distraction. – cas Jul 15 '21 at 12:17
  • If the reason it runs as root and fails as non-root is a Python library import problem, then I suggest: 1. use a virtualenv in which you install everything required for the tool, 2. write a wrapper script which activates the virtualenv and calls the tool, 3. run the wrapper script as a user who can write to the output directory. – muru Jul 16 '21 at 09:06

2 Answers2

2

There's literally no reason an ML model/classifier needs to run as root. You need to fix that problem, instead of trying to become root. Really.

Marcus Müller
  • 21,602
  • 2
  • 39
  • 54
  • I think I have a [XY-problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) :) Can you give me a hint to solve the problem? Should I change the permissions of `/usr/local/bin/spleeter` to `www-data`? – HaKa Jul 15 '21 at 08:09
  • 1
    I can't tell you why **you** have been running something as root. I assume you have a reason. If that's not the case, what about *simply not doing that*? – Marcus Müller Jul 15 '21 at 11:22
0

I would rather put /usr/local/bin/spleeter under sudo

in /etc/sudoers.d/spleeter

 www-data All=NOPASSWD: /usr/local/bin/spleeter separate -p spleeter:2stems -o /var/www/html/output /var/www/html/*.mp3
  • one must use full command line in sudo.

and in /var/www/html/spleetercommand.sh, insert sudo -u www-data

Archemar
  • 31,183
  • 18
  • 69
  • 104
  • I changed following configs but no effects: **/etc/sudoers.d/spleeter** `www-data All=NOPASSWD: /usr/local/bin/spleeter` **spleetercommand.sh** `sudo -u www-data /usr/local/bin/spleeter separate -p spleeter:2stems -o /var/www/html/output /var/www/html/audio_example.mp3` @Archemar Is there more to do? – HaKa Jul 14 '21 at 20:19
  • I changed **/etc/sudoers.d/spleeter** to `www-data All=NOPASSWD: /usr/local/bin/spleeter separate -p spleeter:2stems -o /var/www/html/output /var/www/html/*.mp3`. Now I'm getting parse error: `>>> /etc/sudoers.d/spleeter: syntax error near line 1 <<< sudo: parse error in /etc/sudoers.d/spleeter near line 1 sudo: no valid sudoers sources found, quitting sudo: unable to initialize policy plugin` – HaKa Jul 14 '21 at 20:38
  • well duno, maybe replace `*.mp3` by `*` (see my previous answer: https://unix.stackexchange.com/questions/395776/how-to-remote-execute-ssh-command-a-sudo-command-without-password/395781#395781 ) – Archemar Jul 14 '21 at 20:45
  • I changed to `*`and also to `audio_example.mp3`. Didn't help. I'm using this command to edit `visudo -f /etc/sudoers.d/spleeter` – HaKa Jul 14 '21 at 21:01