Q-Logo 我的学习笔记分享

Python fabric远程运维之创建用户并配置无密码sudo

Fabric介绍

Fabric是一个Python库,可通过SSH在远程服务器上执行命令,返回有用的Python对象。其官网 是http://www.fabfile.org/ 。

Fabric is a high level Python (2.7, 3.4+) library designed to execute shell commands remotely over SSH, yielding useful Python objects in return

由于历史的原因,Fabric的版本比较混乱。可以参考 http://www.fabfile.org/upgrading.html#upgrading , http://www.fabfile.org/installing.html 及https://www.cnblogs.com/anliven/p/9186994.html 了解关于Fabric版本的更多信息。

Fabric安装

这里使用的是官方最新版的fabric,安装方式如下:

$ pip install fabric

问题

在linux系统中,为避免直接使用root用户带来的安全问题,最好新建一个系统用户,并赋予此用户sudo的权限。在远程运维时,常用的办法是通过ssh远程登录到服务器,然后执行新建用户的命令,并修改/etc/sudoer的内容或在/etc/sudoers.d/目录下新建文件为用户赋予(无密码)sudo的权限。这可以通过使用Python Fabric来实现。

创建Python文件

在本地机器上创建 userutils.py 文件,此文件用于在一个或多个远程机器(在hosts中定义)上,执行一系列bash命令,创建用户,为用户设置密码,并赋予用户无密码sudo 的权限,并打印执行结果。

userutils.py文件内容如下:

# userutils.py

from fabric import Connection

from invoke import Responder

hosts = [

{'hostname':'192.168.99.100', # host name of remote machine

'user':'username', # name of remote machine user

'password':'password', # password of user

},

# {other host ...},

]

def useradd(c, username='username', password=None):

print('-'*20)

cmd = 'useradd {username}'.format(username=username)

if iduser(c, username).failed:

result = c.run( cmd, hide=True, warn=True)

else:

print('user with id {} already existed. There is no need to create it.'.format(username))

if password:

newuserpass = Responder(

pattern = r'New password:',

response = '{}\n'.format(password),

)

retypepass = Responder(

pattern = r'Retype new password:',

response = '{}\n'.format(password),

)

print(newuserpass.response)

print(retypepass.response)

result = c.run('passwd {username}'.format(username=username), hide=True, pty=True, warn=True, watchers=[newuserpass, retypepass])

print('result:')

print(result)

def grantnopasswdsudo(c, username):

cmd = 'echo "{username} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/{username}'.format(username=username)

result = c.run( cmd, hide=True, warn=True)

def iduser(c, username):

print('-'*20)

cmd = 'id {username}'.format(username=username)

result = c.run( cmd, hide=True, warn=True)

return result

def userdel(c, username):

print('-'*20)

cmd = 'userdel -r {username}'.format(username=username)

if iduser(c, username).ok:

result = c.run( cmd, hide=True, warn=True)

else:

print('user with id {username} does not existed. There is no need to delete it.'.format(username=username))

if __name__ == "__main__":

for host in hosts:

conn = Connection(host=host.get('hostname'),user=host.get('user'),connect_kwargs={'password':host.get('password')})

username = 'username'

password = 'password'

useradd(conn, username=username, password=password)

print('user is added.')

grantnopasswdsudo(conn, username=username)

print('nopasswd sudo granted.')

# iduser(conn,username)

# userdel(conn,username)

# iduser(conn,username)

conn.close()

print('connection is closed.')

运行并查看结果

在本机命令行运行userutils.py,即可在远程机器上新建用户username,设置用户密码为password,并赋予username用户无密码sudo权限。 。