jupyterhub / sudospawner

Spawn JupyterHub single-user servers with sudo
BSD 3-Clause "New" or "Revised" License
50 stars 41 forks source link

'Add User' not working for admin users with JupyterHub run using PAMAuthentication and SudoSpawner #58

Open kipstakkr opened 5 years ago

kipstakkr commented 5 years ago

I've configured Jupyterhub with SudoSpawner (which runs as a non-root user) and I'm able to run it without any trouble. But when I logged in with the user rhea (as provided in the example) with admin permissions set, I'm not able to add users in the system. I'm getting the following error:

[E 2019-07-24 08:26:56.638 JupyterHub users:94] Failed to create user: newuser Traceback (most recent call last): File "/opt/conda/lib/python3.6/site-packages/jupyterhub/apihandlers/users.py", line 92, in post await maybe_future(self.authenticator.add_user(user)) File "/opt/conda/lib/python3.6/site-packages/jupyterhub/auth.py", line 711, in add_user await maybe_future(self.add_system_user(user)) File "/opt/conda/lib/python3.6/site-packages/jupyterhub/auth.py", line 771, in add_system_user raise RuntimeError("Failed to create system user %s: %s" % (name, err)) RuntimeError: Failed to create system user newuser: adduser: Only root may add a user or group to the system.

I'm guessing it is caused by running JupyterHub as a non-root user and also using PAM Authentication which eventually uses the system users. The only limitation for my project is I must not run JupyterHub as a root user. Is there a way to add users using sudospawner with a different authenticator, else Is there a way to give restricted sudo permission for the user rhea to be able to add users to the system?? @minrk @willingc @yuvipanda

guobingzhou commented 3 years ago

I have the same question,have you solved it ?

QuantumEntangledAndy commented 3 years ago

So I thought I would comment since I have a way to do this:

The issue is that you don't have root anymore so that the adduser command fails.

The local authenticators usually allow you to set an add_user_cmd field:

(Change NameOfAuthenticator to the name of your authentication plugin)

c.NameOfAuthenticator.add_user_cmd = [
    "a_command",
    "an_arg",
    "annother_arg",
]

Which is the command that is passed the username to add to.

You can change it to something like this:

c.NameOfAuthenticator.add_user_cmd = [
    "/usr/bin/sudo",
    "/useradder.sh",
]

Where /useradder.sh is the command that will create and hopefully validate the user.

#! /bin/bash
username="${1}"

# Only except names with 0-9 a-z A-Z and a -
if ! [[ "${username}" =~ ^[0-9a-zA-Z-]+$ ]]; then
  echo "Invalid username" >&2
  exit 1
fi

home="/home/${username}"

# Check if home exists and error if it does
if [ -e "${home}" ]; then
    exit 1
fi

options=(
  "--home-dir=${home}"
  "--create-home"
  "--shell=/bin/bash"
  "--password='!'"
  "${username}"
)

useradd "${options[@]}"

You should ensure this /useradder.sh is tightly controlled on who can read or edit it.

chown root:root /useradder.sh
chmod 700 /useradder.sh

Finally we need a sudoers entry that will allow this user to run the command without password

Mine is in /etc/sudoers.d/hubsudoer with these contents. Change TheUserHubRunsAs to the user that run the hub

Cmnd_Alias JUPYTER_USERADD = /useradder.sh *
TheUserHubRunsAs ALL=(root) NOPASSWD:JUPYTER_USERADD

Which should get it working for you