DockerWrapper.wrap(): run as config.runtime.uid instead of root

This commit is contained in:
InsanePrawn 2022-08-27 05:55:19 +02:00
parent a13fdc70e1
commit ba13293b93
5 changed files with 50 additions and 5 deletions

View file

@ -2,11 +2,11 @@ FROM archlinux:base-devel
RUN pacman-key --init && \
pacman -Sy --noconfirm archlinux-keyring && \
pacman -Su --noconfirm \
pacman -Su --noconfirm --needed \
python python-pip \
arch-install-scripts rsync \
aarch64-linux-gnu-gcc aarch64-linux-gnu-binutils aarch64-linux-gnu-glibc aarch64-linux-gnu-linux-api-headers \
git \
git sudo \
android-tools openssh inetutils \
parted
@ -32,5 +32,7 @@ RUN pip install -r requirements.txt
COPY . .
RUN python -c "from distro import distro; distro.get_kupfer_local(arch=None,in_chroot=False).repos_config_snippet()" | tee -a /etc/pacman.conf
RUN useradd -m -g users kupfer
RUN echo "kupfer ALL=(ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/kupfer
WORKDIR /

1
local/bin/wrapper_su_helper Symbolic link
View file

@ -0,0 +1 @@
../../wrapper_su_helper.py

View file

@ -62,10 +62,13 @@ class DockerWrapper(BaseWrapper):
wrapped_config = self.generate_wrapper_config()
target_user = 'root' if config.runtime.uid == 0 else 'kupfer'
target_home = '/root' if target_user == 'root' else f'/home/{target_user}'
ssh_dir = os.path.join(pathlib.Path.home(), '.ssh')
if not os.path.exists(ssh_dir):
os.makedirs(ssh_dir, mode=0o700)
volumes = self.get_bind_mounts_default(wrapped_config)
volumes = self.get_bind_mounts_default(wrapped_config, ssh_dir=ssh_dir, target_home=target_home)
volumes |= dict({config.get_path(vol_name): vol_dest for vol_name, vol_dest in DOCKER_PATHS.items()})
docker_cmd = [
'docker',
@ -78,7 +81,9 @@ class DockerWrapper(BaseWrapper):
'--privileged',
] + docker_volumes_args(volumes) + [tag]
kupfer_cmd = ['kupferbootstrap', '--config', '/root/.config/kupfer/kupferbootstrap.toml'] + self.filter_args_wrapper(sys.argv[1:])
kupfer_cmd = ['kupferbootstrap', '--config', volumes[wrapped_config]] + self.filter_args_wrapper(sys.argv[1:])
if config.runtime.uid:
kupfer_cmd = ['wrapper_su_helper', '--uid', str(config.runtime.uid), '--username', 'kupfer', '--'] + kupfer_cmd
cmd = docker_cmd + kupfer_cmd
logging.debug('Wrapping in docker:' + repr(cmd))

View file

@ -27,7 +27,7 @@ class Wrapper(Protocol):
class BaseWrapper(Wrapper):
id: str
uuid: str
identifier: str
type: str
wrapped_config_path: str

37
wrapper_su_helper.py Executable file
View file

@ -0,0 +1,37 @@
#!/bin/python3
import click
import os
import pwd
from logger import logging, setup_logging
from exec.cmd import run_cmd
from exec.file import chown
@click.command('kupferbootstrap_su')
@click.option('--username', default='kupfer', help="The user's name. If --uid is provided, the user's uid will be changed to this in passwd")
@click.option('--uid', default=1000, type=int, help='uid to change $username to and run as')
@click.argument('cmd', type=str, nargs=-1)
def kupferbootstrap_su(cmd: list[str], uid: int = 1000, username: str = 'kupfer'):
"Changes `username`'s uid to `uid` and executes kupferbootstrap as that user"
cmd = list(cmd)
user = pwd.getpwnam(username)
home = user.pw_dir
if uid != user.pw_uid:
run_cmd(['usermod', '-u', str(uid), username]).check_returncode() # type: ignore[union-attr]
chown(home, username, recursive=False)
env = os.environ | {
'HOME': home,
'USER': username,
}
logging.debug(f'wrapper: running {cmd} as {repr(username)}')
result = run_cmd(cmd, attach_tty=True, switch_user=username, env=env)
assert isinstance(result, int)
exit(result)
if __name__ == '__main__':
setup_logging(True)
kupferbootstrap_su(prog_name='kupferbootstrap_su_helper')