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

Add user to docker group if not superuser #1095

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

NeilW
Copy link

@NeilW NeilW commented Oct 10, 2024

This allows docker commands to function with a non-root ssh user

Fixes: #980

@NeilW
Copy link
Author

NeilW commented Oct 10, 2024

Finished in 562.249692s, 0.9124 runs/s, 3.2939 assertions/s.
513 runs, 1852 assertions, 0 failures, 0 errors, 0 skips

@dhh
Copy link
Member

dhh commented Oct 10, 2024

I thought any group changes requires we logout/back-in or maybe even restart the server? We had that issue with Omakub.

@NeilW NeilW force-pushed the fix-980 branch 2 times, most recently from 86af751 to 61a92dd Compare October 11, 2024 11:13
@NeilW
Copy link
Author

NeilW commented Oct 11, 2024

Finished in 597.636880s, 0.8617 runs/s, 3.1909 assertions/s.
515 runs, 1907 assertions, 0 failures, 0 errors, 0 skips

@NeilW
Copy link
Author

NeilW commented Oct 11, 2024

Thanks for the comment @dhh

I've updated the fix and it should now work with kamal setup as well as kamal server bootstrap.

I've created a kamal container for anybody who wants to test this version with their configuration.

alias kamal='docker run -it --rm -v "${PWD}:/workdir" --network=host -v "${SSH_AUTH_SOCK}:/ssh-agent" -v /var/run/docker.sock:/var/run/docker.sock -e "SSH_AUTH_SOCK=/ssh-agent" cr.brightbox.com/acc-tqs4c/docker/kamal:latest'

Please give it a go and flag up any issues.

@NeilW
Copy link
Author

NeilW commented Oct 11, 2024

Update to reduce the ferocity of the session termination. Now only terminates the initiating kamal session.

@dhh
Copy link
Member

dhh commented Oct 11, 2024

Hmm, starting to think that we're probably better off failing fast and telling the user to do this themselves with clear instructions.

@NeilW
Copy link
Author

NeilW commented Oct 11, 2024

If you don’t like the kill then the original change is fine in the bootstrap since kamal disconnects.

Then the next time kamal is run, all is well.

What’s the issue you are seeing?

@NeilW
Copy link
Author

NeilW commented Oct 12, 2024

Turns out a HUP signal does work with sshd when it's the session lead allowing it to clean up properly.

@kdiogenes
Copy link

I thought any group changes requires we logout/back-in or maybe even restart the server? We had that issue with Omakub.

The newgrp command can be used to load the new group during a session: https://linux.die.net/man/1/newgrp

# If we're not root and not already in the docker group
# add us to the docker group and terminate all our current sessions
def add_group
[ '[ "${EUID:-$(id -u)}" -eq 0 ] || id -nG "${USER:-$(id -un)}" | grep -qw docker || { sudo usermod -aG docker "${USER:-$(id -un)}" && kill -HUP ${PPID:-ps -o ppid= -p $$}; }' ]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NeilW - could you try the newgrp command that @kdiogenes suggested?

Also I think we should have sudo -n to ensure that it fails rather than prompt for a password if one is needed.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, /etc/ssh/sshd_config should set PermitRootLogin no and PasswordAuthentication no. What you think?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newgrp won't work. The persistent session is on the parent user sshd process, which will remain with the original group set, in a different terminal session. You have to terminate that to force a re-authentication to pick up the new group set.

Even exec newgrp won't do the trick. There's no persistent shell process to replace

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, /etc/ssh/sshd_config should set PermitRootLogin no and PasswordAuthentication no. What you think?

I don't think we want to get too far into configuring the servers. The docker group change makes sense here because it is only used when we have just installed docker and we know it's going to be a problem.

newgrp won't work. The persistent session is on the parent user sshd process, which will remain with the original group set, in a different terminal session. You have to terminate that to force a re-authentication to pick up the new group set.

Ok I think signalling is probably ok then - it's a bit of a shame it has to done that way, but I think it's worth it for making this a smoother process.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think we just need to add -n to sudo, and then make sure there's a nice error message if the user doesn't have sudo access.


# If the groups change, the session is terminated to force a re-login.
# Catch the resulting IOError and inform the user
rescue IOError
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a more specific error we can rescue here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is the specific error. We get back "IOError: closed stream" from the terminated ssh session. The only subclass of IOError is EOFError. It's not a part of the SystemCallError tree.

This allows docker commands to function with a non-root
ssh user

Fixes: basecamp#980
@NeilW
Copy link
Author

NeilW commented Oct 25, 2024

I've added the -n option to the sudo call and altered the superuser? check so that it checks sudo can at least call the usermod command. That should be a better proxy for whether sudo can complete the task than the previous iteration.

I've removed the su test in superuser? since that isn't going to be useful. Far better to be opinionated and require sudo if root isn't directly available.

If sudo cannot be called without a password or hasn't sufficient privileges to run the usermod command we then get the manual install error message

Ensure Docker is installed...
  INFO [e4cd943d] Running docker -v on ipv6.srv-qaket.gb1s.brightbox.com
  INFO [320089ed] Running docker -v on ipv6.srv-m9ng9.gb1s.brightbox.com
  INFO [320089ed] Finished in 0.068 seconds with exit status 127 (failed).
  INFO [558dfcd8] Running [ "${EUID:-$(id -u)}" -eq 0 ] || sudo -nl usermod >/dev/null on ipv6.srv-m9ng9.gb1s.brightbox.com
  INFO [e4cd943d] Finished in 0.118 seconds with exit status 127 (failed).
  INFO [f421ab33] Running [ "${EUID:-$(id -u)}" -eq 0 ] || sudo -nl usermod >/dev/null on ipv6.srv-qaket.gb1s.brightbox.com
  INFO [558dfcd8] Finished in 0.131 seconds with exit status 1 (failed).
  INFO [f421ab33] Finished in 0.128 seconds with exit status 1 (failed).
Releasing the deploy lock...
  Finished all in 2.0 seconds
  ERROR (RuntimeError): Docker is not installed on ipv6.srv-m9ng9.gb1s.brightbox.com, ipv6.srv-qaket.gb1s.brightbox.com and can't be automatically installed without having root access and either `wget` or `curl`. Install Docker manually: https://docs.docker.com/engine/install/

@NeilW
Copy link
Author

NeilW commented Oct 25, 2024

The docker image above has been updated for anybody who wants to test out the new iteration

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.

kamal 2: fixing docker user permission automatically on setup?
5 participants