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

WIP: Enable non-root users to use the geodesic shell #710

Closed
wants to merge 4 commits into from

Conversation

sboardwell
Copy link

@sboardwell sboardwell commented May 26, 2021

Work In Progress

This is part of a larger push to help create a geodesic non-root user with which to run the geodesic.

  • This can be seen as the initial PoC since there are, without doubt, other areas which still need adjustment. e.g.
    • The central use /conf directory would need to be looked at
    • The alpine distribution would need to include the sudo package.

what

  • add a _root_detection function to enable a conditional sudo prefix for non-root users
  • ensure /etc/profile.dprompt:kube-ps1.sh is readable by non-root users

POC - Testing purposes only

Place the following Dockerfile.non-root-example in the PR's root directory.

The Dockerfile adds the geodesic user. See NOTE: sections for explanations and context.

Dockerfile.non-root-example
# NOTE: using 0.142.0 in this example since the naming convention for EKS clusters changed after this.
ARG VERSION=0.142.0
ARG OS=debian
FROM cloudposse/geodesic:$VERSION-$OS

ENV BANNER="non-root"

# NOTE: TEMPORARY
# - install docker for tests later
RUN export DOCKER_VERSION="20.10.5" && \
    export DOCKER_SHA256SUM="3f18edc66e1faae607d428349e77f9800bdea554528521f0f6c49fc3f1de6abf" && \
    echo "Installing Docker ${DOCKER_VERSION}..." && \
    curl -SsL -o "docker-${DOCKER_VERSION}.tgz" "https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz" && \
    echo "Verifying docker-${DOCKER_VERSION}.tgz checksum..." && \
    sha256sum "docker-${DOCKER_VERSION}.tgz" && \
    echo "${DOCKER_SHA256SUM} *docker-${DOCKER_VERSION}.tgz" | sha256sum -c - && \
    tar -xzC /usr/local/bin --strip-components=1 -f "docker-${DOCKER_VERSION}.tgz" && \
    rm -f "docker-${DOCKER_VERSION}.tgz"

# NOTE: TEMPORARY
# - adding _root_detection to the necesary files
# - make "/etc/profile.d/prompt:kube_ps1.sh"
# - mentioned in https://github.com/cloudposse/geodesic/pull/710
COPY rootfs/etc/profile.d/_preferences.sh /etc/profile.d/_preferences.sh
COPY rootfs/etc/profile.d/syslog-ng.sh /etc/profile.d/syslog-ng.sh
RUN chmod -R a+r /etc/profile.d/

# NOTE: TEMPORARY
# - installing as root means the bin directories are not readable by mere mortals
# - mentioned in https://github.com/cloudposse/packages/pull/1320
RUN find /usr/share/ -maxdepth 3 -type d -name bin | xargs sudo chmod a+rX

# NOTE: Add geodesic user to replace root usage
# - uses https://github.com/boxboat/fixuid
# - this needs to be integrated in the geodesic image
# - UID/GID = 1001
#   - is simply for testing alternate UID's since my own UID already 1000
#   - ideally the UID/GID would be 1000 and things would work automatically for most users.
# For debian / ubuntu
ARG GEODESIC_UID=1001
ARG GEODESIC_GID=1001
RUN USER=geodesic && \
    GROUP=geodesic && \
    [ $(getent group docker) ] || addgroup --gid 999 docker && \
    addgroup --gid ${GEODESIC_GID} $GROUP && \
    adduser --uid ${GEODESIC_UID} --ingroup $GROUP --home /home/$USER --shell /bin/bash --disabled-password --gecos "Geodesic User" $USER && \
    usermod $USER -G sudo,docker && \
    echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
    id $USER && \
    curl -SsL https://github.com/boxboat/fixuid/releases/download/v0.5/fixuid-0.5-linux-amd64.tar.gz | tar -C /usr/local/bin -xzf - && \
    chown root:root /usr/local/bin/fixuid && \
    chmod 4755 /usr/local/bin/fixuid && \
    mkdir -p /etc/fixuid && \
    printf "user: $USER\ngroup: $GROUP\n" > /etc/fixuid/config.yml

# NOTE: TEMPORARY
# - this should not be needed after
#   - the above is integrated into the geodesic shell
#   - the new HOME would point to /home/geodesic instead of /conf
# copy /conf to the geodesic users new home
RUN cp -r /conf/.[^.]* /home/geodesic && \
    chown -R geodesic:geodesic /home/geodesic

# NOTE: become the geodesic user
ENV HOME="/home/geodesic"
USER geodesic
WORKDIR /home/geodesic
ENV KUBECONFIG="/home/geodesic/.kube/config"

ENTRYPOINT ["fixuid", "-q", "/bin/bash"]

# custom envs which are not part of the main geodesic shell
ENV NAMESPACE="nbo"
ENV AWS_PROFILE="nbo-identity"
ENV AWS_REGION="us-east-2"
ENV AWS_DEFAULT_REGION="us-east-2"

Minimal steps to test:

# set initial variables
{
	TEST_IMAGE=cloudposse/non-root
	INSTALL_PREFIX=
	[ -z "${GEODESIC_INSTALL_PATH:-}" ] || INSTALL_PREFIX="INSTALL_PATH=${GEODESIC_INSTALL_PATH}"
}

# create initial geodesic init script with
{
    docker run --rm cloudposse/geodesic:latest init | $INSTALL_PREFIX bash
}

# print the geodesic binary
{
    command -v geodesic
}

# build custom image
{
    docker build -t cloudposse/non-root -f Dockerfile.non-root-example .
}

# enter shell with...
{
    WITH_DOCKER=true GEODESIC_IMAGE=cloudposse/non-root GEODESIC_DOCKER_EXTRA_ARGS="-u $(id -u):$(id -g) --group-add sudo --group-add docker" geodesic
}

# Finally, in the new shell
# - use the normal 'assume-role', 'set-cluster', etc
# - touch a new file in the /localhost - check that the permissions are correct, etc

@sboardwell sboardwell requested a review from a team as a code owner May 26, 2021 07:21
@nitrocode nitrocode dismissed a stale review via 0297dd9 June 18, 2021 16:05
@nitrocode
Copy link
Member

nitrocode commented Jun 18, 2021

Hi @sboardwell. Thank you for contributing.

This is an issue that plagues me so much that I do not create files from the container on to my /localhost. I do like the option of creating a non root user that uses the same uid and gid as my host user. This would allow me to run specific commands from geodesic that alter my host machine's file system without having to sudo chown -R $(id -u):$(id -g) somedir.

After reviewing the PR code, merging the changes in the Dockerfile example in your PR with my local setup, with the build args --build-arg GEODESIC_GID=$(id -g) --build-arg GEODESIC_UID=$(id -u), I can say that I'm comfortably in my container as the geodesic user and using the host user and group ids.

testing in shell
. [none] / ⨠ whoami
geodesic
 ✗ . [none] / ⨠ id
uid=1000(geodesic) gid=1000(geodesic) groups=1000(geodesic),27(sudo),999(docker)
 ✗ . [none] / ⨠ ls -la | grep localhost
drwxr-xr-x 111 geodesic geodesic 4096 Jun 18 16:06 localhost
 ✗ . [none] / ⨠ touch /localhost/files
 ✗ . [none] / ⨠ rm /localhost/files
 ✗ . [none] / ⨠ sudo apt update
Hit:1 http://security.debian.org/debian-security buster/updates InRelease
Hit:2 https://packages.cloud.google.com/apt cloud-sdk InRelease              
Get:3 https://dl.cloudsmith.io/public/cloudposse/packages/deb/debian buster InRelease [4938 B]
Hit:4 http://deb.debian.org/debian buster InRelease      
Hit:5 http://deb.debian.org/debian buster-updates InRelease
Fetched 4938 B in 1s (5689 B/s)
Reading package lists... Done
Building dependency tree       
Reading state information... Done
14 packages can be upgraded. Run 'apt list --upgradable' to see them.
 ✗ . [none] / ⨠ sudo apt install aws-vault
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  aws-vault
0 upgraded, 1 newly installed, 0 to remove and 14 not upgraded.
Need to get 7023 kB of archives.
After this operation, 15.3 MB of additional disk space will be used.
Get:1 https://dl.cloudsmith.io/public/cloudposse/packages/deb/debian buster/main amd64 aws-vault amd64 6.3.1-1 [7023 kB]
Fetched 7023 kB in 3s (2704 kB/s)    
Selecting previously unselected package aws-vault.
(Reading database ... 54459 files and directories currently installed.)
Preparing to unpack .../aws-vault_6.3.1-1_amd64.deb ...
Unpacking aws-vault (6.3.1-1) ...
Setting up aws-vault (6.3.1-1) ...
 ✗ . [none] / ⨠ which aws-vault
/usr/bin/aws-vault

I tried running _root_detection from my shell and it wasn't working properly so I committed a small change.

Anyone using this method would have to prefix their run commands with sudo for any root level perms so to simplify, if your changes were added as is, you can simply USER root before the installs and then USER geodesic at the end.

@Nuru how do you feel about these changes ? Could you give it a second review ?

I'm also partial to adding a Dockerfile.non-root to give consumers the option. We can also try this out locally for a bit and if it works well, we can use it as the default in the future.

@sboardwell
Copy link
Author

Hi @nitrocode

thanks for the feedback and testing. I would, personally, be okay with prefixing my own commands with sudo since it makes it a conscious decision.

Not having root detection tends to lead to people running entire scripts as sudo which can lead to similar problems (node caches owned by root, etc).

Easy either way I guess, although I prefer the transparency and conscious decision making when using SUDO_CMD.

@sboardwell
Copy link
Author

sboardwell commented Jun 18, 2021

I see your point now with the RUN commands in the Dockerfile and, yes, this would work as well.

I thought you were talking all the /etc/profile.d/... stuff as root.

@nitrocode
Copy link
Member

nitrocode commented Jun 18, 2021

Yes, it's probably better to be explicit.

Here's another issue I came across. We use update-alternatives to install specific versions of terraform and the method we currently use

# as root in Dockerfile
$ update-alternatives --set terraform /usr/share/terraform/{version}/bin/terraform

# as geodesic in container
$ ls -la /usr/share/terraform/1/bin/
ls: cannot open directory '/usr/share/terraform/1/bin/': Permission denied

Installs it as root without any read permissions. We'll have to find a way around that. Perhaps by setting an alternative non-root user directory.

@sboardwell
Copy link
Author

Check my other PR in the packages repo wrt the read-only root permissions . I thought it was only in the download area.

@Nuru
Copy link
Sponsor Contributor

Nuru commented Jun 19, 2021

@sboardwell @nitrocode I think we should not risk all the issues that come from running as non-root inside Geodesic. In particular, once of the great advantages of Geodesic is that it works the same for everyone, so we do not get these "works in my environment" problems, and having some people running as root and some running as non-root seems like it will kill that off.

I took a fresh look at this today and think we can solve the underlying issue of file ownership using BindFS without otherwise altering Geodesic. That seems a better path to me. Are you willing to give that a try?

@sboardwell
Copy link
Author

@Nuru - please try. If it works, all the better.

@Nuru Nuru added do not merge Do not merge this PR, doing so would cause problems wip Work in Progress: Not ready for final review or merge labels Jul 8, 2021
leb4r pushed a commit that referenced this pull request Jan 25, 2022
@Nuru Nuru added the wontfix This will not be worked on label Feb 15, 2022
@Nuru
Copy link
Sponsor Contributor

Nuru commented Feb 15, 2022

Closing this in favor of #771

@Nuru Nuru closed this Feb 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do not merge Do not merge this PR, doing so would cause problems wip Work in Progress: Not ready for final review or merge wontfix This will not be worked on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants