correct method to create user in alpine docker container so that sudo works correctly - linux

When attempting to execute sudo in a docker container using alpine 3.8 I get the following output.
I am logged into the container using docker exec -i -t MYIMAGE /bin/bash
bash-4.4$ whoami
payara
bash-4.4$ sudo -s
bash-4.4$ whoami
payara
bash-4.4$ su root
su: incorrect password
bash-4.4$
My docker file contains the following user related commands to try and setup a user specifically for payara. I want sudo to work correctly though, if possible.
DockerFile
FROM "alpine:latest"
ENV LANG C.UTF-8
ENV http_proxy 'http://u:p#160.48.234.129:80'
ENV https_proxy 'http://u:p#160.48.234.129:80'
RUN apk add --no-cache bash gawk sed grep bc coreutils git openssh-client libarchive libarchive-tools busybox-suid sudo
RUN addgroup -S payara && adduser -S -G payara payara
RUN echo "payara ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# CHANGE TO PAYARA USER
USER payara
... rest of setup.

From man sudo:
-s, --shell
Run the shell specified by the SHELL environment variable if it is set or the shell specified by the invoking user's password database entry.
You have neither SHELL variable set, nor correct (interactive) default shell set in /etc/passwd for user payara. This is because you are creating a system user (-S) - this user has a default shell /bin/false (which just exits with exit code 1 - you may check with echo $? after unsuccessfull sudo -s).
You may overcome this in different ways:
a) specify the SHELL variable:
bash-4.4$ SHELL=/bin/bash sudo -s
bed662af470d:~#
b) use su, which will use the default root's shell:
bash-4.4$ sudo su -
bed662af470d:~#
c) just run the required privileged commands with sudo directly, without spawning an interactive shell.

Related

Using SSH inside docker with correct file permissions?

There are a few posts on how to use Docker + SSH. There are also posts on how to edit files mounted in a docker container, such that editing them won't cause the permissions to become root.
I'm trying to combine the 2 things, so I can SSH into a docker container and edit files without messing up their permissions.
For, using the correct file permissions, I use:
- /etc/passwd:/etc/passwd:ro
- /etc/group:/etc/group:ro
in my docker-compose.yml and
docker compose -f commands/dev/docker-compose.yml run \
--service-ports \
--user $(id -u) \
develop \
bash
so that when I start the docker container, my user is the same user as my local computer.
However, this breaks up my SSH setup inside the Docker container:
useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo ubuntu
echo 'ubuntu:ubuntu' | chpasswd
# passwd -d ubuntu
apt install -y --no-install-recommends openssh-server vim-tiny sudo
# See: https://stackoverflow.com/questions/22886470/start-sshd-automatically-with-docker-container
sed 's#session\s*required\s*pam_loginuid.so#session optional pam_loginuid.so#g' -i /etc/pam.d/sshd
mkdir /var/run/sshd
bash -c 'install -m755 <(printf "#!/bin/sh\nexit 0") /usr/sbin/policy-rc.d'
ex +'%s/^#\zeListenAddress/\1/g' -scwq /etc/ssh/sshd_config
ex +'%s/^#\zeHostKey .*ssh_host_.*_key/\1/g' -scwq /etc/ssh/sshd_config
RUNLEVEL=1 dpkg-reconfigure openssh-server
ssh-keygen -A -v
update-rc.d ssh defaults
# Configure sudo
ex +"%s/^%sudo.*$/%sudo ALL=(ALL:ALL) NOPASSWD:ALL/g" -scwq! /etc/sudoers
Here I'm creating a user called ubuntu with password ubuntu for SSH-ing. This lets me SSH in ubuntu#localhost using the password ubuntu.
The issue is that by mounting the /etc/passwd file into my container, I erase the ubuntu user inside the container. This means when I try to ssh in with ssh -p 9002 ubuntu#localhost, the authentication fails (9002 is what I bind port 22 in the container to on the host).
Does anyone have a solution?
Here's a first pass answer.
I can use:
useradd -rm -d /home/yourusername -s /bin/bash -g root -G sudo yourusername
instead of
useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo ubuntu
echo 'ubuntu:ubuntu' | chpasswd
then, I:
Run the ssh server in the container with:
su root
/usr/sbin/sshd -D -o ListenAddress=0.0.0.0 -o PermitRootLogin=yes
I can ssh into the container as root (using the root password "root", which I set with RUN echo 'root:root' | chpasswd in the Dockerfile).
Then, I can do su yourusername, to switch my user.
While this works, it is pretty annoying since I need to bake the user name into the Docker container.

Unable to run command chsh -s /bin/bash ${USERNAME}

I have a docker file where I have customized image myimage derived from some-debian-image (which derived from debian upstream.)
FROM some-debian-image myimge
USERNAME root:root
...........................
RUN chsh -s /bin/bash ${USERNAME}
docker build fails saying :
Password: chsh: PAM: Authentication failure
However, it does not fail with upstream
FROM bebain:bullseye myimage
USERNAME root:root
...........................
RUN chsh -s /bin/bash ${USERNAME}
Developers who have build the some-debian-image have done something add on with /etc/passwd , and it is having content
root:x:0:0:root:/root:/usr/sbin/nologin
May I please know how to successfully run this command :
RUN chsh -s /bin/bash ${USERNAME}
I am comparing docker images setup where it is working and where it is not working , and I found that:
The setup where the above command RUN chsh -s /bin/bash ${USERNAME} is working sudo su can be expected without any password
$ sudo su
#
In contrast in setup where I am facing issue ask for password when run the command sudo su
May I pleas know what changes I should do so that sudo su shall not ask for password?

Why does a Github Action on a Linux self-hosted runner require a user swap for every command if you dont want to run on root

I'm wrote a workflow to install some tool dependencies on a Linux self-hosted GitHub runner VM. I'm using homebrew to do the tool installs. Using homebrew requires that it not be run on the root user which is what the GitHub Runner logs in as. I'm wondering why when I create a step that switches the user from root to my test user things break but when I sudo to that user in every step things work fine, I think I explained this poorly so see below:
Failing Workflow (you can see the first step switches the user to testUser):
installHomebrew:
name: Install Homebrew
runs-on: [self-hosted]
steps:
- name: Switch to etpAdmin user
run: sudo -u testUser -i
- name: Install Homebrew silently
run: sudo apt install linuxbrew-wrapper -y
- name: Run brew for the first time to create the .linuxbrew directory
run: brew -h
This will fail on the last step claiming homebrew shouldn't be run on root while the following workflow works just fine.
installHomebrew:
name: Install Homebrew
runs-on: [self-hosted]
steps:
- name: Install Homebrew silently
run: sudo apt install linuxbrew-wrapper -y
- name: Run brew for the first time to create the .linuxbrew directory
run: sudo -u testUser -i brew -h
My Linux is a little rusty but I was under the impression using sudo -u (username) -i will log the terminal into the specified user until logout/switching user again, am I wrong or is there a better way to accomplish this?
Disclaimer; I'm not familiar with the platform you are running on or the tool you are using, but I do have an educated guess.. and I hope this also how the -i flag behaves.
As most provisioners work, they usually run each step (mostly) independently from other steps. Which (again, usually) means that environment from one step is not carried over to the next one. So in this case, running sudo -i in one step will not have any effect on subsequent steps. You can try this to see how the provisioner in your case operates:
testUserChange:
name: Test active user
runs-on: [self-hosted]
steps:
- name: Default user
run: whoami
- name: Sudo user
run: sudo -u testUser -i whoami
- name: Should be default user again
run: whoami
- name: Maybe interactive shell like in first attempt
run: sudo -u testUser -i
- name: Who am I now
run: whoami
Now as for the -i, the manual states:
This means that login-specific resource files such as .profile or .login will be read by the shell. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is specified, an interactive shell is executed.
While this may be a bit confusing, as most provisioners don't expect user interactive input at runtime, they would usually close the STDIN handle (the input to the process). If we have two users, user0ne and usertw0, I hope I can demonstrate the behavior;
$ export PS1="This is user0ne env \$ " # just to show when environment variables are re-set due to loading the login scripts
This is user0ne env $
This is user0ne env $ whoami
user0ne
This is user0ne env $ sudo -u usertw0 /bin/sh
This is user0ne env $ whoami
usertw0
This is user0ne env $ exit
This is user0ne env $ whoami
user0ne
This is user0ne env $
In the above example, you can see that while the effective user is tw0, the environment is still set to what 0ne has set. Let's try with -i:
This is user0ne env $ sudo -u usertw0 -i /bin/sh
$ whoami
usertw0
$ exit
This is user0ne env $
So by now, looks like -i sets the environment (and login) to tw0's. Now, while the documentation does state that without any argument an interactive shell is opened:
This is user0ne env $ sudo -u usertw0 -i
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
usertw0#ubuntu:~$ logout
This is user0ne env $
Let's see what happens if we close the input handler (or more accurately, input nothing):
This is user0ne env $ sudo -u usertw0 -i < /dev/null
This is user0ne env $ whoami
user0ne
This is user0ne env $
And the same will happen even if you provide /bin/sh as the command to run, like shown in a snippet above:
This is user0ne env $ sudo -u usertw0 -i /bin/sh < /dev/null
This is user0ne env $ whoami
user0ne
This is user0ne env $
So even though the documentation does state it will open an interactive shell, the shell closes once there is no input to be read, and the state returns to the previous user.
Cheers! :)

eval $(docker-machine env myvm1) does not switch to shell to talk to myvm1

Folks,
I'm following the Docker tutorial here: https://docs.docker.com/get-started/part4/#configure-a-docker-machine-shell-to-the-swarm-manager and coming up against resistance when running this particular command:
eval $(docker-machine env myvm1)
I'm actually running (as above but with addition of sudo).
eval $(sudo docker-machine env myvm1)
I get no output from the command line to tell me anything has been done and when I run:
sudo docker-machine ls
I see that myvm1 does not have an active state as expected. I do know that this step isn't necessary but I'd like to understand why the command is not working and try to fix it.
I am running docker 17.09.0-ce
On Ubuntu 16.04 LTS
zsh shell (have tried switching to bash)
This is just on my local machine by the way, not a server.
Any help would be much appreciated.
There's less to go wrong if you run the eval on the far side of sudo:
sudo sh -c 'eval "$(docker-machine env myvm1)"; docker-machine ls'
Otherwise, the environment variables set by evaling the output of docker-machine env aren't necessarily (barring some very specific /etc/sudoers configuration) propagated through to the future docker-machine invocation.
If you wanted to automate this with a shell function, that can be done:
# docker-env sudo; usage: desudo vm-name command-to-run
desudo() {
local cmd1 cmd2
printf -v cmd1 'eval "$(docker-machine env %q)"' "$1"; shift
printf -v cmd2 '%q ' "$#"
sudo bash -c "${cmd1} && exec ${cmd2}"
}
...used as:
desudo vm1 docker-machine ls
You should run eval $(docker-machine env myvm1).
In fact, you don't have to add sudo.
But you may doesn't have permission to run docker without sudo, here is how to solve this issue on Linux.
Following the steps in this article "Post-installation steps for Linux"
Create the docker group. sudo groupadd docker
Add your user to the docker group. sudo usermod -aG docker $USER
Log out and log back in so that your group membership is re-evaluated.
Verify that you can run docker commands without sudo.docker run hello-world.
If you see the following error:
WARNING: Error loading config file: /home/user/.docker/config.json -
stat /home/user/.docker/config.json: permission denied
Fix it with:
$ sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
$ sudo chmod g+rwx "/home/$USER/.docker" -R
I too was having the exact same problem as posted and have spent the better part of the morning googling for an answer. I went back through the documentation and realised that I completely omitted the post-installation steps for Linux.
https://docs.docker.com/install/linux/linux-postinstall/
I followed the instructions laid out in the section labelled Manage Docker as a non-root user and eval $(sudo docker-machine env myvm1) and the subsequent docker-machine ls worked as expected. In addition... it eliminates the need to prefix all your docker commands withsudo.
I should have RTFM I guess?
I'm actually running (as above but with addition of sudo).
eval $(sudo docker-machine env myvm1)
I get no output from the command line to tell me anything has been done and when I run:
sudo docker-machine ls
I see that myvm1 does not have an active state as expected.
run this command it will work
sudo sh -c 'eval "$(docker-machine env myvm1)"; docker-machine ls'

Difference between sudo -s and sudo su in mac os

Both sudo -s and sudo su makes user root. is there any some difference?
With sudo -s
with sudo su
From man sudo:
-s, --shell
Run the shell specified by the SHELL environment variable if it is set or the shell specified by the invoking user's password
database entry. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is
specified, an interactive shell is executed.
So -s keeps your current shell (bash in this case), while omitting it uses the shell of the root user (sh). Myself, I prefer sudo -Es to keep both my shell and environment variables.

Resources