Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Fabric Sudo su - user

I currently do the following from the command line:

$ ssh myuser@remote-server 
password:
[myuser@remote-server ~]$ sudo su - dev_user
[dev_user@remote-server ~]$ whoami
dev_user
[dev_user@remote-server ~]$

No permission issue.

The myuser has enough permission to do what typed above, but it does not have permission to do sudo su -c whoami dev_user

I tried the following code

from fabric import Connection, task

@task
def abcd(ctx):
    sudo_pass = getpass.getpass("What's your sudo password?")
    config = Config(overrides={'sudo': {'password': sudo_pass}})
    with Connection('dev-server', user='myuser', connect_kwargs={"password": sudo_pass}, config=config) as c:
        c.sudo('/bin/bash -l -c whoami', user='dev_user')

I get the following output:

fab abcd
What's your sudo password?
[sudo] password: Sorry, user myuser is not allowed to execute '/bin/bash -l -c whoami' as dev_user on dev-server.

Is there a way to get fabric do what I did from the command line?

Editing the sudoers file is not an option.

The remote server is Linux RH 7.6.

Thank you.

like image 820
jibhas Avatar asked Feb 11 '19 20:02

jibhas


Video Answer


2 Answers

The following works:

c.run("echo 'whoami' | sudo su - dev_user")
c.run("echo 'cd /some/directory && ./somescript.sh' | sudo su - dev_user")
like image 37
jibhas Avatar answered Oct 16 '22 22:10

jibhas


Yes, you can use sudo with a user= argument, to use sudo to switch to another user, just like you are doing in the shell:

from  fabric import Connection

c = Connection('host')
c.sudo('/bin/bash -l -c whoami', user='dev_user')

sudo accepts additional user and group arguments, which are passed to sudo and allow you to run as some user and/or group other than root. On most systems, the sudo program can take a string username/group or an integer userid/groupid (uid/gid); user and group may likewise be strings or integers.

http://docs.fabfile.org/en/1.14/api/core/operations.html?highlight=sudo#fabric.operations.sudo

The above solution will only work if you can run sudo without entering your password. If your account, myuser requires a password to run sudo, then you can prompt for that password, and pass it to fabric's config:

import getpass
from fabric import Connection, Config

sudo_pass = getpass.getpass("What's your sudo password?")
config = Config(overrides={'sudo': {'password': sudo_pass}})
c = Connection('host', config=config)

c.sudo('/bin/bash -l -c whoami', user='dev_user')

http://docs.fabfile.org/en/2.3/getting-started.html#the-sudo-helper

One final idea:

from  fabric import Connection, Config

config = Config(overrides={'sudo': {'user': 'sudo_user'}})
c = Connection('host', config=config)

c.sudo('whoami')

Note that no sudo password is provided in this case, but a user is, in the Config setup. And c.sudo is changed back to a simple c.sudo('whoami'). This should be interpreted as sudo su - sudo_user by Fabric.

like image 160
Nikolas Stevenson-Molnar Avatar answered Oct 17 '22 00:10

Nikolas Stevenson-Molnar