Merge branch 'master' into dev

pull/31/head
ibuler 2015-12-26 10:53:01 +08:00
commit b370f01551
10 changed files with 58 additions and 60 deletions

View File

@ -58,12 +58,7 @@ Web批量执行命令
### 团队 ### 团队
* **广宏伟** ibuler ![](https://github.com/ibuler/static/raw/master/jumpserver3/team.jpg)
* **王墉** halcyon
* **陈尚委** 假想控
* **喻茂峻** 紫川秀
* **刘正** evanescunt
* **柯连春** 遍地节操

View File

@ -32,7 +32,7 @@ from jperm.ansible_api import MyRunner
from jlog.models import ExecLog, FileLog from jlog.models import ExecLog, FileLog
login_user = get_object(User, username=getpass.getuser()) login_user = get_object(User, username=getpass.getuser())
remote_ip = os.popen("who -m | awk '{ print $5 }'").read().strip('()\n') remote_ip = os.popen("who -m | awk '{ print $NF }'").read().strip('()\n')
try: try:
import termios import termios

View File

@ -6,7 +6,7 @@ import time
import os import os
import sys import sys
import MySQLdb import MySQLdb
from smtplib import SMTP, SMTPAuthenticationError, SMTPConnectError from smtplib import SMTP, SMTPAuthenticationError, SMTPConnectError, SMTPSenderRefused
import ConfigParser import ConfigParser
import socket import socket
import fcntl import fcntl
@ -127,7 +127,7 @@ class PreSetup(object):
smtp.quit() smtp.quit()
return True return True
except (SMTPAuthenticationError, socket.timeout, socket.gaierror), e: except (SMTPAuthenticationError, socket.timeout, socket.gaierror, SMTPSenderRefused, SMTPConnectError), e:
color_print(e, 'red') color_print(e, 'red')
return False return False

View File

@ -7,6 +7,7 @@ import django
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
import shutil import shutil
import urllib import urllib
import socket
jms_dir = os.path.dirname(os.path.abspath(os.path.dirname(__file__))) jms_dir = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
sys.path.append(jms_dir) sys.path.append(jms_dir)
@ -19,6 +20,8 @@ from juser.user_api import db_add_user, get_object, User
from install import color_print from install import color_print
from jumpserver.api import get_mac_address from jumpserver.api import get_mac_address
socket.setdefaulttimeout(2)
class Setup(object): class Setup(object):
""" """
@ -33,8 +36,11 @@ class Setup(object):
def _pull(): def _pull():
color_print('开始更新jumpserver', 'green') color_print('开始更新jumpserver', 'green')
# bash('git pull') # bash('git pull')
mac = get_mac_address() try:
version = urllib.urlopen('http://jumpserver.org/version/?id=%s' % mac) mac = get_mac_address()
version = urllib.urlopen('http://jumpserver.org/version/?id=%s' % mac)
except:
pass
os.chdir(jms_dir) os.chdir(jms_dir)
os.chmod('logs', 0777) os.chmod('logs', 0777)
os.chmod('keys', 0777) os.chmod('keys', 0777)
@ -83,7 +89,7 @@ class Setup(object):
def _run_service(): def _run_service():
os.system('sh %s start' % os.path.join(jms_dir, 'service.sh')) os.system('sh %s start' % os.path.join(jms_dir, 'service.sh'))
print print
color_print('安装成功请访问web, 祝你使用愉快。请访问 https://github.com/ibuler/jumpserver 查看文档') color_print('安装成功请访问web, 祝你使用愉快。\n请访问 https://github.com/ibuler/jumpserver 查看文档', 'green')
def start(self): def start(self):
print "开始安装Jumpserver, 要求环境为 CentOS 6.5 x86_64" print "开始安装Jumpserver, 要求环境为 CentOS 6.5 x86_64"

View File

@ -29,7 +29,10 @@ def get_group_user_perm(ob):
""" """
perm = {} perm = {}
if isinstance(ob, User): if isinstance(ob, User):
rule_all = PermRule.objects.filter(user=ob) rule_all = set(PermRule.objects.filter(user=ob))
for user_group in ob.group.all():
rule_all = rule_all.union(set(PermRule.objects.filter(user_group=user_group)))
elif isinstance(ob, UserGroup): elif isinstance(ob, UserGroup):
rule_all = PermRule.objects.filter(user_group=ob) rule_all = PermRule.objects.filter(user_group=ob)
else: else:
@ -80,6 +83,7 @@ def get_group_user_perm(ob):
else: else:
perm_asset[asset] = {'role': perm_asset_group[asset_group].get('role', set()), perm_asset[asset] = {'role': perm_asset_group[asset_group].get('role', set()),
'rule': perm_asset_group[asset_group].get('rule', set())} 'rule': perm_asset_group[asset_group].get('rule', set())}
print perm
return perm return perm

View File

@ -681,7 +681,7 @@ def perm_role_get(request):
asset = get_object(Asset, id=asset_id) asset = get_object(Asset, id=asset_id)
if asset: if asset:
role = user_have_perm(request.user, asset=asset) role = user_have_perm(request.user, asset=asset)
logger.debug('#' + ','.join([i.name for i in role]) + '#') logger.debug(u'获取授权系统用户: ' + ','.join([i.name for i in role]))
return HttpResponse(','.join([i.name for i in role])) return HttpResponse(','.join([i.name for i in role]))
else: else:
roles = get_group_user_perm(request.user).get('role').keys() roles = get_group_user_perm(request.user).get('role').keys()

View File

@ -19,5 +19,5 @@ email_host = smtp.qq.com
email_port = 25 email_port = 25
email_host_user = xxxxxxxx@qq.com email_host_user = xxxxxxxx@qq.com
email_host_password = xxxxxx email_host_password = xxxxxx
email_use_tls = True email_use_tls = False

View File

@ -165,7 +165,7 @@ class PyCrypt(object):
self.mode = AES.MODE_CBC self.mode = AES.MODE_CBC
@staticmethod @staticmethod
def gen_rand_pass(length, especial=False): def gen_rand_pass(length=16, especial=False):
""" """
random password random password
随机生成密码 随机生成密码

View File

@ -33,7 +33,7 @@ except ImportError:
define("port", default=3000, help="run on the given port", type=int) define("port", default=3000, help="run on the given port", type=int)
define("host", default='0.0.0.0', help="run port on", type=str) define("host", default='0.0.0.0', help="run port on given host", type=str)
def require_auth(role='user'): def require_auth(role='user'):
@ -44,29 +44,28 @@ def require_auth(role='user'):
else: else:
session_key = request.get_argument('sessionid', '') session_key = request.get_argument('sessionid', '')
logger.debug('Websocket: session_key: %s' % session_key) logger.debug(u'请求session_key: %s' % session_key)
if session_key: if session_key:
session = get_object(Session, session_key=session_key) session = get_object(Session, session_key=session_key)
logger.debug('Websocket: session: %s' % session)
if session and datetime.datetime.now() < session.expire_date: if session and datetime.datetime.now() < session.expire_date:
user_id = session.get_decoded().get('_auth_user_id') user_id = session.get_decoded().get('_auth_user_id')
user = get_object(User, id=user_id) user = get_object(User, id=user_id)
if user: if user:
logger.debug('Websocket: user [ %s ] request websocket' % user.username) logger.debug(u'用户 [ %s ] 请求websocket' % user.username)
request.user = user request.user = user
if role == 'admin': if role == 'admin':
if user.role in ['SU', 'GA']: if user.role in ['SU', 'GA']:
return func(request, *args, **kwargs) return func(request, *args, **kwargs)
logger.debug('Websocket: user [ %s ] is not admin.' % user.username) logger.debug(u'用户 [ %s ] 不是admin.' % user.username)
else: else:
return func(request, *args, **kwargs) return func(request, *args, **kwargs)
else: else:
logger.debug('Websocket: session expired: %s' % session_key) logger.debug(u'session过期 %s' % session_key)
try: try:
request.close() request.close()
except AttributeError: except AttributeError:
pass pass
logger.warning('Websocket: Request auth failed.') logger.warning('认证失败,非法请求')
return _deco2 return _deco2
return _deco return _deco
@ -96,10 +95,10 @@ def file_monitor(path='.', client=None):
notifier = AsyncNotifier(wm, EventHandler(client)) notifier = AsyncNotifier(wm, EventHandler(client))
wm.add_watch(path, mask, auto_add=True, rec=True) wm.add_watch(path, mask, auto_add=True, rec=True)
if not os.path.isfile(path): if not os.path.isfile(path):
logger.debug("File %s does not exist." % path) logger.debug(u"文件 %s 不存在." % path)
sys.exit(3) sys.exit(3)
else: else:
logger.debug("Now starting monitor file %s." % path) logger.debug(u"开始监控文件 %s." % path)
global f global f
f = open(path, 'r') f = open(path, 'r')
st_size = os.stat(path)[6] st_size = os.stat(path)[6]
@ -149,8 +148,8 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
MonitorHandler.clients.remove(self) MonitorHandler.clients.remove(self)
MonitorHandler.threads.remove(MonitorHandler.threads[client_index]) MonitorHandler.threads.remove(MonitorHandler.threads[client_index])
logger.debug("Websocket: Monitor client num: %s, thread num: %s" % (len(MonitorHandler.clients), logger.debug(u"监控在线数量: %s, 线程数量: %s" % (len(MonitorHandler.clients),
len(MonitorHandler.threads))) len(MonitorHandler.threads)))
def on_message(self, message): def on_message(self, message):
# 监控日志,发生变动发向客户端 # 监控日志,发生变动发向客户端
@ -160,7 +159,7 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
# 客户端主动关闭 # 客户端主动关闭
# self.close() # self.close()
logger.debug("Websocket: Monitor client close request") logger.debug("监控请求关闭")
try: try:
client_index = MonitorHandler.clients.index(self) client_index = MonitorHandler.clients.index(self)
MonitorHandler.clients.remove(self) MonitorHandler.clients.remove(self)
@ -184,10 +183,10 @@ class WebTerminalKillHandler(tornado.web.RequestHandler):
Log.objects.filter(id=ws_id).update(is_finished=True) Log.objects.filter(id=ws_id).update(is_finished=True)
for ws in WebTerminalHandler.clients: for ws in WebTerminalHandler.clients:
if ws.id == int(ws_id): if ws.id == int(ws_id):
logger.debug("Kill log id %s" % ws_id) logger.debug(u"终结logID %s" % ws_id)
ws.log.save() ws.log.save()
ws.close() ws.close()
logger.debug('Websocket: web terminal client num: %s' % len(WebTerminalHandler.clients)) logger.debug(u'WebTerminal在线数量: %s' % len(WebTerminalHandler.clients))
class ExecHandler(tornado.websocket.WebSocketHandler): class ExecHandler(tornado.websocket.WebSocketHandler):
@ -209,7 +208,7 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
@require_auth('user') @require_auth('user')
def open(self): def open(self):
logger.debug('Websocket: Open exec request') logger.debug('web批量命令执行请求')
role_name = self.get_argument('role', 'sb') role_name = self.get_argument('role', 'sb')
self.remote_ip = self.request.remote_ip self.remote_ip = self.request.remote_ip
logger.debug('Web执行命令: 请求系统用户 %s' % role_name) logger.debug('Web执行命令: 请求系统用户 %s' % role_name)
@ -255,7 +254,6 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
for k, v in self.runner.results.items(): for k, v in self.runner.results.items():
for host, output in v.items(): for host, output in v.items():
output = newline_pattern.sub('<br />', output) output = newline_pattern.sub('<br />', output)
logger.debug(output)
if k == 'ok': if k == 'ok':
header = "<span style='color: green'>[ %s => %s]</span>\n" % (host, 'Ok') header = "<span style='color: green'>[ %s => %s]</span>\n" % (host, 'Ok')
else: else:
@ -266,7 +264,7 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
self.write_message('\n~o~ Task finished ~o~\n') self.write_message('\n~o~ Task finished ~o~\n')
def on_close(self): def on_close(self):
logger.debug('关闭web_exec请求') logger.debug('关闭web批量命令请求')
class WebTerminalHandler(tornado.websocket.WebSocketHandler): class WebTerminalHandler(tornado.websocket.WebSocketHandler):
@ -289,30 +287,31 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
@require_auth('user') @require_auth('user')
def open(self): def open(self):
logger.debug('Websocket: Open request') logger.debug('WebTerminal请求')
role_name = self.get_argument('role', 'sb') role_name = self.get_argument('role', 'sb')
asset_id = self.get_argument('id', 9999) asset_id = self.get_argument('id', 9999)
asset = get_object(Asset, id=asset_id) asset = get_object(Asset, id=asset_id)
if asset: if asset:
roles = user_have_perm(self.user, asset) roles = user_have_perm(self.user, asset)
logger.debug(roles) logger.debug('请求系统用户: %s' % role_name)
logger.debug('系统用户: %s' % role_name)
login_role = '' login_role = ''
for role in roles: for role in roles:
if role.name == role_name: if role.name == role_name:
login_role = role login_role = role
break break
if not login_role: if not login_role:
logger.warning('Websocket: Not that Role %s for Host: %s User: %s ' % (role_name, asset.hostname, logger.warning(u'%s 这台主机上没有为用户%s 授权系统用户%s ' % (asset.hostname,
self.user.username)) self.user.username,
role_name))
self.close() self.close()
return return
else: else:
logger.warning('Websocket: No that Host: %s User: %s ' % (asset_id, self.user.username)) logger.warning(u'没有授权该主机 %s' % asset_id)
self.close() self.close()
return return
logger.debug('Websocket: request web terminal Host: %s User: %s Role: %s' % (asset.hostname, self.user.username, logger.debug('web terminal 请求主机: %s 用户: %s 系统用户: %s' % (asset.hostname,
login_role.name)) self.user.username,
login_role.name))
self.term = WebTty(self.user, asset, login_role, login_type='web') self.term = WebTty(self.user, asset, login_role, login_type='web')
self.term.remote_ip = self.request.remote_ip self.term.remote_ip = self.request.remote_ip
self.ssh = self.term.get_connection() self.ssh = self.term.get_connection()
@ -352,7 +351,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
self.channel.send(data['data']) self.channel.send(data['data'])
def on_close(self): def on_close(self):
logger.debug('Websocket: Close request') logger.debug('关闭websocket请求')
if self in WebTerminalHandler.clients: if self in WebTerminalHandler.clients:
WebTerminalHandler.clients.remove(self) WebTerminalHandler.clients.remove(self)
try: try:
@ -425,6 +424,6 @@ if __name__ == '__main__':
server = tornado.httpserver.HTTPServer(app) server = tornado.httpserver.HTTPServer(app)
server.bind(options.port, options.host) server.bind(options.port, options.host)
#server.listen(options.port) #server.listen(options.port)
server.start(num_processes=10) #server.start(num_processes=5)
print "Run server on %s:%s" % (options.host, options.port) print "Run server on %s:%s" % (options.host, options.port)
tornado.ioloop.IOLoop.instance().start() tornado.ioloop.IOLoop.instance().start()

View File

@ -27,7 +27,7 @@ start() {
else else
daemon python $base_dir/manage.py runserver 0.0.0.0:80 &>> /tmp/jumpserver.log 2>&1 & daemon python $base_dir/manage.py runserver 0.0.0.0:80 &>> /tmp/jumpserver.log 2>&1 &
daemon python $base_dir/run_websocket.py &> /dev/null 2>&1 & daemon python $base_dir/run_websocket.py &> /dev/null 2>&1 &
sleep 2 sleep 4
echo -n "$jump_start" echo -n "$jump_start"
nums=0 nums=0
@ -53,23 +53,17 @@ stop() {
echo -n $"Stopping ${PROC_NAME} service:" echo -n $"Stopping ${PROC_NAME} service:"
if [ -e $lockfile ];then ps aux | grep -E 'manage.py|run_websocket.py' | grep -v grep | awk '{print $2}' | xargs kill -9 &> /dev/null
ps aux | grep -E 'manage.py|run_websocket.py' | grep -v grep | awk '{print $2}' | xargs kill -9 &> /dev/null ret=$?
ret=$?
if [ $ret -eq 0 ]; then
if [ $ret -eq 0 ]; then echo_success
echo_success echo
echo rm -f "$lockfile"
rm -f "$lockfile"
else
echo_failure
echo
rm -f "$lockfile"
fi
else else
echo_success echo_failure
echo echo
rm -f "$lockfile"
fi fi
} }