Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonroot #40

Closed
wants to merge 5 commits into from
Closed

Nonroot #40

wants to merge 5 commits into from

Conversation

behrmann
Copy link
Contributor

@behrmann behrmann commented Oct 26, 2018

Hi,

thanks a lot for this spawner, here are a couple of additions I made this week and that I'd like to share.

I wasn't too happy to have the jupyterhub run as root, so this adds a spawner that relies on service files that are installed on the system. This obviates the need for most of the config that SystemdSpawner has, since those options move to the service file.

The jupyterhub service runs as system user jupyter (or whatever you configure) and can either start the user instances via sudo, which needs a rule along the lines of

Cmnd_Alias JUPYTERSTART = /usr/bin/systemctl start jupyter-singleuser@[[\:alpha\:]]?[[\:alnum\:]]*.service
Cmnd_Alias JUPYTERSTOP = /usr/bin/systemctl stop jupyter-singleuser@[[\:alpha\:]]?[[\:alnum\:]]*.service
Cmnd_Alias JUPYTERRESET = /usr/bin/systemctl reset-failed jupyter-singleuser@[[\:alpha\:]]?[[\:alnum\:]]*.service
Defaults!JUPTERSTART !requiretty
Defaults!JUPTERSTOP !requiretty
Defaults!JUPTERRESET !requiretty
jupyter HOST = (root) NOPASSWD: JUPYTERSTART
jupyter HOST = (root) NOPASSWD: JUPYTERSTOP
jupyter HOST = (root) NOPASSWD: JUPYTERRESET

or plain systemctl using a policykit rule that could look like this

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units") {
        if (action.lookup("unit").match(/^jupyter-singleuser@[a-zA-Z]?\w*.service$/)) {
            var verb = action.lookup("verb");
            if ((verb == "start" || 
                 verb == "stop" || 
                 verb == "reset-failed") && 
                subject.user == "jupyter") {
                return polkit.Result.YES;
            }
        }
    }
});

I have tested both cases, but the latter requires a policykit version of 106 or later and Debian (and its derivatives like Ubuntu) only ship a heavily patched policykit 105 and require the sudo way. The sudo way also precludes the use of NoNewPriviliges for the jupyterhub service.

To get the arguments from the jupyterhub server to the single user instances, I use an environment file. Since it contains sensitive information and therefore cannot be world readable, I use ACLs to make it readable for the user of the instance, since only root can chown.

So far I've tested this on Debian Sid (unstable), were it works fine, but it lacks documentation and is still geared towards my use case.

So, what needs to be done to get this upstreamed (if there is interested from your side)? :)

@behrmann
Copy link
Contributor Author

I just updated a couple of small issues and a bug, when stopping user servers, that I just noticed today.

It would be wonderful if I could get some feedback on whether and if so how, this could be merged. Thanks in advance!

@yuvipanda yuvipanda self-requested a review January 9, 2019 17:51
@behrmann
Copy link
Contributor Author

behrmann commented May 8, 2019

I just rebased on the current master and cleaned this up a little.

@behrmann
Copy link
Contributor Author

behrmann commented Aug 1, 2019

I recently got around to also testing on a reasonable version of policykit and updated this accordingly and also added some documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant