修改变量命名

pull/26/head
ibuler 2015-11-14 22:57:34 +08:00
commit f9c06c22ae
6 changed files with 54 additions and 125 deletions

View File

@ -13,16 +13,19 @@ import textwrap
import getpass import getpass
import readline import readline
import django import django
from multiprocessing import Pool
import paramiko import paramiko
import struct, fcntl, signal, socket, select, fnmatch import struct, fcntl, signal, socket, select
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings' os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
if django.get_version() != '1.6': if django.get_version() != '1.6':
django.setup() django.setup()
from jumpserver.api import ServerError, User, Asset, AssetGroup, get_object from jumpserver.api import ServerError, User, Asset, AssetGroup, get_object
from jumpserver.api import logger, is_dir, Log, TtyLog from jumpserver.api import logger, mkdir, Log, TtyLog
from jumpserver.settings import log_dir from jumpserver.settings import LOG_DIR
login_user = get_object(User, username=getpass.getuser())
try: try:
import termios import termios
@ -32,11 +35,6 @@ except ImportError:
time.sleep(3) time.sleep(3)
sys.exit() sys.exit()
VIM_FLAG = False
VIM_COMMAND = ''
SSH_TTY = ''
login_user = get_object(User, username=getpass.getuser())
def color_print(msg, color='red', exits=False): def color_print(msg, color='red', exits=False):
""" """
@ -53,49 +51,6 @@ def color_print(msg, color='red', exits=False):
sys.exit() sys.exit()
def verify_connect(user, option):
"""
Check user was permed or not . Check ip is unique or not.
鉴定用户是否有该主机权限 匹配到的ip是否唯一
"""
ip_matched = []
try:
assets_info = login_user.get_asset_info()
except ServerError, e:
color_print(e, 'red')
return False
for ip, asset_info in assets_info.items():
if option in asset_info[1:] and option:
ip_matched = [asset_info[1]]
break
for info in asset_info[1:]:
if option in info:
ip_matched.append(ip)
logger.debug('%s matched input %s: %s' % (login_user.username, option, ip_matched))
ip_matched = list(set(ip_matched))
if len(ip_matched) > 1: # 如果匹配ip不唯一
ip_comment = {}
for ip in ip_matched:
ip_comment[ip] = assets_info[ip][2]
for ip in sorted(ip_comment):
if ip_comment[ip]:
print '%-15s -- %s' % (ip, ip_comment[ip])
else:
print '%-15s' % ip
print ''
elif len(ip_matched) < 1: # 如果没匹配到
color_print('没有该主机,或者您没有该主机的权限 No Permission or No host.', 'red')
else: # 恰好是1个
asset = get_object(Asset, ip=ip_matched[0])
jtty = Jtty(user, asset)
jtty.connect()
def check_vim_status(command, ssh): def check_vim_status(command, ssh):
global SSH_TTY global SSH_TTY
print command print command
@ -208,7 +163,6 @@ def deal_command(str_r, ssh):
result_command += pattern_list[0] result_command += pattern_list[0]
pattern_list = pattern_list[1:] pattern_list = pattern_list[1:]
control_char = re.compile(r""" control_char = re.compile(r"""
\x1b[ #%()*+\-.\/]. | \x1b[ #%()*+\-.\/]. |
\r | #匹配 回车符(CR) \r | #匹配 回车符(CR)
@ -237,14 +191,6 @@ def deal_command(str_r, ssh):
return '' return ''
def newline_code_in(strings):
for i in ['\r', '\r\n', '\n']:
if i in strings:
#print "new line"
return True
return False
class Tty(object): class Tty(object):
""" """
A virtual tty class A virtual tty class
@ -256,8 +202,8 @@ class Tty(object):
self.ip = None self.ip = None
self.port = 22 self.port = 22
self.channel = None self.channel = None
self.user = None #self.asset = get_object(Asset, name=asset_name)
self.asset = None #self.user = get_object(User, username=username)
self.role = None self.role = None
self.ssh = None self.ssh = None
self.connect_info = None self.connect_info = None
@ -292,44 +238,45 @@ class Tty(object):
return line_filtered return line_filtered
def get_log_file(self): def get_log(self):
""" """
Logging user command and output. Logging user command and output.
记录用户的日志 记录用户的日志
""" """
tty_log_dir = os.path.join(log_dir, 'tty') tty_log_dir = os.path.join(LOG_DIR, 'tty')
timestamp_start = int(time.time()) date_today = datetime.datetime.now()
date_start = time.strftime('%Y%m%d', time.localtime(timestamp_start)) date_start = date_today.strftime('%Y%m%d')
time_start = time.strftime('%H%M%S', time.localtime(timestamp_start)) time_start = date_today.strftime('%H%M%S')
today_connect_log_dir = os.path.join(tty_log_dir, date_start) today_connect_log_dir = os.path.join(tty_log_dir, date_start)
log_file_path = os.path.join(today_connect_log_dir, '%s_%s_%s' % (self.username, self.asset_name, time_start)) log_file_path = os.path.join(today_connect_log_dir, '%s_%s_%s' % (self.username, self.asset_name, time_start))
try: try:
is_dir(today_connect_log_dir, mode=0777) mkdir(today_connect_log_dir, mode=0777)
except OSError: except OSError:
logger.debug('创建目录 %s 失败,请修改%s目录权限' % (today_connect_log_dir, tty_log_dir))
raise ServerError('Create %s failed, Please modify %s permission.' % (today_connect_log_dir, tty_log_dir)) raise ServerError('Create %s failed, Please modify %s permission.' % (today_connect_log_dir, tty_log_dir))
try: try:
log_file_f = open(log_file_path + '.log', 'a') log_file_f = open(log_file_path + '.log', 'a')
log_time_f = open(log_file_path + '.time', 'a') log_time_f = open(log_file_path + '.time', 'a')
except IOError: except IOError:
logger.debug('创建tty日志文件失败, 请修改目录%s权限' % today_connect_log_dir)
raise ServerError('Create logfile failed, Please modify %s permission.' % today_connect_log_dir) raise ServerError('Create logfile failed, Please modify %s permission.' % today_connect_log_dir)
if self.login_type == 'ssh': if self.login_type == 'ssh': # 如果是ssh连接过来记录connect.py的pidweb terminal记录为日志的id
pid = os.getpid() pid = os.getpid()
remote_ip = os.popen("who -m | awk '{ print $5 }'").read().strip('()\n') remote_ip = os.popen("who -m | awk '{ print $5 }'").read().strip('()\n') # 获取远端IP
log = Log(user=self.username, host=self.asset_name, remote_ip=remote_ip, log = Log(user=self.username, host=self.asset_name, remote_ip=remote_ip,
log_path=log_file_path, start_time=datetime.datetime.now(), pid=pid) log_path=log_file_path, start_time=date_today, pid=pid)
else: else:
remote_ip = 'Web' remote_ip = 'Web'
log = Log(user=self.username, host=self.asset_name, remote_ip=remote_ip, log = Log(user=self.username, host=self.asset_name, remote_ip=remote_ip,
log_path=log_file_path, start_time=datetime.datetime.now(), pid=0) log_path=log_file_path, start_time=date_today, pid=0)
log.save() log.save()
log.pid = log.id log.pid = log.id
log.save()
log_file_f.write('Start at %s\n' % datetime.datetime.now())
log.save() log.save()
log_file_f.write('Start at %s\n' % datetime.datetime.now())
return log_file_f, log_time_f, log return log_file_f, log_time_f, log
def get_connect_info(self): def get_connect_info(self):
@ -413,10 +360,10 @@ class SshTty(Tty):
Use paramiko channel connect server interactive. Use paramiko channel connect server interactive.
使用paramiko模块的channel连接后端进入交互式 使用paramiko模块的channel连接后端进入交互式
""" """
log_file_f, log_time_f, log = self.get_log_file() log_file_f, log_time_f, log = self.get_log()
old_tty = termios.tcgetattr(sys.stdin) old_tty = termios.tcgetattr(sys.stdin)
pre_timestamp = time.time() pre_timestamp = time.time()
input_r = '' data = ''
input_mode = False input_mode = False
try: try:
@ -445,22 +392,20 @@ class SshTty(Tty):
log_time_f.flush() log_time_f.flush()
if input_mode and not self.is_output(x): if input_mode and not self.is_output(x):
input_r += x data += x
except socket.timeout: except socket.timeout:
pass pass
if sys.stdin in r: if sys.stdin in r:
x = os.read(sys.stdin.fileno(), 1) x = os.read(sys.stdin.fileno(), 1)
if not input_mode: input_mode = True
input_mode = True
if str(x) in ['\r', '\n', '\r\n']: if str(x) in ['\r', '\n', '\r\n']:
# input_r = deal_command(input_r,ssh) data = self.remove_control_char(data)
input_r = self.remove_control_char(input_r)
TtyLog(log=log, datetime=datetime.datetime.now(), cmd=input_r).save() TtyLog(log=log, datetime=datetime.datetime.now(), cmd=data).save()
input_r = '' data = ''
input_mode = False input_mode = False
if len(x) == 0: if len(x) == 0:

View File

@ -8,7 +8,7 @@ from django.http import HttpResponseNotFound
from jlog.log_api import renderTemplate from jlog.log_api import renderTemplate
from models import Log from models import Log
from jumpserver.settings import web_socket_host from jumpserver.settings import WEB_SOCKET_HOST
@require_role('admin') @require_role('admin')
@ -48,8 +48,8 @@ def log_list(request, offset):
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request) contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
web_monitor_uri = 'ws://%s/monitor' % web_socket_host web_monitor_uri = 'ws://%s/monitor' % WEB_SOCKET_HOST
web_kill_uri = 'http://%s/kill' % web_socket_host web_kill_uri = 'http://%s/kill' % WEB_SOCKET_HOST
return render_to_response('jlog/log_%s.html' % offset, locals(), context_instance=RequestContext(request)) return render_to_response('jlog/log_%s.html' % offset, locals(), context_instance=RequestContext(request))
@ -108,6 +108,6 @@ def web_terminal(request):
token = request.COOKIES.get('sessionid') token = request.COOKIES.get('sessionid')
username = request.user.username username = request.user.username
asset_name = '127.0.0.1' asset_name = '127.0.0.1'
web_terminal_uri = 'ws://%s/terminal?username=%s&asset_name=%s&token=%s' % (web_socket_host, username, asset_name, token) web_terminal_uri = 'ws://%s/terminal?username=%s&asset_name=%s&token=%s' % (WEB_SOCKET_HOST, username, asset_name, token)
return render_to_response('jlog/web_terminal.html', locals()) return render_to_response('jlog/web_terminal.html', locals())

View File

@ -14,14 +14,6 @@ password = mysql234
database = jumpserver database = jumpserver
[ldap]
ldap_enable = 1
host_url = ldap://127.0.0.1:389
base_dn = dc=jumpserver, dc=org
root_dn = cn=admin,dc=jumpserver,dc=org
root_pw = secret234
[websocket] [websocket]
web_socket_host = 192.168.244.129:3000 web_socket_host = 192.168.244.129:3000

View File

@ -25,7 +25,6 @@ import json
import logging import logging
def set_log(level): def set_log(level):
""" """
return a log file object return a log file object
@ -35,7 +34,7 @@ def set_log(level):
'critical': logging.CRITICAL} 'critical': logging.CRITICAL}
logger_f = logging.getLogger('jumpserver') logger_f = logging.getLogger('jumpserver')
logger_f.setLevel(logging.DEBUG) logger_f.setLevel(logging.DEBUG)
fh = logging.FileHandler(JLOG_FILE) fh = logging.FileHandler(os.path.join(LOG_DIR, 'jumpserver.log'))
fh.setLevel(log_level_total.get(level, logging.DEBUG)) fh.setLevel(log_level_total.get(level, logging.DEBUG))
formatter = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s') formatter = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter) fh.setFormatter(formatter)
@ -86,7 +85,6 @@ def pages(post_objects, request):
return post_objects, paginator, page_objects, page_range, current_page, show_first, show_end return post_objects, paginator, page_objects, page_range, current_page, show_first, show_end
class PyCrypt(object): class PyCrypt(object):
""" """
This class used to encrypt and decrypt password. This class used to encrypt and decrypt password.
@ -98,7 +96,7 @@ class PyCrypt(object):
self.mode = AES.MODE_CBC self.mode = AES.MODE_CBC
@staticmethod @staticmethod
def random_pass(length, especial=False): def gen_rand_pass(length, especial=False):
""" """
random password random password
随机生成密码 随机生成密码
@ -139,7 +137,7 @@ class PyCrypt(object):
对称加密之加密生成密码 对称加密之加密生成密码
""" """
if not passwd: if not passwd:
passwd = self.random_pass() passwd = self.gen_rand_pass()
cryptor = AES.new(self.key, self.mode, b'8122ca7d906ad5e1') cryptor = AES.new(self.key, self.mode, b'8122ca7d906ad5e1')
try: try:
@ -256,6 +254,7 @@ def get_session_user_info(request):
# return [user.id, user.username, user] # return [user.id, user.username, user]
return [request.user.id, request.user.username, request.user] return [request.user.id, request.user.username, request.user]
def get_user_dept(request): def get_user_dept(request):
""" """
get the user dept id get the user dept id
@ -389,7 +388,7 @@ def bash(cmd):
return subprocess.call(cmd, shell=True) return subprocess.call(cmd, shell=True)
def is_dir(dir_name, username='root', mode=0755): def mkdir(dir_name, username='root', mode=0755):
""" """
insure the dir exist and mode ok insure the dir exist and mode ok
目录存在如果不存在就建立并且权限正确 目录存在如果不存在就建立并且权限正确
@ -414,5 +413,5 @@ def my_render(template, data, request):
CRYPTOR = PyCrypt(KEY) CRYPTOR = PyCrypt(KEY)
logger = set_log(log_level) logger = set_log(LOG_LEVEL)

View File

@ -34,18 +34,12 @@ EMAIL_USE_TLS = config.getboolean('mail', 'email_use_tls')
EMAIL_TIMEOUT = 5 EMAIL_TIMEOUT = 5
# ======== Log ========== # ======== Log ==========
LOG = False
LOG_DIR = os.path.join(BASE_DIR, 'logs') LOG_DIR = os.path.join(BASE_DIR, 'logs')
JLOG_FILE = os.path.join(LOG_DIR, 'jumpserver.log')
SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys') SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys')
# SERVER_KEY_DIR = os.path.join(SSH_KEY_DIR, 'server')
KEY = config.get('base', 'key') KEY = config.get('base', 'key')
LOGIN_NAME = getpass.getuser()
# LDAP_ENABLE = CONF.getint('ldap', 'ldap_enable')
URL = config.get('base', 'url') URL = config.get('base', 'url')
log_dir = os.path.join(BASE_DIR, 'logs') LOG_LEVEL = config.get('base', 'log')
log_level = config.get('base', 'log') WEB_SOCKET_HOST = config.get('websocket', 'web_socket_host')
web_socket_host = config.get('websocket', 'web_socket_host')
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/

View File

@ -179,7 +179,7 @@ class WebTty(Tty):
super(WebTty, self).__init__(*args, **kwargs) super(WebTty, self).__init__(*args, **kwargs)
self.login_type = 'web' self.login_type = 'web'
self.ws = None self.ws = None
self.input_r = '' self.data = ''
self.input_mode = False self.input_mode = False
@ -197,12 +197,11 @@ class WebTerminalKillHandler(tornado.web.RequestHandler):
class WebTerminalHandler(tornado.websocket.WebSocketHandler): class WebTerminalHandler(tornado.websocket.WebSocketHandler):
tasks = []
clients = [] clients = []
tasks = []
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.term = None self.term = None
self.channel = None
self.log_file_f = None self.log_file_f = None
self.log_time_f = None self.log_time_f = None
self.log = None self.log = None
@ -220,7 +219,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
print asset_name, username, token print asset_name, username, token
self.term = WebTty('a', 'b') self.term = WebTty('a', 'b')
self.term.get_connection() self.term.get_connection()
self.channel = self.term.ssh.invoke_shell(term='xterm') self.term.channel = self.term.ssh.invoke_shell(term='xterm')
WebTerminalHandler.tasks.append(MyThread(target=self.forward_outbound)) WebTerminalHandler.tasks.append(MyThread(target=self.forward_outbound))
WebTerminalHandler.clients.append(self) WebTerminalHandler.clients.append(self)
@ -237,10 +236,10 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
if data.get('data'): if data.get('data'):
self.term.input_mode = True self.term.input_mode = True
if str(data['data']) in ['\r', '\n', '\r\n']: if str(data['data']) in ['\r', '\n', '\r\n']:
TtyLog(log=self.log, datetime=datetime.datetime.now(), cmd=self.term.remove_control_char(self.term.input_r)).save() TtyLog(log=self.log, datetime=datetime.datetime.now(), cmd=self.term.remove_control_char(self.term.data)).save()
self.term.input_r = '' self.term.data = ''
self.term.input_mode = False self.term.input_mode = False
self.channel.send(data['data']) self.term.channel.send(data['data'])
def on_close(self): def on_close(self):
print 'On_close' print 'On_close'
@ -256,15 +255,15 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
pass pass
def forward_outbound(self): def forward_outbound(self):
self.log_file_f, self.log_time_f, self.log = self.term.get_log_file() self.log_file_f, self.log_time_f, self.log = self.term.get_log()
self.id = self.log.id self.id = self.log.id
try: try:
data = '' data = ''
pre_timestamp = time.time() pre_timestamp = time.time()
while True: while True:
r, w, e = select.select([self.channel, sys.stdin], [], []) r, w, e = select.select([self.term.channel, sys.stdin], [], [])
if self.channel in r: if self.term.channel in r:
recv = self.channel.recv(1024) recv = self.term.channel.recv(1024)
if not len(recv): if not len(recv):
return return
data += recv data += recv
@ -277,7 +276,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
self.log_file_f.flush() self.log_file_f.flush()
self.log_time_f.flush() self.log_time_f.flush()
if self.term.input_mode and not self.term.is_output(data): if self.term.input_mode and not self.term.is_output(data):
self.term.input_r += data self.term.data += data
data = '' data = ''
except UnicodeDecodeError: except UnicodeDecodeError:
pass pass