mirror of https://github.com/jumpserver/jumpserver
[future] 添加sudo相关的表,以及实现生成sudo内容的方法
parent
8716d9c725
commit
d9278c2c24
|
@ -4,7 +4,9 @@ from __future__ import unicode_literals, absolute_import
|
|||
import logging
|
||||
import json
|
||||
|
||||
from jinja2 import Template
|
||||
from django.db import models
|
||||
from assets.models import Asset
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
|
@ -220,47 +222,195 @@ class HostAlia(models.Model):
|
|||
|
||||
|
||||
class UserAlia(models.Model):
|
||||
name = models.CharField(max_length=128, blank=True, null=True, unique=True, verbose_name=_('Host_Alias'))
|
||||
host_items = models.TextField(blank=True, null=True, verbose_name=_('Host_Items'))
|
||||
name = models.CharField(max_length=128, blank=True, null=True, unique=True, verbose_name=_('User_Alias'))
|
||||
user_items = models.TextField(blank=True, null=True, verbose_name=_('Host_Items'))
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class CmdAlia(models.Model):
|
||||
name = models.CharField(max_length=128, blank=True, null=True, unique=True, verbose_name=_('Host_Alias'))
|
||||
host_items = models.TextField(blank=True, null=True, verbose_name=_('Host_Items'))
|
||||
name = models.CharField(max_length=128, blank=True, null=True, unique=True, verbose_name=_('Command_Alias'))
|
||||
cmd_items = models.TextField(blank=True, null=True, verbose_name=_('Host_Items'))
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class RunasAlia(models.Model):
|
||||
name = models.CharField(max_length=128, blank=True, null=True, unique=True, verbose_name=_('Host_Alias'))
|
||||
host_items = models.TextField(blank=True, null=True, verbose_name=_('Host_Items'))
|
||||
name = models.CharField(max_length=128, blank=True, null=True, unique=True, verbose_name=_('Runas_Alias'))
|
||||
runas_items = models.TextField(blank=True, null=True, verbose_name=_('Host_Items'))
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class Privilege(models.Model):
|
||||
name = models.CharField(max_length=128, blank=True, null=True, unique=True, verbose_name=_('Host_Alias'))
|
||||
host_items = models.TextField(blank=True, null=True, verbose_name=_('Host_Items'))
|
||||
user = models.ForeignKey(UserAlia, blank=True, null=True, related_name='privileges')
|
||||
host = models.ForeignKey(HostAlia, blank=True, null=True, related_name='privileges')
|
||||
runas = models.ForeignKey(RunasAlia, blank=True, null=True, related_name='privileges')
|
||||
command = models.ForeignKey(CmdAlia, blank=True, null=True, related_name='privileges')
|
||||
nopassword = models.BooleanField(default=True, verbose_name=_('Is_NoPassword'))
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
return "[%s %s %s %s %s]" % (self.user.name,
|
||||
self.host.name,
|
||||
self.runas.name,
|
||||
self.command.name,
|
||||
self.nopassword)
|
||||
|
||||
def to_tuple(self):
|
||||
return self.user.name, self.host.name, self.runas.name, self.command.name, self.nopassword
|
||||
|
||||
|
||||
class Extra_conf(models.Model):
|
||||
line = models.TextField(blank=True, null=True, verbose_name=_('Extra_Item'))
|
||||
|
||||
def __unicode__(self):
|
||||
return self.line
|
||||
|
||||
|
||||
class Sudo(models.Model):
|
||||
host_alias = models.ManyToManyField(HostAlia, related_name='sudos', blank=True, null=True)
|
||||
user_alias = models.ManyToManyField(UserAlia, related_name='sudos', blank=True, null=True)
|
||||
cmd_alias = models.ManyToManyField(CmdAlia, related_name='sudos', blank=True, null=True)
|
||||
runas_alias = models.ManyToManyField(RunasAlia, related_name='sudos', blank=True, null=True)
|
||||
privileges = models.ManyToManyField(Privilege, related_name='sudos', blank=True, null=True)
|
||||
"""
|
||||
Sudo配置文件对象, 用于配置sudo的配置文件
|
||||
|
||||
:param user_alias: <dict> {<alia>: <users_list>}
|
||||
:param cmnd_alias: <dict> {<alia>: <commands_list>}
|
||||
:param host_alias: <dict> {<alia>: <hosts_list>}
|
||||
:param runas_alias: <dict> {<alia>: <runas_list>}
|
||||
:param extra_lines: <list> [<line1>, <line2>,...]
|
||||
:param privileges: <list> [(user, host, runas, command, nopassword),]
|
||||
"""
|
||||
|
||||
asset = models.ForeignKey(Asset, null=True, blank=True, related_name='sudos')
|
||||
host_alias = models.ManyToManyField(HostAlia, related_name='sudos', blank=True)
|
||||
user_alias = models.ManyToManyField(UserAlia, related_name='sudos', blank=True)
|
||||
cmnd_alias = models.ManyToManyField(CmdAlia, related_name='sudos', blank=True)
|
||||
runas_alias = models.ManyToManyField(RunasAlia, related_name='sudos', blank=True)
|
||||
extra_lines = models.ManyToManyField(Extra_conf, related_name='sudos', blank=True)
|
||||
privilege_items = models.ManyToManyField(Privilege, related_name='sudos', blank=True)
|
||||
|
||||
@property
|
||||
def users(self):
|
||||
ret = {}
|
||||
for user in self.user_alias.all():
|
||||
ret[user.name] = user.user_items.split(',')
|
||||
return ret
|
||||
|
||||
@property
|
||||
def commands(self):
|
||||
ret = {}
|
||||
for cmd in self.cmnd_alias.all():
|
||||
ret[cmd.name] = cmd.cmd_items.split(',')
|
||||
return ret
|
||||
|
||||
@property
|
||||
def hosts(self):
|
||||
ret = {}
|
||||
for host in self.host_alias.all():
|
||||
ret[host.name] = host.host_items.split(',')
|
||||
return ret
|
||||
|
||||
@property
|
||||
def runas(self):
|
||||
ret = {}
|
||||
for runas in self.runas_alias.all():
|
||||
ret[runas.name] = runas.runas_items.split(',')
|
||||
return ret
|
||||
|
||||
@property
|
||||
def extras(self):
|
||||
return [extra.line for extra in self.extra_lines.all()]
|
||||
|
||||
@property
|
||||
def privileges(self):
|
||||
return [privilege.to_tuple() for privilege in self.privilege_items.all()]
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
pass
|
||||
template = Template(self.__sudoers_jinja2_tmp__)
|
||||
context = {"User_Alias": self.users,
|
||||
"Cmnd_Alias": self.commands,
|
||||
"Host_Alias": self.hosts,
|
||||
"Runas_Alias": self.runas,
|
||||
"Extra_Lines": self.extras,
|
||||
"privileges": self.privileges}
|
||||
return template.render(context)
|
||||
|
||||
@property
|
||||
def __sudoers_jinja2_tmp__(self):
|
||||
return """# management by JumpServer
|
||||
# This file MUST be edited with the 'visudo' command as root.
|
||||
#
|
||||
# Please consider adding local content in /etc/sudoers.d/ instead of
|
||||
# directly modifying this file.
|
||||
#
|
||||
# See the man page for details on how to write a sudoers file.
|
||||
#
|
||||
Defaults env_reset
|
||||
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
# JumpServer Generate Other Configure is here
|
||||
{% if Extra_Lines -%}
|
||||
{% for line in Extra_Lines -%}
|
||||
{{ line }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# Host alias specification
|
||||
{% if Host_Alias -%}
|
||||
{% for flag, items in Host_Alias.iteritems() -%}
|
||||
Host_Alias {{ flag }} = {{ items|join(', ') }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# User alias specification
|
||||
{% if User_Alias -%}
|
||||
{% for flag, items in User_Alias.iteritems() -%}
|
||||
User_Alias {{ flag }} = {{ items|join(', ') }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
|
||||
# Cmnd alias specification
|
||||
{% if Cmnd_Alias -%}
|
||||
{% for flag, items in Cmnd_Alias.iteritems() -%}
|
||||
Cmnd_Alias {{ flag }} = {{ items|join(', ') }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# Run as alias specification
|
||||
{% if Runas_Alias -%}
|
||||
{% for flag, items in Runas_Alias.iteritems() -%}
|
||||
Runas_Alias {{ flag }} = {{ items|join(', ') }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# User privilege specification
|
||||
root ALL=(ALL:ALL) ALL
|
||||
|
||||
# JumpServer Generate User privilege is here.
|
||||
# Note privileges is a tuple list like [(user, host, runas, command, nopassword),]
|
||||
{% if privileges -%}
|
||||
{% for User_Flag, Host_Flag, Runas_Flag, Command_Flag, NopassWord in privileges -%}
|
||||
{% if NopassWord -%}
|
||||
{{ User_Flag }} {{ Host_Flag }}=({{ Runas_Flag }}) NOPASSWD: {{ Command_Flag }}
|
||||
{%- else -%}
|
||||
{{ User_Flag }} {{ Host_Flag }}=({{ Runas_Flag }}) {{ Command_Flag }}
|
||||
{%- endif %}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# Members of the admin group may gain root privileges
|
||||
%admin ALL=(ALL) ALL
|
||||
|
||||
# Allow members of group sudo to execute any command
|
||||
%sudo ALL=(ALL:ALL) ALL
|
||||
|
||||
# See sudoers(5) for more information on "#include" directives:
|
||||
|
||||
#includedir /etc/sudoers.d
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""
|
||||
该模块主要用于提供一个统一的api来管理sudo的配置文件,
|
||||
支持管理的系统包括: ubuntu(/etc/sudoers)
|
||||
|
||||
因为sudoers配置文件很危险,所以采用生成临时文件, 验证ok后, 进行替换来变更
|
||||
"""
|
||||
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
|
||||
__sudoers_tmp__ = """# management by JumpServer
|
||||
# This file MUST be edited with the 'visudo' command as root.
|
||||
#
|
||||
# Please consider adding local content in /etc/sudoers.d/ instead of
|
||||
# directly modifying this file.
|
||||
#
|
||||
# See the man page for details on how to write a sudoers file.
|
||||
#
|
||||
Defaults env_reset
|
||||
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
# JumpServer Generate Other Configure is here
|
||||
{% if Extra_Lines -%}
|
||||
{% for line in Extra_Lines -%}
|
||||
{{ line }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# Host alias specification
|
||||
{% if Host_Alias -%}
|
||||
{% for flag, items in Host_Alias.iteritems() -%}
|
||||
Host_Alias {{ flag }} = {{ items|join(', ') }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# User alias specification
|
||||
{% if User_Alias -%}
|
||||
{% for flag, items in User_Alias.iteritems() -%}
|
||||
User_Alias {{ flag }} = {{ items|join(', ') }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
|
||||
# Cmnd alias specification
|
||||
{% if Cmnd_Alias -%}
|
||||
{% for flag, items in Cmnd_Alias.iteritems() -%}
|
||||
Cmnd_Alias {{ flag }} = {{ items|join(', ') }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# Run as alias specification
|
||||
{% if Runas_Alias -%}
|
||||
{% for flag, items in Runas_Alias.iteritems() -%}
|
||||
Runas_Alias {{ flag }} = {{ items|join(', ') }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# User privilege specification
|
||||
root ALL=(ALL:ALL) ALL
|
||||
|
||||
# JumpServer Generate User privilege is here.
|
||||
# Note privileges is a tuple list like [(user, host, runas, command, nopassword),]
|
||||
{% if privileges -%}
|
||||
{% for User_Flag, Host_Flag, Runas_Flag, Command_Flag, NopassWord in privileges -%}
|
||||
{% if NopassWord -%}
|
||||
{{ User_Flag }} {{ Host_Flag }}=({{ Runas_Flag }}) NOPASSWD: {{ Command_Flag }}
|
||||
{%- else -%}
|
||||
{{ User_Flag }} {{ Host_Flag }}=({{ Runas_Flag }}) {{ Command_Flag }}
|
||||
{%- endif %}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
|
||||
# Members of the admin group may gain root privileges
|
||||
%admin ALL=(ALL) ALL
|
||||
|
||||
# Allow members of group sudo to execute any command
|
||||
%sudo ALL=(ALL:ALL) ALL
|
||||
|
||||
# See sudoers(5) for more information on "#include" directives:
|
||||
|
||||
#includedir /etc/sudoers.d
|
||||
"""
|
||||
|
||||
|
||||
class Sudo(object):
|
||||
"""
|
||||
Sudo配置文件API, 用于配置sudo的配置文件
|
||||
|
||||
:param user_alias: <dict> {<alia>: <users_list>}
|
||||
:param cmnd_alias: <dict> {<alia>: <commands_list>}
|
||||
:param host_alias: <dict> {<alia>: <hosts_list>}
|
||||
:param runas_alias: <dict> {<alia>: <runas_list>}
|
||||
:param extra_lines: <list> [<line1>, <line2>,...]
|
||||
:param privileges: <list> [(user, host, runas, command, nopassword),]
|
||||
"""
|
||||
|
||||
def __init__(self, user_alias, cmnd_alias, privileges, host_alias=None, runas_alias=None, extra_lines=None):
|
||||
self.extras = extra_lines
|
||||
self.users = user_alias
|
||||
self.commands = cmnd_alias
|
||||
self.hosts = host_alias
|
||||
self.runas = runas_alias
|
||||
self.privileges = privileges
|
||||
|
||||
def get_tmp(self):
|
||||
template = Template(__sudoers_tmp__)
|
||||
context = {"User_Alias": self.users,
|
||||
"Cmnd_Alias": self.commands,
|
||||
"Host_Alias": self.hosts,
|
||||
"Runas_Alias": self.runas,
|
||||
"Extra_Lines": self.extras,
|
||||
"privileges": self.privileges}
|
||||
return template.render(context)
|
||||
|
||||
def gen_privileges(self):
|
||||
pass
|
||||
|
||||
def get_sudo_from_db(self):
|
||||
pass
|
||||
|
||||
def check_users(self):
|
||||
pass
|
||||
|
||||
def check_commands(self):
|
||||
pass
|
||||
|
||||
def check_hosts(self):
|
||||
pass
|
||||
|
||||
def check_runas(self):
|
||||
pass
|
||||
|
||||
def check_privileges(self):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
users = {"a": ['host1, host2'], "b": ["host3", "host4"]}
|
||||
commands = {"dba": ["bin/bash"], "dev": ["bin/bash"]}
|
||||
privileges = [("a", "ALL", "root", "dba", True), ("a", "ALL", "root", "dba", False)]
|
||||
sudo = Sudo(users, commands, privileges, extra_lines=['aaaaaasf sdfasdf', 'bbbbb sfdsdf'])
|
||||
print sudo.get_tmp()
|
||||
|
Loading…
Reference in New Issue