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 "sudo" option to link plugin #125

Open
nagromc opened this issue May 31, 2017 · 32 comments
Open

Add "sudo" option to link plugin #125

nagromc opened this issue May 31, 2017 · 32 comments

Comments

@nagromc
Copy link
Contributor

nagromc commented May 31, 2017

Dotbot is used by multiple usersincluding me — to symlink files in folders that need root privileges.

It would be nice to add an option (just like path or create) to the link plugin to describe if the target needs to be symlinked with root privileges. We could name this option sudo or root.

For example:

- link:
    /etc/some/restricted/path/whatever.conf: whatever.conf
        create: true
        sudo: true
    ~/.vimrc: vimrc
        sudo: false

Running ./install would create two symlinks:

  • /etc/some/restricted/path/whatever.conf created as root
  • ~/.vimrc created as regular current user

If you prefer to keep Dotbot simple, we could create a plugin that extends the link plugin.

@nagromc nagromc changed the title Add "sudo" option to link plugin Add "sudo" option to link plugin May 31, 2017
@anishathalye
Copy link
Owner

The idea sounds good! Having a sudo option on link seems useful. A couple questions:

  1. When would the user enter the password?
  2. Would you be interested in implementing this?

@nagromc
Copy link
Contributor Author

nagromc commented May 31, 2017

Great!

  1. When would the user enter the password?

According to the man pages, sudo seems to cache the password for 15 minutes by default (at least on the latest Ubuntu LTS):

Security policies may support credential caching to allow the user to run sudo again for a period of time without requiring authentication. The sudoers policy caches credentials for 15 minutes, unless overridden in sudoers(5).

So I think the password should be asked by sudo itself to let it cache the credentials. So when the user runs ./install, as soon as Dotbot process a link with sudo option enabled, the password prompt appears. Would it be a good UX?

  1. Would you be interested in implementing this?

Yeah sure. Just to let you know I'm not used to code in Python, but I'm rigorous in my work and I love to learn. I will try my best and will submit a PR.

@anishathalye
Copy link
Owner

  1. Well, we use Python's os.symlink() function to create symlinks. I don't think we want to switch to shelling out to sudo ln -s .... I'm not sure what's the recommended way of doing this with Python.

  2. Ok, sounds great! I can give you feedback on the code 😄 And feel free to ask if you have any questions.

@sharethewisdom
Copy link

sharethewisdom commented Jun 25, 2017

I personally think that shelling out is not a good practice. Likewise running dotbot as a super user or making system config's symbolic links somewhere in the a user's home directory is a terrible idea.

In issue #128 I suggest to mimic the options for the install(1) command trough copy:, which sets the file's attributes (access controls). Surely it would be no problem to run an idempotent installer (but you'll have to remember) after editing files yet-to-be copied. The install command also allows for a simple in-place backup to be made (maybe also to clean old backups).

I'll reflect upon this subject, and I'll look around to find out how to achieve this with syscalls and subprocess privileges. (However, I'm not a programmer ...) Please let me hear your thoughts.

edit: privilege dropping script

@ShikherVerma
Copy link

+1

@sharethewisdom
Copy link

I encourage users to manage /etc with etckeeper, which uses git. It has hooks for common package managers. Make sure to take a look at Automatic push to remote repo on the page I linked. A remote repo could obviously be a thumb drive, a repo on a computer in your LAN or a private repo on the public internet.

Still it would be cool indeed if Dotbot could drop privileges and change file attributes without shelling out.

@ShikherVerma
Copy link

Using this ugly line now 😭
wish dotbot had sudo support for link.

@ashkitten
Copy link

@ShikherVerma i'd use [ -e /etc/fonts/local.conf ] || sudo ln fontconfig /etc/fonts/local.conf to make it slightly prettier

@anishathalye
Copy link
Owner

I have nothing against adding some kind of sudo functionality to link, as long as it's implemented in some reasonable way. Does anyone have good ideas for how to do this?

@flyingchipmunk
Copy link

flyingchipmunk commented Sep 28, 2017

@anishathalye you are welcome to take inspiration from my dotbot-yum plugin where I implemented a "sudo: true" param - https://gitlab.com/flyingchipmunk/dotbot-yum

edit: ah scratch that just went and looked at link.py, it's using os.symlink(...), not easy to shoehorn sudo in there. Maybe an option for folks is to have a different install_links.conf.yaml with only the link directives and sudo dotbot -c install_links.conf.yaml

That way the security is handled by the os layer instead of managing it in link.py

@ddnomad
Copy link

ddnomad commented Feb 3, 2018

Ok, does somebody want a separate plugin that will do link with sudo rights? It would add a keyword, say, linksu and all /etc/ stuff etc should be linked via this plugin.

Most probably there will be a need to shell out though if the password is prompted on Python side and passed via STDIN the whole thing should be more or less secure.

@anishathalye
Copy link
Owner

We can even include such functionality in Dotbot core, as long as we have some reasonable way to do it.

I don't think there's too much to worry about security: everything in this scenario is trusted (Dotbot + everything else in your dotfiles).

Also, it's fine to have it start out as a plugin, and if there's interest, we can merge it into core at some point.

@ddnomad
Copy link

ddnomad commented Feb 3, 2018

Good point! I'll do my best to squeeze out some time to make a pilot version of a plugin. I'll let you know when there will be something.

@dsifford
Copy link
Contributor

@anishathalye Can you clarify what the major hurdle is for implementing this functionality into core?

You mention implementing it in a "reasonable" way a couple of times. Can you clarify what that means?

To answer the questions you asked...

1. When would the user enter the password?

Without too much thought here, I would imagine this would happen when the code first encounters a link target that requires elevated privileges, no?

In 99% of the cases, the user would just have to enter the password one time because, according to the sudo man page...

"[...] the default password prompt timeout for the sudoers security policy is 5 minutes."

which is well beyond the time it would take to execute the entire program (and, if not, the user will just have to enter it a second time if sudo is needed again).

Is there something that I'm missing here that makes this more complicated?

2. Would you be interested in implementing this?

Yep, very much so. Only interested if this goes directly into core though. Not a plugin.

@anishathalye
Copy link
Owner

I don't really have a set of rules that I can write down to explain what I mean by "reasonable" implementation. One example of something that I think won't be good enough is shelling out to sudo ln -s. At the very least, the solution should be robust (no worse error handling than the current version) and cross-platform.

@dsifford
Copy link
Contributor

Fair enough. Thanks for chiming back.

Might take a stab at this either this weekend or next if time allows. (unless @ddnomad has already got something together that satisfies those provisions).

@ddnomad
Copy link

ddnomad commented Feb 16, 2018

@dsifford mine version is just a sketch right now and I do shell out. Thus you definitely can take a stab yourself.

@dsifford
Copy link
Contributor

@ddnomad @anishathalye Gonna unfortunately tap out of this one.

Ergonomics are too weird to contribute. I really don't want to install vagrant just to run tests (though, I do appreciate the reason it's being used -- encapsulation).

I still think that simply adding a "sudo" field that accepts a boolean that, when true, runs sudo -u "$USER" ln -s [...] is totally an acceptable and easy to implement solution.

@mainrs
Copy link

mainrs commented Apr 4, 2018

@dsifford That would need special configuration for windows users though as people might use dotbot for non-unix/linux OS'.

@dsifford
Copy link
Contributor

dsifford commented Apr 4, 2018

@sirwindfield Why would windows users even use the sudo option?

@mainrs
Copy link

mainrs commented Apr 4, 2018

No idea, aren't there protected directories too? o.O

Anyway, I just had a small idea. Maybe link each normal file first and after that, re-run the script (automatically) passing it a flag like sudo=true. Dotbot would then only link all files that are declared as sudo. Youd could even change the owner of the files to the sudo caller by using SUDO_UID and SUDO_GID environment variables and calling os.chown. It would basically be a two step process.

@FatBoyXPC
Copy link

Just came across this issue, this is something I've been looking for ever since I've started using dotbot back in 2015!

Definitely keeping an eye on this one!

@swsnr
Copy link

swsnr commented Nov 8, 2019

Isn't this a security issue? Linking a system file to a user-writable target would let any process running as that user change the file, which kind of defeats the purpose of having system files in the first place. For some files (e.g. systemd unit overrides) this would effectively allow the user to run arbitrary processes at root, without even noticing.

Personally I use shell to install system files, e.g.

- shell:
 - command: sudo -n install -D -m644 systemd/timesyncd.conf /etc/systemd/timesyncd.conf
    stderr: true

sudo -n makes sudo fail if it would have to prompt for password, so that ./install runs without stopping at any prompts even if I have no active sudo ticket. To install system files I use sudo -v && ./install which acquires a sudo ticket before installing my dotfiles.

@FatBoyXPC
Copy link

FatBoyXPC commented Nov 8, 2019

I actually want those systemd overrides. In this case, one would also need to ProtectHome=no - so at least you know you're doing something that comes with some risk.

Using shell works, but then you kind of lose the niceness of the yaml config. I found custom install scripts on the wiki and I've created install.sudo.conf.yaml and an install-sudo script. I think this is a good compromise.

I used to ./install and immediately follow it with sudo ./install - but that would put a bunch of symlinks in root's directory, which was obviously not preferable. Now I have shell with sudo ./install-sudo in it, so ./install can take care of all of it, with nothing irrelevant going to root's directory.

@dagadbm
Copy link

dagadbm commented Jul 15, 2020

any news on this?

@FatBoyXPC
Copy link

I think the install-sudo script is an alright enough way to go. That allows things to stay separate if need be.

See these files: install-sudo, install.sudo.conf.yaml, and install.conf.yaml

@anishathalye
Copy link
Owner

anishathalye commented Jul 15, 2020

Yeah, I think that's the recommended approach, at a high level. Have two separate .conf.yaml files, and call Dotbot on each, once without sudo, and the other time with sudo.

You could use variations of that, e.g. having an install.conf.yaml and a sudo.conf.yaml, and then having your ./install script itself be modified to call Dotbot on each of those (I think I would do that rather than putting a shell: line in the install.conf.yaml).

@FatBoyXPC
Copy link

I honestly didn't even thinking about having the install script call sudo.conf.yaml!

@DrDynamic
Copy link

Hi,
I also had the problem, that i needed to execute parts of my install.con.yaml as root.
So I write a plugin for this purpose.
Maybe this could help you too:
dotbot-sudo
Please let me know what you think :)

@anishathalye
Copy link
Owner

You could add it to the plugins list for extra visibility.

@DrDynamic
Copy link

Added some plugins to the plugin list :)

@ecarlson94
Copy link

I know this is really outdated, but the new install scripts solve this problem by allowing you to add -sudo to the end of any configuration. i.e. ./install-standalone some-config other-config-sudo. Only downside is that it requires you to have implemented the more advanced setup from the Tips and Tricks section of the wiki.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests